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();
1225 QStringList header = line.split(
" ",QString::SkipEmptyParts);
1226 if ( header.size() != 5 ) {
1230 QString version = header[4];
1232 header.removeLast();
1234 QString magic = header.join(
" ");
1236 if ( magic !=
"# vtk DataFile Version" ) {
1242 QString fileTypeStr = in.readLine();
1244 fileTypeStr = fileTypeStr.simplified();
1246 if ( fileTypeStr.toLower() ==
"binary" ) {
1248 }
else if ( fileTypeStr.toLower() ==
"ascii" ) {
1256 while ( line.simplified() ==
"" )
1257 line = in.readLine();
1259 QStringList datasetList = line.split(
" ",QString::SkipEmptyParts);
1261 if ( datasetList.size() != 2 ) {
1267 datasetList[1] = datasetList[1].simplified();
1269 if ( datasetList[1] ==
"STRUCTURED_POINTS" )
1270 dataset = STRUCTURED_POINTS;
1271 else if ( datasetList[1] ==
"STRUCTURED_GRID" )
1272 dataset = STRUCTURED_GRID;
1273 else if ( datasetList[1] ==
"RECTILINEAR_GRID" )
1274 dataset = RECTILINEAR_GRID;
1275 else if ( datasetList[1] ==
"POLYDATA" )
1277 else if ( datasetList[1] ==
"UNSTRUCTURED_GRID" )
1278 dataset = UNSTRUCTURED_GRID;
1284 if ((dataset == STRUCTURED_POINTS) || (dataset == STRUCTURED_GRID) || (dataset == RECTILINEAR_GRID) )
1289 else if (dataset == POLYDATA)
1296 line = in.readLine();
1299 while ( !line.contains(
"POLYGONS") ) {
1307 line = in.readLine();
1310 QStringList polygonsLine = line.split(
" ",QString::SkipEmptyParts);
1313 if ( polygonsLine.size() != 3 ) {
1314 emit log(
LOGERR,tr(
"Expected to get Points line with exactly 3 entries, but %1 found!").arg(polygonsLine.size()));
1321 quint32 polygoncount = polygonsLine[1].toUInt(&ok);
1324 emit log(
LOGERR,tr(
"Expected to get number of points and entries, but read %1 !").arg(polygonsLine.join(
" ")));
1329 while ( read < polygoncount) {
1336 in.device()->read((
char*)&valence,
sizeof(quint32));
1341 return BMT_PolyMesh;
1347 for (
unsigned int i = 0 ; i < valence; ++i ) {
1353 in.device()->read((
char*)&valence,
sizeof(quint32));
1369 line = in.readLine();
1372 while ( !line.contains(
"CELL_TYPES") ) {
1380 line = in.readLine();
1384 QStringList cellLine = line.split(
" ",QString::SkipEmptyParts);
1387 if ( cellLine.size() != 2 ) {
1388 emit log(
LOGERR,tr(
"Expected to get CELL_TYPES line with exactly 2 entries, but %1 found!").arg(cellLine.size()));
1395 quint32 cellCountTypes = cellLine[1].toUInt(&ok);
1398 emit log(
LOGERR,tr(
"Expected to get number of cell types, but read %1 !").arg(cellLine[1]));
1402 bool triMeshPossible =
true;
1403 bool polyMeshPossible =
true;
1405 #ifndef ENABLE_HEXAHEDRALMESH_SUPPORT 1406 bool hexahedralMeshPossible =
false;
1408 bool hexahedralMeshPossible =
true;
1410 #ifndef ENABLE_POLYHEDRALMESH_SUPPORT 1411 bool polyhedralMeshPossible =
false;
1413 bool polyhedralMeshPossible =
true;
1415 #ifndef ENABLE_TETRAHEDRALMESH_SUPPORT 1416 bool tetrahedralMeshPossible =
false;
1418 bool tetrahedralMeshPossible =
true;
1422 while ( read < cellCountTypes) {
1429 in.device()->read((
char*)&type,
sizeof(quint32));
1432 if (( 1 <= type ) && (type <= 6 ))
1436 hexahedralMeshPossible =
false;
1437 tetrahedralMeshPossible =
false;
1439 else if (( 7 <= type ) && (type <= 9 ))
1444 triMeshPossible =
false;
1445 hexahedralMeshPossible =
false;
1446 tetrahedralMeshPossible =
false;
1449 else if ( 10 == type )
1452 triMeshPossible =
false;
1453 polyMeshPossible =
false;
1454 hexahedralMeshPossible =
false;
1456 else if (( 13 == type ) || (type == 14 ))
1460 triMeshPossible =
false;
1461 polyMeshPossible =
false;
1462 hexahedralMeshPossible =
false;
1463 tetrahedralMeshPossible =
false;
1466 else if (( 11 == type ) || ( 12 == type ))
1470 triMeshPossible =
false;
1471 polyMeshPossible =
false;
1475 if ( in.status() != QTextStream::Ok ) {
1476 emit log(
LOGERR,tr(
"Read corrupted cell type data!"));
1482 if (triMeshPossible)
1484 else if (polyMeshPossible)
1485 return BMT_PolyMesh;
1486 else if (hexahedralMeshPossible)
1487 return BMT_HexahedralMesh;
1488 else if (tetrahedralMeshPossible)
1489 return BMT_TetrahedralMesh;
1490 else if (polyhedralMeshPossible)
1491 return BMT_PolyhedralMesh;
1502 std::cerr <<
"Loading vtk file" << std::endl;
1506 QFile file(_filename);
1508 if ( !file.open(QIODevice::ReadOnly) ) {
1509 emit log(
LOGERR,
"Unable to open vtk file!");
1513 QTextStream in(&file);
1515 std::cerr <<
"File is open!" << std::endl;
1517 QString line = in.readLine();
1519 std::cerr <<
"Got line: " << std::endl;
1520 std::cerr << line.toStdString() << std::endl;
1522 QStringList header = line.split(
" ",QString::SkipEmptyParts);
1524 if ( header.size() != 5 ) {
1525 emit log(
LOGERR,tr(
"Bad VTK header? ") + line);
1529 QString version = header[4];
1531 header.removeLast();
1533 QString magic = header.join(
" ");
1535 if ( magic !=
"# vtk DataFile Version" ) {
1536 emit log(
LOGERR,tr(
"Bad VTK header magic? ") + magic);
1542 QString fileTypeStr = in.readLine();
1544 fileTypeStr = fileTypeStr.simplified();
1546 if ( fileTypeStr.toLower() ==
"binary" ) {
1548 emit log(
LOGINFO,tr(
"Loading VTK binary file of version %1.").arg(version));
1549 emit log(
LOGERR,tr(
"Not yet implemented!"));
1550 }
else if ( fileTypeStr.toLower() ==
"ascii" ) {
1552 emit log(
LOGINFO,tr(
"Loading VTK ascii file of version %1.").arg(version));
1554 emit log(
LOGERR,tr(
"Bad VTK type? ") + fileTypeStr);
1558 emit log(
LOGINFO,description);
1562 while ( line.simplified() ==
"" )
1563 line = in.readLine();
1565 QStringList datasetList = line.split(
" ",QString::SkipEmptyParts);
1567 if ( datasetList.size() != 2 ) {
1568 emit log(
LOGERR,tr(
"Bad dataset specification!"));
1574 datasetList[1] = datasetList[1].simplified();
1576 if ( datasetList[1] ==
"STRUCTURED_POINTS" )
1577 dataset = STRUCTURED_POINTS;
1578 else if ( datasetList[1] ==
"STRUCTURED_GRID" )
1579 dataset = STRUCTURED_GRID;
1580 else if ( datasetList[1] ==
"RECTILINEAR_GRID" )
1581 dataset = RECTILINEAR_GRID;
1582 else if ( datasetList[1] ==
"POLYDATA" )
1584 else if ( datasetList[1] ==
"UNSTRUCTURED_GRID" )
1585 dataset = UNSTRUCTURED_GRID;
1587 emit log(
LOGERR,tr(
"Unknown dataset specification! %1").arg(datasetList[1]));
1592 bool is_OpenVolumeMesh =
false;
1594 if ( (forceTriangleMesh_) || (bestType == BMT_TriMesh) ){
1608 if ( !loadMesh(in,_mesh,dataset) ) {
1609 emit log(
LOGERR,
"Unable to load mesh!");
1613 emit log(
LOGERR,
"Unable to add empty triangle mesh!");
1623 else if ((bestType == BMT_PolyMesh) || (bestType == BMT_None))
1638 if ( !loadMesh(in,_mesh,dataset) ) {
1639 emit log(
LOGERR,
"Unable to load mesh!");
1643 emit log(
LOGERR,
"Unable to add empty poly mesh!");
1653 #ifdef ENABLE_POLYHEDRALMESH_SUPPORT 1654 else if (bestType == BMT_PolyhedralMesh)
1657 is_OpenVolumeMesh =
true;
1669 if ( !loadMesh(in,_mesh,dataset) ) {
1670 emit log(
LOGERR,
"Unable to load mesh!");
1674 emit log(
LOGERR,
"Unable to add empty polyhedral mesh!");
1682 #endif //ENABLE_POLYHEDRALMESH_SUPPORT 1683 #ifdef ENABLE_HEXAHEDRALMESH_SUPPORT 1684 else if (bestType == BMT_HexahedralMesh)
1687 is_OpenVolumeMesh =
true;
1699 if ( !loadMesh(in,_mesh,dataset) ) {
1700 emit log(
LOGERR,
"Unable to load mesh!");
1704 emit log(
LOGERR,
"Unable to add empty hexahedral mesh!");
1711 #endif //ENABLE_HEXAHEDRALMESH_SUPPORT 1712 #ifdef ENABLE_TETRAHEDRALMESH_SUPPORT 1713 else if (bestType == BMT_TetrahedralMesh)
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 tetrahedral mesh!");
1740 #endif //ENABLE_TETRAHEDRALMESH_SUPPORT 1747 if (is_OpenVolumeMesh)
1756 emit openedFile( baseObj->
id() );
1758 return baseObj->
id();
1761 emit log(
LOGERR,tr(
"Error in load mesh!"));
1768 template <
typename MeshT>
1771 std::cerr <<
"loadMeshPoints" << std::endl;
1776 QStringList pointsLine = _spec.split(
" ",QString::SkipEmptyParts);
1779 if ( pointsLine.size() != 3 ) {
1780 emit log(
LOGERR,tr(
"Expected to get Points line with exactly 3 entries, but %1 found!").arg(pointsLine.size()));
1785 quint32 points = pointsLine[1].toUInt(&ok);
1788 emit log(
LOGERR,tr(
"Expected to get number of points, but read %1 !").arg(pointsLine[1]));
1796 while ( read < points ) {
1802 if ( pointsLine[2] ==
"float" ) {
1805 _in.device()->read((
char*)&vecf[0],
sizeof(
float));
1806 _in.device()->read((
char*)&vecf[1],
sizeof(
float));
1807 _in.device()->read((
char*)&vecf[2],
sizeof(
float));
1812 emit log(
LOGERR,tr(
"Not implemented data type %1 !").arg(pointsLine[2]));
1818 _in >> vec[0] >> vec[1] >> vec[2];
1825 if ( _in.status() == QTextStream::Ok ) {
1826 _mesh->add_vertex(vec);
1828 emit log(
LOGERR,tr(
"Read corrupted point data!"));
1835 if ( pointsLine[2] ==
"float" ) {
1838 _in.seek(_in.pos() + read * 3 *
sizeof(float) /
sizeof(
char) );
1846 template <
typename MeshT>
1848 std::cerr <<
"loadMeshLines" << std::endl;
1853 QStringList linesLine = _spec.split(
" ",QString::SkipEmptyParts);
1856 if ( linesLine.size() != 3 ) {
1857 emit log(
LOGERR,tr(
"Expected to get LINES line with exactly 3 entries, but %1 found!").arg(linesLine.size()));
1862 quint32 linecount = linesLine[1].toUInt(&ok);
1865 quint32 entrycount = linesLine[2].toUInt(&ok);
1868 emit log(
LOGERR,tr(
"Expected to get number of lines and entries, but read %1 !").arg(linesLine.join(
" ")));
1874 while ( read < linecount) {
1882 _in.device()->read((
char*)&valence,
sizeof(quint32));
1887 if ( _in.status() == QTextStream::Ok ) {
1890 for (
unsigned int i = 0 ; i < valence; ++i )
1893 for (
unsigned int i = 0 ; i < valence; ++i )
1894 _in.device()->read((
char*)&valence,
sizeof(quint32));
1897 if ( _in.status() == QTextStream::Ok ) {
1902 emit log(
LOGERR,tr(
"Read corrupted face data!"));
1907 emit log(
LOGERR,tr(
"Read corrupted POLYGONS data!"));
1917 _in.seek(_in.pos() + entrycount *
sizeof(quint32) /
sizeof(
char) );
1920 emit log(
LOGWARN,tr(
"Lines not supported yet ... skipped!"));
1925 template <
typename MeshT>
1927 std::cerr <<
"loadMeshPolygons" << std::endl;
1932 QStringList polygonsLine = _spec.split(
" ",QString::SkipEmptyParts);
1935 if ( polygonsLine.size() != 3 ) {
1936 emit log(
LOGERR,tr(
"Expected to get Points line with exactly 3 entries, but %1 found!").arg(polygonsLine.size()));
1941 quint32 polygoncount = polygonsLine[1].toUInt(&ok);
1944 quint32 entrycount = polygonsLine[2].toUInt(&ok);
1947 emit log(
LOGERR,tr(
"Expected to get number of points and entries, but read %1 !").arg(polygonsLine.join(
" ")));
1952 bool errorEnabled = omerr().is_enabled();
1956 while ( read < polygoncount) {
1963 _in.device()->read((
char*)&valence,
sizeof(quint32));
1967 std::vector< quint32 > indices;
1969 for (
unsigned int i = 0 ; i < valence; ++i ) {
1975 _in.device()->read((
char*)&valence,
sizeof(quint32));
1978 indices.push_back( index );
1981 if ( _in.status() == QTextStream::Ok ) {
1984 remove_duplicated_vertices(indices);
1986 if (indices.size() >= 3)
1990 cell.indices = indices;
1991 cell.index =
addFace(_mesh, indices);
1992 _cells.push_back(cell);
1995 emit log(
LOGERR,tr(
"Read corrupted face data!"));
2013 _in.seek(_in.pos() + entrycount *
sizeof(qint32) /
sizeof(
char) );
2019 template <
typename MeshT>
2024 if (_vhandles.empty())
return -1;
2027 if (! _mesh->get_property_handle(originalVertexIdx,
"FileVTKPlugin_originalVertexIdx")) {
2028 _mesh->add_property( originalVertexIdx,
"FileVTKPlugin_originalVertexIdx" );
2031 typename MeshT::VertexIter vit = _mesh->vertices_begin();
2032 typename MeshT::VertexIter vend = _mesh->vertices_end();
2033 for(; vit != vend; ++vit) {
2039 for (
unsigned int j = 0; j < _vhandles.size(); ++j)
2041 typename MeshT::Point p = _mesh->point(_vhandles[j]);
2043 _vhandles[j] = _mesh->add_vertex(p);
2048 if (_mesh->has_vertex_status()) {
2049 _mesh->status(_vhandles[j]).set_fixed_nonmanifold(
true);
2052 _mesh->property (originalVertexIdx, _vhandles[j]) = original_handle;
2059 if (_mesh->has_face_status())
2060 _mesh->status(fh).set_fixed_nonmanifold(
true);
2063 if (_mesh->has_edge_status()) {
2064 typename MeshT::FaceEdgeIter fe_it = _mesh->fe_iter(fh);
2065 for (; fe_it.is_valid(); ++fe_it) {
2066 _mesh->status(*fe_it).set_fixed_nonmanifold(
true);
2074 template <
typename MeshT>
2076 std::cerr <<
"loadMeshTriangleStrips" << std::endl;
2081 QStringList triStripsLine = _spec.split(
" ",QString::SkipEmptyParts);
2084 if ( triStripsLine.size() != 3 ) {
2085 emit log(
LOGERR,tr(
"Expected to get TRIANGLE_STRIPS line with exactly 3 entries, but %1 found!").arg(triStripsLine.size()));
2090 quint32 stripcount = triStripsLine[1].toUInt(&ok);
2093 quint32 entrycount = triStripsLine[2].toUInt(&ok);
2096 emit log(
LOGERR,tr(
"Expected to get number of strips and entries, but read %1 !").arg(triStripsLine.join(
" ")));
2101 while ( read < stripcount) {
2108 _in.device()->read((
char*)&valence,
sizeof(quint32));
2112 QList< quint32 > indices;
2115 for (
unsigned int i = 0 ; i < 2; ++i ) {
2121 _in.device()->read((
char*)&valence,
sizeof(quint32));
2124 indices.push_back( index );
2128 for (
unsigned int i = 2 ; i < valence; ++i ) {
2134 _in.device()->read((
char*)&valence,
sizeof(quint32));
2137 indices.push_back( index );
2139 if ( _in.status() == QTextStream::Ok ) {
2143 cell.indices.resize(3);
2144 cell.indices[0] = indices[i];
2145 cell.indices[1] = indices[i-1];
2146 cell.indices[2] = indices[i-2];
2148 std::swap(cell.indices[1],cell.indices[2]);
2149 cell.index =
addFace(_mesh, cell.indices);
2150 _cells.push_back(cell);
2152 emit log(
LOGERR,tr(
"Read corrupted face data!"));
2166 _in.seek(_in.pos() + entrycount *
sizeof(qint32) /
sizeof(
char) );
2172 template <
typename MeshT>
2174 std::cerr <<
"loadMeshNormals" << std::endl;
2177 QStringList normalsLine = _spec.split(
" ",QString::SkipEmptyParts);
2180 if ( normalsLine.size() != 3 ) {
2181 emit log(
LOGERR,tr(
"Expected to get NORMALS line with exactly 3 entries, but %1 found!").arg(normalsLine.size()));
2189 while ( read < _count) {
2194 if ( normalsLine[2] ==
"float" ) {
2198 _in.device()->read((
char*)&vecf[0],
sizeof(
float));
2199 _in.device()->read((
char*)&vecf[1],
sizeof(
float));
2200 _in.device()->read((
char*)&vecf[2],
sizeof(
float));
2205 emit log(
LOGERR,tr(
"Not implemented data type %1 !").arg(normalsLine[2]));
2211 _in >> normal[0] >> normal[1] >> normal[2];
2215 if ( _in.status() == QTextStream::Ok ) {
2217 if ( _pointNormal ) {
2225 emit log(
LOGERR,tr(
"Read corrupted point data!"));
2234 if ( normalsLine[2] ==
"float" ) {
2237 _in.seek(_in.pos() + read * 3 *
sizeof(float) /
sizeof(
char) );
2247 template <
typename MeshT>
2250 std::cerr <<
"loadMeshCells" << std::endl;
2253 QStringList cellLine = _spec.split(
" ",QString::SkipEmptyParts);
2256 if ( cellLine.size() != 3 ) {
2257 emit log(
LOGERR,tr(
"Expected to get CELLS line with exactly 3 entries, but %1 found!").arg(cellLine.size()));
2264 quint32 cellCount = cellLine[1].toUInt(&ok);
2267 quint32 entryCount = cellLine[2].toUInt(&ok);
2271 emit log(
LOGERR,tr(
"Expected to get number of cells and entries, but read %1 !").arg(cellLine.join(
" ")));
2276 while ( read < cellCount) {
2285 _in.device()->read((
char*)&valence,
sizeof(quint32));
2290 for (
unsigned int i = 0 ; i < valence; ++i ) {
2296 _in.device()->read((
char*)&valence,
sizeof(quint32));
2299 currentCell.indices.push_back( index );
2302 if ( _in.status() == QTextStream::Ok ) {
2303 _cells.push_back(currentCell);
2305 emit log(
LOGERR,tr(
"Read corrupted face data!"));
2315 _in.seek(_in.pos() + entryCount *
sizeof(quint32) /
sizeof(
char) );
2327 while ( _spec.simplified().size() == 0 ) {
2330 if ( _in.atEnd() ) {
2331 emit log(
LOGERR,tr(
"File end when reading cell specification!"));
2335 _spec = _in.readLine();
2338 if ( ! _spec.contains(
"CELL_TYPES") ) {
2339 emit log(
LOGERR,tr(
"Wrong token! Expected CELL_TYPES but got : %1").arg(_spec));
2344 cellLine = _spec.split(
" ",QString::SkipEmptyParts);
2347 if ( cellLine.size() != 2 ) {
2348 emit log(
LOGERR,tr(
"Expected to get CELL_TYPES line with exactly 2 entries, but %1 found!").arg(cellLine.size()));
2353 quint32 cellCountTypes = cellLine[1].toUInt(&ok);
2356 emit log(
LOGERR,tr(
"Expected to get number of cell types, but read %1 !").arg(cellLine[1]));
2360 if (cellCountTypes != cellCount ) {
2361 emit log(
LOGERR,tr(
"cellCountTypes != cellCount !").arg(cellLine.size()));
2366 while ( read < cellCount) {
2373 _in.device()->read((
char*)&type,
sizeof(quint32));
2377 _cells[read].type = type;
2379 if ( _in.status() != QTextStream::Ok ) {
2380 emit log(
LOGERR,tr(
"Read corrupted cell type data!"));
2389 _in.seek(_in.pos() + read *
sizeof(quint32) /
sizeof(
char) );
2397 for (
unsigned int i = 0 ; i < _cells.size() ; ++i ) {
2398 if ( _cells[i].type == 1 ) {
2403 }
else if ( _cells[i].type == 2 ) {
2408 }
else if ( _cells[i].type == 3 ) {
2411 emit log(
LOGWARN,tr(
"Unsupported Cell Type LINE") );
2413 }
else if ( _cells[i].type == 4 ) {
2416 emit log(
LOGWARN,tr(
"Unsupported Cell Type POLY_LINE") );
2418 }
else if ( _cells[i].type == 5 ) {
2420 _cells[i].index =
addFace(_mesh, _cells[i].indices);
2421 }
else if ( _cells[i].type == 6 ) {
2424 for (
unsigned int j = 2 ; j < _cells[i].indices.size() ; ++j) {
2426 _cells[i].index =
addFace(_mesh, _cells[i].indices[j-2],_cells[i].indices[j],_cells[i].indices[j-1]);
2428 _cells[i].index =
addFace(_mesh, _cells[i].indices[j-2],_cells[i].indices[j-1],_cells[i].indices[j]);
2433 }
else if ( _cells[i].type == 7 ) {
2436 _cells[i].index =
addFace(_mesh, _cells[i].indices);
2438 }
else if ( _cells[i].type == 8 ) {
2441 emit log(
LOGWARN,tr(
"Unsupported Cell Type PIXEL") );
2443 }
else if ( _cells[i].type == 9 ) {
2446 _cells[i].index =
addFace(_mesh, _cells[i].indices);
2448 }
else if ( _cells[i].type == 10 ) {
2450 _cells[i].index =
addTetraCell(_mesh, _cells[i].indices);
2452 }
else if ( _cells[i].type == 11 ) {
2455 emit log(
LOGWARN,tr(
"Unsupported Cell Type VOXEL") );
2457 }
else if ( _cells[i].type == 12 ) {
2460 _cells[i].index =
addHexaCell(_mesh, _cells[i].indices);
2461 }
else if ( _cells[i].type == 13 ) {
2464 _cells[i].index =
addWedgeCell(_mesh, _cells[i].indices);
2465 }
else if ( _cells[i].type == 14 ) {
2471 emit log(
LOGERR,tr(
"Unknown cell type").arg(_cells[i].type) );
2475 std::cerr <<
"Read " << read <<
" Cells " << std::endl;
2476 std::cerr <<
"Vector has size: " << _cells.size() << std::endl;
2482 template <
typename MeshT>
2483 bool FileVTKPlugin::loadMesh(QTextStream& _in,MeshT*& _mesh, Dataset _type){
2486 if ( _type != POLYDATA && _type != UNSTRUCTURED_GRID ) {
2487 emit log(
LOGERR,
"Unsupported DATASET" );
2496 bool pointNormalsRead =
false;
2497 bool faceNormalsRead =
false;
2500 bool pointData =
false;
2503 quint32 pointDataSize = 0;
2506 bool cellData =
false;
2509 quint32 cellDataSize = 0;
2511 std::vector<CellType> cells;
2515 line = _in.readLine();
2518 while ( line.simplified().size() == 0 ) {
2521 if ( _in.atEnd() ) {
2523 std::cerr <<
"atEnd" << std::endl;
2527 line = _in.readLine();
2534 std::cerr <<
"Line is: " << line.toStdString() << std::endl;
2537 if ( line.contains(
"POINTS") ) {
2540 }
else if ( line.contains(
"POINT_DATA") ) {
2545 QStringList pointDataLine = line.split(
" ",QString::SkipEmptyParts);
2548 if ( pointDataLine.size() != 2 ) {
2549 emit log(
LOGERR,tr(
"Expected to get POINT_DATA line with exactly 2 entries, but %1 found!").arg(line.size()));
2554 pointDataSize = pointDataLine[1].toUInt(&ok);
2559 std::cerr <<
"Point data mode with " << pointDataSize <<
"Elements" << std::endl;
2561 }
else if ( line.contains(
"CELL_DATA") ) {
2566 QStringList cellDataLine = line.split(
" ",QString::SkipEmptyParts);
2569 if ( cellDataLine.size() != 2 ) {
2570 emit log(
LOGERR,tr(
"Expected to get CELL_DATA line with exactly 2 entries, but %1 found!").arg(line.size()));
2575 cellDataSize = cellDataLine[1].toUInt(&ok);
2580 std::cerr <<
"Cell data mode with " << cellDataSize <<
"Elements" << std::endl;
2582 }
else if ( line.contains(
"VERTICES") ) {
2583 std::cerr <<
"Vertices will be skipped as they are already added!" << std::endl;
2584 }
else if ( line.contains(
"LINES") ) {
2586 }
else if ( line.contains(
"POLYGONS") ) {
2588 }
else if ( line.contains(
"TRIANGLE_STRIPS") ) {
2590 }
else if ( line.contains(
"CELL") ) {
2592 }
else if ( line.contains(
"NORMALS") ) {
2596 pointNormalsRead =
true;
2597 }
else if (cellData) {
2599 faceNormalsRead =
true;
2601 emit log(
LOGERR,tr(
"Got normals keyword but we are neither in pointdata nor celldata mode") );
2606 std::cerr <<
"Unrecognized keyword : " << line.toStdString() << std::endl;
2611 if ( !faceNormalsRead )
2614 if ( !pointNormalsRead )
2628 forceTriangleMesh_ =
true;
2630 forcePolyMesh_ =
true;
2637 bool FileVTKPlugin::saveObject(
int _id, QString _filename) {
2641 emit log(
LOGERR, tr(
"saveObject : cannot get object id %1 for save name %2").arg(_id).arg(_filename) );
2645 std::string filename = std::string( _filename.toUtf8() );
2647 std::fstream ofs( filename.c_str(), std::ios_base::out );
2651 emit log(
LOGERR, tr(
"saveObject : Cannot not open file %1 for writing!").arg(_filename) );
2660 object->setFromFileName(_filename);
2661 object->setName(object->
filename());
2666 emit log(
LOGINFO, tr(
"Saved object to ") + _filename );
2670 emit log(
LOGERR, tr(
"Unable to save ") + _filename);
2676 object->setFromFileName(_filename);
2677 object->setName(object->
filename());
2682 emit log(
LOGINFO, tr(
"Saved object to ") + _filename );
2686 emit log(
LOGERR, tr(
"Unable to save ") + _filename);
2691 #ifdef ENABLE_POLYHEDRALMESH_SUPPORT 2695 object->setFromFileName(_filename);
2696 object->setName(object->
filename());
2701 emit log(
LOGINFO, tr(
"Saved object to ") + _filename );
2705 emit log(
LOGERR, tr(
"Unable to save ") + _filename);
2711 #ifdef ENABLE_HEXAHEDRALMESH_SUPPORT 2715 object->setFromFileName(_filename);
2716 object->setName(object->
filename());
2721 emit log(
LOGINFO, tr(
"Saved object to ") + _filename );
2725 emit log(
LOGERR, tr(
"Unable to save ") + _filename);
2731 #ifdef ENABLE_TETRAHEDRALMESH_SUPPORT 2735 object->setFromFileName(_filename);
2736 object->setName(object->
filename());
2741 emit log(
LOGINFO, tr(
"Saved object to ") + _filename );
2745 emit log(
LOGERR, tr(
"Unable to save ") + _filename);
2753 emit log(
LOGERR, tr(
"Unable to save (object is not a compatible mesh type)"));
2762 template<
class MeshT >
2769 _out <<
"# vtk DataFile Version 2.0\n";
2771 _out <<
"Mesh saved from OpenFlipper - www.openflipper.org\n";
2791 if( OpenFlipper::Options::nogui() )
2796 if(saveBinary_->isChecked()) userWriteOptions_ |= BINARY;
2797 else {
if(userWriteOptions_ & BINARY) userWriteOptions_ -= BINARY; }
2799 if(saveFaceNormals_) {
2800 if(saveFaceNormals_->isChecked()) userWriteOptions_ |= FACENORMALS;
2801 else {
if(userWriteOptions_ & FACENORMALS) userWriteOptions_ -= FACENORMALS; }
2803 if(saveVertexNormals_) {
2804 if(saveVertexNormals_->isChecked()) userWriteOptions_ |= VERTEXNORMALS;
2805 else {
if(userWriteOptions_ & VERTEXNORMALS) userWriteOptions_ -= VERTEXNORMALS; }
2807 if(saveVertexTexCoords_) {
2808 if(saveVertexTexCoords_->isChecked()) userWriteOptions_ |= VERTEXTEXCOORDS;
2809 else {
if(userWriteOptions_ & VERTEXTEXCOORDS) userWriteOptions_ -= VERTEXTEXCOORDS; }
DLLEXPORT OpenFlipperQSettings & OpenFlipperSettings()
QSettings object containing all program settings of OpenFlipper.
bool loadMeshLines(QString _spec, QTextStream &_in, MeshT *&_mesh)
Reads lines from the stream and adds them to the mesh.
int addFaceToOpenMesh(MeshT *&_mesh, std::vector< quint32 > _indices)
Adds a face to the mesh.
const UpdateType UPDATE_ALL(UpdateTypeSet(1))
Identifier for all updates.
void addFaceNormal(TriMesh *&_mesh, quint32 _index, OpenMesh::Vec3d _normal)
Adds a face normal.
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.
Handle for a vertex entity.
void setNormalsOfDuplicatedVertices(TriMesh *&_mesh)
Sets normals of duplicated vertices that were created for non-manifold meshes.
DataType supportedType()
Return your supported object type( e.g. DATA_TRIANGLE_MESH )
void removeTemporaryProperties(TriMesh *&_mesh)
Removed temporary properties that might have been added during file reading.
bool loadMeshPoints(QString _spec, QTextStream &_in, MeshT *&_mesh)
Reads points from the stream and adds them to the mesh.
int addTetraCellToOpenMesh(MeshT _mesh, std::vector< quint32 > _indices)
Adds a tetra cell to the mesh. (Does nothing, yet)
bool binary_
Reading binary file?
bool loadMeshPolygons(QString _spec, QTextStream &_in, MeshT *&_mesh, std::vector< CellType > &_cells)
Reads polygons from the stream and adds them to the mesh.
QWidget * saveOptionsWidget(QString)
int addFace(TriMesh *&_mesh, const std::vector< quint32 > &_indices)
Adds a face to the mesh.
void updateVertexNormalsOfOpenMesh(MeshT *&_mesh)
Updates vertex normals.
const DrawMode & getDrawMode(const std::string &_name)
Get a custom DrawMode.
bool writeMesh(std::ostream &_out, MeshT &_mesh)
Writes the header of the VTK file, then calls writeASCIIData (binary VTK is currently unsupported) ...
void setFromFileName(const QString &_filename)
void setValue(const QString &key, const QVariant &value)
Wrapper function which makes it possible to enable Debugging output with -DOPENFLIPPER_SETTINGS_DEBUG...
void addVertexNormalToOpenMesh(MeshT _mesh, quint32 _index, OpenMesh::Vec3d _normal)
Adds a vertex normal.
bool dataType(DataType _type) const
MeshT * mesh()
return a pointer to the mesh
int addHexaCell(TriMesh *&_mesh, const std::vector< quint32 > &_indices)
Adds a hexa cell to the mesh. (Does nothing, yet)
bool writeASCIIDataOfOpenMesh(std::ostream &_out, MeshT &_mesh)
Writes the data of the VTK file in ASCII format.
void updateVertexNormals(TriMesh *&_mesh)
Updates vertex normals.
int addWedgeCell(TriMesh *&_mesh, const std::vector< quint32 > &_indices)
Adds a wedge cell to the mesh. (Does nothing, yet)
BestMeshType findBestObjectType(QString _filename)
Reads the file to check for present primitives and returns the object type that fits best...
#define DATA_TETRAHEDRAL_MESH
void addVertexNormal(TriMesh *&_mesh, quint32 _index, OpenMesh::Vec3d _normal)
Adds a vertex normal.
bool getMesh(int _identifier, PolyMesh *&_mesh)
Get the Poly Mesh which has the given identifier.
virtual void setName(QString _name)
path to the file from which the object is loaded ( defaults to "." )
bool getObject(const int _identifier, BaseObject *&_object)
Get the object which has the given identifier.
Type for a MeshObject containing a triangle mesh.
PolyhedralMesh * polyhedralMesh(BaseObjectData *_object)
Get an PolyhedralMesh from an object.
int loadObject(QString _filename)
Loads Object and converts it to a triangle mesh if possible.
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.
int addHexaCellToOpenMesh(MeshT _mesh, std::vector< quint32 > _indices)
Adds a hexa cell to the mesh. (Does nothing, yet)
void addCellNormal(MeshT *&_mesh, const CellType &_cell, OpenMesh::Vec3d _normal)
Adds a normal to the cell.
QString filename() const
return the filename of the object
Handle for a face entity.
int add_non_manifold_face(MeshT *&_mesh, std::vector< OpenMesh::VertexHandle > &_vhandles)
Helper function for loadMeshPolygons() that takes care of adding non-manifold faces.
QWidget * loadOptionsWidget(QString)
void updateFaceNormals(TriMesh *&_mesh)
Updates face normals.
Add 2D texture coordinates (vertices, halfedges)
#define DATA_HEXAHEDRAL_MESH
void removeTemporaryPropertiesOfOpenMesh(MeshT *&_mesh)
Removed temporary properties that might have been added during file reading.
const DataType DATA_GROUP(1)
Items used for Grouping.
int addPyramidCell(TriMesh *&_mesh, const std::vector< quint32 > &_indices)
Adds a pyramid cell to the mesh. (Does nothing, yet)
int idx() const
Get the underlying index of this handle.
void slotSaveDefault()
Slot called when user wants to save the given Save options as default.
#define DATA_POLYHEDRAL_MESH
int addWedgeCellToOpenMesh(MeshT _mesh, std::vector< quint32 > _indices)
Adds a wedge cell to the mesh. (Does nothing, yet)
void setObjectDrawMode(const ACG::SceneGraph::DrawModes::DrawMode &_mode, const bool &_force=false)
Set the draw mode for the object.
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.
static constexpr size_t size()
returns dimension of the vector
bool is_valid() const
The handle is valid iff the index is not negative.
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 updateFaceNormalsOfOpenMesh(MeshT *&_mesh)
Updates face normals.
#define DATA_TRIANGLE_MESH
MeshT * mesh()
return a pointer to the mesh
QString description()
Return a description of what the plugin is doing.
Type for a Meshobject containing a poly mesh.
int addTetraCell(TriMesh *&_mesh, const std::vector< quint32 > &_indices)
Adds a tetra cell to the mesh. (Does nothing, yet)
FileVTKPlugin()
Constructor.
TetrahedralMesh * tetrahedralMesh(BaseObjectData *_object)
Get an TetrahedralMesh from an object.
void initializePlugin()
Initialize Plugin.
void setNormalsOfDuplicatedVerticesOfOpenMesh(MeshT *&_mesh)
Sets normals of duplicated vertices that were created for non-manifold meshes.
bool writeASCIIData(std::ostream &_out, TriMesh &_mesh)
Writes the data of the VTK file in ASCII format.
void addFaceNormalToOpenMesh(MeshT _mesh, quint32 _index, OpenMesh::Vec3d _normal)
Adds a face normal.