mirror of https://github.com/CGAL/cgal
Merge pull request #3659 from maxGimeno/Demo-Fix_VTU_visu-GF
Polyhedron Demo: Rework of VTK_io_plugin
This commit is contained in:
commit
f74d33af49
|
|
@ -35,7 +35,7 @@ if (VTK_FOUND)
|
||||||
if ("${VTK_VERSION_MAJOR}" GREATER "5")
|
if ("${VTK_VERSION_MAJOR}" GREATER "5")
|
||||||
if(VTK_LIBRARIES)
|
if(VTK_LIBRARIES)
|
||||||
polyhedron_demo_plugin(vtk_plugin VTK_io_plugin KEYWORDS IO Mesh_3)
|
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
|
vtkCommonCore vtkIOCore vtkIOLegacy vtkIOXML
|
||||||
vtkFiltersCore vtkFiltersSources)
|
vtkFiltersCore vtkFiltersSources)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -20,11 +20,12 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
#include <CGAL/Mesh_3/io_signature.h>
|
#include <CGAL/Mesh_3/io_signature.h>
|
||||||
#include "Scene_c3t3_item.h"
|
|
||||||
#include <QtCore/qglobal.h>
|
#include <QtCore/qglobal.h>
|
||||||
|
|
||||||
#include "Scene_surface_mesh_item.h"
|
#include "Scene_surface_mesh_item.h"
|
||||||
|
#include "Scene_c3t3_item.h"
|
||||||
#include "Scene_polylines_item.h"
|
#include "Scene_polylines_item.h"
|
||||||
|
#include "Scene_points_with_normal_item.h"
|
||||||
|
|
||||||
#include <CGAL/Three/Polyhedron_demo_plugin_helper.h>
|
#include <CGAL/Three/Polyhedron_demo_plugin_helper.h>
|
||||||
#include <CGAL/Three/Polyhedron_demo_io_plugin_interface.h>
|
#include <CGAL/Three/Polyhedron_demo_io_plugin_interface.h>
|
||||||
|
|
@ -45,6 +46,7 @@
|
||||||
#include <CGAL/boost/graph/Euler_operations.h>
|
#include <CGAL/boost/graph/Euler_operations.h>
|
||||||
#include <CGAL/property_map.h>
|
#include <CGAL/property_map.h>
|
||||||
#include <CGAL/IO/Complex_3_in_triangulation_3_to_vtk.h>
|
#include <CGAL/IO/Complex_3_in_triangulation_3_to_vtk.h>
|
||||||
|
#include <CGAL/Mesh_3/tet_soup_to_c3t3.h>
|
||||||
#include <CGAL/IO/output_to_vtu.h>
|
#include <CGAL/IO/output_to_vtu.h>
|
||||||
#include <CGAL/boost/graph/io.h>
|
#include <CGAL/boost/graph/io.h>
|
||||||
|
|
||||||
|
|
@ -161,6 +163,10 @@ namespace CGAL{
|
||||||
//extract cells
|
//extract cells
|
||||||
for (vtkIdType i = 0; i<nb_cells; ++i)
|
for (vtkIdType i = 0; i<nb_cells; ++i)
|
||||||
{
|
{
|
||||||
|
if(poly_data->GetCellType(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);
|
vtkCell* cell_ptr = poly_data->GetCell(i);
|
||||||
|
|
||||||
vtkIdType nb_vertices = cell_ptr->GetNumberOfPoints();
|
vtkIdType nb_vertices = cell_ptr->GetNumberOfPoints();
|
||||||
|
|
@ -195,13 +201,17 @@ namespace CGAL{
|
||||||
//extract segments
|
//extract segments
|
||||||
for (vtkIdType i = 0; i<nb_cells; ++i)
|
for (vtkIdType i = 0; i<nb_cells; ++i)
|
||||||
{
|
{
|
||||||
|
if(poly_data->GetCellType(i) != 3
|
||||||
|
&& poly_data->GetCellType(i) != 4)
|
||||||
|
continue;
|
||||||
vtkCell* cell_ptr = poly_data->GetCell(i);
|
vtkCell* cell_ptr = poly_data->GetCell(i);
|
||||||
|
|
||||||
vtkIdType nb_vertices = cell_ptr->GetNumberOfPoints();
|
vtkIdType nb_vertices = cell_ptr->GetNumberOfPoints();
|
||||||
if (nb_vertices !=2) continue;
|
|
||||||
segments.push_back( std::vector<Point_3>() );
|
segments.push_back( std::vector<Point_3>() );
|
||||||
segments.back().push_back(point_map[cell_ptr->GetPointId(0)]);
|
for(int j = 0; j < nb_vertices; ++j)
|
||||||
segments.back().push_back(point_map[cell_ptr->GetPointId(1)]);
|
{
|
||||||
|
segments.back().push_back(point_map[cell_ptr->GetPointId(j)]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -372,17 +382,16 @@ public:
|
||||||
|
|
||||||
std::string fname = fileinfo.absoluteFilePath().toStdString();
|
std::string fname = fileinfo.absoluteFilePath().toStdString();
|
||||||
|
|
||||||
FaceGraph* poly = new FaceGraph();
|
|
||||||
// Try to read .vtk in a facegraph
|
// Try to read .vtk in a facegraph
|
||||||
|
|
||||||
if(fileinfo.size() == 0)
|
if(fileinfo.size() == 0)
|
||||||
{
|
{
|
||||||
CGAL::Three::Three::warning( tr("The file you are trying to load is empty."));
|
CGAL::Three::Three::warning( tr("The file you are trying to load is empty."));
|
||||||
Scene_facegraph_item* item =
|
Scene_facegraph_item* item =
|
||||||
new Scene_facegraph_item(poly);
|
new Scene_facegraph_item();
|
||||||
item->setName(fileinfo.completeBaseName());
|
item->setName(fileinfo.completeBaseName());
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
|
||||||
vtkSmartPointer<vtkPointSet> data;
|
vtkSmartPointer<vtkPointSet> data;
|
||||||
vtkSmartPointer<CGAL::ErrorObserverVtk> obs =
|
vtkSmartPointer<CGAL::ErrorObserverVtk> obs =
|
||||||
vtkSmartPointer<CGAL::ErrorObserverVtk>::New();
|
vtkSmartPointer<CGAL::ErrorObserverVtk>::New();
|
||||||
|
|
@ -446,24 +455,183 @@ public:
|
||||||
msgBox.exec();
|
msgBox.exec();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//check celltypes
|
||||||
|
bool is_polygon_mesh(false),
|
||||||
|
is_c3t3(false),
|
||||||
|
is_polyline(false);
|
||||||
|
for(int i = 0; i< data->GetNumberOfCells(); ++i)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
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))
|
if (CGAL::vtkPointSet_to_polygon_mesh(data, *poly))
|
||||||
{
|
{
|
||||||
Scene_facegraph_item* poly_item = new Scene_facegraph_item(poly);
|
Scene_facegraph_item* poly_item = new Scene_facegraph_item(poly);
|
||||||
poly_item->setName(fileinfo.fileName());
|
if(group)
|
||||||
return poly_item;
|
{
|
||||||
|
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{
|
else{
|
||||||
// extract only segments
|
poly_item->setName(fileinfo.baseName());
|
||||||
|
return poly_item;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_c3t3)
|
||||||
|
{
|
||||||
|
typedef boost::array<int, 3> Facet; // 3 = id
|
||||||
|
typedef boost::array<int, 5> 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<Tr::Point> 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<Tet_with_ref> 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<int>(domains->GetComponent(i,0))
|
||||||
|
:1;
|
||||||
|
finite_cells.push_back(cell);
|
||||||
|
}
|
||||||
|
std::map<Facet, int> border_facets;
|
||||||
|
//Preprocessing for build_triangulation
|
||||||
|
//check for orientation and swap in cells if not good.
|
||||||
|
for(std::size_t i=0; i<finite_cells.size(); ++i)
|
||||||
|
{
|
||||||
|
Point_3 test_points[4];
|
||||||
|
for (int j = 0; j < 4; ++j)
|
||||||
|
{
|
||||||
|
Tr::Point tp = points[finite_cells[i][j]];
|
||||||
|
test_points[j] = Point_3(tp.x(), tp.y(), tp.z());
|
||||||
|
}
|
||||||
|
if(CGAL::orientation(test_points[0], test_points[1], test_points[2], test_points[3])
|
||||||
|
!= CGAL::POSITIVE)
|
||||||
|
{
|
||||||
|
std::swap(finite_cells[i][1], finite_cells[i][3]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CGAL::build_triangulation<Tr, true>(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<Point> > segments;
|
std::vector< std::vector<Point> > segments;
|
||||||
extract_segments_from_vtkPointSet(data,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();
|
Scene_polylines_item* polyline_item = new Scene_polylines_item();
|
||||||
polyline_item->setName(fileinfo.fileName());
|
|
||||||
BOOST_FOREACH(const std::vector<Point>& segment, segments)
|
BOOST_FOREACH(const std::vector<Point>& segment, segments)
|
||||||
polyline_item->polylines.push_back(segment);
|
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 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
|
}; // end Polyhedron_demo_vtk_plugin
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -98,16 +98,15 @@ Scene::replaceItem(Scene::Item_id index, CGAL::Three::Scene_item* item, bool emi
|
||||||
this, SLOT(callDraw()));
|
this, SLOT(callDraw()));
|
||||||
CGAL::Three::Scene_group_item* group =
|
CGAL::Three::Scene_group_item* group =
|
||||||
qobject_cast<CGAL::Three::Scene_group_item*>(m_entries[index]);
|
qobject_cast<CGAL::Three::Scene_group_item*>(m_entries[index]);
|
||||||
|
QList<Scene_item*> group_children;
|
||||||
if(group)
|
if(group)
|
||||||
{
|
{
|
||||||
QList<int> group_children;
|
|
||||||
Q_FOREACH(Item_id id, group->getChildren())
|
Q_FOREACH(Item_id id, group->getChildren())
|
||||||
{
|
{
|
||||||
CGAL::Three::Scene_item* child = group->getChild(id);
|
CGAL::Three::Scene_item* child = group->getChild(id);
|
||||||
group->unlockChild(child);
|
group->unlockChild(child);
|
||||||
group_children << item_id(child);
|
group_children << child;
|
||||||
}
|
}
|
||||||
erase(group_children);
|
|
||||||
}
|
}
|
||||||
CGAL::Three::Scene_group_item* parent = m_entries[index]->parentGroup();
|
CGAL::Three::Scene_group_item* parent = m_entries[index]->parentGroup();
|
||||||
bool is_locked = false;
|
bool is_locked = false;
|
||||||
|
|
@ -148,6 +147,10 @@ Scene::replaceItem(Scene::Item_id index, CGAL::Three::Scene_item* item, bool emi
|
||||||
Q_EMIT restoreCollapsedState();
|
Q_EMIT restoreCollapsedState();
|
||||||
redraw_model();
|
redraw_model();
|
||||||
Q_EMIT selectionChanged(index);
|
Q_EMIT selectionChanged(index);
|
||||||
|
Q_FOREACH(Scene_item* child, group_children)
|
||||||
|
{
|
||||||
|
erase(item_id(child));
|
||||||
|
}
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1013,10 +1016,13 @@ Scene::setData(const QModelIndex &index,
|
||||||
{
|
{
|
||||||
RenderingMode rendering_mode = static_cast<RenderingMode>(value.toInt());
|
RenderingMode rendering_mode = static_cast<RenderingMode>(value.toInt());
|
||||||
// Find next supported rendering mode
|
// Find next supported rendering mode
|
||||||
|
int counter = 0;
|
||||||
while ( ! item->supportsRenderingMode(rendering_mode)
|
while ( ! item->supportsRenderingMode(rendering_mode)
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
rendering_mode = static_cast<RenderingMode>( (rendering_mode+1) % NumberOfRenderingMode );
|
rendering_mode = static_cast<RenderingMode>( (rendering_mode+1) % NumberOfRenderingMode );
|
||||||
|
if(counter++ == NumberOfRenderingMode)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
item->setRenderingMode(rendering_mode);
|
item->setRenderingMode(rendering_mode);
|
||||||
QModelIndex nindex = createIndex(m_entries.size()-1,RenderingModeColumn+1);
|
QModelIndex nindex = createIndex(m_entries.size()-1,RenderingModeColumn+1);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue