Chaste  Build::
MultiFormatMeshWriter.cpp
1 /*
2 
3 Copyright (c) 2005-2016, University of Oxford.
4  All rights reserved.
5 
6  University of Oxford means the Chancellor, Masters and Scholars of the
7  University of Oxford, having an administrative office at Wellington
8  Square, Oxford OX1 2JD, UK.
9 
10  This file is part of Chaste.
11 
12  Redistribution and use in source and binary forms, with or without
13  modification, are permitted provided that the following conditions are met:
14  * Redistributions of source code must retain the above copyright notice,
15  this list of conditions and the following disclaimer.
16  * Redistributions in binary form must reproduce the above copyright notice,
17  this list of conditions and the following disclaimer in the documentation
18  and/or other materials provided with the distribution.
19  * Neither the name of the University of Oxford nor the names of its
20  contributors may be used to endorse or promote products derived from this
21  software without specific prior written permission.
22 
23  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
24  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
27  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
29  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
32  OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 
34  */
35 
36 #include "Exception.hpp"
37 #include <boost/filesystem.hpp>
38 #define _BACKWARD_BACKWARD_WARNING_H 1 //Cut out the vtk deprecated warning
39 #include <vtkXMLUnstructuredGridWriter.h>
40 #include <vtkTriangle.h>
41 #include <vtkPoints.h>
42 #include <vtkTetra.h>
43 #include <vtkGeometryFilter.h>
44 #include <vtkTriangleFilter.h>
45 #include <vtkSTLWriter.h>
46 #include <vtkCleanPolyData.h>
47 #include <vtkIdList.h>
48 #include <vtkCellArray.h>
49 #include <vtkDataSetTriangleFilter.h>
50 #include <vtkExtractUnstructuredGrid.h>
51 #include <vtkDataSetSurfaceFilter.h>
52 //#include <dolfin.h>
53 #include "MultiFormatMeshWriter.hpp"
54 
55 template<unsigned DIM>
57  : mpVtkMesh(),
58  mpMesh(),
59  mFilepath(),
60  mOutputFormat(MeshFormat::VTU)
61 {
62 
63 }
64 
65 template<unsigned DIM>
66 boost::shared_ptr<MultiFormatMeshWriter<DIM> > MultiFormatMeshWriter<DIM>::Create()
67 {
68  MAKE_PTR(MultiFormatMeshWriter<DIM>, pSelf);
69  return pSelf;
70 }
71 
72 template<unsigned DIM>
74 {
75 
76 }
77 
78 template<unsigned DIM>
79 void MultiFormatMeshWriter<DIM>::SetMesh(vtkSmartPointer<vtkUnstructuredGrid> pMesh)
80 {
81  mpVtkMesh = pMesh;
82 }
83 
84 template<unsigned DIM>
86 {
87  mpMesh = pMesh;
88 }
89 
90 template<unsigned DIM>
91 void MultiFormatMeshWriter<DIM>::SetFilename(const std::string& filename)
92 {
93  mFilepath = filename;
94 }
95 
96 template<unsigned DIM>
97 void MultiFormatMeshWriter<DIM>::SetOutputFormat(MeshFormat::Value outputFormat)
98 {
99  mOutputFormat = outputFormat;
100 }
101 
102 template<unsigned DIM>
104 {
105  if(mFilepath == "")
106  {
107  EXCEPTION("Output file not specified for mesh writer");
108  }
109 
110  if(mOutputFormat == MeshFormat::VTU or mOutputFormat == MeshFormat::STL)
111  {
112  // If there is a DiscreteContinuum mesh convert it to vtk format first
113  if(mpMesh)
114  {
115  vtkSmartPointer<vtkPoints> p_vtk_points = vtkSmartPointer<vtkPoints>::New();
116  std::vector<c_vector<double, DIM> > node_locations = mpMesh->GetNodeLocations();
117  p_vtk_points->SetNumberOfPoints(node_locations.size());
118  for(unsigned idx=0; idx<node_locations.size(); idx++)
119  {
120  if(DIM==3)
121  {
122  p_vtk_points->InsertPoint(idx, node_locations[idx][0], node_locations[idx][1], node_locations[idx][2]);
123  }
124  else
125  {
126  p_vtk_points->InsertPoint(idx, node_locations[idx][0], node_locations[idx][1], 0.0);
127  }
128  }
129  mpVtkMesh->SetPoints(p_vtk_points);
130 
131  // Add vtk tets or triangles
132  std::vector<std::vector<unsigned> > element_connectivity = mpMesh->GetConnectivity();
133  unsigned num_elements = element_connectivity.size();
134  mpVtkMesh->Allocate(num_elements, num_elements);
135 
136  for(unsigned idx=0; idx<num_elements; idx++)
137  {
138  if(DIM==3)
139  {
140  vtkSmartPointer<vtkTetra> p_vtk_element = vtkSmartPointer<vtkTetra>::New();
141  unsigned num_nodes = element_connectivity[idx].size();
142  for(unsigned jdx=0; jdx<num_nodes; jdx++)
143  {
144  p_vtk_element->GetPointIds()->SetId(jdx, element_connectivity[idx][jdx]);
145  }
146  mpVtkMesh->InsertNextCell(p_vtk_element->GetCellType(), p_vtk_element->GetPointIds());
147  }
148  else
149  {
150  vtkSmartPointer<vtkTriangle> p_vtk_element = vtkSmartPointer<vtkTriangle>::New();
151  unsigned num_nodes = element_connectivity[idx].size();
152  for(unsigned jdx=0; jdx<num_nodes; jdx++)
153  {
154  p_vtk_element->GetPointIds()->SetId(jdx, element_connectivity[idx][jdx]);
155  }
156  mpVtkMesh->InsertNextCell(p_vtk_element->GetCellType(), p_vtk_element->GetPointIds());
157  }
158  }
159  }
160 
161  if(!mpVtkMesh)
162  {
163  EXCEPTION("No mesh has been set, cannot do write.");
164  }
165 
166  if(mOutputFormat == MeshFormat::VTU)
167  {
168  vtkSmartPointer<vtkXMLUnstructuredGridWriter> p_writer1 = vtkSmartPointer<vtkXMLUnstructuredGridWriter>::New();
169  p_writer1->SetFileName((mFilepath + ".vtu").c_str());
170  #if VTK_MAJOR_VERSION <= 5
171  p_writer1->SetInput(mpVtkMesh);
172  #else
173  p_writer1->SetInputData(mpVtkMesh);
174  #endif
175  p_writer1->Write();
176  }
177  else
178  {
179  vtkSmartPointer<vtkGeometryFilter> p_geom_filter = vtkSmartPointer<vtkGeometryFilter>::New();
180  #if VTK_MAJOR_VERSION <= 5
181  p_geom_filter->SetInput(mpVtkMesh);
182  #else
183  p_geom_filter->SetInputData(mpVtkMesh);
184  #endif
185 
186  p_geom_filter->Update();
187 
188  vtkSmartPointer<vtkTriangleFilter> p_tri_filter = vtkSmartPointer<vtkTriangleFilter>::New();
189  p_tri_filter->SetInputConnection(p_geom_filter->GetOutputPort());
190 
191  vtkSmartPointer<vtkCleanPolyData> p_clean_filter = vtkSmartPointer<vtkCleanPolyData>::New();
192  p_clean_filter->SetInputConnection(p_tri_filter->GetOutputPort());
193  p_clean_filter->Update();
194 
195  vtkSmartPointer<vtkSTLWriter> p_writer1 = vtkSmartPointer<vtkSTLWriter>::New();
196  p_writer1->SetFileName((mFilepath + ".stl").c_str());
197 
198  #if VTK_MAJOR_VERSION <= 5
199  p_writer1->SetInput(p_clean_filter->GetOutput());
200  #else
201  p_writer1->SetInputData(p_clean_filter->GetOutput());
202  #endif
203  p_writer1->SetFileTypeToASCII();
204  p_writer1->Write();
205  }
206  }
207 // else if (mOutputFormat == MeshFormat::DOLFIN)
208 // {
209 // // Use DiscreteContinuum mesh directly
210 // if(mpMesh)
211 // {
212 // dolfin::MeshEditor editor;
213 // dolfin::Mesh dolfin_mesh;
214 // editor.open(dolfin_mesh, DIM, DIM);
215 //
216 // std::vector<std::vector<double> > node_locations = mpMesh->GetNodeLocations();
217 // std::vector<std::vector<unsigned> > element_connectivity = mpMesh->GetConnectivity();
218 // editor.init_vertices(node_locations.size());
219 // editor.init_cells(element_connectivity.size());
220 //
221 // for(unsigned idx=0; idx<node_locations.size(); idx++)
222 // {
223 // if(DIM==2)
224 // {
225 // editor.add_vertex(idx, node_locations[idx][0],
226 // node_locations[idx][1]);
227 // }
228 // else
229 // {
230 // editor.add_vertex(idx, node_locations[idx][0],
231 // node_locations[idx][1],
232 // node_locations[idx][2]);
233 // }
234 //
235 // }
236 //
237 // for(unsigned idx=0; idx<element_connectivity.size(); idx++)
238 // {
239 // if(DIM==2)
240 // {
241 // editor.add_cell(idx, element_connectivity[idx][0],
242 // element_connectivity[idx][1],
243 // element_connectivity[idx][2]);
244 // }
245 // else
246 // {
247 // editor.add_cell(idx, element_connectivity[idx][0],
248 // element_connectivity[idx][1],
249 // element_connectivity[idx][2],
250 // element_connectivity[idx][3]);
251 // }
252 // }
253 //
254 // editor.close();
255 // dolfin_mesh.init();
256 //
257 // // Write the mesh to file
258 // dolfin::File mesh_file (mFilepath + ".xml");
259 // mesh_file << (dolfin_mesh);
260 // }
261 //
339 // }
340 }
341 
342 // Explicit instantiation
343 template class MultiFormatMeshWriter<2>;
344 template class MultiFormatMeshWriter<3>;
MeshFormat::Value mOutputFormat
static boost::shared_ptr< MultiFormatMeshWriter > Create()
boost::shared_ptr< DiscreteContinuumMesh< DIM > > mpMesh
void SetMesh(vtkSmartPointer< vtkUnstructuredGrid > pMesh)
void SetFilename(const std::string &rFilename)
vtkSmartPointer< vtkUnstructuredGrid > mpVtkMesh
void SetOutputFormat(MeshFormat::Value outputFormat)