52 #ifdef ENABLE_OPENVOLUMEMESH_HEXAHEDRAL_SUPPORT 54 #ifdef ENABLE_OPENVOLUMEMESH_POLYHEDRAL_SUPPORT 57 #if QT_VERSION >= 0x050000 64 void remove_duplicated_vertices(std::vector<quint32>& _indices)
66 std::vector<quint32>::iterator endIter = _indices.end();
67 for (std::vector<quint32>::iterator iter = _indices.begin(); iter != endIter; ++iter)
68 endIter = std::remove(iter+1, endIter, *(iter));
70 _indices.erase(endIter,_indices.end());
77 forceTriangleMesh_(false),
78 forcePolyMesh_(false),
82 saveVertexNormals_(0),
83 saveVertexTexCoords_(0),
84 savePrecisionLabel_(0),
97 userWriteOptions_ |= BINARY;
99 userWriteOptions_ |= FACENORMALS;
101 userWriteOptions_ |= VERTEXNORMALS;
103 userWriteOptions_ |= VERTEXTEXCOORDS;
109 return QString( tr(
"Visualization Toolkit ASCII ( *.vtk )") );
115 return QString( tr(
"Visualization Toolkit ASCII ( *.vtk )") );
123 #ifdef ENABLE_OPENVOLUMEMESH_POLYHEDRAL_SUPPORT 126 #ifdef ENABLE_OPENVOLUMEMESH_HEXAHEDRAL_SUPPORT 129 #ifdef ENABLE_OPENVOLUMEMESH_TETRAHEDRAL_SUPPORT 130 type |= DATA_TETRAHEDRAL_MESH;
146 if (saveOptions_ == 0){
148 saveOptions_ =
new QWidget();
149 QVBoxLayout* layout =
new QVBoxLayout();
150 layout->setAlignment(Qt::AlignTop);
152 saveBinary_ =
new QCheckBox(
"Save Binary");
153 layout->addWidget(saveBinary_);
154 saveBinary_->setCheckable(
false);
156 saveFaceNormals_ =
new QCheckBox(
"Save Face Normals");
157 layout->addWidget(saveFaceNormals_);
159 saveVertexNormals_ =
new QCheckBox(
"Save Vertex Normals");
160 layout->addWidget(saveVertexNormals_);
162 saveVertexTexCoords_ =
new QCheckBox(
"Save Vertex TexCoords");
163 layout->addWidget(saveVertexTexCoords_);
165 savePrecisionLabel_ =
new QLabel(
"Writer Precision");
166 layout->addWidget(savePrecisionLabel_);
168 savePrecision_ =
new QSpinBox();
169 savePrecision_->setMinimum(1);
170 savePrecision_->setMaximum(12);
171 savePrecision_->setValue(6);
172 layout->addWidget(savePrecision_);
174 saveDefaultButton_ =
new QPushButton(
"Make Default");
175 layout->addWidget(saveDefaultButton_);
177 saveOptions_->setLayout(layout);
179 connect(saveBinary_, SIGNAL(clicked(
bool)), savePrecision_, SLOT(setDisabled(
bool)));
180 connect(saveDefaultButton_, SIGNAL(clicked()),
this, SLOT(
slotSaveDefault()));
182 saveBinary_->setChecked(
OpenFlipperSettings().value(
"FileVtk/Save/Binary",
false).toBool() );
183 saveFaceNormals_->setChecked(
OpenFlipperSettings().value(
"FileVtk/Save/FaceNormals",
true).toBool() );
184 saveVertexNormals_->setChecked(
OpenFlipperSettings().value(
"FileVtk/Save/VertexNormals",
true).toBool() );
185 saveVertexTexCoords_->setChecked(
OpenFlipperSettings().value(
"FileVtk/Save/VertexTexCoords",
true).toBool() );
210 template <
typename MeshT>
213 emit log(
LOGWARN,tr(
"Unsupported Cell Type TETRA") );
217 template <
typename MeshT>
220 emit log(
LOGWARN,tr(
"Unsupported Cell Type HEXAHEDRON") );
224 template <
typename MeshT>
227 emit log(
LOGWARN,tr(
"Unsupported Cell Type WEDGE") );
231 template <
typename MeshT>
234 emit log(
LOGWARN,tr(
"Unsupported Cell Type PYRAMID") );
238 template <
typename MeshT>
241 std::vector<OpenMesh::VertexHandle> handles;
242 for (std::vector<quint32>::const_iterator it = _indices.begin(); it != _indices.end(); ++it)
243 handles.push_back(_mesh->vertex_handle(*it));
250 std::vector< OpenMesh::VertexHandle > inverseHandles;
251 for (
int i = handles.size()-1 ; i >= 0 ; --i)
252 inverseHandles.push_back(handles[i]);
254 fh = _mesh->add_face(inverseHandles);
263 template <
typename MeshT>
269 return _mesh->add_face(v1,v2,v3).
idx();
272 template <
typename MeshT>
275 _mesh->update_face_normals();
282 template <
typename MeshT>
285 _mesh->update_vertex_normals();
288 template <
typename MeshT>
293 if (! _mesh->get_property_handle(originalVertexIdx,
"FileVTKPlugin_originalVertexIdx")) {
294 _mesh->remove_property( originalVertexIdx );
298 template <
typename MeshT>
303 _mesh->set_normal( vh , _normal );
307 template <
typename MeshT>
312 _mesh->set_normal( fh, _normal );
315 template <
typename MeshT>
318 if ((_cell.type <= 4) || (_cell.type >= 10))
321 emit log(
LOGWARN,tr(
"Normals not supported for type %1").arg(_cell.type) );
323 else if (_cell.type == 5)
328 else if (_cell.type == 6)
331 int numberOfTriangles = _cell.indices.size() - 2;
333 for (
int i = 0; i < numberOfTriangles; i++)
336 else if ((_cell.type >= 7) && (_cell.type <= 9))
339 if (forceTriangleMesh_)
345 int numberOfTriangles = _cell.indices.size() - 2;
346 for (
int i = 0; i < numberOfTriangles; i++)
358 template <
typename MeshT>
363 if (! _mesh->get_property_handle(originalVertexIdx,
"FileVTKPlugin_originalVertexIdx")) {
370 typename MeshT::VertexIter vit = _mesh->vertices_begin();
371 typename MeshT::VertexIter vend = _mesh->vertices_end();
373 for(; vit != vend; ++vit) {
374 if ( _mesh->property(originalVertexIdx, *vit).is_valid() ) {
376 _mesh->set_normal( *vit, _mesh->normal(_mesh->property (originalVertexIdx, *vit) ) );
381 template<
class MeshT >
384 if ( !OpenFlipper::Options::savingSettings() && saveOptions_ != 0)
385 _out.precision(savePrecision_->value());
387 _out <<
"DATASET POLYDATA\n";
389 typename MeshT::Point p;
394 typename MeshT::VertexIter vit = _mesh.vertices_begin();
395 typename MeshT::VertexIter end_vit = _mesh.vertices_end();
396 typename MeshT::FaceIter fit = _mesh.faces_begin();
397 typename MeshT::FaceIter end_fit = _mesh.faces_end();
398 typename MeshT::FaceVertexIter fvit;
400 int total_face_vertices = _mesh.n_faces();
401 for (; fit != end_fit; ++fit) {
402 total_face_vertices += _mesh.valence(*fit);
405 _out <<
"POINTS " << _mesh.n_vertices() <<
" float\n";
406 for (; vit != end_vit; ++vit) {
408 p = _mesh.point(*vit);
409 _out << p[0] <<
" " << p[1] <<
" " << p[2];
414 _out <<
"POLYGONS "<< _mesh.n_faces() <<
" " << total_face_vertices <<
"\n";
415 for (fit = _mesh.faces_begin(); fit != end_fit; ++fit) {
417 _out << _mesh.valence(*fit);
420 fvit = _mesh.fv_iter(*fit);
423 for (;fvit.is_valid(); ++fvit) {
424 _out <<
" " << fvit->idx();
434 _out <<
"CELL_DATA "<< _mesh.n_faces() <<
"\n";
437 if (_mesh.has_face_normals() && (userWriteOptions_ & FileVTKPlugin::FACENORMALS)) {
438 _out <<
"NORMALS faceNormals float\n";
439 for (fit = _mesh.faces_begin(); fit != end_fit; ++fit) {
440 n = _mesh.normal(*fit);
441 _out << n[0] <<
" " << n[1] <<
" " << n[2];
447 _out <<
"POINT_DATA "<< _mesh.n_vertices() <<
"\n";
450 if (_mesh.has_vertex_normals() && (userWriteOptions_ & FileVTKPlugin::VERTEXNORMALS)) {
451 _out <<
"NORMALS vertexNormals float\n";
452 for (vit = _mesh.vertices_begin(); vit != end_vit; ++vit) {
453 n = _mesh.normal(*vit);
454 _out << n[0] <<
" " << n[1] <<
" " << n[2];
460 if (_mesh.has_vertex_texcoords2D() && (userWriteOptions_ & FileVTKPlugin::VERTEXTEXCOORDS)) {
461 _out <<
"TEXTURE_COORDINATES vertexTexcoords 2 float\n";
462 for (vit = _mesh.vertices_begin(); vit != end_vit; ++vit) {
463 t = _mesh.texcoord2D(*vit);
464 _out << t[0] <<
" " << t[1];
509 #ifdef ENABLE_OPENVOLUMEMESH_SUPPORT 511 template <
typename MeshT>
512 int FileVTKPlugin::addTetraCellToOpenVolumeMesh(MeshT _mesh, std::vector<quint32> _indices)
514 if (_indices.size() != 4)
517 std::vector< std::vector<OpenVolumeMesh::VertexHandle> > faces;
518 faces.push_back(std::vector<OpenVolumeMesh::VertexHandle>());
519 faces[0].push_back(_indices[0]);
520 faces[0].push_back(_indices[1]);
521 faces[0].push_back(_indices[2]);
522 faces.push_back(std::vector<OpenVolumeMesh::VertexHandle>());
523 faces[1].push_back(_indices[0]);
524 faces[1].push_back(_indices[3]);
525 faces[1].push_back(_indices[1]);
526 faces.push_back(std::vector<OpenVolumeMesh::VertexHandle>());
527 faces[2].push_back(_indices[1]);
528 faces[2].push_back(_indices[3]);
529 faces[2].push_back(_indices[2]);
530 faces.push_back(std::vector<OpenVolumeMesh::VertexHandle>());
531 faces[3].push_back(_indices[0]);
532 faces[3].push_back(_indices[2]);
533 faces[3].push_back(_indices[3]);
535 std::vector<OpenVolumeMesh::HalfFaceHandle> halffacehandles;
536 for (
unsigned int i = 0; i < faces.size(); i++)
537 halffacehandles.push_back(_mesh->halfface(faces[i]));
539 for (
unsigned int i = 0; i < halffacehandles.size(); i++)
544 halffacehandles[i] = _mesh->halfface_handle(fh, 0);
547 return _mesh->add_cell(halffacehandles).idx();
551 template <
typename MeshT>
552 int FileVTKPlugin::addHexaCellToOpenVolumeMesh(MeshT _mesh, std::vector<quint32> _indices)
554 if (_indices.size() != 8)
555 { emit log(
LOGWARN,tr(
"Expected 8 indices to add Hexahedron but got %1").arg(_indices.size()) ); }
557 std::vector< std::vector<OpenVolumeMesh::VertexHandle> > faces;
558 faces.push_back(std::vector<OpenVolumeMesh::VertexHandle>());
559 faces[0].push_back(_indices[0]);
560 faces[0].push_back(_indices[1]);
561 faces[0].push_back(_indices[2]);
562 faces[0].push_back(_indices[3]);
563 faces.push_back(std::vector<OpenVolumeMesh::VertexHandle>());
564 faces[1].push_back(_indices[0]);
565 faces[1].push_back(_indices[4]);
566 faces[1].push_back(_indices[5]);
567 faces[1].push_back(_indices[1]);
568 faces.push_back(std::vector<OpenVolumeMesh::VertexHandle>());
569 faces[2].push_back(_indices[0]);
570 faces[2].push_back(_indices[3]);
571 faces[2].push_back(_indices[7]);
572 faces[2].push_back(_indices[4]);
573 faces.push_back(std::vector<OpenVolumeMesh::VertexHandle>());
574 faces[3].push_back(_indices[1]);
575 faces[3].push_back(_indices[5]);
576 faces[3].push_back(_indices[6]);
577 faces[3].push_back(_indices[2]);
578 faces.push_back(std::vector<OpenVolumeMesh::VertexHandle>());
579 faces[4].push_back(_indices[2]);
580 faces[4].push_back(_indices[6]);
581 faces[4].push_back(_indices[7]);
582 faces[4].push_back(_indices[3]);
583 faces.push_back(std::vector<OpenVolumeMesh::VertexHandle>());
584 faces[5].push_back(_indices[4]);
585 faces[5].push_back(_indices[7]);
586 faces[5].push_back(_indices[6]);
587 faces[5].push_back(_indices[5]);
589 std::vector<OpenVolumeMesh::HalfFaceHandle> halffacehandles;
590 for (
unsigned int i = 0; i < faces.size(); i++)
591 halffacehandles.push_back(_mesh->halfface(faces[i]));
593 for (
unsigned int i = 0; i < halffacehandles.size(); i++)
598 halffacehandles[i] = _mesh->halfface_handle(fh, 0);
601 return _mesh->add_cell(halffacehandles).idx();
604 template <
typename MeshT>
605 int FileVTKPlugin::addWedgeCellToOpenVolumeMesh(MeshT _mesh, std::vector<quint32> _indices)
607 if (_indices.size() != 6)
608 { emit log(
LOGWARN,tr(
"Expected 6 indices to add Hexahedron but got %1").arg(_indices.size()) ); }
610 std::vector< std::vector<OpenVolumeMesh::VertexHandle> > faces;
611 faces.push_back(std::vector<OpenVolumeMesh::VertexHandle>());
612 faces[0].push_back(_indices[0]);
613 faces[0].push_back(_indices[1]);
614 faces[0].push_back(_indices[4]);
615 faces[0].push_back(_indices[3]);
616 faces.push_back(std::vector<OpenVolumeMesh::VertexHandle>());
617 faces[1].push_back(_indices[0]);
618 faces[1].push_back(_indices[2]);
619 faces[1].push_back(_indices[1]);
620 faces.push_back(std::vector<OpenVolumeMesh::VertexHandle>());
621 faces[2].push_back(_indices[3]);
622 faces[2].push_back(_indices[4]);
623 faces[2].push_back(_indices[5]);
624 faces.push_back(std::vector<OpenVolumeMesh::VertexHandle>());
625 faces[3].push_back(_indices[0]);
626 faces[3].push_back(_indices[3]);
627 faces[3].push_back(_indices[5]);
628 faces[3].push_back(_indices[2]);
629 faces.push_back(std::vector<OpenVolumeMesh::VertexHandle>());
630 faces[4].push_back(_indices[1]);
631 faces[4].push_back(_indices[2]);
632 faces[4].push_back(_indices[5]);
633 faces[4].push_back(_indices[4]);
635 std::vector<OpenVolumeMesh::HalfFaceHandle> halffacehandles;
636 for (
unsigned int i = 0; i < faces.size(); i++)
637 halffacehandles.push_back(_mesh->halfface(faces[i]));
639 for (
unsigned int i = 0; i < halffacehandles.size(); i++)
644 halffacehandles[i] = _mesh->halfface_handle(fh, 0);
647 return _mesh->add_cell(halffacehandles).idx();
650 template <
typename MeshT>
651 int FileVTKPlugin::addPyramidCellToOpenVolumeMesh(MeshT _mesh, std::vector<quint32> _indices)
653 if (_indices.size() != 6)
654 { emit log(
LOGWARN,tr(
"Expected 6 indices to add Hexahedron but got %1").arg(_indices.size()) ); }
656 std::vector< std::vector<OpenVolumeMesh::VertexHandle> > faces;
657 faces.push_back(std::vector<OpenVolumeMesh::VertexHandle>());
658 faces[0].push_back(_indices[0]);
659 faces[0].push_back(_indices[1]);
660 faces[0].push_back(_indices[2]);
661 faces[0].push_back(_indices[3]);
662 faces.push_back(std::vector<OpenVolumeMesh::VertexHandle>());
663 faces[1].push_back(_indices[0]);
664 faces[1].push_back(_indices[4]);
665 faces[1].push_back(_indices[1]);
666 faces.push_back(std::vector<OpenVolumeMesh::VertexHandle>());
667 faces[2].push_back(_indices[0]);
668 faces[2].push_back(_indices[3]);
669 faces[2].push_back(_indices[4]);
670 faces.push_back(std::vector<OpenVolumeMesh::VertexHandle>());
671 faces[3].push_back(_indices[2]);
672 faces[3].push_back(_indices[4]);
673 faces[3].push_back(_indices[3]);
674 faces.push_back(std::vector<OpenVolumeMesh::VertexHandle>());
675 faces[4].push_back(_indices[1]);
676 faces[4].push_back(_indices[4]);
677 faces[4].push_back(_indices[2]);
679 std::vector<OpenVolumeMesh::HalfFaceHandle> halffacehandles;
680 for (
unsigned int i = 0; i < faces.size(); i++)
681 halffacehandles.push_back(_mesh->halfface(faces[i]));
683 for (
unsigned int i = 0; i < halffacehandles.size(); i++)
688 halffacehandles[i] = _mesh->halfface_handle(fh, 0);
691 return _mesh->add_cell(halffacehandles).idx();
694 template <
typename MeshT>
695 int FileVTKPlugin::addFaceToOpenVolumeMesh(MeshT*& _mesh, std::vector<quint32> _indices)
697 if (_indices.size() < 3)
698 { emit log(
LOGWARN,tr(
"Expected at least 3 indices to add a face but got %1").arg(_indices.size()) ); }
700 std::vector<OpenVolumeMesh::VertexHandle> face;
701 for (
unsigned int i = 0; i < _indices.size(); i++)
706 halffacehandle = _mesh->halfface(face);
707 if (halffacehandle == -1)
710 halffacehandle = _mesh->halfface_handle(fh, 0);
712 return halffacehandle.idx();
715 template <
typename MeshT>
716 int FileVTKPlugin::addFaceToOpenVolumeMesh(MeshT*& _mesh, quint32 _index1, quint32 _index2, quint32 _index3)
718 std::vector<OpenVolumeMesh::VertexHandle> face;
724 halffacehandle = _mesh->halfface(face);
725 if (halffacehandle == -1)
728 halffacehandle = _mesh->halfface_handle(fh, 0);
730 return halffacehandle.idx();
733 template <
typename MeshT>
734 void FileVTKPlugin::addVertexNormalToOpenVolumeMesh(MeshT _mesh, quint32 _index,
OpenMesh::Vec3d _normal)
740 template <
typename MeshT>
741 void FileVTKPlugin::addFaceNormalToOpenVolumeMesh(MeshT _mesh, quint32 _index,
OpenMesh::Vec3d _normal)
747 if (hfh == _mesh->halfface_handle(fh, 0))
748 faceNormals[_mesh->face_handle(_index)] = _normal;
750 faceNormals[_mesh->face_handle(_index)] = -_normal;
754 template <
typename MeshT>
757 int incidentFaces = _mesh.cell(_cellHandle).halffaces().
size();
758 int incidentVertices = 0;
762 if ((incidentFaces == 4) && (incidentVertices == 4))
764 else if ((incidentFaces == 6) && (incidentVertices == 8))
766 else if ((incidentFaces == 5) && (incidentVertices == 6))
768 else if ((incidentFaces == 5) && (incidentVertices == 5))
774 template <
typename MeshT>
777 std::vector<OpenVolumeMesh::HalfEdgeHandle> halfedges = _mesh.face(_faceHandle).halfedges();
778 if (halfedges.size() == 3)
784 template <
typename MeshT>
793 std::vector<OpenVolumeMesh::HalfEdgeHandle> halfedges = face.halfedges();
794 std::vector<int> indices;
795 for (
unsigned int i = 0; i < halfedges.size(); i++)
796 indices.push_back(_mesh.halfedge(halfedges[i]).from_vertex().idx());
798 if ((cvit->idx() != indices[0]) && ((*cvit).idx() != indices[1]) && ((*cvit).idx() != indices[2]))
799 indices.push_back(cvit->idx());
802 else if (_cellType == 12)
809 std::vector<int> indices;
810 for (
unsigned int i = 0; i < 4; i++)
813 indices.push_back(edge.from_vertex().idx());
814 heh = _mesh.next_halfedge_in_halfface(heh, hfh);
819 heh = _mesh.opposite_halfedge_handle(heh);
820 heh = _mesh.next_halfedge_in_halfface(heh, intermediateHalfFaceHandle);
821 heh = _mesh.next_halfedge_in_halfface(heh, intermediateHalfFaceHandle);
823 heh = _mesh.opposite_halfedge_handle(heh);
826 for (
unsigned int i = 0; i < 4; i++)
829 indices.push_back(edge.to_vertex().idx());
830 heh = _mesh.prev_halfedge_in_halfface(heh, oppositeHalfFaceHandle);
834 else if (_cellType == 13)
839 for (
unsigned int i = 0; i < cell.halffaces().size(); i++)
840 if (_mesh.halfface(cell.halffaces()[i]).halfedges().size() == 3)
841 hfh = cell.halffaces()[i];
844 std::vector<int> indices;
845 for (
unsigned int i = 0; i < 3; i++)
848 indices.push_back(edge.from_vertex().idx());
849 heh = _mesh.prev_halfedge_in_halfface(heh, hfh);
854 heh = _mesh.opposite_halfedge_handle(heh);
855 heh = _mesh.next_halfedge_in_halfface(heh, intermediateHalfFaceHandle);
856 heh = _mesh.next_halfedge_in_halfface(heh, intermediateHalfFaceHandle);
858 heh = _mesh.opposite_halfedge_handle(heh);
861 for (
unsigned int i = 0; i < 3; i++)
864 indices.push_back(edge.to_vertex().idx());
865 heh = _mesh.next_halfedge_in_halfface(heh, oppositeHalfFaceHandle);
870 else if (_cellType == 14)
875 std::vector<OpenVolumeMesh::HalfFaceHandle> halffaces = cell.halffaces();
877 for (
unsigned int i = 0; i < halffaces.size(); i++)
878 if (_mesh.halfface(halffaces[i]).halfedges().size() == 4)
879 face = _mesh.halfface(halffaces[i]);
880 std::vector<OpenVolumeMesh::HalfEdgeHandle> halfedges = face.halfedges();
881 std::vector<int> indices;
882 for (
unsigned int i = 0; i < halfedges.size(); i++)
883 indices.push_back(_mesh.halfedge(halfedges[i]).from_vertex().idx());
885 if ((cvit->idx() != indices[0]) && ((*cvit).idx() != indices[1]) && ((*cvit).idx() != indices[2]) && ((*cvit).idx() != indices[3]))
886 indices.push_back(cvit->idx());
890 return std::vector<int>();
893 template <
typename MeshT>
894 bool FileVTKPlugin::writeASCIIDataOfOpenVolumeMesh(std::ostream& _out, MeshT& _mesh)
896 if ( !OpenFlipper::Options::savingSettings() && saveOptions_ != 0)
897 _out.precision(savePrecision_->value());
899 _out <<
"DATASET UNSTRUCTURED_GRID\n";
906 _out <<
"POINTS " << _mesh.n_vertices() <<
" float\n";
907 for (; vit != end_vit; ++vit) {
910 _out << p[0] <<
" " << p[1] <<
" " << p[2];
926 quint32 listSize = 0;
929 int cellType = getCellType(_mesh, *cit);
933 else if (cellType == 12 )
935 else if (cellType == 13 )
937 else if (cellType == 14 )
944 std::vector<OpenVolumeMesh::HalfFaceHandle> halffaces = _mesh.cell(*cit).halffaces();
945 for (
unsigned int i = 0; i < halffaces.size(); i++)
948 if (!(fpAlreadyStored[fh]))
952 if (!(userWriteOptions_ & FileVTKPlugin::FACENORMALS))
953 fpAlreadyStored[fh] =
true;
956 for (std::vector<OpenVolumeMesh::HalfEdgeHandle>::const_iterator heit = face.halfedges().begin();
957 heit != face.halfedges().end();
960 epAlreadyStored[_mesh.edge_handle(*heit)] =
true;
968 if (!(fpAlreadyStored[*fit]))
971 std::vector<OpenVolumeMesh::HalfEdgeHandle> halfedges = _mesh.face(*fit).halfedges();
972 for (
unsigned int i = 0; i < halfedges.size(); i++)
973 epAlreadyStored[_mesh.edge_handle(halfedges[i])] =
true;
976 listSize += 1 + halfedges.size();
984 if (!(epAlreadyStored[*eit]))
991 _out <<
"CELLS " << cellCount <<
" " << listSize <<
"\n";
1000 int cellType = getCellType(_mesh, *cit);
1003 if (cellType == 10 )
1005 else if (cellType == 12 )
1007 else if (cellType == 13 )
1009 else if (cellType == 14 )
1018 std::vector<int> indices = getCellVertexIndices(_mesh, *cit, cellType);
1019 _out << indices.size();
1020 for (
unsigned int i = 0; i < indices.size(); i++)
1021 _out <<
" " << indices[i];
1031 if (!(fpAlreadyStored[*fit]))
1033 std::vector<OpenVolumeMesh::HalfEdgeHandle> halfedges = _mesh.face(*fit).halfedges();
1035 _out << halfedges.size();
1036 for (
unsigned int i = 0; i < halfedges.size(); i++)
1040 _out <<
" " << edge.from_vertex().idx();
1052 if (!(epAlreadyStored[*eit]))
1056 _out <<
" " << edge.from_vertex().idx();
1057 _out <<
" " << edge.to_vertex().idx();
1066 _out <<
"CELL_TYPES " << cellCount <<
"\n";
1071 int cellType = getCellType(_mesh, *cit);
1075 _out << cellType <<
"\n";
1082 if (!(fpAlreadyStored[*fit]))
1084 int cellType = getCellType(_mesh,*fit);
1088 _out << cellType <<
"\n";
1096 if (!(epAlreadyStored[*eit]))
1113 if ((userWriteOptions_ & FileVTKPlugin::VERTEXNORMALS))
1115 _out <<
"POINT_DATA "<< _mesh.n_vertices() <<
"\n";
1118 _out <<
"NORMALS vertex_normals float\n";
1121 _out << n[0] <<
" " << n[1] <<
" " << n[2];
1128 if ((userWriteOptions_ & FileVTKPlugin::FACENORMALS))
1130 _out <<
"CELL_DATA "<< cellCount <<
"\n";
1131 _out <<
"NORMALS face_normals float\n";
1136 int cellType = getCellType(_mesh, *cit);
1138 if (cellType == -1 )
1142 _out << 1 <<
" " << 0 <<
" " << 0;
1153 _out << n[0] <<
" " << n[1] <<
" " << n[2];
1161 if (!(epAlreadyStored[*eit]))
1163 _out << 1 <<
" " << 0 <<
" " << 0;
1174 #endif //ENABLE_OPENVOLUMEMESH_SUPPORT 1176 #ifdef ENABLE_OPENVOLUMEMESH_HEXAHEDRAL_SUPPORT 1186 #endif //ENABLE_OPENVOLUMEMESH_HEXAHEDRAL_SUPPORT 1189 #ifdef ENABLE_OPENVOLUMEMESH_POLYHEDRAL_SUPPORT 1199 #endif //ENABLE_OPENVOLUMEMESH_POLYHEDRAL_SUPPORT 1202 #ifdef ENABLE_OPENVOLUMEMESH_TETRAHEDRAL_SUPPORT 1203 int FileVTKPlugin::addTetraCell(TetrahedralMesh*& _mesh, std::vector<quint32> indices) {
return addTetraCellToOpenVolumeMesh(_mesh, indices); }
1204 int FileVTKPlugin::addHexaCell(TetrahedralMesh*& _mesh, std::vector<quint32> indices) {
return addHexaCellToOpenVolumeMesh(_mesh, indices); }
1205 int FileVTKPlugin::addWedgeCell(TetrahedralMesh*& _mesh, std::vector<quint32> indices) {
return addWedgeCellToOpenVolumeMesh(_mesh, indices); }
1206 int FileVTKPlugin::addPyramidCell(TetrahedralMesh*& _mesh, std::vector<quint32> indices) {
return addPyramidCellToOpenVolumeMesh(_mesh, indices); }
1207 int FileVTKPlugin::addFace(TetrahedralMesh*& _mesh, std::vector<quint32> indices) {
return addFaceToOpenVolumeMesh(_mesh, indices); }
1208 int FileVTKPlugin::addFace(TetrahedralMesh*& _mesh, quint32 _index1, quint32 _index2, quint32 _index3) {
return addFaceToOpenVolumeMesh(_mesh, _index1, _index2, _index3); }
1212 #endif //ENABLE_OPENVOLUMEMESH_TETRAHEDRAL_SUPPORT 1222 QFile file(_filename);
1224 if ( !file.open(QIODevice::ReadOnly) ) {
1228 QTextStream in(&file);
1230 QString line = in.readLine();
1232 QStringList header = line.split(
" ",QString::SkipEmptyParts);
1233 if ( header.size() != 5 ) {
1237 QString version = header[4];
1239 header.removeLast();
1241 QString magic = header.join(
" ");
1243 if ( magic !=
"# vtk DataFile Version" ) {
1249 QString fileTypeStr = in.readLine();
1251 fileTypeStr = fileTypeStr.simplified();
1253 if ( fileTypeStr.toLower() ==
"binary" ) {
1255 }
else if ( fileTypeStr.toLower() ==
"ascii" ) {
1263 while ( line.simplified() ==
"" )
1264 line = in.readLine();
1266 QStringList datasetList = line.split(
" ",QString::SkipEmptyParts);
1268 if ( datasetList.size() != 2 ) {
1274 datasetList[1] = datasetList[1].simplified();
1276 if ( datasetList[1] ==
"STRUCTURED_POINTS" )
1277 dataset = STRUCTURED_POINTS;
1278 else if ( datasetList[1] ==
"STRUCTURED_GRID" )
1279 dataset = STRUCTURED_GRID;
1280 else if ( datasetList[1] ==
"RECTILINEAR_GRID" )
1281 dataset = RECTILINEAR_GRID;
1282 else if ( datasetList[1] ==
"POLYDATA" )
1284 else if ( datasetList[1] ==
"UNSTRUCTURED_GRID" )
1285 dataset = UNSTRUCTURED_GRID;
1291 if ((dataset == STRUCTURED_POINTS) || (dataset == STRUCTURED_GRID) || (dataset == RECTILINEAR_GRID) )
1296 else if (dataset == POLYDATA)
1303 line = in.readLine();
1306 while ( !line.contains(
"POLYGONS") ) {
1314 line = in.readLine();
1317 QStringList polygonsLine = line.split(
" ",QString::SkipEmptyParts);
1320 if ( polygonsLine.size() != 3 ) {
1321 emit log(
LOGERR,tr(
"Expected to get Points line with exactly 3 entries, but %1 found!").arg(polygonsLine.size()));
1328 quint32 polygoncount = polygonsLine[1].toUInt(&ok);
1331 emit log(
LOGERR,tr(
"Expected to get number of points and entries, but read %1 !").arg(polygonsLine.join(
" ")));
1336 while ( read < polygoncount) {
1343 in.device()->read((
char*)&valence,
sizeof(quint32));
1348 return BMT_PolyMesh;
1354 for (
unsigned int i = 0 ; i < valence; ++i ) {
1360 in.device()->read((
char*)&valence,
sizeof(quint32));
1376 line = in.readLine();
1379 while ( !line.contains(
"CELL_TYPES") ) {
1387 line = in.readLine();
1391 QStringList cellLine = line.split(
" ",QString::SkipEmptyParts);
1394 if ( cellLine.size() != 2 ) {
1395 emit log(
LOGERR,tr(
"Expected to get CELL_TYPES line with exactly 2 entries, but %1 found!").arg(cellLine.size()));
1402 quint32 cellCountTypes = cellLine[1].toUInt(&ok);
1405 emit log(
LOGERR,tr(
"Expected to get number of cell types, but read %1 !").arg(cellLine[1]));
1409 bool triMeshPossible =
true;
1410 bool polyMeshPossible =
true;
1412 #ifndef ENABLE_OPENVOLUMEMESH_HEXAHEDRAL_SUPPORT 1413 bool hexahedralMeshPossible =
false;
1415 bool hexahedralMeshPossible =
true;
1417 #ifndef ENABLE_OPENVOLUMEMESH_POLYHEDRAL_SUPPORT 1418 bool polyhedralMeshPossible =
false;
1420 bool polyhedralMeshPossible =
true;
1422 #ifndef ENABLE_OPENVOLUMEMESH_TETRAHEDRAL_SUPPORT 1423 bool tetrahedralMeshPossible =
false;
1425 bool tetrahedralMeshPossible =
true;
1429 while ( read < cellCountTypes) {
1436 in.device()->read((
char*)&type,
sizeof(quint32));
1439 if (( 1 <= type ) && (type <= 6 ))
1443 hexahedralMeshPossible =
false;
1444 tetrahedralMeshPossible =
false;
1446 else if (( 7 <= type ) && (type <= 9 ))
1451 triMeshPossible =
false;
1452 hexahedralMeshPossible =
false;
1453 tetrahedralMeshPossible =
false;
1456 else if ( 10 == type )
1459 triMeshPossible =
false;
1460 polyMeshPossible =
false;
1461 hexahedralMeshPossible =
false;
1463 else if (( 13 == type ) || (type == 14 ))
1467 triMeshPossible =
false;
1468 polyMeshPossible =
false;
1469 hexahedralMeshPossible =
false;
1470 tetrahedralMeshPossible =
false;
1473 else if (( 11 == type ) || ( 12 == type ))
1477 triMeshPossible =
false;
1478 polyMeshPossible =
false;
1482 if ( in.status() != QTextStream::Ok ) {
1483 emit log(
LOGERR,tr(
"Read corrupted cell type data!"));
1489 if (triMeshPossible)
1491 else if (polyMeshPossible)
1492 return BMT_PolyMesh;
1493 else if (hexahedralMeshPossible)
1494 return BMT_HexahedralMesh;
1495 else if (tetrahedralMeshPossible)
1496 return BMT_TetrahedralMesh;
1497 else if (polyhedralMeshPossible)
1498 return BMT_PolyhedralMesh;
1509 std::cerr <<
"Loading vtk file" << std::endl;
1513 QFile file(_filename);
1515 if ( !file.open(QIODevice::ReadOnly) ) {
1516 emit log(
LOGERR,
"Unable to open vtk file!");
1520 QTextStream in(&file);
1522 std::cerr <<
"File is open!" << std::endl;
1524 QString line = in.readLine();
1526 std::cerr <<
"Got line: " << std::endl;
1527 std::cerr << line.toStdString() << std::endl;
1529 QStringList header = line.split(
" ",QString::SkipEmptyParts);
1531 if ( header.size() != 5 ) {
1532 emit log(
LOGERR,tr(
"Bad VTK header? ") + line);
1536 QString version = header[4];
1538 header.removeLast();
1540 QString magic = header.join(
" ");
1542 if ( magic !=
"# vtk DataFile Version" ) {
1543 emit log(
LOGERR,tr(
"Bad VTK header magic? ") + magic);
1549 QString fileTypeStr = in.readLine();
1551 fileTypeStr = fileTypeStr.simplified();
1553 if ( fileTypeStr.toLower() ==
"binary" ) {
1555 emit log(
LOGINFO,tr(
"Loading VTK binary file of version %1.").arg(version));
1556 emit log(
LOGERR,tr(
"Not yet implemented!"));
1557 }
else if ( fileTypeStr.toLower() ==
"ascii" ) {
1559 emit log(
LOGINFO,tr(
"Loading VTK ascii file of version %1.").arg(version));
1561 emit log(
LOGERR,tr(
"Bad VTK type? ") + fileTypeStr);
1565 emit log(
LOGINFO,description);
1569 while ( line.simplified() ==
"" )
1570 line = in.readLine();
1572 QStringList datasetList = line.split(
" ",QString::SkipEmptyParts);
1574 if ( datasetList.size() != 2 ) {
1575 emit log(
LOGERR,tr(
"Bad dataset specification!"));
1581 datasetList[1] = datasetList[1].simplified();
1583 if ( datasetList[1] ==
"STRUCTURED_POINTS" )
1584 dataset = STRUCTURED_POINTS;
1585 else if ( datasetList[1] ==
"STRUCTURED_GRID" )
1586 dataset = STRUCTURED_GRID;
1587 else if ( datasetList[1] ==
"RECTILINEAR_GRID" )
1588 dataset = RECTILINEAR_GRID;
1589 else if ( datasetList[1] ==
"POLYDATA" )
1591 else if ( datasetList[1] ==
"UNSTRUCTURED_GRID" )
1592 dataset = UNSTRUCTURED_GRID;
1594 emit log(
LOGERR,tr(
"Unknown dataset specification! %1").arg(datasetList[1]));
1600 if ( (forceTriangleMesh_) || (bestType == BMT_TriMesh) ){
1614 if ( !loadMesh(in,_mesh,dataset) ) {
1615 emit log(
LOGERR,
"Unable to load mesh!");
1619 emit log(
LOGERR,
"Unable to add empty triangle mesh!");
1629 else if ((bestType == BMT_PolyMesh) || (bestType == BMT_None))
1644 if ( !loadMesh(in,_mesh,dataset) ) {
1645 emit log(
LOGERR,
"Unable to load mesh!");
1649 emit log(
LOGERR,
"Unable to add empty poly mesh!");
1659 #ifdef ENABLE_OPENVOLUMEMESH_POLYHEDRAL_SUPPORT 1660 else if (bestType == BMT_PolyhedralMesh)
1674 if ( !loadMesh(in,_mesh,dataset) ) {
1675 emit log(
LOGERR,
"Unable to load mesh!");
1679 emit log(
LOGERR,
"Unable to add empty polyhedral mesh!");
1687 #endif //ENABLE_OPENVOLUMEMESH_POLYHEDRAL_SUPPORT 1688 #ifdef ENABLE_OPENVOLUMEMESH_HEXAHEDRAL_SUPPORT 1689 else if (bestType == BMT_HexahedralMesh)
1703 if ( !loadMesh(in,_mesh,dataset) ) {
1704 emit log(
LOGERR,
"Unable to load mesh!");
1708 emit log(
LOGERR,
"Unable to add empty hexahedral mesh!");
1715 #endif //ENABLE_OPENVOLUMEMESH_HEXAHEDRAL_SUPPORT 1716 #ifdef ENABLE_OPENVOLUMEMESH_TETRAHEDRAL_SUPPORT 1717 else if (bestType == BMT_TetrahedralMesh)
1721 emit addEmptyObject(DATA_TETRAHEDRAL_MESH,
id);
1723 TetrahedralMeshObject* object(0);
1727 TetrahedralMesh* _mesh;
1728 _mesh = PluginFunctions::tetrahedralMesh(
object);
1731 if ( !loadMesh(in,_mesh,dataset) ) {
1732 emit log(
LOGERR,
"Unable to load mesh!");
1736 emit log(
LOGERR,
"Unable to add empty tetrahedral mesh!");
1743 #endif //ENABLE_OPENVOLUMEMESH_TETRAHEDRAL_SUPPORT 1754 emit openedFile( baseObj->
id() );
1756 return baseObj->
id();
1759 emit log(
LOGERR,tr(
"Error in load mesh!"));
1766 template <
typename MeshT>
1769 std::cerr <<
"loadMeshPoints" << std::endl;
1774 QStringList pointsLine = _spec.split(
" ",QString::SkipEmptyParts);
1777 if ( pointsLine.size() != 3 ) {
1778 emit log(
LOGERR,tr(
"Expected to get Points line with exactly 3 entries, but %1 found!").arg(pointsLine.size()));
1783 quint32 points = pointsLine[1].toUInt(&ok);
1786 emit log(
LOGERR,tr(
"Expected to get number of points, but read %1 !").arg(pointsLine[1]));
1794 while ( read < points ) {
1800 if ( pointsLine[2] ==
"float" ) {
1803 _in.device()->read((
char*)&vecf[0],
sizeof(
float));
1804 _in.device()->read((
char*)&vecf[1],
sizeof(
float));
1805 _in.device()->read((
char*)&vecf[2],
sizeof(
float));
1810 emit log(
LOGERR,tr(
"Not implemented data type %1 !").arg(pointsLine[2]));
1816 _in >> vec[0] >> vec[1] >> vec[2];
1823 if ( _in.status() == QTextStream::Ok ) {
1824 _mesh->add_vertex(vec);
1826 emit log(
LOGERR,tr(
"Read corrupted point data!"));
1833 if ( pointsLine[2] ==
"float" ) {
1836 _in.seek(_in.pos() + read * 3 *
sizeof(float) /
sizeof(
char) );
1844 template <
typename MeshT>
1846 std::cerr <<
"loadMeshLines" << std::endl;
1851 QStringList linesLine = _spec.split(
" ",QString::SkipEmptyParts);
1854 if ( linesLine.size() != 3 ) {
1855 emit log(
LOGERR,tr(
"Expected to get LINES line with exactly 3 entries, but %1 found!").arg(linesLine.size()));
1860 quint32 linecount = linesLine[1].toUInt(&ok);
1863 quint32 entrycount = linesLine[2].toUInt(&ok);
1866 emit log(
LOGERR,tr(
"Expected to get number of lines and entries, but read %1 !").arg(linesLine.join(
" ")));
1872 while ( read < linecount) {
1880 _in.device()->read((
char*)&valence,
sizeof(quint32));
1885 if ( _in.status() == QTextStream::Ok ) {
1888 for (
unsigned int i = 0 ; i < valence; ++i )
1891 for (
unsigned int i = 0 ; i < valence; ++i )
1892 _in.device()->read((
char*)&valence,
sizeof(quint32));
1895 if ( _in.status() == QTextStream::Ok ) {
1900 emit log(
LOGERR,tr(
"Read corrupted face data!"));
1905 emit log(
LOGERR,tr(
"Read corrupted POLYGONS data!"));
1915 _in.seek(_in.pos() + entrycount *
sizeof(quint32) /
sizeof(
char) );
1918 emit log(
LOGWARN,tr(
"Lines not supported yet ... skipped!"));
1923 template <
typename MeshT>
1925 std::cerr <<
"loadMeshPolygons" << std::endl;
1930 QStringList polygonsLine = _spec.split(
" ",QString::SkipEmptyParts);
1933 if ( polygonsLine.size() != 3 ) {
1934 emit log(
LOGERR,tr(
"Expected to get Points line with exactly 3 entries, but %1 found!").arg(polygonsLine.size()));
1939 quint32 polygoncount = polygonsLine[1].toUInt(&ok);
1942 quint32 entrycount = polygonsLine[2].toUInt(&ok);
1945 emit log(
LOGERR,tr(
"Expected to get number of points and entries, but read %1 !").arg(polygonsLine.join(
" ")));
1950 bool errorEnabled = omerr().is_enabled();
1954 while ( read < polygoncount) {
1961 _in.device()->read((
char*)&valence,
sizeof(quint32));
1965 std::vector< quint32 > indices;
1967 for (
unsigned int i = 0 ; i < valence; ++i ) {
1973 _in.device()->read((
char*)&valence,
sizeof(quint32));
1976 indices.push_back( index );
1979 if ( _in.status() == QTextStream::Ok ) {
1982 remove_duplicated_vertices(indices);
1984 if (indices.size() >= 3)
1988 cell.indices = indices;
1989 cell.index =
addFace(_mesh, indices);
1990 _cells.push_back(cell);
1993 emit log(
LOGERR,tr(
"Read corrupted face data!"));
2011 _in.seek(_in.pos() + entrycount *
sizeof(qint32) /
sizeof(
char) );
2017 template <
typename MeshT>
2022 if (_vhandles.empty())
return -1;
2025 if (! _mesh->get_property_handle(originalVertexIdx,
"FileVTKPlugin_originalVertexIdx")) {
2026 _mesh->add_property( originalVertexIdx,
"FileVTKPlugin_originalVertexIdx" );
2029 typename MeshT::VertexIter vit = _mesh->vertices_begin();
2030 typename MeshT::VertexIter vend = _mesh->vertices_end();
2031 for(; vit != vend; ++vit) {
2037 for (
unsigned int j = 0; j < _vhandles.size(); ++j)
2039 typename MeshT::Point p = _mesh->point(_vhandles[j]);
2041 _vhandles[j] = _mesh->add_vertex(p);
2046 if (_mesh->has_vertex_status()) {
2047 _mesh->status(_vhandles[j]).set_fixed_nonmanifold(
true);
2050 _mesh->property (originalVertexIdx, _vhandles[j]) = original_handle;
2057 if (_mesh->has_face_status())
2058 _mesh->status(fh).set_fixed_nonmanifold(
true);
2061 if (_mesh->has_edge_status()) {
2062 typename MeshT::FaceEdgeIter fe_it = _mesh->fe_iter(fh);
2063 for (; fe_it.is_valid(); ++fe_it) {
2064 _mesh->status(*fe_it).set_fixed_nonmanifold(
true);
2072 template <
typename MeshT>
2074 std::cerr <<
"loadMeshTriangleStrips" << std::endl;
2079 QStringList triStripsLine = _spec.split(
" ",QString::SkipEmptyParts);
2082 if ( triStripsLine.size() != 3 ) {
2083 emit log(
LOGERR,tr(
"Expected to get TRIANGLE_STRIPS line with exactly 3 entries, but %1 found!").arg(triStripsLine.size()));
2088 quint32 stripcount = triStripsLine[1].toUInt(&ok);
2091 quint32 entrycount = triStripsLine[2].toUInt(&ok);
2094 emit log(
LOGERR,tr(
"Expected to get number of strips and entries, but read %1 !").arg(triStripsLine.join(
" ")));
2099 while ( read < stripcount) {
2106 _in.device()->read((
char*)&valence,
sizeof(quint32));
2110 QList< quint32 > indices;
2113 for (
unsigned int i = 0 ; i < 2; ++i ) {
2119 _in.device()->read((
char*)&valence,
sizeof(quint32));
2122 indices.push_back( index );
2126 for (
unsigned int i = 2 ; i < valence; ++i ) {
2132 _in.device()->read((
char*)&valence,
sizeof(quint32));
2135 indices.push_back( index );
2137 if ( _in.status() == QTextStream::Ok ) {
2141 cell.indices.resize(3);
2142 cell.indices[0] = indices[i];
2143 cell.indices[1] = indices[i-1];
2144 cell.indices[2] = indices[i-2];
2146 std::swap(cell.indices[1],cell.indices[2]);
2147 cell.index =
addFace(_mesh, cell.indices);
2148 _cells.push_back(cell);
2150 emit log(
LOGERR,tr(
"Read corrupted face data!"));
2164 _in.seek(_in.pos() + entrycount *
sizeof(qint32) /
sizeof(
char) );
2170 template <
typename MeshT>
2172 std::cerr <<
"loadMeshNormals" << std::endl;
2175 QStringList normalsLine = _spec.split(
" ",QString::SkipEmptyParts);
2178 if ( normalsLine.size() != 3 ) {
2179 emit log(
LOGERR,tr(
"Expected to get NORMALS line with exactly 3 entries, but %1 found!").arg(normalsLine.size()));
2187 while ( read < _count) {
2192 if ( normalsLine[2] ==
"float" ) {
2196 _in.device()->read((
char*)&vecf[0],
sizeof(
float));
2197 _in.device()->read((
char*)&vecf[1],
sizeof(
float));
2198 _in.device()->read((
char*)&vecf[2],
sizeof(
float));
2203 emit log(
LOGERR,tr(
"Not implemented data type %1 !").arg(normalsLine[2]));
2209 _in >> normal[0] >> normal[1] >> normal[2];
2213 if ( _in.status() == QTextStream::Ok ) {
2215 if ( _pointNormal ) {
2223 emit log(
LOGERR,tr(
"Read corrupted point data!"));
2232 if ( normalsLine[2] ==
"float" ) {
2235 _in.seek(_in.pos() + read * 3 *
sizeof(float) /
sizeof(
char) );
2245 template <
typename MeshT>
2248 std::cerr <<
"loadMeshCells" << std::endl;
2251 QStringList cellLine = _spec.split(
" ",QString::SkipEmptyParts);
2254 if ( cellLine.size() != 3 ) {
2255 emit log(
LOGERR,tr(
"Expected to get CELLS line with exactly 3 entries, but %1 found!").arg(cellLine.size()));
2262 quint32 cellCount = cellLine[1].toUInt(&ok);
2265 quint32 entryCount = cellLine[2].toUInt(&ok);
2269 emit log(
LOGERR,tr(
"Expected to get number of cells and entries, but read %1 !").arg(cellLine.join(
" ")));
2274 while ( read < cellCount) {
2283 _in.device()->read((
char*)&valence,
sizeof(quint32));
2288 for (
unsigned int i = 0 ; i < valence; ++i ) {
2294 _in.device()->read((
char*)&valence,
sizeof(quint32));
2297 currentCell.indices.push_back( index );
2300 if ( _in.status() == QTextStream::Ok ) {
2301 _cells.push_back(currentCell);
2303 emit log(
LOGERR,tr(
"Read corrupted face data!"));
2313 _in.seek(_in.pos() + entryCount *
sizeof(quint32) /
sizeof(
char) );
2325 while ( _spec.simplified().size() == 0 ) {
2328 if ( _in.atEnd() ) {
2329 emit log(
LOGERR,tr(
"File end when reading cell specification!"));
2333 _spec = _in.readLine();
2336 if ( ! _spec.contains(
"CELL_TYPES") ) {
2337 emit log(
LOGERR,tr(
"Wrong token! Expected CELL_TYPES but got : %1").arg(_spec));
2342 cellLine = _spec.split(
" ",QString::SkipEmptyParts);
2345 if ( cellLine.size() != 2 ) {
2346 emit log(
LOGERR,tr(
"Expected to get CELL_TYPES line with exactly 2 entries, but %1 found!").arg(cellLine.size()));
2351 quint32 cellCountTypes = cellLine[1].toUInt(&ok);
2354 emit log(
LOGERR,tr(
"Expected to get number of cell types, but read %1 !").arg(cellLine[1]));
2358 if (cellCountTypes != cellCount ) {
2359 emit log(
LOGERR,tr(
"cellCountTypes != cellCount !").arg(cellLine.size()));
2364 while ( read < cellCount) {
2371 _in.device()->read((
char*)&type,
sizeof(quint32));
2375 _cells[read].type = type;
2377 if ( _in.status() != QTextStream::Ok ) {
2378 emit log(
LOGERR,tr(
"Read corrupted cell type data!"));
2387 _in.seek(_in.pos() + read *
sizeof(quint32) /
sizeof(
char) );
2395 for (
unsigned int i = 0 ; i < _cells.size() ; ++i ) {
2396 if ( _cells[i].type == 1 ) {
2401 }
else if ( _cells[i].type == 2 ) {
2406 }
else if ( _cells[i].type == 3 ) {
2409 emit log(
LOGWARN,tr(
"Unsupported Cell Type LINE") );
2411 }
else if ( _cells[i].type == 4 ) {
2414 emit log(
LOGWARN,tr(
"Unsupported Cell Type POLY_LINE") );
2416 }
else if ( _cells[i].type == 5 ) {
2418 _cells[i].index =
addFace(_mesh, _cells[i].indices);
2419 }
else if ( _cells[i].type == 6 ) {
2422 for (
unsigned int j = 2 ; j < _cells[i].indices.size() ; ++j) {
2424 _cells[i].index =
addFace(_mesh, _cells[i].indices[j-2],_cells[i].indices[j],_cells[i].indices[j-1]);
2426 _cells[i].index =
addFace(_mesh, _cells[i].indices[j-2],_cells[i].indices[j-1],_cells[i].indices[j]);
2431 }
else if ( _cells[i].type == 7 ) {
2434 _cells[i].index =
addFace(_mesh, _cells[i].indices);
2436 }
else if ( _cells[i].type == 8 ) {
2439 emit log(
LOGWARN,tr(
"Unsupported Cell Type PIXEL") );
2441 }
else if ( _cells[i].type == 9 ) {
2444 _cells[i].index =
addFace(_mesh, _cells[i].indices);
2446 }
else if ( _cells[i].type == 10 ) {
2448 _cells[i].index =
addTetraCell(_mesh, _cells[i].indices);
2450 }
else if ( _cells[i].type == 11 ) {
2453 emit log(
LOGWARN,tr(
"Unsupported Cell Type VOXEL") );
2455 }
else if ( _cells[i].type == 12 ) {
2458 _cells[i].index =
addHexaCell(_mesh, _cells[i].indices);
2459 }
else if ( _cells[i].type == 13 ) {
2462 _cells[i].index =
addWedgeCell(_mesh, _cells[i].indices);
2463 }
else if ( _cells[i].type == 14 ) {
2469 emit log(
LOGERR,tr(
"Unknown cell type").arg(_cells[i].type) );
2473 std::cerr <<
"Read " << read <<
" Cells " << std::endl;
2474 std::cerr <<
"Vector has size: " << _cells.size() << std::endl;
2480 template <
typename MeshT>
2481 bool FileVTKPlugin::loadMesh(QTextStream& _in,MeshT*& _mesh, Dataset _type){
2484 if ( _type != POLYDATA && _type != UNSTRUCTURED_GRID ) {
2485 emit log(
LOGERR,
"Unsupported DATASET" );
2494 bool pointNormalsRead =
false;
2495 bool faceNormalsRead =
false;
2498 bool pointData =
false;
2501 quint32 pointDataSize = 0;
2504 bool cellData =
false;
2507 quint32 cellDataSize = 0;
2509 std::vector<CellType> cells;
2513 line = _in.readLine();
2516 while ( line.simplified().size() == 0 ) {
2519 if ( _in.atEnd() ) {
2521 std::cerr <<
"atEnd" << std::endl;
2525 line = _in.readLine();
2532 std::cerr <<
"Line is: " << line.toStdString() << std::endl;
2535 if ( line.contains(
"POINTS") ) {
2538 }
else if ( line.contains(
"POINT_DATA") ) {
2543 QStringList pointDataLine = line.split(
" ",QString::SkipEmptyParts);
2546 if ( pointDataLine.size() != 2 ) {
2547 emit log(
LOGERR,tr(
"Expected to get POINT_DATA line with exactly 2 entries, but %1 found!").arg(line.size()));
2552 pointDataSize = pointDataLine[1].toUInt(&ok);
2557 std::cerr <<
"Point data mode with " << pointDataSize <<
"Elements" << std::endl;
2559 }
else if ( line.contains(
"CELL_DATA") ) {
2564 QStringList cellDataLine = line.split(
" ",QString::SkipEmptyParts);
2567 if ( cellDataLine.size() != 2 ) {
2568 emit log(
LOGERR,tr(
"Expected to get CELL_DATA line with exactly 2 entries, but %1 found!").arg(line.size()));
2573 cellDataSize = cellDataLine[1].toUInt(&ok);
2578 std::cerr <<
"Cell data mode with " << cellDataSize <<
"Elements" << std::endl;
2580 }
else if ( line.contains(
"VERTICES") ) {
2581 std::cerr <<
"Vertices will be skipped as they are already added!" << std::endl;
2582 }
else if ( line.contains(
"LINES") ) {
2584 }
else if ( line.contains(
"POLYGONS") ) {
2586 }
else if ( line.contains(
"TRIANGLE_STRIPS") ) {
2588 }
else if ( line.contains(
"CELL") ) {
2590 }
else if ( line.contains(
"NORMALS") ) {
2594 pointNormalsRead =
true;
2595 }
else if (cellData) {
2597 faceNormalsRead =
true;
2599 emit log(
LOGERR,tr(
"Got normals keyword but we are neither in pointdata nor celldata mode") );
2604 std::cerr <<
"Unrecognized keyword : " << line.toStdString() << std::endl;
2609 if ( !faceNormalsRead )
2612 if ( !pointNormalsRead )
2626 forceTriangleMesh_ =
true;
2628 forcePolyMesh_ =
true;
2635 bool FileVTKPlugin::saveObject(
int _id, QString _filename) {
2639 emit log(
LOGERR, tr(
"saveObject : cannot get object id %1 for save name %2").arg(_id).arg(_filename) );
2643 std::string filename = std::string( _filename.toUtf8() );
2645 std::fstream ofs( filename.c_str(), std::ios_base::out );
2649 emit log(
LOGERR, tr(
"saveObject : Cannot not open file %1 for writing!").arg(_filename) );
2658 object->setFromFileName(_filename);
2659 object->setName(object->
filename());
2664 emit log(
LOGINFO, tr(
"Saved object to ") + _filename );
2668 emit log(
LOGERR, tr(
"Unable to save ") + _filename);
2674 object->setFromFileName(_filename);
2675 object->setName(object->
filename());
2680 emit log(
LOGINFO, tr(
"Saved object to ") + _filename );
2684 emit log(
LOGERR, tr(
"Unable to save ") + _filename);
2689 #ifdef ENABLE_OPENVOLUMEMESH_POLYHEDRAL_SUPPORT 2693 object->setFromFileName(_filename);
2694 object->setName(object->
filename());
2699 emit log(
LOGINFO, tr(
"Saved object to ") + _filename );
2703 emit log(
LOGERR, tr(
"Unable to save ") + _filename);
2709 #ifdef ENABLE_OPENVOLUMEMESH_HEXAHEDRAL_SUPPORT 2713 object->setFromFileName(_filename);
2714 object->setName(object->
filename());
2719 emit log(
LOGINFO, tr(
"Saved object to ") + _filename );
2723 emit log(
LOGERR, tr(
"Unable to save ") + _filename);
2729 #ifdef ENABLE_OPENVOLUMEMESH_TETRAHEDRAL_SUPPORT 2730 else if ( object->
dataType( DATA_TETRAHEDRAL_MESH ) )
2733 object->setFromFileName(_filename);
2734 object->setName(object->
filename());
2736 TetrahedralMeshObject* tetrahedralObj =
dynamic_cast<TetrahedralMeshObject*
>( object );
2738 if (
writeMesh(ofs, *tetrahedralObj->mesh())) {
2739 emit log(
LOGINFO, tr(
"Saved object to ") + _filename );
2743 emit log(
LOGERR, tr(
"Unable to save ") + _filename);
2751 emit log(
LOGERR, tr(
"Unable to save (object is not a compatible mesh type)"));
2760 template<
class MeshT >
2767 _out <<
"# vtk DataFile Version 2.0\n";
2769 _out <<
"Mesh saved from OpenFlipper - www.openflipper.org\n";
2789 if( OpenFlipper::Options::nogui() )
2794 if(saveBinary_->isChecked()) userWriteOptions_ |= BINARY;
2795 else {
if(userWriteOptions_ & BINARY) userWriteOptions_ -= BINARY; }
2797 if(saveFaceNormals_) {
2798 if(saveFaceNormals_->isChecked()) userWriteOptions_ |= FACENORMALS;
2799 else {
if(userWriteOptions_ & FACENORMALS) userWriteOptions_ -= FACENORMALS; }
2801 if(saveVertexNormals_) {
2802 if(saveVertexNormals_->isChecked()) userWriteOptions_ |= VERTEXNORMALS;
2803 else {
if(userWriteOptions_ & VERTEXNORMALS) userWriteOptions_ -= VERTEXNORMALS; }
2805 if(saveVertexTexCoords_) {
2806 if(saveVertexTexCoords_->isChecked()) userWriteOptions_ |= VERTEXTEXCOORDS;
2807 else {
if(userWriteOptions_ & VERTEXTEXCOORDS) userWriteOptions_ -= VERTEXTEXCOORDS; }
2811 #if QT_VERSION < 0x050000
void slotSaveDefault()
Slot called when user wants to save the given Save options as default.
static constexpr size_t size()
returns dimension of the vector
void updateVertexNormalsOfOpenMesh(MeshT *&_mesh)
Updates vertex normals.
void updateFaceNormalsOfOpenMesh(MeshT *&_mesh)
Updates face normals.
Add normals to mesh item (vertices/faces)
int loadObject(QString _filename)
Loads Object and converts it to a triangle mesh if possible.
Type for a MeshObject containing a triangle mesh.
bool getMesh(int _identifier, PolyMesh *&_mesh)
Get the Poly Mesh which has the given identifier.
void initializePlugin()
Initialize Plugin.
int addHexaCellToOpenMesh(MeshT _mesh, std::vector< quint32 > _indices)
Adds a hexa cell to the mesh. (Does nothing, yet)
QString filename() const
return the filename of the object
bool loadMeshLines(QString _spec, QTextStream &_in, MeshT *&_mesh)
Reads lines from the stream and adds them to the mesh.
bool getObject(int _identifier, BSplineCurveObject *&_object)
DataType supportedType()
Return your supported object type( e.g. DATA_TRIANGLE_MESH )
bool dataType(DataType _type) const
#define DATA_POLYHEDRAL_MESH
bool loadMeshPolygons(QString _spec, QTextStream &_in, MeshT *&_mesh, std::vector< CellType > &_cells)
Reads polygons from the stream and adds them to the mesh.
MeshT * mesh()
return a pointer to the mesh
DLLEXPORT OpenFlipperQSettings & OpenFlipperSettings()
QSettings object containing all program settings of OpenFlipper.
int addTetraCellToOpenMesh(MeshT _mesh, std::vector< quint32 > _indices)
Adds a tetra cell to the mesh. (Does nothing, yet)
void addCellNormal(MeshT *&_mesh, const CellType &_cell, OpenMesh::Vec3d _normal)
Adds a normal to the cell.
void setFromFileName(const QString &_filename)
MeshT * mesh()
return a pointer to the mesh
int addHexaCell(TriMesh *&_mesh, std::vector< quint32 > _indices)
Adds a hexa cell to the mesh. (Does nothing, yet)
bool is_valid() const
The handle is valid iff the index is not equal to -1.
void updateFaceNormals(TriMesh *&_mesh)
Updates face normals.
Property classes for the different entity types.
void updateVertexNormals(TriMesh *&_mesh)
Updates vertex normals.
#define DATA_HEXAHEDRAL_MESH
void setValue(const QString &key, const QVariant &value)
Wrapper function which makes it possible to enable Debugging output with -DOPENFLIPPER_SETTINGS_DEBUG...
int idx() const
Get the underlying index of this handle.
QWidget * loadOptionsWidget(QString)
bool binary_
Reading binary file?
bool writeMesh(std::ostream &_out, MeshT &_mesh)
Writes the header of the VTK file, then calls writeASCIIData (binary VTK is currently unsupported) ...
void removeTemporaryProperties(TriMesh *&_mesh)
Removed temporary properties that might have been added during file reading.
BestMeshType findBestObjectType(QString _filename)
Reads the file to check for present primitives and returns the object type that fits best...
const DataType DATA_GROUP(1)
Items used for Grouping.
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 addFaceNormalToOpenMesh(MeshT _mesh, quint32 _index, OpenMesh::Vec3d _normal)
Adds a face normal.
bool writeASCIIData(std::ostream &_out, TriMesh &_mesh)
Writes the data of the VTK file in ASCII format.
int addWedgeCellToOpenMesh(MeshT _mesh, std::vector< quint32 > _indices)
Adds a wedge cell to the mesh. (Does nothing, yet)
Handle for a vertex entity.
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.
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.
int addTetraCell(TriMesh *&_mesh, std::vector< quint32 > _indices)
Adds a tetra cell to the mesh. (Does nothing, yet)
void addVertexNormalToOpenMesh(MeshT _mesh, quint32 _index, OpenMesh::Vec3d _normal)
Adds a vertex normal.
int addFaceToOpenMesh(MeshT *&_mesh, std::vector< quint32 > _indices)
Adds a face to the mesh.
FileVTKPlugin()
Constructor.
PolyhedralMesh * polyhedralMesh(BaseObjectData *_object)
Get an PolyhedralMesh from an object.
QWidget * saveOptionsWidget(QString)
void addFaceNormal(TriMesh *&_mesh, quint32 _index, OpenMesh::Vec3d _normal)
Adds a face normal.
void removeTemporaryPropertiesOfOpenMesh(MeshT *&_mesh)
Removed temporary properties that might have been added during file reading.
int addPyramidCell(TriMesh *&_mesh, std::vector< quint32 > _indices)
Adds a pyramid cell to the mesh. (Does nothing, yet)
void setNormalsOfDuplicatedVertices(TriMesh *&_mesh)
Sets normals of duplicated vertices that were created for non-manifold meshes.
Add 2D texture coordinates (vertices, halfedges)
bool loadMeshTriangleStrips(QString _spec, QTextStream &_in, MeshT *&_mesh, std::vector< CellType > &_cells)
Reads triangle strips from the stream and adds them to the mesh.
Handle for a face entity.
Type for a Meshobject containing a poly mesh.
bool writeASCIIDataOfOpenMesh(std::ostream &_out, MeshT &_mesh)
Writes the data of the VTK file in ASCII format.
int addWedgeCell(TriMesh *&_mesh, std::vector< quint32 > _indices)
Adds a wedge cell to the mesh. (Does nothing, yet)
const UpdateType UPDATE_ALL(UpdateTypeSet(1))
Identifier for all updates.
void addVertexNormal(TriMesh *&_mesh, quint32 _index, OpenMesh::Vec3d _normal)
Adds a vertex normal.
bool loadMeshPoints(QString _spec, QTextStream &_in, MeshT *&_mesh)
Reads points 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.
QString description()
Return a description of what the plugin is doing.
#define DATA_TRIANGLE_MESH
HexahedralMesh * hexahedralMesh(BaseObjectData *_object)
Get an HexahedralMesh from an object.
virtual void setName(QString _name)
path to the file from which the object is loaded ( defaults to "." )
int addPyramidCellToOpenMesh(MeshT _mesh, std::vector< quint32 > _indices)
Adds a pyramid cell to the mesh. (Does nothing, yet)
int addFace(TriMesh *&_mesh, std::vector< quint32 > _indices)
Adds a face to the mesh.