Dear all, This is driving me round the bend. When I have a meshing coming from a rectilinear source, I get NANs from my normal and face area calculations. When all other input meshes are used, i.e. unstructured, the results are correct. To test this I've written the following test code which makes a single cell mesh and produces the NANs. I then demonstrate that by using the transform classes, with zero rotation, I can then extract the same mesh back as a structured grid, and the errors disappear. I can also apply a non-zero rotation and the errors disappear too.
Note I apply a rotation, zero or otherwise, because my hypothesis having stepped through 6.1 in the debugger, is that the vtk_pixel cell type (axis aligned) coming from the rectilinear grid does not play well with the normal calculation. But I can't find the bug, only that all entries of the normal are zero and the rest of the function fails. Clearly, and more likely, is that I could also not be using the classes correctly, and if so please let me know?? Hope somebody can find the bug, I've got nowhere on this after a day of looking. Again, anything non-axis aligned and or non vtk_pixel would appear to work as expected. Help appreciated, Cheers again, Andy
cmake_minimum_required(VERSION 2.8) PROJECT(weird) set(CMAKE_COLOR_MAKEFILE ON) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wextra -Wall -Wconversion -pedantic -Wuninitialized -std=c++11 -Wno-extra-semi") FIND_PACKAGE(VTK REQUIRED NO_MODULE) INCLUDE(${VTK_USE_FILE}) find_package(Qt5Widgets REQUIRED) set(SOURCES main.cxx) ADD_EXECUTABLE(weird ${SOURCES}) TARGET_LINK_LIBRARIES(weird ${VTK_LIBRARIES})
#include "vtkRectilinearGrid.h" #include "vtkXMLRectilinearGridWriter.h" #include "vtkXMLStructuredGridWriter.h" #include "vtkDoubleArray.h" #include "vtkSmartPointer.h" #include "vtkCell.h" #include "vtkPolygon.h" #include "vtkPoints.h" #include "vtkIdTypeArray.h" #include "vtkTransform.h" #include "vtkTransformFilter.h" #include "vtkPointSet.h" #include "vtkStructuredGrid.h" // #include <array> int main() { vtkSmartPointer<vtkRectilinearGrid>rg3D = vtkSmartPointer<vtkRectilinearGrid>::New(); vtkSmartPointer<vtkDoubleArray> xdata = vtkSmartPointer<vtkDoubleArray>::New(); vtkSmartPointer<vtkDoubleArray> ydata = vtkSmartPointer<vtkDoubleArray>::New(); vtkSmartPointer<vtkDoubleArray> zdata = vtkSmartPointer<vtkDoubleArray>::New(); const double deltaX = 0.01; xdata->InsertNextValue(0.0); xdata->InsertNextValue(deltaX); ydata->InsertNextValue(0.0); ydata->InsertNextValue(deltaX); zdata->InsertNextValue(0.0); zdata->InsertNextValue(deltaX); rg3D->SetDimensions(2,2,2); rg3D->SetXCoordinates(xdata); rg3D->SetYCoordinates(ydata); rg3D->SetZCoordinates(zdata); vtkSmartPointer<vtkXMLRectilinearGridWriter> writer = vtkSmartPointer<vtkXMLRectilinearGridWriter>::New(); writer->SetInputData(rg3D); writer->SetFileName("rgrid.vtr"); writer->Write(); vtkSmartPointer<vtkTransform> transform = vtkSmartPointer<vtkTransform>::New(); //transform->RotateZ(1.2345); // makes no difference transform->RotateZ(0.0); vtkSmartPointer<vtkTransformFilter> transformFilter = vtkSmartPointer<vtkTransformFilter>::New(); transformFilter->SetInputData(rg3D); transformFilter->SetTransform(transform); transformFilter->Update(); vtkSmartPointer<vtkXMLStructuredGridWriter> writer2 = vtkSmartPointer<vtkXMLStructuredGridWriter>::New(); writer2->SetInputData(transformFilter->GetStructuredGridOutput()); writer2->SetFileName("sgrid.vts"); writer2->Write(); /////// switch these two round to enable weirdness. //auto grid = transformFilter->GetStructuredGridOutput(); // removes NaNs auto grid = rg3D; // gives NaNs //////// for(uint c = 0; c < grid->GetNumberOfCells(); c++) { auto cell = grid->GetCell(c); const auto numFaces = cell->GetNumberOfFaces(); for(uint f = 0; f < numFaces; f++) { const auto face = cell->GetFace(f); //std::cout << cell->GetCellType() << " " << face->GetCellType() << std::endl; vtkSmartPointer<vtkPolygon> polygon = vtkSmartPointer<vtkPolygon>::New(); polygon->GetPoints()->SetNumberOfPoints(4); polygon->GetPointIds()->SetNumberOfIds(4); for(uint i = 0; i < face->GetNumberOfPoints(); i++) { polygon->GetPointIds()->SetId(i,i); } for(uint p = 0; p < face->GetNumberOfPoints(); p++) { std::array<double,3> pp; face->GetPoints()->GetPoint(p, pp.data()); polygon->GetPoints()->SetPoint(p, pp[0], pp[1], pp[2]); } const double area = polygon->ComputeArea(); std::cout << "Area " << area << std::endl; std::array<double,3> faceNormal; const double faceArea = vtkPolygon::ComputeArea(polygon->GetPoints(), face->GetNumberOfPoints(), polygon->GetPointIds()->GetPointer(0), faceNormal.data()); std::cout << "Area 2 " << faceArea << std::endl; std::cout << "Face Normal " << faceNormal[0] << " " << faceNormal[1] << " " << faceNormal[2] << std::endl; vtkSmartPointer<vtkIdTypeArray> pointsIDs = vtkSmartPointer<vtkIdTypeArray>::New(); for(uint i = 0; i < face->GetNumberOfPoints(); i++) { pointsIDs->InsertNextValue(i); } std::array<double,3> faceCentre; vtkPolygon::ComputeCentroid(pointsIDs, polygon->GetPoints(), faceCentre.data()); std::cout << "Face Centre " << faceCentre[0] << " " << faceCentre[1] << " " << faceCentre[2] << std::endl; } } }
_______________________________________________ Powered by www.kitware.com Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html Please keep messages on-topic and check the ParaView Wiki at: http://paraview.org/Wiki/ParaView Follow this link to subscribe/unsubscribe: http://public.kitware.com/mailman/listinfo/paraview