diff --git a/Polyhedron/demo/Polyhedron/Plugins/IO/CMakeLists.txt b/Polyhedron/demo/Polyhedron/Plugins/IO/CMakeLists.txt index e5d500cc9db..eff76a7c0d5 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/IO/CMakeLists.txt +++ b/Polyhedron/demo/Polyhedron/Plugins/IO/CMakeLists.txt @@ -35,7 +35,7 @@ if (VTK_FOUND) if ("${VTK_VERSION_MAJOR}" GREATER "5") if(VTK_LIBRARIES) polyhedron_demo_plugin(vtk_plugin VTK_io_plugin KEYWORDS IO Mesh_3) - target_link_libraries(vtk_plugin PUBLIC scene_surface_mesh_item scene_polylines_item scene_c3t3_item + target_link_libraries(vtk_plugin PUBLIC scene_surface_mesh_item scene_polylines_item scene_c3t3_item scene_points_with_normal_item vtkCommonCore vtkIOCore vtkIOLegacy vtkIOXML vtkFiltersCore vtkFiltersSources) diff --git a/Polyhedron/demo/Polyhedron/Plugins/IO/VTK_io_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/IO/VTK_io_plugin.cpp index c340b70aa24..30855054d34 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/IO/VTK_io_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/IO/VTK_io_plugin.cpp @@ -20,11 +20,12 @@ // #include -#include "Scene_c3t3_item.h" #include #include "Scene_surface_mesh_item.h" +#include "Scene_c3t3_item.h" #include "Scene_polylines_item.h" +#include "Scene_points_with_normal_item.h" #include #include @@ -45,6 +46,7 @@ #include #include #include +#include #include #include @@ -161,6 +163,10 @@ namespace CGAL{ //extract cells for (vtkIdType i = 0; iGetCellType(i) != 5 + && poly_data->GetCellType(i) != 7 + && poly_data->GetCellType(i) != 9) //only supported cells are triangles, quads and polygons + continue; vtkCell* cell_ptr = poly_data->GetCell(i); vtkIdType nb_vertices = cell_ptr->GetNumberOfPoints(); @@ -195,13 +201,17 @@ namespace CGAL{ //extract segments for (vtkIdType i = 0; iGetCellType(i) != 3 + && poly_data->GetCellType(i) != 4) + continue; vtkCell* cell_ptr = poly_data->GetCell(i); vtkIdType nb_vertices = cell_ptr->GetNumberOfPoints(); - if (nb_vertices !=2) continue; segments.push_back( std::vector() ); - segments.back().push_back(point_map[cell_ptr->GetPointId(0)]); - segments.back().push_back(point_map[cell_ptr->GetPointId(1)]); + for(int j = 0; j < nb_vertices; ++j) + { + segments.back().push_back(point_map[cell_ptr->GetPointId(j)]); + } } } @@ -372,17 +382,16 @@ public: std::string fname = fileinfo.absoluteFilePath().toStdString(); - FaceGraph* poly = new FaceGraph(); // Try to read .vtk in a facegraph - if(fileinfo.size() == 0) { CGAL::Three::Three::warning( tr("The file you are trying to load is empty.")); Scene_facegraph_item* item = - new Scene_facegraph_item(poly); + new Scene_facegraph_item(); item->setName(fileinfo.completeBaseName()); return item; } + vtkSmartPointer data; vtkSmartPointer obs = vtkSmartPointer::New(); @@ -446,24 +455,183 @@ public: msgBox.exec(); } - if (CGAL::vtkPointSet_to_polygon_mesh(data, *poly)) + //check celltypes + bool is_polygon_mesh(false), + is_c3t3(false), + is_polyline(false); + for(int i = 0; i< data->GetNumberOfCells(); ++i) { - Scene_facegraph_item* poly_item = new Scene_facegraph_item(poly); - poly_item->setName(fileinfo.fileName()); - return poly_item; + int t = data->GetCellType(i); + if( t == 5 || t == 7 || t == 9) //tri, quad or polygon + is_polygon_mesh = true; + else if(t == 10) //tetrahedron + is_c3t3 = true; + else if( t == 3 || t == 4) //line or polyline + is_polyline = true; } - else{ - // extract only segments + Scene_group_item* group = nullptr; + if((is_polygon_mesh && is_c3t3) + || (is_polygon_mesh && is_polyline) + || (is_c3t3 && is_polyline) ) + { + group = new Scene_group_item(fileinfo.baseName()); + group->setScene(CGAL::Three::Three::scene()); + } + + if(is_polygon_mesh) + { + FaceGraph* poly = new FaceGraph(); + if (CGAL::vtkPointSet_to_polygon_mesh(data, *poly)) + { + Scene_facegraph_item* poly_item = new Scene_facegraph_item(poly); + if(group) + { + poly_item->setName(QString("%1_faces").arg(fileinfo.baseName())); + CGAL::Three::Three::scene()->addItem(poly_item); + CGAL::Three::Three::scene()->changeGroup(poly_item, group); + } + else{ + poly_item->setName(fileinfo.baseName()); + return poly_item; + } + } + } + + if (is_c3t3) + { + typedef boost::array Facet; // 3 = id + typedef boost::array Tet_with_ref; // first 4 = id, fifth = reference + Scene_c3t3_item* c3t3_item = new Scene_c3t3_item(); + c3t3_item->set_valid(false); + //build a triangulation from data: + std::vector points; + vtkPoints* dataP = data->GetPoints();; + for(int i = 0; i< data->GetNumberOfPoints(); ++i) + { + double *p = dataP->GetPoint(i); + points.push_back(Tr::Point(p[0],p[1],p[2])); + } + std::vector finite_cells; + bool has_mesh_domain = data->GetCellData()->HasArray("MeshDomain"); + vtkDataArray* domains = data->GetCellData()->GetArray("MeshDomain"); + for(int i = 0; i< data->GetNumberOfCells(); ++i) + { + if(data->GetCellType(i) != 10 ) + continue; + vtkIdList* pids = data->GetCell(i)->GetPointIds(); + Tet_with_ref cell; + for(int j = 0; j<4; ++j) + cell[j] = pids->GetId(j); + cell[4] = has_mesh_domain ? static_cast(domains->GetComponent(i,0)) + :1; + finite_cells.push_back(cell); + } + std::map border_facets; + //Preprocessing for build_triangulation + //check for orientation and swap in cells if not good. + for(std::size_t i=0; i(c3t3_item->c3t3().triangulation(), points, finite_cells, border_facets); + + for( C3t3::Triangulation::Finite_cells_iterator + cit = c3t3_item->c3t3().triangulation().finite_cells_begin(); + cit != c3t3_item->c3t3().triangulation().finite_cells_end(); + ++cit) + { + CGAL_assertion(cit->info() >= 0); + c3t3_item->c3t3().add_to_complex(cit, cit->info()); + for(int i=0; i < 4; ++i) + { + if(cit->surface_patch_index(i)>0) + { + c3t3_item->c3t3().add_to_complex(cit, i, cit->surface_patch_index(i)); + } + } + } + + //if there is no facet in the complex, we add the border facets. + if(c3t3_item->c3t3().number_of_facets_in_complex() == 0) + { + for( C3t3::Triangulation::Finite_facets_iterator + fit = c3t3_item->c3t3().triangulation().finite_facets_begin(); + fit != c3t3_item->c3t3().triangulation().finite_facets_end(); + ++fit) + { + typedef C3t3::Triangulation::Cell_handle Cell_handle; + + Cell_handle c = fit->first; + Cell_handle nc = c->neighbor(fit->second); + + // By definition, Subdomain_index() is supposed to be the id of the exterior + if(c->subdomain_index() != C3t3::Triangulation::Cell::Subdomain_index() && + nc->subdomain_index() == C3t3::Triangulation::Cell::Subdomain_index()) + { + // Color the border facet with the index of its cell + c3t3_item->c3t3().add_to_complex(c, fit->second, c->subdomain_index()); + } + } + } + c3t3_item->c3t3_changed(); + c3t3_item->resetCutPlane(); + if(group) + { + c3t3_item->setName(QString("%1_tetrahedra").arg(fileinfo.baseName())); + CGAL::Three::Three::scene()->addItem(c3t3_item); + CGAL::Three::Three::scene()->changeGroup(c3t3_item, group); + } + else{ + c3t3_item->setName(fileinfo.baseName()); + return c3t3_item; + } + } + + if(is_polyline) + { std::vector< std::vector > segments; extract_segments_from_vtkPointSet(data,segments); - if (segments.empty()) return NULL; /// TODO handle point sets Scene_polylines_item* polyline_item = new Scene_polylines_item(); - polyline_item->setName(fileinfo.fileName()); BOOST_FOREACH(const std::vector& segment, segments) - polyline_item->polylines.push_back(segment); - return polyline_item; + polyline_item->polylines.push_back(segment); + if(group) + { + polyline_item->setName(QString("%1_lines").arg(fileinfo.baseName())); + CGAL::Three::Three::scene()->addItem(polyline_item); + CGAL::Three::Three::scene()->changeGroup(polyline_item, group); + } + else{ + polyline_item->setName(fileinfo.baseName()); + return polyline_item; + } } - return NULL; + + if(group) + return group; + + QApplication::restoreOverrideCursor(); + QMessageBox::warning(CGAL::Three::Three::mainWindow(), + "Problematic file", + "Cell type not recognized. Only points will be displayed."); + QApplication::setOverrideCursor(Qt::WaitCursor); + Scene_points_with_normal_item* point_item = new Scene_points_with_normal_item(); + for(int i=0; i< data->GetNumberOfPoints(); ++i) + { + double* p = data->GetPoint(i); + point_item->point_set()->insert(Point_3(p[0], p[1], p[2])); + } + point_item->setName(fileinfo.baseName()); + return point_item; } }; // end Polyhedron_demo_vtk_plugin diff --git a/Polyhedron/demo/Polyhedron/Scene.cpp b/Polyhedron/demo/Polyhedron/Scene.cpp index 38956320395..7994c82d144 100644 --- a/Polyhedron/demo/Polyhedron/Scene.cpp +++ b/Polyhedron/demo/Polyhedron/Scene.cpp @@ -98,16 +98,15 @@ Scene::replaceItem(Scene::Item_id index, CGAL::Three::Scene_item* item, bool emi this, SLOT(callDraw())); CGAL::Three::Scene_group_item* group = qobject_cast(m_entries[index]); + QList group_children; if(group) { - QList group_children; Q_FOREACH(Item_id id, group->getChildren()) { CGAL::Three::Scene_item* child = group->getChild(id); group->unlockChild(child); - group_children << item_id(child); + group_children << child; } - erase(group_children); } CGAL::Three::Scene_group_item* parent = m_entries[index]->parentGroup(); bool is_locked = false; @@ -148,6 +147,10 @@ Scene::replaceItem(Scene::Item_id index, CGAL::Three::Scene_item* item, bool emi Q_EMIT restoreCollapsedState(); redraw_model(); Q_EMIT selectionChanged(index); + Q_FOREACH(Scene_item* child, group_children) + { + erase(item_id(child)); + } return item; } @@ -1013,10 +1016,13 @@ Scene::setData(const QModelIndex &index, { RenderingMode rendering_mode = static_cast(value.toInt()); // Find next supported rendering mode + int counter = 0; while ( ! item->supportsRenderingMode(rendering_mode) ) { rendering_mode = static_cast( (rendering_mode+1) % NumberOfRenderingMode ); + if(counter++ == NumberOfRenderingMode) + break; } item->setRenderingMode(rendering_mode); QModelIndex nindex = createIndex(m_entries.size()-1,RenderingModeColumn+1);