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
143 if (saveOptions_ == 0){
145 saveOptions_ =
new QWidget();
146 QVBoxLayout* layout =
new QVBoxLayout();
147 layout->setAlignment(Qt::AlignTop);
149 saveBinary_ =
new QCheckBox(
"Save Binary");
150 layout->addWidget(saveBinary_);
151 saveBinary_->setCheckable(
false);
153 saveFaceNormals_ =
new QCheckBox(
"Save Face Normals");
154 layout->addWidget(saveFaceNormals_);
156 saveVertexNormals_ =
new QCheckBox(
"Save Vertex Normals");
157 layout->addWidget(saveVertexNormals_);
159 saveVertexTexCoords_ =
new QCheckBox(
"Save Vertex TexCoords");
160 layout->addWidget(saveVertexTexCoords_);
162 savePrecisionLabel_ =
new QLabel(
"Writer Precision");
163 layout->addWidget(savePrecisionLabel_);
165 savePrecision_ =
new QSpinBox();
166 savePrecision_->setMinimum(1);
167 savePrecision_->setMaximum(12);
168 savePrecision_->setValue(6);
169 layout->addWidget(savePrecision_);
171 saveDefaultButton_ =
new QPushButton(
"Make Default");
172 layout->addWidget(saveDefaultButton_);
174 saveOptions_->setLayout(layout);
176 connect(saveBinary_, SIGNAL(clicked(
bool)), savePrecision_, SLOT(setDisabled(
bool)));
177 connect(saveDefaultButton_, SIGNAL(clicked()),
this, SLOT(
slotSaveDefault()));
179 saveBinary_->setChecked(
OpenFlipperSettings().value(
"FileVtk/Save/Binary",
false).toBool() );
180 saveFaceNormals_->setChecked(
OpenFlipperSettings().value(
"FileVtk/Save/FaceNormals",
true).toBool() );
181 saveVertexNormals_->setChecked(
OpenFlipperSettings().value(
"FileVtk/Save/VertexNormals",
true).toBool() );
182 saveVertexTexCoords_->setChecked(
OpenFlipperSettings().value(
"FileVtk/Save/VertexTexCoords",
true).toBool() );
207 template <
typename MeshT>
210 emit log(
LOGWARN,tr(
"Unsupported Cell Type TETRA") );
214 template <
typename MeshT>
217 emit log(
LOGWARN,tr(
"Unsupported Cell Type HEXAHEDRON") );
221 template <
typename MeshT>
224 emit log(
LOGWARN,tr(
"Unsupported Cell Type WEDGE") );
228 template <
typename MeshT>
231 emit log(
LOGWARN,tr(
"Unsupported Cell Type PYRAMID") );
235 template <
typename MeshT>
238 std::vector<OpenMesh::VertexHandle> handles;
239 for (std::vector<quint32>::const_iterator it = _indices.begin(); it != _indices.end(); ++it)
240 handles.push_back(_mesh->vertex_handle(*it));
247 std::vector< OpenMesh::VertexHandle > inverseHandles;
248 for (
int i = handles.size()-1 ; i >= 0 ; --i)
249 inverseHandles.push_back(handles[i]);
251 fh = _mesh->add_face(inverseHandles);
260 template <
typename MeshT>
266 return _mesh->add_face(v1,v2,v3).
idx();
269 template <
typename MeshT>
272 _mesh->update_face_normals();
279 template <
typename MeshT>
282 _mesh->update_vertex_normals();
285 template <
typename MeshT>
290 if (! _mesh->get_property_handle(originalVertexIdx,
"FileVTKPlugin_originalVertexIdx")) {
291 _mesh->remove_property( originalVertexIdx );
295 template <
typename MeshT>
300 _mesh->set_normal( vh , _normal );
304 template <
typename MeshT>
309 _mesh->set_normal( fh, _normal );
312 template <
typename MeshT>
315 if ((_cell.type <= 4) || (_cell.type >= 10))
318 emit log(
LOGWARN,tr(
"Normals not supported for type %1").arg(_cell.type) );
320 else if (_cell.type == 5)
325 else if (_cell.type == 6)
328 int numberOfTriangles = _cell.indices.size() - 2;
330 for (
int i = 0; i < numberOfTriangles; i++)
333 else if ((_cell.type >= 7) && (_cell.type <= 9))
336 if (forceTriangleMesh_)
342 int numberOfTriangles = _cell.indices.size() - 2;
343 for (
int i = 0; i < numberOfTriangles; i++)
355 template <
typename MeshT>
360 if (! _mesh->get_property_handle(originalVertexIdx,
"FileVTKPlugin_originalVertexIdx")) {
367 typename MeshT::VertexIter vit = _mesh->vertices_begin();
368 typename MeshT::VertexIter vend = _mesh->vertices_end();
370 for(; vit != vend; ++vit) {
371 if ( _mesh->property(originalVertexIdx, *vit).is_valid() ) {
373 _mesh->set_normal( *vit, _mesh->normal(_mesh->property (originalVertexIdx, *vit) ) );
378 template<
class MeshT >
381 if ( !OpenFlipper::Options::savingSettings() && saveOptions_ != 0)
382 _out.precision(savePrecision_->value());
384 _out <<
"DATASET POLYDATA\n";
386 typename MeshT::Point p;
391 typename MeshT::VertexIter vit = _mesh.vertices_begin();
392 typename MeshT::VertexIter end_vit = _mesh.vertices_end();
393 typename MeshT::FaceIter fit = _mesh.faces_begin();
394 typename MeshT::FaceIter end_fit = _mesh.faces_end();
395 typename MeshT::FaceVertexIter fvit;
397 int total_face_vertices = _mesh.n_faces();
398 for (; fit != end_fit; ++fit) {
399 total_face_vertices += _mesh.valence(*fit);
402 _out <<
"POINTS " << _mesh.n_vertices() <<
" float\n";
403 for (; vit != end_vit; ++vit) {
405 p = _mesh.point(*vit);
406 _out << p[0] <<
" " << p[1] <<
" " << p[2];
411 _out <<
"POLYGONS "<< _mesh.n_faces() <<
" " << total_face_vertices <<
"\n";
412 for (fit = _mesh.faces_begin(); fit != end_fit; ++fit) {
414 _out << _mesh.valence(*fit);
417 fvit = _mesh.fv_iter(*fit);
420 for (;fvit.is_valid(); ++fvit) {
421 _out <<
" " << fvit->idx();
431 _out <<
"CELL_DATA "<< _mesh.n_faces() <<
"\n";
434 if (_mesh.has_face_normals() && (userWriteOptions_ & FileVTKPlugin::FACENORMALS)) {
435 _out <<
"NORMALS faceNormals float\n";
436 for (fit = _mesh.faces_begin(); fit != end_fit; ++fit) {
437 n = _mesh.normal(*fit);
438 _out << n[0] <<
" " << n[1] <<
" " << n[2];
444 _out <<
"POINT_DATA "<< _mesh.n_vertices() <<
"\n";
447 if (_mesh.has_vertex_normals() && (userWriteOptions_ & FileVTKPlugin::VERTEXNORMALS)) {
448 _out <<
"NORMALS vertexNormals float\n";
449 for (vit = _mesh.vertices_begin(); vit != end_vit; ++vit) {
450 n = _mesh.normal(*vit);
451 _out << n[0] <<
" " << n[1] <<
" " << n[2];
457 if (_mesh.has_vertex_texcoords2D() && (userWriteOptions_ & FileVTKPlugin::VERTEXTEXCOORDS)) {
458 _out <<
"TEXTURE_COORDINATES vertexTexcoords 2 float\n";
459 for (vit = _mesh.vertices_begin(); vit != end_vit; ++vit) {
460 t = _mesh.texcoord2D(*vit);
461 _out << t[0] <<
" " << t[1];
506 #ifdef ENABLE_OPENVOLUMEMESH_SUPPORT
508 template <
typename MeshT>
509 int FileVTKPlugin::addTetraCellToOpenVolumeMesh(MeshT _mesh, std::vector<quint32> _indices)
511 if (_indices.size() != 4)
514 std::vector< std::vector<OpenVolumeMesh::VertexHandle> > faces;
515 faces.push_back(std::vector<OpenVolumeMesh::VertexHandle>());
516 faces[0].push_back(_indices[0]);
517 faces[0].push_back(_indices[1]);
518 faces[0].push_back(_indices[2]);
519 faces.push_back(std::vector<OpenVolumeMesh::VertexHandle>());
520 faces[1].push_back(_indices[0]);
521 faces[1].push_back(_indices[3]);
522 faces[1].push_back(_indices[1]);
523 faces.push_back(std::vector<OpenVolumeMesh::VertexHandle>());
524 faces[2].push_back(_indices[1]);
525 faces[2].push_back(_indices[3]);
526 faces[2].push_back(_indices[2]);
527 faces.push_back(std::vector<OpenVolumeMesh::VertexHandle>());
528 faces[3].push_back(_indices[0]);
529 faces[3].push_back(_indices[2]);
530 faces[3].push_back(_indices[3]);
532 std::vector<OpenVolumeMesh::HalfFaceHandle> halffacehandles;
533 for (
unsigned int i = 0; i < faces.size(); i++)
534 halffacehandles.push_back(_mesh->halfface(faces[i]));
536 for (
unsigned int i = 0; i < halffacehandles.size(); i++)
541 halffacehandles[i] = _mesh->halfface_handle(fh, 0);
544 return _mesh->add_cell(halffacehandles).idx();
548 template <
typename MeshT>
549 int FileVTKPlugin::addHexaCellToOpenVolumeMesh(MeshT _mesh, std::vector<quint32> _indices)
551 if (_indices.size() != 8)
552 { emit log(
LOGWARN,tr(
"Expected 8 indices to add Hexahedron but got %1").arg(_indices.size()) ); }
554 std::vector< std::vector<OpenVolumeMesh::VertexHandle> > faces;
555 faces.push_back(std::vector<OpenVolumeMesh::VertexHandle>());
556 faces[0].push_back(_indices[0]);
557 faces[0].push_back(_indices[1]);
558 faces[0].push_back(_indices[2]);
559 faces[0].push_back(_indices[3]);
560 faces.push_back(std::vector<OpenVolumeMesh::VertexHandle>());
561 faces[1].push_back(_indices[0]);
562 faces[1].push_back(_indices[4]);
563 faces[1].push_back(_indices[5]);
564 faces[1].push_back(_indices[1]);
565 faces.push_back(std::vector<OpenVolumeMesh::VertexHandle>());
566 faces[2].push_back(_indices[0]);
567 faces[2].push_back(_indices[3]);
568 faces[2].push_back(_indices[7]);
569 faces[2].push_back(_indices[4]);
570 faces.push_back(std::vector<OpenVolumeMesh::VertexHandle>());
571 faces[3].push_back(_indices[1]);
572 faces[3].push_back(_indices[5]);
573 faces[3].push_back(_indices[6]);
574 faces[3].push_back(_indices[2]);
575 faces.push_back(std::vector<OpenVolumeMesh::VertexHandle>());
576 faces[4].push_back(_indices[2]);
577 faces[4].push_back(_indices[6]);
578 faces[4].push_back(_indices[7]);
579 faces[4].push_back(_indices[3]);
580 faces.push_back(std::vector<OpenVolumeMesh::VertexHandle>());
581 faces[5].push_back(_indices[4]);
582 faces[5].push_back(_indices[7]);
583 faces[5].push_back(_indices[6]);
584 faces[5].push_back(_indices[5]);
586 std::vector<OpenVolumeMesh::HalfFaceHandle> halffacehandles;
587 for (
unsigned int i = 0; i < faces.size(); i++)
588 halffacehandles.push_back(_mesh->halfface(faces[i]));
590 for (
unsigned int i = 0; i < halffacehandles.size(); i++)
595 halffacehandles[i] = _mesh->halfface_handle(fh, 0);
598 return _mesh->add_cell(halffacehandles).idx();
601 template <
typename MeshT>
602 int FileVTKPlugin::addWedgeCellToOpenVolumeMesh(MeshT _mesh, std::vector<quint32> _indices)
604 if (_indices.size() != 6)
605 { emit log(
LOGWARN,tr(
"Expected 6 indices to add Hexahedron but got %1").arg(_indices.size()) ); }
607 std::vector< std::vector<OpenVolumeMesh::VertexHandle> > faces;
608 faces.push_back(std::vector<OpenVolumeMesh::VertexHandle>());
609 faces[0].push_back(_indices[0]);
610 faces[0].push_back(_indices[1]);
611 faces[0].push_back(_indices[4]);
612 faces[0].push_back(_indices[3]);
613 faces.push_back(std::vector<OpenVolumeMesh::VertexHandle>());
614 faces[1].push_back(_indices[0]);
615 faces[1].push_back(_indices[2]);
616 faces[1].push_back(_indices[1]);
617 faces.push_back(std::vector<OpenVolumeMesh::VertexHandle>());
618 faces[2].push_back(_indices[3]);
619 faces[2].push_back(_indices[4]);
620 faces[2].push_back(_indices[5]);
621 faces.push_back(std::vector<OpenVolumeMesh::VertexHandle>());
622 faces[3].push_back(_indices[0]);
623 faces[3].push_back(_indices[3]);
624 faces[3].push_back(_indices[5]);
625 faces[3].push_back(_indices[2]);
626 faces.push_back(std::vector<OpenVolumeMesh::VertexHandle>());
627 faces[4].push_back(_indices[1]);
628 faces[4].push_back(_indices[2]);
629 faces[4].push_back(_indices[5]);
630 faces[4].push_back(_indices[4]);
632 std::vector<OpenVolumeMesh::HalfFaceHandle> halffacehandles;
633 for (
unsigned int i = 0; i < faces.size(); i++)
634 halffacehandles.push_back(_mesh->halfface(faces[i]));
636 for (
unsigned int i = 0; i < halffacehandles.size(); i++)
641 halffacehandles[i] = _mesh->halfface_handle(fh, 0);
644 return _mesh->add_cell(halffacehandles).idx();
647 template <
typename MeshT>
648 int FileVTKPlugin::addPyramidCellToOpenVolumeMesh(MeshT _mesh, std::vector<quint32> _indices)
650 if (_indices.size() != 6)
651 { emit log(
LOGWARN,tr(
"Expected 6 indices to add Hexahedron but got %1").arg(_indices.size()) ); }
653 std::vector< std::vector<OpenVolumeMesh::VertexHandle> > faces;
654 faces.push_back(std::vector<OpenVolumeMesh::VertexHandle>());
655 faces[0].push_back(_indices[0]);
656 faces[0].push_back(_indices[1]);
657 faces[0].push_back(_indices[2]);
658 faces[0].push_back(_indices[3]);
659 faces.push_back(std::vector<OpenVolumeMesh::VertexHandle>());
660 faces[1].push_back(_indices[0]);
661 faces[1].push_back(_indices[4]);
662 faces[1].push_back(_indices[1]);
663 faces.push_back(std::vector<OpenVolumeMesh::VertexHandle>());
664 faces[2].push_back(_indices[0]);
665 faces[2].push_back(_indices[3]);
666 faces[2].push_back(_indices[4]);
667 faces.push_back(std::vector<OpenVolumeMesh::VertexHandle>());
668 faces[3].push_back(_indices[2]);
669 faces[3].push_back(_indices[4]);
670 faces[3].push_back(_indices[3]);
671 faces.push_back(std::vector<OpenVolumeMesh::VertexHandle>());
672 faces[4].push_back(_indices[1]);
673 faces[4].push_back(_indices[4]);
674 faces[4].push_back(_indices[2]);
676 std::vector<OpenVolumeMesh::HalfFaceHandle> halffacehandles;
677 for (
unsigned int i = 0; i < faces.size(); i++)
678 halffacehandles.push_back(_mesh->halfface(faces[i]));
680 for (
unsigned int i = 0; i < halffacehandles.size(); i++)
685 halffacehandles[i] = _mesh->halfface_handle(fh, 0);
688 return _mesh->add_cell(halffacehandles).idx();
691 template <
typename MeshT>
692 int FileVTKPlugin::addFaceToOpenVolumeMesh(MeshT*& _mesh, std::vector<quint32> _indices)
694 if (_indices.size() < 3)
695 { emit log(
LOGWARN,tr(
"Expected at least 3 indices to add a face but got %1").arg(_indices.size()) ); }
697 std::vector<OpenVolumeMesh::VertexHandle> face;
698 for (
unsigned int i = 0; i < _indices.size(); i++)
703 halffacehandle = _mesh->halfface(face);
704 if (halffacehandle == -1)
707 halffacehandle = _mesh->halfface_handle(fh, 0);
709 return halffacehandle.idx();
712 template <
typename MeshT>
713 int FileVTKPlugin::addFaceToOpenVolumeMesh(MeshT*& _mesh, quint32 _index1, quint32 _index2, quint32 _index3)
715 std::vector<OpenVolumeMesh::VertexHandle> face;
721 halffacehandle = _mesh->halfface(face);
722 if (halffacehandle == -1)
725 halffacehandle = _mesh->halfface_handle(fh, 0);
727 return halffacehandle.idx();
730 template <
typename MeshT>
731 void FileVTKPlugin::addVertexNormalToOpenVolumeMesh(MeshT _mesh, quint32 _index,
OpenMesh::Vec3d _normal)
737 template <
typename MeshT>
738 void FileVTKPlugin::addFaceNormalToOpenVolumeMesh(MeshT _mesh, quint32 _index,
OpenMesh::Vec3d _normal)
744 if (hfh == _mesh->halfface_handle(fh, 0))
745 faceNormals[_mesh->face_handle(_index)] = _normal;
747 faceNormals[_mesh->face_handle(_index)] = -_normal;
751 template <
typename MeshT>
754 int incidentFaces = _mesh.cell(_cellHandle).halffaces().size();
755 int incidentVertices = 0;
759 if ((incidentFaces == 4) && (incidentVertices == 4))
761 else if ((incidentFaces == 6) && (incidentVertices == 8))
763 else if ((incidentFaces == 5) && (incidentVertices == 6))
765 else if ((incidentFaces == 5) && (incidentVertices == 5))
771 template <
typename MeshT>
774 std::vector<OpenVolumeMesh::HalfEdgeHandle> halfedges = _mesh.face(_faceHandle).halfedges();
775 if (halfedges.size() == 3)
781 template <
typename MeshT>
790 std::vector<OpenVolumeMesh::HalfEdgeHandle> halfedges = face.halfedges();
791 std::vector<int> indices;
792 for (
unsigned int i = 0; i < halfedges.size(); i++)
793 indices.push_back(_mesh.halfedge(halfedges[i]).from_vertex().idx());
795 if ((cvit->idx() != indices[0]) && ((*cvit).idx() != indices[1]) && ((*cvit).idx() != indices[2]))
796 indices.push_back(cvit->idx());
799 else if (_cellType == 12)
806 std::vector<int> indices;
807 for (
unsigned int i = 0; i < 4; i++)
810 indices.push_back(edge.from_vertex().idx());
811 heh = _mesh.next_halfedge_in_halfface(heh, hfh);
816 heh = _mesh.opposite_halfedge_handle(heh);
817 heh = _mesh.next_halfedge_in_halfface(heh, intermediateHalfFaceHandle);
818 heh = _mesh.next_halfedge_in_halfface(heh, intermediateHalfFaceHandle);
820 heh = _mesh.opposite_halfedge_handle(heh);
823 for (
unsigned int i = 0; i < 4; i++)
826 indices.push_back(edge.to_vertex().idx());
827 heh = _mesh.prev_halfedge_in_halfface(heh, oppositeHalfFaceHandle);
831 else if (_cellType == 13)
836 for (
unsigned int i = 0; i < cell.halffaces().size(); i++)
837 if (_mesh.halfface(cell.halffaces()[i]).halfedges().size() == 3)
838 hfh = cell.halffaces()[i];
841 std::vector<int> indices;
842 for (
unsigned int i = 0; i < 3; i++)
845 indices.push_back(edge.from_vertex().idx());
846 heh = _mesh.prev_halfedge_in_halfface(heh, hfh);
851 heh = _mesh.opposite_halfedge_handle(heh);
852 heh = _mesh.next_halfedge_in_halfface(heh, intermediateHalfFaceHandle);
853 heh = _mesh.next_halfedge_in_halfface(heh, intermediateHalfFaceHandle);
855 heh = _mesh.opposite_halfedge_handle(heh);
858 for (
unsigned int i = 0; i < 3; i++)
861 indices.push_back(edge.to_vertex().idx());
862 heh = _mesh.next_halfedge_in_halfface(heh, oppositeHalfFaceHandle);
867 else if (_cellType == 14)
872 std::vector<OpenVolumeMesh::HalfFaceHandle> halffaces = cell.halffaces();
874 for (
unsigned int i = 0; i < halffaces.size(); i++)
875 if (_mesh.halfface(halffaces[i]).halfedges().size() == 4)
876 face = _mesh.halfface(halffaces[i]);
877 std::vector<OpenVolumeMesh::HalfEdgeHandle> halfedges = face.halfedges();
878 std::vector<int> indices;
879 for (
unsigned int i = 0; i < halfedges.size(); i++)
880 indices.push_back(_mesh.halfedge(halfedges[i]).from_vertex().idx());
882 if ((cvit->idx() != indices[0]) && ((*cvit).idx() != indices[1]) && ((*cvit).idx() != indices[2]) && ((*cvit).idx() != indices[3]))
883 indices.push_back(cvit->idx());
887 return std::vector<int>();
890 template <
typename MeshT>
891 bool FileVTKPlugin::writeASCIIDataOfOpenVolumeMesh(std::ostream& _out, MeshT& _mesh)
893 if ( !OpenFlipper::Options::savingSettings() && saveOptions_ != 0)
894 _out.precision(savePrecision_->value());
896 _out <<
"DATASET UNSTRUCTURED_GRID\n";
903 _out <<
"POINTS " << _mesh.n_vertices() <<
" float\n";
904 for (; vit != end_vit; ++vit) {
907 _out << p[0] <<
" " << p[1] <<
" " << p[2];
923 quint32 listSize = 0;
926 int cellType = getCellType(_mesh, *cit);
930 else if (cellType == 12 )
932 else if (cellType == 13 )
934 else if (cellType == 14 )
941 std::vector<OpenVolumeMesh::HalfFaceHandle> halffaces = _mesh.cell(*cit).halffaces();
942 for (
unsigned int i = 0; i < halffaces.size(); i++)
945 if (!(fpAlreadyStored[fh]))
949 if (!(userWriteOptions_ & FileVTKPlugin::FACENORMALS))
950 fpAlreadyStored[fh] =
true;
953 for (std::vector<OpenVolumeMesh::HalfEdgeHandle>::const_iterator heit = face.halfedges().begin();
954 heit != face.halfedges().end();
957 epAlreadyStored[_mesh.edge_handle(*heit)] =
true;
965 if (!(fpAlreadyStored[*fit]))
968 std::vector<OpenVolumeMesh::HalfEdgeHandle> halfedges = _mesh.face(*fit).halfedges();
969 for (
unsigned int i = 0; i < halfedges.size(); i++)
970 epAlreadyStored[_mesh.edge_handle(halfedges[i])] =
true;
973 listSize += 1 + halfedges.size();
981 if (!(epAlreadyStored[*eit]))
988 _out <<
"CELLS " << cellCount <<
" " << listSize <<
"\n";
997 int cellType = getCellType(_mesh, *cit);
1000 if (cellType == 10 )
1002 else if (cellType == 12 )
1004 else if (cellType == 13 )
1006 else if (cellType == 14 )
1015 std::vector<int> indices = getCellVertexIndices(_mesh, *cit, cellType);
1016 _out << indices.size();
1017 for (
unsigned int i = 0; i < indices.size(); i++)
1018 _out <<
" " << indices[i];
1028 if (!(fpAlreadyStored[*fit]))
1030 std::vector<OpenVolumeMesh::HalfEdgeHandle> halfedges = _mesh.face(*fit).halfedges();
1032 _out << halfedges.size();
1033 for (
unsigned int i = 0; i < halfedges.size(); i++)
1037 _out <<
" " << edge.from_vertex().idx();
1049 if (!(epAlreadyStored[*eit]))
1053 _out <<
" " << edge.from_vertex().idx();
1054 _out <<
" " << edge.to_vertex().idx();
1063 _out <<
"CELL_TYPES " << cellCount <<
"\n";
1068 int cellType = getCellType(_mesh, *cit);
1072 _out << cellType <<
"\n";
1079 if (!(fpAlreadyStored[*fit]))
1081 int cellType = getCellType(_mesh,*fit);
1085 _out << cellType <<
"\n";
1093 if (!(epAlreadyStored[*eit]))
1110 if ((userWriteOptions_ & FileVTKPlugin::VERTEXNORMALS))
1112 _out <<
"POINT_DATA "<< _mesh.n_vertices() <<
"\n";
1115 _out <<
"NORMALS vertex_normals float\n";
1118 _out << n[0] <<
" " << n[1] <<
" " << n[2];
1125 if ((userWriteOptions_ & FileVTKPlugin::FACENORMALS))
1127 _out <<
"CELL_DATA "<< cellCount <<
"\n";
1128 _out <<
"NORMALS face_normals float\n";
1133 int cellType = getCellType(_mesh, *cit);
1135 if (cellType == -1 )
1139 _out << 1 <<
" " << 0 <<
" " << 0;
1150 _out << n[0] <<
" " << n[1] <<
" " << n[2];
1158 if (!(epAlreadyStored[*eit]))
1160 _out << 1 <<
" " << 0 <<
" " << 0;
1171 #endif //ENABLE_OPENVOLUMEMESH_SUPPORT
1173 #ifdef ENABLE_OPENVOLUMEMESH_HEXAHEDRAL_SUPPORT
1183 #endif //ENABLE_OPENVOLUMEMESH_HEXAHEDRAL_SUPPORT
1186 #ifdef ENABLE_OPENVOLUMEMESH_POLYHEDRAL_SUPPORT
1196 #endif //ENABLE_OPENVOLUMEMESH_POLYHEDRAL_SUPPORT
1206 QFile file(_filename);
1208 if ( !file.open(QIODevice::ReadOnly) ) {
1212 QTextStream in(&file);
1214 QString line = in.readLine();
1216 QStringList header = line.split(
" ",QString::SkipEmptyParts);
1217 if ( header.size() != 5 ) {
1221 QString version = header[4];
1223 header.removeLast();
1225 QString magic = header.join(
" ");
1227 if ( magic !=
"# vtk DataFile Version" ) {
1233 QString fileTypeStr = in.readLine();
1235 fileTypeStr = fileTypeStr.simplified();
1237 if ( fileTypeStr.toLower() ==
"binary" ) {
1239 }
else if ( fileTypeStr.toLower() ==
"ascii" ) {
1247 while ( line.simplified() ==
"" )
1248 line = in.readLine();
1250 QStringList datasetList = line.split(
" ",QString::SkipEmptyParts);
1252 if ( datasetList.size() != 2 ) {
1258 datasetList[1] = datasetList[1].simplified();
1260 if ( datasetList[1] ==
"STRUCTURED_POINTS" )
1261 dataset = STRUCTURED_POINTS;
1262 else if ( datasetList[1] ==
"STRUCTURED_GRID" )
1263 dataset = STRUCTURED_GRID;
1264 else if ( datasetList[1] ==
"RECTILINEAR_GRID" )
1265 dataset = RECTILINEAR_GRID;
1266 else if ( datasetList[1] ==
"POLYDATA" )
1268 else if ( datasetList[1] ==
"UNSTRUCTURED_GRID" )
1269 dataset = UNSTRUCTURED_GRID;
1275 if ((dataset == STRUCTURED_POINTS) || (dataset == STRUCTURED_GRID) || (dataset == RECTILINEAR_GRID) )
1280 else if (dataset == POLYDATA)
1287 line = in.readLine();
1290 while ( !line.contains(
"POLYGONS") ) {
1298 line = in.readLine();
1301 QStringList polygonsLine = line.split(
" ",QString::SkipEmptyParts);
1304 if ( polygonsLine.size() != 3 ) {
1305 emit log(
LOGERR,tr(
"Expected to get Points line with exactly 3 entries, but %1 found!").arg(polygonsLine.size()));
1312 quint32 polygoncount = polygonsLine[1].toUInt(&ok);
1315 emit log(
LOGERR,tr(
"Expected to get number of points and entries, but read %1 !").arg(polygonsLine.join(
" ")));
1320 while ( read < polygoncount) {
1327 in.device()->read((
char*)&valence,
sizeof(quint32));
1332 return BMT_PolyMesh;
1338 for (
unsigned int i = 0 ; i < valence; ++i ) {
1344 in.device()->read((
char*)&valence,
sizeof(quint32));
1360 line = in.readLine();
1363 while ( !line.contains(
"CELL_TYPES") ) {
1371 line = in.readLine();
1375 QStringList cellLine = line.split(
" ",QString::SkipEmptyParts);
1378 if ( cellLine.size() != 2 ) {
1379 emit log(
LOGERR,tr(
"Expected to get CELL_TYPES line with exactly 2 entries, but %1 found!").arg(cellLine.size()));
1386 quint32 cellCountTypes = cellLine[1].toUInt(&ok);
1389 emit log(
LOGERR,tr(
"Expected to get number of cell types, but read %1 !").arg(cellLine[1]));
1393 bool triMeshPossible =
true;
1394 bool polyMeshPossible =
true;
1396 #ifndef ENABLE_OPENVOLUMEMESH_HEXAHEDRAL_SUPPORT
1397 bool hexahedralMeshPossible =
false;
1399 bool hexahedralMeshPossible =
true;
1401 #ifndef ENABLE_OPENVOLUMEMESH_POLYHEDRAL_SUPPORT
1402 bool polyhedralMeshPossible =
false;
1404 bool polyhedralMeshPossible =
true;
1408 while ( read < cellCountTypes) {
1415 in.device()->read((
char*)&type,
sizeof(quint32));
1418 if (( 1 <= type ) && (type <= 6 ))
1422 hexahedralMeshPossible =
false;
1424 else if (( 7 <= type ) && (type <= 9 ))
1429 triMeshPossible =
false;
1430 hexahedralMeshPossible =
false;
1433 else if (( 10 == type ) || ( 13 == type ) || (type == 14 ))
1437 triMeshPossible =
false;
1438 polyMeshPossible =
false;
1439 hexahedralMeshPossible =
false;
1441 else if (( 11 == type ) || ( 12 == type ))
1445 triMeshPossible =
false;
1446 polyMeshPossible =
false;
1450 if ( in.status() != QTextStream::Ok ) {
1451 emit log(
LOGERR,tr(
"Read corrupted cell type data!"));
1457 if (triMeshPossible)
1459 else if (polyMeshPossible)
1460 return BMT_PolyMesh;
1461 else if (hexahedralMeshPossible)
1462 return BMT_HexahedralMesh;
1463 else if (polyhedralMeshPossible)
1464 return BMT_PolyhedralMesh;
1475 std::cerr <<
"Loading vtk file" << std::endl;
1479 QFile file(_filename);
1481 if ( !file.open(QIODevice::ReadOnly) ) {
1482 emit log(
LOGERR,
"Unable to open vtk file!");
1486 QTextStream in(&file);
1488 std::cerr <<
"File is open!" << std::endl;
1490 QString line = in.readLine();
1492 std::cerr <<
"Got line: " << std::endl;
1493 std::cerr << line.toStdString() << std::endl;
1495 QStringList header = line.split(
" ",QString::SkipEmptyParts);
1497 if ( header.size() != 5 ) {
1498 emit log(
LOGERR,tr(
"Bad VTK header? ") + line);
1502 QString version = header[4];
1504 header.removeLast();
1506 QString magic = header.join(
" ");
1508 if ( magic !=
"# vtk DataFile Version" ) {
1509 emit log(
LOGERR,tr(
"Bad VTK header magic? ") + magic);
1515 QString fileTypeStr = in.readLine();
1517 fileTypeStr = fileTypeStr.simplified();
1519 if ( fileTypeStr.toLower() ==
"binary" ) {
1521 emit log(
LOGINFO,tr(
"Loading VTK binary file of version %1.").arg(version));
1522 emit log(
LOGERR,tr(
"Not yet implemented!"));
1523 }
else if ( fileTypeStr.toLower() ==
"ascii" ) {
1525 emit log(
LOGINFO,tr(
"Loading VTK ascii file of version %1.").arg(version));
1527 emit log(
LOGERR,tr(
"Bad VTK type? ") + fileTypeStr);
1531 emit log(
LOGINFO,description);
1535 while ( line.simplified() ==
"" )
1536 line = in.readLine();
1538 QStringList datasetList = line.split(
" ",QString::SkipEmptyParts);
1540 if ( datasetList.size() != 2 ) {
1541 emit log(
LOGERR,tr(
"Bad dataset specification!"));
1547 datasetList[1] = datasetList[1].simplified();
1549 if ( datasetList[1] ==
"STRUCTURED_POINTS" )
1550 dataset = STRUCTURED_POINTS;
1551 else if ( datasetList[1] ==
"STRUCTURED_GRID" )
1552 dataset = STRUCTURED_GRID;
1553 else if ( datasetList[1] ==
"RECTILINEAR_GRID" )
1554 dataset = RECTILINEAR_GRID;
1555 else if ( datasetList[1] ==
"POLYDATA" )
1557 else if ( datasetList[1] ==
"UNSTRUCTURED_GRID" )
1558 dataset = UNSTRUCTURED_GRID;
1560 emit log(
LOGERR,tr(
"Unknown dataset specification! %1").arg(datasetList[1]));
1566 if ( (forceTriangleMesh_) || (bestType == BMT_TriMesh) ){
1580 if ( !loadMesh(in,_mesh,dataset) ) {
1581 emit log(
LOGERR,
"Unable to load mesh!");
1585 emit log(
LOGERR,
"Unable to add empty triangle mesh!");
1595 else if ((bestType == BMT_PolyMesh) || (bestType == BMT_None))
1610 if ( !loadMesh(in,_mesh,dataset) ) {
1611 emit log(
LOGERR,
"Unable to load mesh!");
1615 emit log(
LOGERR,
"Unable to add empty poly mesh!");
1625 #ifdef ENABLE_OPENVOLUMEMESH_POLYHEDRAL_SUPPORT
1626 else if (bestType == BMT_PolyhedralMesh)
1640 if ( !loadMesh(in,_mesh,dataset) ) {
1641 emit log(
LOGERR,
"Unable to load mesh!");
1645 emit log(
LOGERR,
"Unable to add empty polyhedral mesh!");
1653 #endif //ENABLE_OPENVOLUMEMESH_POLYHEDRAL_SUPPORT
1654 #ifdef ENABLE_OPENVOLUMEMESH_HEXAHEDRAL_SUPPORT
1655 else if (bestType == BMT_HexahedralMesh)
1669 if ( !loadMesh(in,_mesh,dataset) ) {
1670 emit log(
LOGERR,
"Unable to load mesh!");
1674 emit log(
LOGERR,
"Unable to add empty hexahedral mesh!");
1681 #endif //ENABLE_OPENVOLUMEMESH_HEXAHEDRAL_SUPPORT
1692 emit openedFile( baseObj->
id() );
1694 return baseObj->
id();
1697 emit log(
LOGERR,tr(
"Error in load mesh!"));
1704 template <
typename MeshT>
1707 std::cerr <<
"loadMeshPoints" << std::endl;
1712 QStringList pointsLine = _spec.split(
" ",QString::SkipEmptyParts);
1715 if ( pointsLine.size() != 3 ) {
1716 emit log(
LOGERR,tr(
"Expected to get Points line with exactly 3 entries, but %1 found!").arg(pointsLine.size()));
1721 quint32 points = pointsLine[1].toUInt(&ok);
1724 emit log(
LOGERR,tr(
"Expected to get number of points, but read %1 !").arg(pointsLine[1]));
1732 while ( read < points ) {
1738 if ( pointsLine[2] ==
"float" ) {
1741 _in.device()->read((
char*)&vecf[0],
sizeof(
float));
1742 _in.device()->read((
char*)&vecf[1],
sizeof(
float));
1743 _in.device()->read((
char*)&vecf[2],
sizeof(
float));
1748 emit log(
LOGERR,tr(
"Not implemented data type %1 !").arg(pointsLine[2]));
1754 _in >> vec[0] >> vec[1] >> vec[2];
1761 if ( _in.status() == QTextStream::Ok ) {
1762 _mesh->add_vertex(vec);
1764 emit log(
LOGERR,tr(
"Read corrupted point data!"));
1771 if ( pointsLine[2] ==
"float" ) {
1774 _in.seek(_in.pos() + read * 3 *
sizeof(float) /
sizeof(
char) );
1782 template <
typename MeshT>
1784 std::cerr <<
"loadMeshLines" << std::endl;
1789 QStringList linesLine = _spec.split(
" ",QString::SkipEmptyParts);
1792 if ( linesLine.size() != 3 ) {
1793 emit log(
LOGERR,tr(
"Expected to get LINES line with exactly 3 entries, but %1 found!").arg(linesLine.size()));
1798 quint32 linecount = linesLine[1].toUInt(&ok);
1801 quint32 entrycount = linesLine[2].toUInt(&ok);
1804 emit log(
LOGERR,tr(
"Expected to get number of lines and entries, but read %1 !").arg(linesLine.join(
" ")));
1810 while ( read < linecount) {
1818 _in.device()->read((
char*)&valence,
sizeof(quint32));
1823 if ( _in.status() == QTextStream::Ok ) {
1826 for (
unsigned int i = 0 ; i < valence; ++i )
1829 for (
unsigned int i = 0 ; i < valence; ++i )
1830 _in.device()->read((
char*)&valence,
sizeof(quint32));
1833 if ( _in.status() == QTextStream::Ok ) {
1838 emit log(
LOGERR,tr(
"Read corrupted face data!"));
1843 emit log(
LOGERR,tr(
"Read corrupted POLYGONS data!"));
1853 _in.seek(_in.pos() + entrycount *
sizeof(quint32) /
sizeof(
char) );
1856 emit log(
LOGWARN,tr(
"Lines not supported yet ... skipped!"));
1861 template <
typename MeshT>
1863 std::cerr <<
"loadMeshPolygons" << std::endl;
1868 QStringList polygonsLine = _spec.split(
" ",QString::SkipEmptyParts);
1871 if ( polygonsLine.size() != 3 ) {
1872 emit log(
LOGERR,tr(
"Expected to get Points line with exactly 3 entries, but %1 found!").arg(polygonsLine.size()));
1877 quint32 polygoncount = polygonsLine[1].toUInt(&ok);
1880 quint32 entrycount = polygonsLine[2].toUInt(&ok);
1883 emit log(
LOGERR,tr(
"Expected to get number of points and entries, but read %1 !").arg(polygonsLine.join(
" ")));
1888 bool errorEnabled = omerr().is_enabled();
1892 while ( read < polygoncount) {
1899 _in.device()->read((
char*)&valence,
sizeof(quint32));
1903 std::vector< quint32 > indices;
1905 for (
unsigned int i = 0 ; i < valence; ++i ) {
1911 _in.device()->read((
char*)&valence,
sizeof(quint32));
1914 indices.push_back( index );
1917 if ( _in.status() == QTextStream::Ok ) {
1920 remove_duplicated_vertices(indices);
1922 if (indices.size() >= 3)
1926 cell.indices = indices;
1927 cell.index =
addFace(_mesh, indices);
1928 _cells.push_back(cell);
1931 emit log(
LOGERR,tr(
"Read corrupted face data!"));
1949 _in.seek(_in.pos() + entrycount *
sizeof(qint32) /
sizeof(
char) );
1955 template <
typename MeshT>
1960 if (_vhandles.empty())
return -1;
1963 if (! _mesh->get_property_handle(originalVertexIdx,
"FileVTKPlugin_originalVertexIdx")) {
1964 _mesh->add_property( originalVertexIdx,
"FileVTKPlugin_originalVertexIdx" );
1967 typename MeshT::VertexIter vit = _mesh->vertices_begin();
1968 typename MeshT::VertexIter vend = _mesh->vertices_end();
1969 for(; vit != vend; ++vit) {
1975 for (
unsigned int j = 0; j < _vhandles.size(); ++j)
1977 typename MeshT::Point p = _mesh->point(_vhandles[j]);
1979 _vhandles[j] = _mesh->add_vertex(p);
1984 if (_mesh->has_vertex_status()) {
1985 _mesh->status(_vhandles[j]).set_fixed_nonmanifold(
true);
1988 _mesh->property (originalVertexIdx, _vhandles[j]) = original_handle;
1995 if (_mesh->has_face_status())
1996 _mesh->status(fh).set_fixed_nonmanifold(
true);
1999 if (_mesh->has_edge_status()) {
2000 typename MeshT::FaceEdgeIter fe_it = _mesh->fe_iter(fh);
2001 for (; fe_it.is_valid(); ++fe_it) {
2002 _mesh->status(*fe_it).set_fixed_nonmanifold(
true);
2010 template <
typename MeshT>
2012 std::cerr <<
"loadMeshTriangleStrips" << std::endl;
2017 QStringList triStripsLine = _spec.split(
" ",QString::SkipEmptyParts);
2020 if ( triStripsLine.size() != 3 ) {
2021 emit log(
LOGERR,tr(
"Expected to get TRIANGLE_STRIPS line with exactly 3 entries, but %1 found!").arg(triStripsLine.size()));
2026 quint32 stripcount = triStripsLine[1].toUInt(&ok);
2029 quint32 entrycount = triStripsLine[2].toUInt(&ok);
2032 emit log(
LOGERR,tr(
"Expected to get number of strips and entries, but read %1 !").arg(triStripsLine.join(
" ")));
2037 while ( read < stripcount) {
2044 _in.device()->read((
char*)&valence,
sizeof(quint32));
2048 QList< quint32 > indices;
2051 for (
unsigned int i = 0 ; i < 2; ++i ) {
2057 _in.device()->read((
char*)&valence,
sizeof(quint32));
2060 indices.push_back( index );
2064 for (
unsigned int i = 2 ; i < valence; ++i ) {
2070 _in.device()->read((
char*)&valence,
sizeof(quint32));
2073 indices.push_back( index );
2075 if ( _in.status() == QTextStream::Ok ) {
2079 cell.indices.resize(3);
2080 cell.indices[0] = indices[i];
2081 cell.indices[1] = indices[i-1];
2082 cell.indices[2] = indices[i-2];
2084 std::swap(cell.indices[1],cell.indices[2]);
2085 cell.index =
addFace(_mesh, cell.indices);
2086 _cells.push_back(cell);
2088 emit log(
LOGERR,tr(
"Read corrupted face data!"));
2102 _in.seek(_in.pos() + entrycount *
sizeof(qint32) /
sizeof(
char) );
2108 template <
typename MeshT>
2110 std::cerr <<
"loadMeshNormals" << std::endl;
2113 QStringList normalsLine = _spec.split(
" ",QString::SkipEmptyParts);
2116 if ( normalsLine.size() != 3 ) {
2117 emit log(
LOGERR,tr(
"Expected to get NORMALS line with exactly 3 entries, but %1 found!").arg(normalsLine.size()));
2125 while ( read < _count) {
2130 if ( normalsLine[2] ==
"float" ) {
2134 _in.device()->read((
char*)&vecf[0],
sizeof(
float));
2135 _in.device()->read((
char*)&vecf[1],
sizeof(
float));
2136 _in.device()->read((
char*)&vecf[2],
sizeof(
float));
2141 emit log(
LOGERR,tr(
"Not implemented data type %1 !").arg(normalsLine[2]));
2147 _in >> normal[0] >> normal[1] >> normal[2];
2151 if ( _in.status() == QTextStream::Ok ) {
2153 if ( _pointNormal ) {
2161 emit log(
LOGERR,tr(
"Read corrupted point data!"));
2170 if ( normalsLine[2] ==
"float" ) {
2173 _in.seek(_in.pos() + read * 3 *
sizeof(float) /
sizeof(
char) );
2183 template <
typename MeshT>
2186 std::cerr <<
"loadMeshCells" << std::endl;
2189 QStringList cellLine = _spec.split(
" ",QString::SkipEmptyParts);
2192 if ( cellLine.size() != 3 ) {
2193 emit log(
LOGERR,tr(
"Expected to get CELLS line with exactly 3 entries, but %1 found!").arg(cellLine.size()));
2200 quint32 cellCount = cellLine[1].toUInt(&ok);
2203 quint32 entryCount = cellLine[2].toUInt(&ok);
2207 emit log(
LOGERR,tr(
"Expected to get number of cells and entries, but read %1 !").arg(cellLine.join(
" ")));
2212 while ( read < cellCount) {
2221 _in.device()->read((
char*)&valence,
sizeof(quint32));
2226 for (
unsigned int i = 0 ; i < valence; ++i ) {
2232 _in.device()->read((
char*)&valence,
sizeof(quint32));
2235 currentCell.indices.push_back( index );
2238 if ( _in.status() == QTextStream::Ok ) {
2239 _cells.push_back(currentCell);
2241 emit log(
LOGERR,tr(
"Read corrupted face data!"));
2251 _in.seek(_in.pos() + entryCount *
sizeof(quint32) /
sizeof(
char) );
2263 while ( _spec.simplified().size() == 0 ) {
2266 if ( _in.atEnd() ) {
2267 emit log(
LOGERR,tr(
"File end when reading cell specification!"));
2271 _spec = _in.readLine();
2274 if ( ! _spec.contains(
"CELL_TYPES") ) {
2275 emit log(
LOGERR,tr(
"Wrong token! Expected CELL_TYPES but got : %1").arg(_spec));
2280 cellLine = _spec.split(
" ",QString::SkipEmptyParts);
2283 if ( cellLine.size() != 2 ) {
2284 emit log(
LOGERR,tr(
"Expected to get CELL_TYPES line with exactly 2 entries, but %1 found!").arg(cellLine.size()));
2289 quint32 cellCountTypes = cellLine[1].toUInt(&ok);
2292 emit log(
LOGERR,tr(
"Expected to get number of cell types, but read %1 !").arg(cellLine[1]));
2296 if (cellCountTypes != cellCount ) {
2297 emit log(
LOGERR,tr(
"cellCountTypes != cellCount !").arg(cellLine.size()));
2302 while ( read < cellCount) {
2309 _in.device()->read((
char*)&type,
sizeof(quint32));
2313 _cells[read].type = type;
2315 if ( _in.status() != QTextStream::Ok ) {
2316 emit log(
LOGERR,tr(
"Read corrupted cell type data!"));
2325 _in.seek(_in.pos() + read *
sizeof(quint32) /
sizeof(
char) );
2333 for (
unsigned int i = 0 ; i < _cells.size() ; ++i ) {
2334 if ( _cells[i].type == 1 ) {
2339 }
else if ( _cells[i].type == 2 ) {
2344 }
else if ( _cells[i].type == 3 ) {
2347 emit log(
LOGWARN,tr(
"Unsupported Cell Type LINE") );
2349 }
else if ( _cells[i].type == 4 ) {
2352 emit log(
LOGWARN,tr(
"Unsupported Cell Type POLY_LINE") );
2354 }
else if ( _cells[i].type == 5 ) {
2356 _cells[i].index =
addFace(_mesh, _cells[i].indices);
2357 }
else if ( _cells[i].type == 6 ) {
2360 for (
unsigned int j = 2 ; j < _cells[i].indices.size() ; ++j) {
2362 _cells[i].index =
addFace(_mesh, _cells[i].indices[j-2],_cells[i].indices[j],_cells[i].indices[j-1]);
2364 _cells[i].index =
addFace(_mesh, _cells[i].indices[j-2],_cells[i].indices[j-1],_cells[i].indices[j]);
2369 }
else if ( _cells[i].type == 7 ) {
2372 _cells[i].index =
addFace(_mesh, _cells[i].indices);
2374 }
else if ( _cells[i].type == 8 ) {
2377 emit log(
LOGWARN,tr(
"Unsupported Cell Type PIXEL") );
2379 }
else if ( _cells[i].type == 9 ) {
2382 _cells[i].index =
addFace(_mesh, _cells[i].indices);
2384 }
else if ( _cells[i].type == 10 ) {
2386 _cells[i].index =
addTetraCell(_mesh, _cells[i].indices);
2388 }
else if ( _cells[i].type == 11 ) {
2391 emit log(
LOGWARN,tr(
"Unsupported Cell Type VOXEL") );
2393 }
else if ( _cells[i].type == 12 ) {
2396 _cells[i].index =
addHexaCell(_mesh, _cells[i].indices);
2397 }
else if ( _cells[i].type == 13 ) {
2400 _cells[i].index =
addWedgeCell(_mesh, _cells[i].indices);
2401 }
else if ( _cells[i].type == 14 ) {
2407 emit log(
LOGERR,tr(
"Unknown cell type").arg(_cells[i].type) );
2411 std::cerr <<
"Read " << read <<
" Cells " << std::endl;
2412 std::cerr <<
"Vector has size: " << _cells.size() << std::endl;
2418 template <
typename MeshT>
2419 bool FileVTKPlugin::loadMesh(QTextStream& _in,MeshT*& _mesh, Dataset _type){
2422 if ( _type != POLYDATA && _type != UNSTRUCTURED_GRID ) {
2423 emit log(
LOGERR,
"Unsupported DATASET" );
2432 bool pointNormalsRead =
false;
2433 bool faceNormalsRead =
false;
2436 bool pointData =
false;
2439 quint32 pointDataSize = 0;
2442 bool cellData =
false;
2445 quint32 cellDataSize = 0;
2447 std::vector<CellType> cells;
2451 line = _in.readLine();
2454 while ( line.simplified().size() == 0 ) {
2457 if ( _in.atEnd() ) {
2459 std::cerr <<
"atEnd" << std::endl;
2463 line = _in.readLine();
2470 std::cerr <<
"Line is: " << line.toStdString() << std::endl;
2473 if ( line.contains(
"POINTS") ) {
2476 }
else if ( line.contains(
"POINT_DATA") ) {
2481 QStringList pointDataLine = line.split(
" ",QString::SkipEmptyParts);
2484 if ( pointDataLine.size() != 2 ) {
2485 emit log(
LOGERR,tr(
"Expected to get POINT_DATA line with exactly 2 entries, but %1 found!").arg(line.size()));
2490 pointDataSize = pointDataLine[1].toUInt(&ok);
2495 std::cerr <<
"Point data mode with " << pointDataSize <<
"Elements" << std::endl;
2497 }
else if ( line.contains(
"CELL_DATA") ) {
2502 QStringList cellDataLine = line.split(
" ",QString::SkipEmptyParts);
2505 if ( cellDataLine.size() != 2 ) {
2506 emit log(
LOGERR,tr(
"Expected to get CELL_DATA line with exactly 2 entries, but %1 found!").arg(line.size()));
2511 cellDataSize = cellDataLine[1].toUInt(&ok);
2516 std::cerr <<
"Cell data mode with " << cellDataSize <<
"Elements" << std::endl;
2518 }
else if ( line.contains(
"VERTICES") ) {
2519 std::cerr <<
"Vertices will be skipped as they are already added!" << std::endl;
2520 }
else if ( line.contains(
"LINES") ) {
2522 }
else if ( line.contains(
"POLYGONS") ) {
2524 }
else if ( line.contains(
"TRIANGLE_STRIPS") ) {
2526 }
else if ( line.contains(
"CELL") ) {
2528 }
else if ( line.contains(
"NORMALS") ) {
2532 pointNormalsRead =
true;
2533 }
else if (cellData) {
2535 faceNormalsRead =
true;
2537 emit log(
LOGERR,tr(
"Got normals keyword but we are neither in pointdata nor celldata mode") );
2542 std::cerr <<
"Unrecognized keyword : " << line.toStdString() << std::endl;
2547 if ( !faceNormalsRead )
2550 if ( !pointNormalsRead )
2564 forceTriangleMesh_ =
true;
2566 forcePolyMesh_ =
true;
2573 bool FileVTKPlugin::saveObject(
int _id, QString _filename) {
2577 emit log(
LOGERR, tr(
"saveObject : cannot get object id %1 for save name %2").arg(_id).arg(_filename) );
2581 std::string filename = std::string( _filename.toUtf8() );
2583 std::fstream ofs( filename.c_str(), std::ios_base::out );
2587 emit log(
LOGERR, tr(
"saveObject : Cannot not open file %1 for writing!").arg(_filename) );
2596 object->setFromFileName(_filename);
2597 object->setName(object->
filename());
2602 emit log(
LOGINFO, tr(
"Saved object to ") + _filename );
2606 emit log(
LOGERR, tr(
"Unable to save ") + _filename);
2612 object->setFromFileName(_filename);
2613 object->setName(object->
filename());
2618 emit log(
LOGINFO, tr(
"Saved object to ") + _filename );
2622 emit log(
LOGERR, tr(
"Unable to save ") + _filename);
2627 #ifdef ENABLE_OPENVOLUMEMESH_POLYHEDRAL_SUPPORT
2631 object->setFromFileName(_filename);
2632 object->setName(object->
filename());
2637 emit log(
LOGINFO, tr(
"Saved object to ") + _filename );
2641 emit log(
LOGERR, tr(
"Unable to save ") + _filename);
2647 #ifdef ENABLE_OPENVOLUMEMESH_HEXAHEDRAL_SUPPORT
2651 object->setFromFileName(_filename);
2652 object->setName(object->
filename());
2657 emit log(
LOGINFO, tr(
"Saved object to ") + _filename );
2661 emit log(
LOGERR, tr(
"Unable to save ") + _filename);
2669 emit log(
LOGERR, tr(
"Unable to save (object is not a compatible mesh type)"));
2678 template<
class MeshT >
2685 _out <<
"# vtk DataFile Version 2.0\n";
2687 _out <<
"Mesh saved from OpenFlipper - www.openflipper.org\n";
2707 if( OpenFlipper::Options::nogui() )
2712 if(saveBinary_->isChecked()) userWriteOptions_ |= BINARY;
2713 else {
if(userWriteOptions_ & BINARY) userWriteOptions_ -= BINARY; }
2715 if(saveFaceNormals_) {
2716 if(saveFaceNormals_->isChecked()) userWriteOptions_ |= FACENORMALS;
2717 else {
if(userWriteOptions_ & FACENORMALS) userWriteOptions_ -= FACENORMALS; }
2719 if(saveVertexNormals_) {
2720 if(saveVertexNormals_->isChecked()) userWriteOptions_ |= VERTEXNORMALS;
2721 else {
if(userWriteOptions_ & VERTEXNORMALS) userWriteOptions_ -= VERTEXNORMALS; }
2723 if(saveVertexTexCoords_) {
2724 if(saveVertexTexCoords_->isChecked()) userWriteOptions_ |= VERTEXTEXCOORDS;
2725 else {
if(userWriteOptions_ & VERTEXTEXCOORDS) userWriteOptions_ -= VERTEXTEXCOORDS; }
2729 #if QT_VERSION < 0x050000
DLLEXPORT OpenFlipperQSettings & OpenFlipperSettings()
QSettings object containing all program settings of OpenFlipper.
BestMeshType findBestObjectType(QString _filename)
Reads the file to check for present primitives and returns the object type that fits best...
void setNormalsOfDuplicatedVertices(TriMesh *&_mesh)
Sets normals of duplicated vertices that were created for non-manifold meshes.
bool writeMesh(std::ostream &_out, MeshT &_mesh)
Writes the header of the VTK file, then calls writeASCIIData (binary VTK is currently unsupported) ...
MeshT * mesh()
return a pointer to the mesh
bool writeASCIIData(std::ostream &_out, TriMesh &_mesh)
Writes the data of the VTK file in ASCII format.
void updateFaceNormals(TriMesh *&_mesh)
Updates face normals.
MeshT * mesh()
return a pointer to the mesh
Type for a Meshobject containing a poly 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.
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.
int addPyramidCell(TriMesh *&_mesh, std::vector< quint32 > _indices)
Adds a pyramid cell to the mesh. (Does nothing, yet)
void addFaceNormal(TriMesh *&_mesh, quint32 _index, OpenMesh::Vec3d _normal)
Adds a face normal.
QString filename() const
return the filename of the object
Type for a MeshObject containing a triangle mesh.
#define DATA_POLYHEDRAL_MESH
const UpdateType UPDATE_ALL(UpdateTypeSet(1))
Identifier for all updates.
bool getObject(int _identifier, BSplineCurveObject *&_object)
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.
int addFaceToOpenMesh(MeshT *&_mesh, std::vector< quint32 > _indices)
Adds a face to the mesh.
void setFromFileName(const QString &_filename)
int addHexaCellToOpenMesh(MeshT _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.
int idx() const
Get the underlying index of this handle.
int addFace(TriMesh *&_mesh, std::vector< quint32 > _indices)
Adds a face to the mesh.
int addPyramidCellToOpenMesh(MeshT _mesh, std::vector< quint32 > _indices)
Adds a pyramid cell to the mesh. (Does nothing, yet)
QWidget * saveOptionsWidget(QString)
bool dataType(DataType _type) const
void initializePlugin()
Initialize Plugin.
QString description()
Return a description of what the plugin is doing.
bool loadMeshPolygons(QString _spec, QTextStream &_in, MeshT *&_mesh, std::vector< CellType > &_cells)
Reads polygons from the stream and adds them to the mesh.
bool loadMeshPoints(QString _spec, QTextStream &_in, MeshT *&_mesh)
Reads points from the stream and adds them to the mesh.
void updateFaceNormalsOfOpenMesh(MeshT *&_mesh)
Updates face normals.
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)
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.
Add 2D texture coordinates (vertices, halfedges)
void removeTemporaryPropertiesOfOpenMesh(MeshT *&_mesh)
Removed temporary properties that might have been added during file reading.
void updateVertexNormals(TriMesh *&_mesh)
Updates vertex normals.
Handle for a vertex entity.
void slotSaveDefault()
Slot called when user wants to save the given Save options as default.
bool loadMeshLines(QString _spec, QTextStream &_in, MeshT *&_mesh)
Reads lines from the stream and adds them to the mesh.
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.
int addTetraCell(TriMesh *&_mesh, std::vector< quint32 > _indices)
Adds a tetra cell to the mesh. (Does nothing, yet)
QWidget * loadOptionsWidget(QString)
Handle for a face entity.
int loadObject(QString _filename)
Loads Object and converts it to a triangle mesh if possible.
int addTetraCellToOpenMesh(MeshT _mesh, std::vector< quint32 > _indices)
Adds a tetra cell to the mesh. (Does nothing, yet)
bool binary_
Reading binary file?
Property classes for the different entity types.
void updateVertexNormalsOfOpenMesh(MeshT *&_mesh)
Updates vertex normals.
Add normals to mesh item (vertices/faces)
void setNormalsOfDuplicatedVerticesOfOpenMesh(MeshT *&_mesh)
Sets normals of duplicated vertices that were created for non-manifold meshes.
void addVertexNormalToOpenMesh(MeshT _mesh, quint32 _index, OpenMesh::Vec3d _normal)
Adds a vertex normal.
bool loadMeshTriangleStrips(QString _spec, QTextStream &_in, MeshT *&_mesh, std::vector< CellType > &_cells)
Reads triangle strips from the stream and adds them to the mesh.
FileVTKPlugin()
Constructor.
#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...
virtual void setName(QString _name)
path to the file from which the object is loaded ( defaults to "." )
#define DATA_TRIANGLE_MESH
HexahedralMesh * hexahedralMesh(BaseObjectData *_object)
Get an HexahedralMesh from an object.
void addFaceNormalToOpenMesh(MeshT _mesh, quint32 _index, OpenMesh::Vec3d _normal)
Adds a face normal.
int addHexaCell(TriMesh *&_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.
PolyhedralMesh * polyhedralMesh(BaseObjectData *_object)
Get an PolyhedralMesh from an object.
int addWedgeCellToOpenMesh(MeshT _mesh, std::vector< quint32 > _indices)
Adds a wedge cell to the mesh. (Does nothing, yet)