G+Smo  24.08.0
Geometry + Simulation Modules
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
gsWriteParaview.hpp
Go to the documentation of this file.
1 
15 #pragma once
16 
18 #include <gsIO/gsIOUtils.h>
19 
20 #include <gsCore/gsGeometry.h>
21 #include <gsCore/gsGeometrySlice.h>
22 #include <gsCore/gsField.h>
23 #include <gsCore/gsDebug.h>
24 
25 #include <gsCore/gsMultiPatch.h>
26 
28 #include <gsModeling/gsSolid.h>
29 
31 
32 #define PLOT_PRECISION 12
33 
34 namespace gismo
35 {
36 
37 // Export a 3D parametric mesh
38 template<class T>
39 void writeSingleBasisMesh3D(const gsMesh<T> & sl,
40  std::string const & fn)
41 {
42  const unsigned numVer = sl.numVertices();
43  const unsigned numEl = numVer / 8;
44  std::string mfn(fn);
45  mfn.append(".vtu");
46  std::ofstream file(mfn.c_str());
47  if ( ! file.is_open() )
48  gsWarn<<"writeSingleBasisMesh3D: Problem opening file \""<<fn<<"\""<<std::endl;
49  file << std::fixed; // no exponents
50  file << std::setprecision (PLOT_PRECISION);
51 
52  file <<"<?xml version=\"1.0\"?>\n";
53  file <<"<VTKFile type=\"UnstructuredGrid\" version=\"0.1\" byte_order=\"LittleEndian\">\n";
54  file <<"<UnstructuredGrid>\n";
55 
56  // Number of vertices and number of cells
57  file <<"<Piece NumberOfPoints=\""<< numVer <<"\" NumberOfCells=\""<<numEl<<"\">\n";
58 
59  // Coordinates of vertices
60  file <<"<Points>\n";
61  file <<"<DataArray type=\"Float32\" NumberOfComponents=\"3\" format=\"ascii\">\n";
62  for (typename std::vector< gsVertex<T>* >::const_iterator it=sl.vertices().begin(); it!=sl.vertices().end(); ++it)
63  {
64  const gsVertex<T>& vertex = **it;
65  file << vertex[0] << " " << vertex[1] << " " << vertex[2] << " \n";
66  }
67  file << "\n";
68  file <<"</DataArray>\n";
69  file <<"</Points>\n";
70 
71  // Point data
72  file <<"<PointData Scalars=\"CellVolume\">\n";
73  file <<"<DataArray type=\"Float32\" Name=\"CellVolume\" format=\"ascii\" NumberOfComponents=\"1\">\n";
74  for (typename std::vector< gsVertex<T>* >::const_iterator it=sl.vertices().begin(); it!=sl.vertices().end(); ++it)
75  {
76  file << (*it)->data <<" ";
77  }
78  file << "\n";
79  file <<"</DataArray>\n";
80  file <<"</PointData>\n";
81 
82  // Cells
83  file <<"<Cells>\n";
84 
85  // Connectivity
86  file <<"<DataArray type=\"Int32\" Name=\"connectivity\" format=\"ascii\">\n";
87  for (unsigned i = 0; i!= numVer;++i)
88  {
89  file << i << " ";
90  }
91  file << "\n";
92  file <<"</DataArray>\n";
93 
94  // Offsets
95  file << "<DataArray type=\"Int32\" Name=\"offsets\" format=\"ascii\">\n";
96  for (unsigned i = 1; i<= numEl;++i)
97  {
98  file << 8*i << " ";
99  }
100  file << "\n";
101  file << "</DataArray>\n";
102 
103  // Type
104  file << "<DataArray type=\"Int32\" Name=\"types\" format=\"ascii\">\n";
105  for (unsigned i = 1; i<= numEl;++i)
106  {
107  file << "11 ";
108  }
109  file << "\n";
110  file << "</DataArray>\n";
111 
112  file <<"</Cells>\n";
113  file << "</Piece>\n";
114  file <<"</UnstructuredGrid>\n";
115  file <<"</VTKFile>\n";
116  file.close();
117 
118  //if( pvd ) // make a pvd file
119  // makeCollection(fn, ".vtp");
120 }
121 
122 // Export a 2D parametric mesh -- note: duplicates code from writeSingleBasisMesh3D,
123 //
124 template<class T>
125 void writeSingleBasisMesh2D(const gsMesh<T> & sl,
126  std::string const & fn)
127 {
128  const unsigned numVer = sl.numVertices();
129  const unsigned numEl = numVer / 4; //(1<<dim)
130  std::string mfn(fn);
131  mfn.append(".vtu");
132  std::ofstream file(mfn.c_str());
133  if ( ! file.is_open() )
134  gsWarn<<"writeSingleBasisMesh2D: Problem opening file \""<<fn<<"\""<<std::endl;
135  file << std::fixed; // no exponents
136  file << std::setprecision (PLOT_PRECISION);
137 
138  file <<"<?xml version=\"1.0\"?>\n";
139  file <<"<VTKFile type=\"UnstructuredGrid\" version=\"0.1\" byte_order=\"LittleEndian\">\n";
140  file <<"<UnstructuredGrid>\n";
141 
142  // Number of vertices and number of cells
143  file <<"<Piece NumberOfPoints=\""<< numVer <<"\" NumberOfCells=\""<<numEl<<"\">\n";
144 
145  // Coordinates of vertices
146  file <<"<Points>\n";
147  file <<"<DataArray type=\"Float32\" NumberOfComponents=\"3\" format=\"ascii\">\n";
148  for (typename std::vector< gsVertex<T>* >::const_iterator it=sl.vertices().begin(); it!=sl.vertices().end(); it+=4)
149  {
150  // order is important!
151  const gsVertex<T>& vertex0 = **it;
152  const gsVertex<T>& vertex1 = **(it+1);
153  const gsVertex<T>& vertex3 = **(it+3);
154  const gsVertex<T>& vertex2 = **(it+2);
155  file << vertex0[0] << " " << vertex0[1] << " " << vertex0[2] << " \n";
156  file << vertex1[0] << " " << vertex1[1] << " " << vertex1[2] << " \n";
157  file << vertex3[0] << " " << vertex3[1] << " " << vertex3[2] << " \n";
158  file << vertex2[0] << " " << vertex2[1] << " " << vertex2[2] << " \n";
159  }
160  file << "\n";
161  file <<"</DataArray>\n";
162  file <<"</Points>\n";
163 
164  // Point data
165  file <<"<PointData Scalars=\"CellArea\">\n";
166  file <<"<DataArray type=\"Float32\" Name=\"CellVolume\" format=\"ascii\" NumberOfComponents=\"1\">\n";
167  for (typename std::vector< gsVertex<T>* >::const_iterator it=sl.vertices().begin(); it!=sl.vertices().end(); ++it)
168  {
169  file << (*it)->data <<" ";
170  }
171  file << "\n";
172  file <<"</DataArray>\n";
173  file <<"</PointData>\n";
174 
175  // Cells
176  file <<"<Cells>\n";
177 
178  // Connectivity
179  file <<"<DataArray type=\"Int32\" Name=\"connectivity\" format=\"ascii\">\n";
180  for (unsigned i = 0; i!= numVer;++i)
181  {
182  file << i << " ";
183  }
184  file << "\n";
185  file <<"</DataArray>\n";
186 
187  // Offsets
188  file << "<DataArray type=\"Int32\" Name=\"offsets\" format=\"ascii\">\n";
189  for (unsigned i = 1; i<= numEl;++i)
190  {
191  file << 4*i << " "; //step: (1<<dim)
192  }
193  file << "\n";
194  file << "</DataArray>\n";
195 
196  // Type
197  file << "<DataArray type=\"Int32\" Name=\"types\" format=\"ascii\">\n";
198  for (unsigned i = 1; i<= numEl;++i)
199  {
200  file << "9 ";// 11: 3D, 9: 2D
201  }
202  file << "\n";
203  file << "</DataArray>\n";
204 
205  file <<"</Cells>\n";
206  file << "</Piece>\n";
207  file <<"</UnstructuredGrid>\n";
208  file <<"</VTKFile>\n";
209  file.close();
210 
211  //if( pvd ) // make a pvd file
212  // makeCollection(fn, ".vtp");
213 }
214 
215 
217 template<class T>
218 void writeSingleBasisMesh(const gsBasis<T> & basis,
219  std::string const & fn)
220 {
221  gsMesh<T> msh(basis, 0);
222  if ( basis.dim() == 3)
223  writeSingleBasisMesh3D(msh,fn);
224  else if ( basis.dim() == 2)
225  writeSingleBasisMesh2D(msh,fn);
226  else
227  gsWriteParaview(msh, fn, false);
228 }
229 
231 template<class T>
232 void writeSingleCompMesh(const gsBasis<T> & basis, const gsGeometry<T> & Geo,
233  std::string const & fn, unsigned resolution)
234 {
235  gsMesh<T> msh(basis, resolution);
236  Geo.evaluateMesh(msh);
237 
238  // if ( basis.dim() == 3)
239  // writeSingleBasisMesh3D(msh,fn);
240  // else if ( basis.dim() == 2)
241  // writeSingleBasisMesh2D(msh,fn);
242  // else
243  gsWriteParaview(msh, fn, false);
244 }
245 
247 template<class T>
249  std::string const & fn)
250 {
251  const int d = Geo.parDim();
252  gsMesh<T> msh;
253  Geo.controlNet(msh);
254  const unsigned n = Geo.geoDim();
255  if ( n == 1 )
256  {
257  gsMatrix<T> anch = Geo.basis().anchors();
258  // Lift vertices at anchor positions
259  for (size_t i = 0; i!= msh.numVertices(); ++i)
260  {
261  msh.vertex(i)[d] = msh.vertex(i)[0];
262  msh.vertex(i).topRows(d) = anch.col(i);
263  }
264  }
265  else if (n>3)
266  {
267  gsDebug<<"Writing 4th coordinate\n";
268  const gsMatrix<T> & cp = Geo.coefs();
269  gsWriteParaviewPoints<T>(cp.transpose(), fn );
270  return;
271  }
272 
273  gsWriteParaview(msh, fn, false);
274 }
275 
276 template<class T>
277 void gsWriteParaviewTPgrid(const gsMatrix<T> & eval_geo ,
278  const gsMatrix<T> & eval_field,
279  const gsVector<index_t> & np,
280  std::string const & fn)
281 {
282  const int n = eval_geo.rows();
283  GISMO_ASSERT(eval_geo.cols()==eval_field.cols()
284  && static_cast<index_t>(np.prod())==eval_geo.cols(),
285  "Data do not match");
286 
287  std::string mfn(fn);
288  mfn.append(".vts");
289  std::ofstream file(mfn.c_str());
290  file << std::fixed; // no exponents
291  file << std::setprecision (PLOT_PRECISION);
292 
293  index_t np1 = (np.size()>1 ? np(1)-1 : 0);
294  index_t np2 = (np.size()>2 ? np(2)-1 : 0);
295 
296  file <<"<?xml version=\"1.0\"?>\n";
297  file <<"<VTKFile type=\"StructuredGrid\" version=\"0.1\">\n";
298  file <<"<StructuredGrid WholeExtent=\"0 "<< np(0)-1<<" 0 "<< np1 <<" 0 "
299  << np2 <<"\">\n";
300  file <<"<Piece Extent=\"0 "<< np(0)-1<<" 0 "<<np1<<" 0 "
301  << np2 <<"\">\n";
302  file <<"<PointData "<< ( eval_field.rows()==1 ?"Scalars":"Vectors")<<"=\"SolutionField\">\n";
303  file <<"<DataArray type=\"Float32\" Name=\"SolutionField\" format=\"ascii\" NumberOfComponents=\""<< ( eval_field.rows()==1 ? 1 : 3) <<"\">\n";
304  if ( eval_field.rows()==1 )
305  for ( index_t j=0; j<eval_field.cols(); ++j)
306  file<< eval_field.at(j) <<" ";
307  else
308  {
309  for ( index_t j=0; j<eval_field.cols(); ++j)
310  {
311  for ( index_t i=0; i!=eval_field.rows(); ++i)
312  file<< eval_field(i,j) <<" ";
313  for ( index_t i=eval_field.rows(); i<3; ++i)
314  file<<"0 ";
315  }
316  }
317  file <<"</DataArray>\n";
318  file <<"</PointData>\n";
319  file <<"<Points>\n";
320  file <<"<DataArray type=\"Float32\" NumberOfComponents=\"3\">\n";
321  for ( index_t j=0; j<eval_geo.cols(); ++j)
322  {
323  for ( index_t i=0; i!=n; ++i)
324  file<< eval_geo(i,j) <<" ";
325  for ( index_t i=n; i<3; ++i)
326  file<<"0 ";
327  }
328  file <<"</DataArray>\n";
329  file <<"</Points>\n";
330  file <<"</Piece>\n";
331  file <<"</StructuredGrid>\n";
332  file <<"</VTKFile>\n";
333 
334  file.close();
335 }
336 
337 template<class T>
338 void writeSinglePatchField(const gsFunction<T> & geometry,
339  const gsFunction<T> & parField,
340  const bool isParam,
341  std::string const & fn, unsigned npts)
342 {
343  const int n = geometry.targetDim();
344  const int d = geometry.domainDim();
345 
346  gsMatrix<T> ab = geometry.support();
347  gsVector<T> a = ab.col(0);
348  gsVector<T> b = ab.col(1);
349 
350  gsVector<unsigned> np = uniformSampleCount(a, b, npts);
351  gsMatrix<T> pts = gsPointGrid(a, b, np);
352 
353  gsMatrix<T> eval_geo = geometry.eval(pts);//pts
354  gsMatrix<T> eval_field = isParam ? parField.eval(pts) : parField.eval(eval_geo);
355 
356  if ( 3 - d > 0 )
357  {
358  np.conservativeResize(3);
359  np.bottomRows(3-d).setOnes();
360  }
361  else if (d > 3)
362  {
363  gsWarn<< "Cannot plot 4D data.\n";
364  return;
365  }
366 
367  if ( 3 - n > 0 )
368  {
369  eval_geo.conservativeResize(3,eval_geo.cols() );
370  eval_geo.bottomRows(3-n).setZero();
371  }
372  else if (n > 3)
373  {
374  gsWarn<< "Data is more than 3 dimensions.\n";
375  }
376 
377  if ( eval_field.rows() == 2)
378  {
379  eval_field.conservativeResize(3,eval_geo.cols() );
380  eval_field.bottomRows(1).setZero(); // 3-field.dim()
381  }
382 
383  gsWriteParaviewTPgrid(eval_geo, eval_field, np.template cast<index_t>(), fn);
384 }
385 
387 template<class T>
388 void writeSinglePatchField(const gsField<T> & field, int patchNr,
389  std::string const & fn, unsigned npts)
390 {
391  writeSinglePatchField(field.patch(patchNr), field.function(patchNr), field.isParametric(), fn, npts);
392 /*
393  const int n = field.geoDim();
394  const int d = field.parDim();
395 
396  gsMatrix<T> ab = field.patches().parameterRange(patchNr);
397  gsVector<T> a = ab.col(0);
398  gsVector<T> b = ab.col(1);
399 
400  gsVector<unsigned> np = uniformSampleCount(a, b, npts);
401  gsMatrix<T> pts = gsPointGrid(a, b, np);
402 
403  gsMatrix<T> eval_geo = field.point ( pts, patchNr );//pts
404 
405  if ( 3 - d > 0 )
406  {
407  np.conservativeResize(3);
408  np.bottomRows(3-d).setOnes();
409  }
410  else if (d > 3)
411  {
412  gsWarn<< "Cannot plot 4D data.\n";
413  return;
414  }
415 
416  if ( 3 - n > 0 )
417  {
418  eval_geo.conservativeResize(3,eval_geo.cols() );
419  eval_geo.bottomRows(3-n).setZero();
420  }
421  else if (d > 3)
422  {
423  gsWarn<< "Cannot plot 4D data.\n";
424  return;
425  }
426 
427  gsMatrix<T> eval_field = field.value ( pts, patchNr );//values
428  GISMO_ASSERT( eval_field.rows() == field.dim(), "Error in field dimension");
429  if ( eval_field.rows() > 1 )
430  {
431  eval_field.conservativeResize(3,eval_geo.cols() );
432  eval_field.bottomRows( 3-field.dim() ).setZero();
433  }
434 
435  std::string mfn(fn);
436  mfn.append(".vts");
437  std::ofstream file(mfn.c_str());
438  file << std::fixed; // no exponents
439  file << std::setprecision (PLOT_PRECISION);
440 
441  file <<"<?xml version=\"1.0\"?>\n";
442  file <<"<VTKFile type=\"StructuredGrid\" version=\"0.1\">\n";
443  file <<"<StructuredGrid WholeExtent=\"0 "<< np(0)-1<<" 0 "<<np(1)-1<<" 0 "<<np(2)-1<<"\">\n";
444  file <<"<Piece Extent=\"0 "<< np(0)-1<<" 0 "<<np(1)-1<<" 0 "<<np(2)-1<<"\">\n";
445  file <<"<PointData "<< ( field.dim()==1 ?"Scalars":"Vectors")<<"=\"SolutionField\">\n";
446  file <<"<DataArray type=\"Float32\" Name=\"SolutionField\" format=\"ascii\" NumberOfComponents=\""<< eval_field.rows() <<"\">\n";
447  for ( index_t j=0; j<eval_field.cols(); ++j)
448  for ( index_t i=0; i<eval_field.rows(); ++i)
449  file<< eval_field(i,j) <<" ";
450  file <<"</DataArray>\n";
451  file <<"</PointData>\n";
452  file <<"<Points>\n";
453  file <<"<DataArray type=\"Float32\" NumberOfComponents=\""<<eval_geo.rows()<<"\">\n";
454  for ( index_t j=0; j<eval_geo.cols(); ++j)
455  for ( index_t i=0; i<eval_geo.rows(); ++i)
456  file<< eval_geo(i,j) <<" ";
457  file <<"</DataArray>\n";
458  file <<"</Points>\n";
459  file <<"</Piece>\n";
460  file <<"</StructuredGrid>\n";
461  file <<"</VTKFile>\n";
462 
463  file.close();
464 */
465 }
466 
468 template<class T>
470  gsMatrix<T> const& supp,
471  std::string const & fn, unsigned npts)
472 {
473  int n = func.targetDim();
474  const int d = func.domainDim();
475 
476  gsVector<T> a = supp.col(0);
477  gsVector<T> b = supp.col(1);
478  gsVector<unsigned> np = uniformSampleCount(a,b, npts );
479  gsMatrix<T> pts = gsPointGrid(a,b,np) ;
480 
481  gsMatrix<T> eval_func = func.eval ( pts ) ;//pts
482 
483  if ( 3 - d > 0 )
484  {
485  np.conservativeResize(3);
486  np.bottomRows(3-d).setOnes();
487  }
488 
489  if ( 3 - n > 0 )
490  {
491  eval_func.conservativeResize(3,eval_func.cols() );
492  eval_func.bottomRows(3-n).setZero();
493 
494  if ( n == 1 )
495  {
496  if (d==3)
497  {
498  n = 4;
499  eval_func.conservativeResize(4,eval_func.cols() );
500  }
501 
502  //std::swap( eval_geo.row(d), eval_geo.row(0) );
503  eval_func.row(d) = eval_func.row(0);
504  eval_func.topRows(d) = pts;
505  }
506  }
507 
508  std::string mfn(fn);
509  mfn.append(".vts");
510  std::ofstream file(mfn.c_str());
511  if ( ! file.is_open() )
512  gsWarn<<"writeSingleGeometry: Problem opening file \""<<fn<<"\""<<std::endl;
513  file << std::fixed; // no exponents
514  file << std::setprecision (PLOT_PRECISION);
515  file <<"<?xml version=\"1.0\"?>\n";
516  file <<"<VTKFile type=\"StructuredGrid\" version=\"0.1\">\n";
517  file <<"<StructuredGrid WholeExtent=\"0 "<<np(0)-1<<" 0 "<<np(1)-1<<" 0 "<<np(2)-1<<"\">\n";
518  file <<"<Piece Extent=\"0 "<< np(0)-1<<" 0 "<<np(1)-1<<" 0 "<<np(2)-1<<"\">\n";
519  // Add norm of the point as data
520  // file <<"<PointData Scalars =\"PointNorm\">\n";
521  // file <<"<DataArray type=\"Float32\" Name=\"PointNorm\" format=\"ascii\" NumberOfComponents=\""<< 1 <<"\">\n";
522  // for ( index_t j=0; j<eval_geo.cols(); ++j)
523  // file<< eval_geo.col(j).norm() <<" ";
524  // file <<"</DataArray>\n";
525  // file <<"</PointData>\n";
526  // end norm
527 
528  //---------
529  if (n > 3)
530  {
531  //gsWarn<< "4th dimension as scalar data.\n";
532  file <<"<PointData "<< "Scalars=\"Coordinate4\">\n";
533  file <<"<DataArray type=\"Float32\" Name=\"Coordinate4\" format=\"ascii\" NumberOfComponents=\"1\">\n";
534  for ( index_t j=0; j!=eval_func.cols(); ++j)
535  file<< eval_func(3,j) <<" ";
536  file <<"</DataArray>\n";
537  file <<"</PointData>\n";
538  }
539  //---------
540 
541  file <<"<Points>\n";
542  file <<"<DataArray type=\"Float32\" NumberOfComponents=\"3\">\n";
543  for ( index_t j=0; j<eval_func.cols(); ++j)
544  for ( index_t i=0; i!=3; ++i)
545  file<< eval_func(i,j) <<" ";
546  file <<"</DataArray>\n";
547  file <<"</Points>\n";
548  file <<"</Piece>\n";
549  file <<"</StructuredGrid>\n";
550  file <<"</VTKFile>\n";
551  file.close();
552 }
553 
555 template<class T>
557  gsMatrix<T> const& supp,
558  std::string const & fn, unsigned npts)
559 {
560  const unsigned n = func.targetDim();
561  const unsigned d = func.domainDim();
562  GISMO_ASSERT( d == 1, "Not a curve");
563 
564  gsVector<T> a = supp.col(0);
565  gsVector<T> b = supp.col(1);
566  gsVector<unsigned> np = uniformSampleCount(a,b, npts );
567  gsMatrix<T> pts = gsPointGrid(a,b,np) ;
568 
569  gsMatrix<T> eval_func = func.eval ( pts ) ;//pts
570 
571  np.conservativeResize(3);
572  np.bottomRows(2).setOnes();
573 
574  if ( 3 - n > 0 )
575  {
576  eval_func.conservativeResize(3,eval_func.cols() );
577  eval_func.bottomRows(3-n).setZero();
578 
579  if ( n == 1 )
580  {
581  //std::swap( eval_geo.row(d), eval_geo.row(0) );
582  eval_func.row(d) = eval_func.row(0);
583  eval_func.topRows(d) = pts;
584  }
585  }
586 
587  std::string mfn(fn);
588  mfn.append(".vtp");
589  std::ofstream file(mfn.c_str());
590  if ( ! file.is_open() )
591  gsWarn<<"writeSingleCurve: Problem opening file \""<<fn<<"\""<<std::endl;
592  file << std::fixed; // no exponents
593  file << std::setprecision (PLOT_PRECISION);
594  file <<"<?xml version=\"1.0\"?>\n";
595  file <<"<VTKFile type=\"PolyData\" version=\"0.1\" byte_order=\"LittleEndian\">\n";
596  file <<"<PolyData>\n";
597  // Accounting
598  file <<"<Piece NumberOfPoints=\""<< npts
599  <<"\" NumberOfVerts=\"0\" NumberOfLines=\""<< npts-1
600  <<"\" NumberOfStrips=\"0\" NumberOfPolys=\"0\">\n";
601  file <<"<Points>\n";
602  file <<"<DataArray type=\"Float32\" NumberOfComponents=\""<<eval_func.rows()<<"\">\n";
603  for ( index_t j=0; j<eval_func.cols(); ++j)
604  for ( index_t i=0; i<eval_func.rows(); ++i)
605  file<< eval_func(i,j) <<" ";
606  file <<"\n</DataArray>\n";
607  file <<"</Points>\n";
608  // Lines
609  file <<"<Lines>\n";
610  file <<"<DataArray type=\"Int64\" Name=\"connectivity\" format=\"ascii\" RangeMin=\"0\" RangeMax=\""<<npts-1<<"\">\n";
611  for (unsigned i=0; i< npts-1; ++i )
612  {
613  file << i << " " << i+1 << " ";
614  }
615  // offsets
616  file <<"\n</DataArray>\n";
617  unsigned offset(0);
618  file <<"<DataArray type=\"Int64\" Name=\"offsets\" format=\"ascii\" RangeMin=\"0\" RangeMax=\""<<npts-1<<"\">\n";
619  for (unsigned i=0; i< npts-1; ++i )
620  {
621  offset +=2;
622  file << offset << " ";
623  }
624  file <<"\n</DataArray>\n";
625  file <<"</Lines>\n";
626  // Closing
627  file <<"</Piece>\n";
628  file <<"</PolyData>\n";
629  file <<"</VTKFile>\n";
630  file.close();
631 }
632 
633 template<class T>
634 void writeSingleCurve(const gsGeometry<T> & Geo, std::string const & fn, unsigned npts)
635 {
636  gsMatrix<T> ab = Geo.parameterRange();
637  writeSingleCurve( Geo, ab, fn, npts);
638 }
639 
640 template<class T>
641 void writeSingleGeometry(const gsGeometry<T> & Geo, std::string const & fn, unsigned npts)
642 {
643  /*
644  gsMesh<T> msh;
645  Geo.toMesh(msh, npts);
646  gsWriteParaview(msh, fn, false);
647  return;
648  */
649  gsMatrix<T> ab = Geo.parameterRange();
650  writeSingleGeometry( Geo, ab, fn, npts);
651 }
652 
653 template<class T>
654 void writeSingleTrimSurface(const gsTrimSurface<T> & surf,
655  std::string const & fn,
656  unsigned npts)
657 {
658  typename gsMesh<T>::uPtr msh = surf.toMesh(npts);
659  gsWriteParaview( *msh, fn);
660 }
661 
663 template<class T>
664 void gsWriteParaview(const gsField<T> & field,
665  std::string const & fn,
666  unsigned npts, bool mesh,
667  const std::string pDelim)
668 {
669  /*
670  if (mesh && (!field.isParametrized()) )
671  {
672  gsWarn<< "Cannot plot mesh from non-parametric field.";
673  mesh = false;
674  }
675  */
676 
677  const unsigned n = field.nPieces();
678  gsParaviewCollection collection(fn);
679  std::string fileName, fileName_nopath;
680 
681  for ( unsigned i=0; i < n; ++i )
682  {
683  const gsBasis<T> & dom = field.isParametrized() ?
684  field.igaFunction(i).basis() : field.patch(i).basis();
685 
686  fileName = fn + pDelim + util::to_string(i);
687  fileName_nopath = gsFileManager::getFilename(fileName);
688  writeSinglePatchField( field, i, fileName, npts );
689  collection.addPart(fileName_nopath + ".vts");
690  if ( mesh )
691  {
692  fileName+= "_mesh";
693  fileName_nopath = gsFileManager::getFilename(fileName);
694  writeSingleCompMesh(dom, field.patch(i), fileName);
695 
696  collection.addPart(fileName_nopath + ".vtp");
697  }
698 
699  }
700  collection.save();
701 }
702 
704 template<class T>
705 void gsWriteParaview(gsFunctionSet<T> const& geo,
706  gsFunctionSet<T> const& func,
707  std::string const & fn,
708  unsigned npts, const std::string pDelim)
709 {
710  /*
711  if (mesh && (!field.isParametrized()) )
712  {
713  gsWarn<< "Cannot plot mesh from non-parametric field.";
714  mesh = false;
715  }
716  */
717 
718  GISMO_ASSERT(geo.nPieces()==func.nPieces(),"Function sets must have same number of pieces, but func has "<<func.nPieces()<<" and geo has "<<geo.nPieces());
719 
720  const unsigned n = geo.nPieces();
721  gsParaviewCollection collection(fn);
722  std::string fileName, fileName_nopath;
723 
724  for ( unsigned i=0; i < n; ++i )
725  {
726  fileName = fn + pDelim + util::to_string(i);
727  fileName_nopath = gsFileManager::getFilename(fileName);
728  writeSinglePatchField( geo.function(i), func.function(i), true, fileName, npts );
729  collection.addPart(fileName_nopath + ".vts");
730  }
731  collection.save();
732 }
733 
735 template<class T>
736 void gsWriteParaview(gsMappedSpline<2,T> const& mspline,
737  std::string const & fn,
738  unsigned npts)
739 {
740  gsParaviewCollection collection(fn);
741  std::string fileName, fileName_nopath;
742  for ( index_t p=0; p < mspline.nPieces(); ++p )
743  {
744  // Compute the geometry
745  fileName = fn + "_" + util::to_string(p);
746  fileName_nopath = gsFileManager::getFilename(fileName);
747  writeSingleGeometry(mspline.piece(p),mspline.piece(p).support(),fileName,npts);
748  collection.addPart(fileName_nopath + ".vts",-1,"",p);
749  }
750  collection.save();
751 }
752 
754 template<class T>
755 void gsWriteParaview(gsFunctionSet<T> const& geom,
756  gsMappedBasis<2,T> const& mbasis,
757  std::string const & fn,
758  unsigned npts,
759  const bool fullsupport,
760  const std::vector<index_t> indices)
761 {
762  /*
763  We loop over all global basis functions.
764  For each global basis function, we find the patches on which it is active
765  On the patches, we call evalSingle_into and construct a local Paraview file
766  Then, the paraview file is combined as part in a collection.
767  */
768  GISMO_ASSERT(geom.nPieces()==mbasis.nPieces(),"Function sets must have same number of pieces, but the basis has "<<mbasis.nPieces()<<" and the geometry has "<<geom.nPieces());
769 
770  std::vector<index_t> plotIndices;
771  if (indices.size()==0)
772  {
773  plotIndices.resize(mbasis.globalSize());
774  std::generate(plotIndices.begin(), plotIndices.end(), [n = 0] () mutable { return n++; });
775  }
776  else
777  plotIndices = indices;
778 
779  gsParaviewCollection collection(fn);
780  std::string fileName, fileName_nopath;
781  gsMatrix<T> eval_geo, eval_basis, pts, ab;
782  gsVector<T> a, b;
784  for ( index_t p=0; p < geom.nPieces(); ++p )
785  {
786  if (fullsupport)
787  {
788  // Compute the geometry
789  ab = geom.piece(p).support();
790  a = ab.col(0);
791  b = ab.col(1);
792 
793  if (a.prod() == 0 && b.prod()==0)
794  continue;
795 
796  np = uniformSampleCount(a, b, npts);
797  pts = gsPointGrid(a, b, np);
798 
799  eval_geo = geom.piece(p).eval(pts);//pts
800  }
801 
802  for (std::vector<index_t>::const_iterator i = plotIndices.begin(); i!=plotIndices.end(); i++)//, k++)
803  {
804  if (!fullsupport)
805  {
806  // Compute the geometry on the support of the basis function
807  ab = mbasis.piece(p).support(*i);
808  // ab = mbasis.piece(p).support();
809  a = ab.col(0);
810  b = ab.col(1);
811  if (a.prod() == 0 && b.prod()==0)
812  continue;
813 
814  np = uniformSampleCount(a, b, npts);
815  pts = gsPointGrid(a, b, np);
816 
817  eval_geo = geom.piece(p).eval(pts);//pts
818  }
819 
820  fileName = fn + util::to_string(*i) + "_" + util::to_string(p);
821  fileName_nopath = gsFileManager::getFilename(fileName);
822 
823  eval_basis = mbasis.piece(p).evalSingle(*i,pts);
824  gsWriteParaviewTPgrid(eval_geo, eval_basis, np.template cast<index_t>(), fileName);
825 
826  collection.addPart(fileName_nopath + ".vts",*i,"",p);
827  }
828  // for (index_t k = 0; k < mbasis.globalSize(); k++)
829  // {
830  // fileName = fn + util::to_string(k) + "_" + util::to_string(p);
831  // fileName_nopath = gsFileManager::getFilename(fileName);
832 
833  // eval_basis = mbasis.piece(p).evalSingle(k,pts);
834  // gsWriteParaviewTPgrid(eval_geo, eval_basis, np.template cast<index_t>(), fileName);
835 
836  // collection.addPart(fileName_nopath + ".vts",k,"",p);
837  // }
838  }
839  collection.save();
840 }
841 
843 template<class T>
844 void gsWriteParaview(const gsGeometry<T> & Geo, std::string const & fn,
845  unsigned npts, bool mesh, bool ctrlNet)
846 {
847  const bool curve = ( Geo.domainDim() == 1 );
848 
849  gsParaviewCollection collection(fn);
850  std::string fn_nopath = gsFileManager::getFilename(fn);
851  if ( curve )
852  {
853  writeSingleCurve(Geo, fn, npts);
854  collection.addPart(fn_nopath + ".vtp");
855  }
856  else
857  {
858  writeSingleGeometry(Geo, fn, npts);
859  collection.addPart(fn_nopath + ".vts");
860  }
861 
862  if ( mesh ) // Output the underlying mesh
863  {
864  const std::string fileName = fn + "_mesh";
865  std::string fileName_nopath = gsFileManager::getFilename(fileName);
866 
867  int ptsPerEdge;
868 
869  // If not using default, compute the resolution from npts.
870  if(npts!=8)
871  {
872  const T evalPtsPerElem = npts * (1.0 / Geo.basis().numElements());
873 
874  // The following complicated formula should ensure similar
875  // resolution of the mesh edges and the surface. The
876  // additional multiplication by deg - 1 ensures quadratic
877  // elements to be approximated by at least two lines etc.
878  ptsPerEdge = cast<T,int>(
879  static_cast<T>(math::max(Geo.basis().maxDegree()-1, (short_t)1)) * math::pow(evalPtsPerElem, T(1.0)/static_cast<T>(Geo.domainDim())) );
880  }
881  else
882  {
883  ptsPerEdge = npts;
884  }
885 
886  writeSingleCompMesh(Geo.basis(), Geo, fileName, ptsPerEdge);
887  collection.addPart(fileName_nopath + ".vtp");
888  }
889 
890  if ( ctrlNet ) // Output the control net
891  {
892  const std::string fileName = fn + "_cnet";
893  std::string fileName_nopath = gsFileManager::getFilename(fileName);
894  writeSingleControlNet(Geo, fileName);
895  collection.addPart(fileName_nopath + ".vtp");
896  }
897 
898  // Write out the collection file
899  collection.save();
900 }
901 
902 // Export a multibasis mesh
903 template<class T>
904 void gsWriteParaview(const gsMultiBasis<T> & mb, const gsMultiPatch<T> & domain,
905  std::string const & fn, unsigned npts)
906 {
907  // GISMO_ASSERT sizes
908 
909  gsParaviewCollection collection(fn);
910 
911  for (size_t i = 0; i != domain.nPatches(); ++i)
912  {
913  const std::string fileName = fn + util::to_string(i) + "_mesh";
914  const std::string fileName_nopath = gsFileManager::getFilename(fileName);
915  writeSingleCompMesh(mb[i], domain.patch(i), fileName, npts);
916  collection.addPart(fileName_nopath + ".vtp");
917  }
918 
919  // Write out the collection file
920  collection.save();
921 }
922 
924 template<class T>
925 void gsWriteParaview(const gsGeometrySlice<T> & Geo,
926  std::string const & fn,
927  unsigned npts)
928 {
929  const gsMatrix<T> supp = Geo.parameterRange();
930  writeSingleGeometry(Geo, supp, fn, npts);
931  // Write out a pvd file
932  makeCollection(fn, ".vts"); // make also a pvd file
933 }
934 
935 
937 template<class T>
938 void gsWriteParaview( std::vector<gsGeometry<T> *> const & Geo,
939  std::string const & fn,
940  unsigned npts, bool mesh, bool ctrlNet, const std::string pDelim)
941 {
942  const size_t n = Geo.size();
943 
944  gsParaviewCollection collection(fn);
945  std::string fnBase, fnBase_nopath;
946 
947  for ( size_t i=0; i<n ; i++)
948  {
949  fnBase = fn + pDelim + util::to_string(i);
950  fnBase_nopath = gsFileManager::getFilename(fnBase);
951 
952  if ( Geo.at(i)->domainDim() == 1 )
953  {
954  writeSingleCurve(*Geo[i], fnBase, npts);
955  collection.addPart(fnBase_nopath + ".vtp");
956  }
957  else
958  {
959  writeSingleGeometry( *Geo[i], fnBase, npts ) ;
960  collection.addPart(fnBase_nopath + ".vts");
961  }
962 
963  if ( mesh )
964  {
965  const std::string fileName = fnBase + "_mesh";
966  const std::string fileName_nopath = gsFileManager::getFilename(fileName);
967  writeSingleCompMesh(Geo[i]->basis(), *Geo[i], fileName);
968  collection.addPart(fileName_nopath + ".vtp");
969  }
970 
971  if ( ctrlNet ) // Output the control net
972  {
973  const std::string fileName = fnBase + "_cnet";
974  const std::string fileName_nopath = gsFileManager::getFilename(fileName);
975  writeSingleControlNet(*Geo[i], fileName);
976  collection.addPart(fileName_nopath + ".vtp");
977  }
978  }
979  collection.save();
980 }
981 
983 template<class T>
984 void gsWriteParaview_basisFnct(int i, gsBasis<T> const& basis, std::string const & fn, unsigned npts)
985 {
986  // basis.support(i) --> returns a (tight) bounding box for the
987  // supp. of i-th basis func.
988  int d= basis.dim();
989  int n= d+1;
990 
991  gsMatrix<T> ab = basis.support(i) ;
992  gsVector<T> a = ab.col(0);
993  gsVector<T> b = ab.col(1);
994  gsVector<unsigned> np = uniformSampleCount(a,b, npts );
995  gsMatrix<T> pts = gsPointGrid(a,b,np) ;
996 
997  gsMatrix<T> eval_geo = basis.evalSingle ( i, pts ) ;
998 
999  if ( 3 - d > 0 )
1000  {
1001  np.conservativeResize(3);
1002  np.bottomRows(3-d).setOnes();
1003  }
1004 
1005  if ( 2 - d > 0 )
1006  {
1007  pts.conservativeResize(2,eval_geo.cols());
1008  pts.bottomRows(2-d).setZero();
1009  }
1010 
1011  if ( d > 2 )
1012  {
1013 // gsWarn<<"Info: The dimension is to big, projecting into first 2 coordinatess..\n";
1014  d=2;
1015  pts.conservativeResize(2,eval_geo.cols());
1016  }
1017 
1018  if ( 3 - n > 0 )
1019  {
1020  eval_geo.conservativeResize(3,eval_geo.cols() );
1021  eval_geo.bottomRows(3-n).setZero();
1022  }
1023 
1024  std::string mfn(fn);
1025  mfn.append(".vts");
1026  std::ofstream file(mfn.c_str());
1027  if ( ! file.is_open() )
1028  gsWarn<<"gsWriteParaview_basisFnct: Problem opening file \""<<fn<<"\""<<std::endl;
1029  file << std::fixed; // no exponents
1030  file << std::setprecision (PLOT_PRECISION);
1031  file <<"<?xml version=\"1.0\"?>\n";
1032  file <<"<VTKFile type=\"StructuredGrid\" version=\"0.1\">\n";
1033  file <<"<StructuredGrid WholeExtent=\"0 "<<np(0)-1<<" 0 "<<np(1)-1<<" 0 "<<np(2)-1<<"\">\n";
1034  file <<"<Piece Extent=\"0 "<< np(0)-1<<" 0 "<<np(1)-1<<" 0 "<<np(2)-1<<"\">\n";
1035  // Scalar information
1036  file <<"<PointData "<< "Scalars"<<"=\"SolutionField\">\n";
1037  file <<"<DataArray type=\"Float32\" Name=\"SolutionField\" format=\"ascii\" NumberOfComponents=\""<<1<<"\">\n";
1038  for ( index_t j=0; j<eval_geo.cols(); ++j)
1039  file<< eval_geo(0,j) <<" ";
1040  file <<"</DataArray>\n";
1041  file <<"</PointData>\n";
1042  //
1043  file <<"<Points>\n";
1044  file <<"<DataArray type=\"Float32\" NumberOfComponents=\""<<3<<"\">\n";
1045  for ( index_t j=0; j<eval_geo.cols(); ++j)
1046  {
1047  for ( int l=0; l!=d; ++l)
1048  file<< pts(l,j) <<" ";
1049  file<< eval_geo(0,j) <<" ";
1050  for ( index_t l=d; l!=pts.rows(); ++l)
1051  file<< pts(l,j) <<" ";
1052  }
1053  file <<"</DataArray>\n";
1054  file <<"</Points>\n";
1055  file <<"</Piece>\n";
1056  file <<"</StructuredGrid>\n";
1057  file <<"</VTKFile>\n";
1058  file.close();
1059 }
1060 
1061 // Export a functionSet mesh
1062 template<class T>
1063 void gsWriteParaview(gsFunctionSet<T> const& func, std::string const & fn, unsigned npts)
1064 {
1065  // GISMO_ASSERT sizes
1066 
1067  gsParaviewCollection collection(fn);
1068 
1069  for (index_t i = 0; i != func.size(); ++i)
1070  {
1071  const std::string fileName = fn + util::to_string(i);
1072  const std::string fileName_nopath = gsFileManager::getFilename(fileName);
1073  gsWriteParaview(func.function(i), func.function(i).support(), fileName, npts,false);
1074  collection.addPart(fileName_nopath + ".vts");
1075  }
1076 
1077  // Write out the collection file
1078  collection.save();
1079 }
1080 
1082 template<class T>
1083 void gsWriteParaview(gsFunction<T> const& func, gsMatrix<T> const& supp, std::string const & fn, unsigned npts, bool graph)
1084 {
1085  int d = func.domainDim(); // tested for d==2
1086 
1087  gsVector<T> a = supp.col(0);
1088  gsVector<T> b = supp.col(1);
1089  gsVector<unsigned> np = uniformSampleCount(a,b, npts );
1090  gsMatrix<T> pts = gsPointGrid(a,b,np);
1091 
1092  gsMatrix<T> ev;
1093  func.eval_into(pts, ev);
1094 
1095  if ( 3 - d > 0 )
1096  {
1097  np.conservativeResize(3);
1098  np.bottomRows(3-d).setOnes();
1099  }
1100 
1101  std::string mfn(fn);
1102  mfn.append(".vts");
1103  std::ofstream file(mfn.c_str());
1104  if ( ! file.is_open() )
1105  gsWarn<<"gsWriteParaview: Problem opening file \""<<fn<<"\""<<std::endl;
1106  file << std::fixed; // no exponents
1107  file << std::setprecision (PLOT_PRECISION);
1108  file <<"<?xml version=\"1.0\"?>\n";
1109  file <<"<VTKFile type=\"StructuredGrid\" version=\"0.1\">\n";
1110  file <<"<StructuredGrid WholeExtent=\"0 "<<np(0)-1<<" 0 "<<np(1)-1<<" 0 "<<np(2)-1<<"\">\n";
1111  file <<"<Piece Extent=\"0 "<< np(0)-1<<" 0 "<<np(1)-1<<" 0 "<<np(2)-1<<"\">\n";
1112  // Scalar information (Not really used)
1113  file <<"<PointData "<< "Scalars"<<"=\"SolutionField\">\n";
1114  file <<"<DataArray type=\"Float32\" Name=\"SolutionField\" format=\"ascii\" NumberOfComponents=\""<< 1 <<"\">\n";
1115  for ( index_t j=0; j<ev.cols(); ++j)
1116  file<< ev(0,j) <<" ";
1117  file <<"</DataArray>\n";
1118  file <<"</PointData>\n";
1119  //
1120  file <<"<Points>\n";
1121  file <<"<DataArray type=\"Float32\" NumberOfComponents=\""<<3<<"\">\n";
1122  if (graph)
1123  {
1124  for ( index_t j=0; j<ev.cols(); ++j)
1125  {
1126  for ( int i=0; i< d; ++i)
1127  file<< pts(i,j) <<" ";
1128  file<< ev(0,j) <<" ";
1129  }
1130  }
1131  else
1132  {
1133  for ( index_t j=0; j<ev.cols(); ++j)
1134  {
1135  for ( index_t i=0; i!=ev.rows(); ++i)
1136  file<< ev(i,j) <<" ";
1137  for ( index_t i=ev.rows(); i<3; ++i)
1138  file<<"0 ";
1139  }
1140  }
1141  file <<"</DataArray>\n";
1142  file <<"</Points>\n";
1143  file <<"</Piece>\n";
1144  file <<"</StructuredGrid>\n";
1145  file <<"</VTKFile>\n";
1146  file.close();
1147 }
1148 
1149 
1151 template<class T>
1152 void gsWriteParaview(gsBasis<T> const& basis, std::string const & fn,
1153  unsigned npts, bool mesh)
1154 {
1155  const index_t n = basis.size();
1156  gsParaviewCollection collection(fn);
1157 
1158  for ( index_t i=0; i< n; i++)
1159  {
1160  std::string fileName = fn + util::to_string(i);
1161  std::string fileName_nopath = gsFileManager::getFilename(fileName);
1162  gsWriteParaview_basisFnct<T>(i, basis, fileName, npts ) ;
1163  collection.addPart(fileName_nopath + ".vts");
1164  }
1165 
1166  if ( mesh )
1167  {
1168  std::string fileName = fn + "_mesh";
1169  std::string fileName_nopath = gsFileManager::getFilename(fileName);
1170  writeSingleBasisMesh(basis, fileName);
1171  //collection.addPart(fileName, ".vtp");
1172  collection.addPart(fileName_nopath + ".vtu");
1173  }
1174 
1175  collection.save();
1176 }
1177 
1179 template<class T>
1180 void writeSingleHBox(gsHBox<2,T> & box, std::string const & fn)
1181 {
1182  gsMatrix<T> points, values(3,4),corners(2,2);
1183  gsVector<index_t> np(2);
1184  np<<2,2;
1185  box.computeCoordinates();
1186  points = gsPointGrid<T>(box.getCoordinates(),4);
1187  values.row(0).setConstant(box.level());
1188  values.row(1).setConstant(box.error());
1189  values.row(2).setConstant(box.projectedErrorRef());
1190  gsWriteParaviewTPgrid(points,values,np,fn);
1191 }
1192 
1194 template<class T>
1195 void gsWriteParaview(gsHBox<2,T> & box, std::string const & fn)
1196 {
1197  gsParaviewCollection collection(fn);
1198 
1199  writeSingleHBox(box,fn);
1200  collection.addPart(fn + ".vts");
1201 
1202  // Write out the collection file
1203  collection.save();
1204 }
1205 
1207 template<class T>
1208 void gsWriteParaview(gsHBoxContainer<2,T> & boxes, std::string const & fn)
1209 {
1210  gsParaviewCollection collection(fn);
1211 
1212  index_t i=0;
1213  std::string fileName;
1214  for (typename gsHBoxContainer<2,T>::HIterator Hit = boxes.begin(); Hit!=boxes.end(); Hit++)
1215  for (typename gsHBoxContainer<2,T>::Iterator Cit = Hit->begin(); Cit!=Hit->end(); Cit++, i++)
1216  {
1217  fileName = fn + util::to_string(i);
1218  writeSingleHBox<T>(*Cit,fileName);
1219  fileName = gsFileManager::getFilename(fileName);
1220  collection.addPart(fileName + ".vts",-1,"",i);
1221  }
1222 
1223  // Write out the collection file
1224  collection.save();
1225 }
1226 
1228 template<class T>
1229 void gsWriteParaview(gsMultiPatch<T> const& mp, gsMultiBasis<T> const& mb,
1230  std::string const & fn, unsigned npts)
1231 {
1232  GISMO_ENSURE(mp.nPatches()==mb.nBases(),"Number of bases and patches do not correspond");
1233 
1234  gsParaviewCollection collection(fn);
1235 
1236  gsMatrix<T> eval_geo, eval_basis, pts, ab;
1237  gsVector<T> a, b;
1238 
1239  index_t k=0;
1240  for (size_t p=0; p!=mp.nPatches(); p++)
1241  for ( index_t i=0; i< mb.basis(p).size(); i++, k++)
1242  {
1243  // Compute the geometry on the support of the basis function
1244  ab = mb.basis(p).support(i);
1245  a = ab.col(0);
1246  b = ab.col(1);
1247 
1248  gsVector<unsigned> np = uniformSampleCount(a, b, npts);
1249  pts = gsPointGrid(a, b, np);
1250 
1251  eval_geo = mp.patch(p).eval(pts);//pts
1252 
1253  std::string fileName = fn + "_" + util::to_string(k);
1254  std::string fileName_nopath = gsFileManager::getFilename(fileName);
1255 
1256  eval_basis = mb.basis(p).evalSingle(i,pts);
1257  gsWriteParaviewTPgrid(eval_geo, eval_basis, np.template cast<index_t>(), fileName);
1258  // gsWriteParaview_basisFnct<T>(i, basis, fileName, npts ) ;
1259  // collection.addPart(fileName_nopath + ".vts",-1,"",k);
1260  collection.addPart(fileName_nopath + ".vts",k);
1261  }
1262  collection.save();
1263 }
1264 
1266 template<class T>
1267 void gsWriteParaviewPoints(gsMatrix<T> const& X, gsMatrix<T> const& Y, std::string const & fn)
1268 {
1269  assert( X.cols() == Y.cols() );
1270  assert( X.rows() == 1 && Y.rows() == 1 );
1271  index_t np = X.cols();
1272 
1273  std::string mfn(fn);
1274  mfn.append(".vtp");
1275  std::ofstream file(mfn.c_str());
1276  if ( ! file.is_open() )
1277  gsWarn<<"gsWriteParaviewPoints: Problem opening file \""<<fn<<"\""<<std::endl;
1278  file << std::fixed; // no exponents
1279  file << std::setprecision (PLOT_PRECISION);
1280  file <<"<?xml version=\"1.0\"?>\n";
1281  file <<"<VTKFile type=\"PolyData\" version=\"0.1\" byte_order=\"LittleEndian\">\n";
1282  file <<"<PolyData>\n";
1283  file <<"<Piece NumberOfPoints=\""<<np<<"\" NumberOfVerts=\"1\" NumberOfLines=\"0\" NumberOfStrips=\"0\" NumberOfPolys=\"0\">\n";
1284  file <<"<PointData>\n";
1285  file <<"</PointData>\n";
1286  file <<"<CellData>\n";
1287  file <<"</CellData>\n";
1288  file <<"<Points>\n";
1289  file <<"<DataArray type=\"Float32\" Name=\"Points\" NumberOfComponents=\"3\" format=\"ascii\" RangeMin=\""<<X.minCoeff()<<"\" RangeMax=\""<<X.maxCoeff()<<"\">\n";
1290  for (index_t i=0; i< np; ++i )
1291  file << X(0,i) <<" "<<Y(0,i)<<" "<< 0.0 <<"\n";
1292  file <<"\n</DataArray>\n";
1293  file <<"</Points>\n";
1294  file <<"<Verts>\n";
1295  file <<"<DataArray type=\"Int64\" Name=\"connectivity\" format=\"ascii\" RangeMin=\""<<0<<"\" RangeMax=\""<<np-1<<"\">\n";
1296  for (index_t i=0; i< np; ++i )
1297  file << i<<" ";
1298  file <<"\n</DataArray>\n";
1299  file <<"<DataArray type=\"Int64\" Name=\"offsets\" format=\"ascii\" RangeMin=\""<<np<<"\" RangeMax=\""<<np<<"\">\n"<<np<<"\n";
1300  file <<"</DataArray>\n";
1301  file <<"</Verts>\n";
1302  file <<"<Lines>\n";
1303  file <<"<DataArray type=\"Int64\" Name=\"connectivity\" format=\"ascii\" RangeMin=\"0\" RangeMax=\""<<np-1<<"\">\n";
1304  file <<"</DataArray>\n";
1305  file <<"<DataArray type=\"Int64\" Name=\"offsets\" format=\"ascii\" RangeMin=\""<<np<<"\" RangeMax=\""<<np<<"\">\n";
1306  file <<"</DataArray>\n";
1307  file <<"</Lines>\n";
1308  file <<"<Strips>\n";
1309  file <<"<DataArray type=\"Int64\" Name=\"connectivity\" format=\"ascii\" RangeMin=\"0\" RangeMax=\""<<np-1<<"\">\n";
1310  file <<"</DataArray>\n";
1311  file <<"<DataArray type=\"Int64\" Name=\"offsets\" format=\"ascii\" RangeMin=\""<<np<<"\" RangeMax=\""<<np<<"\">\n";
1312  file <<"</DataArray>\n";
1313  file <<"</Strips>\n";
1314  file <<"<Polys>\n";
1315  file <<"<DataArray type=\"Int64\" Name=\"connectivity\" format=\"ascii\" RangeMin=\"0\" RangeMax=\""<<np-1<<"\">\n";
1316  file <<"</DataArray>\n";
1317  file <<"<DataArray type=\"Int64\" Name=\"offsets\" format=\"ascii\" RangeMin=\""<<np<<"\" RangeMax=\""<<np<<"\">\n";
1318  file <<"</DataArray>\n";
1319  file <<"</Polys>\n";
1320  file <<"</Piece>\n";
1321  file <<"</PolyData>\n";
1322  file <<"</VTKFile>\n";
1323  file.close();
1324 
1325  makeCollection(fn, ".vtp"); // make also a pvd file
1326 }
1327 
1328 template<class T>
1330  gsMatrix<T> const& Y,
1331  gsMatrix<T> const& Z,
1332  std::string const & fn)
1333 {
1334  GISMO_ASSERT(X.cols() == Y.cols() && X.cols() == Z.cols(),
1335  "X, Y and Z must have the same size of columns!");
1336  GISMO_ASSERT(X.rows() == 1 && Y.rows() == 1 && Z.cols(),
1337  "X, Y and Z must be row matrices!");
1338  index_t np = X.cols();
1339 
1340  std::string mfn(fn);
1341  mfn.append(".vtp");
1342  std::ofstream file(mfn.c_str());
1343 
1344  if (!file.is_open())
1345  {
1346  gsWarn << "Problem opening " << fn << " Aborting..." << std::endl;
1347  return;
1348  }
1349 
1350  file << std::fixed; // no exponents
1351  file << std::setprecision (PLOT_PRECISION);
1352 
1353  file <<"<?xml version=\"1.0\"?>\n";
1354  file <<"<VTKFile type=\"PolyData\" version=\"0.1\" byte_order=\"LittleEndian\">\n";
1355  file <<"<PolyData>\n";
1356  file <<"<Piece NumberOfPoints=\""<<np<<"\" NumberOfVerts=\"1\" NumberOfLines=\"0\" NumberOfStrips=\"0\" NumberOfPolys=\"0\">\n";
1357  file <<"<PointData>\n"; //empty
1358  file <<"</PointData>\n";
1359  file <<"<CellData>\n";
1360  file <<"</CellData>\n";
1361  file <<"<Points>\n";
1362  file <<"<DataArray type=\"Float32\" Name=\"Points\" NumberOfComponents=\"3\" format=\"ascii\" RangeMin=\""<<X.minCoeff()<<"\" RangeMax=\""<<X.maxCoeff()<<"\">\n";
1363 
1364  for (index_t i = 0; i < np; ++i)
1365  {
1366  file << X(0, i) << " " << Y(0, i) << " " << Z(0, i) << "\n";
1367  }
1368 
1369  file <<"\n</DataArray>\n";
1370  file <<"</Points>\n";
1371  file <<"<Verts>\n";
1372  file <<"<DataArray type=\"Int64\" Name=\"connectivity\" format=\"ascii\" RangeMin=\""<<0<<"\" RangeMax=\""<<np-1<<"\">\n";
1373 
1374  for (index_t i=0; i< np; ++i )
1375  {
1376  file << i << " ";
1377  }
1378 
1379  file <<"\n</DataArray>\n";
1380  file <<"<DataArray type=\"Int64\" Name=\"offsets\" format=\"ascii\" RangeMin=\""<<np<<"\" RangeMax=\""<<np<<"\">\n"<<np<<"\n";
1381  file <<"</DataArray>\n";
1382  file <<"</Verts>\n";
1383  file <<"<Lines>\n";
1384  file <<"<DataArray type=\"Int64\" Name=\"connectivity\" format=\"ascii\" RangeMin=\"0\" RangeMax=\""<<np-1<<"\">\n";
1385  file <<"</DataArray>\n";
1386  file <<"<DataArray type=\"Int64\" Name=\"offsets\" format=\"ascii\" RangeMin=\""<<np<<"\" RangeMax=\""<<np<<"\">\n";
1387  file <<"</DataArray>\n";
1388  file <<"</Lines>\n";
1389  file <<"<Strips>\n";
1390  file <<"<DataArray type=\"Int64\" Name=\"connectivity\" format=\"ascii\" RangeMin=\"0\" RangeMax=\""<<np-1<<"\">\n";
1391  file <<"</DataArray>\n";
1392  file <<"<DataArray type=\"Int64\" Name=\"offsets\" format=\"ascii\" RangeMin=\""<<np<<"\" RangeMax=\""<<np<<"\">\n";
1393  file <<"</DataArray>\n";
1394  file <<"</Strips>\n";
1395  file <<"<Polys>\n";
1396  file <<"<DataArray type=\"Int64\" Name=\"connectivity\" format=\"ascii\" RangeMin=\"0\" RangeMax=\""<<np-1<<"\">\n";
1397  file <<"</DataArray>\n";
1398  file <<"<DataArray type=\"Int64\" Name=\"offsets\" format=\"ascii\" RangeMin=\""<<np<<"\" RangeMax=\""<<np<<"\">\n";
1399  file <<"</DataArray>\n";
1400  file <<"</Polys>\n";
1401  file <<"</Piece>\n";
1402  file <<"</PolyData>\n";
1403  file <<"</VTKFile>\n";
1404  file.close();
1405 
1406  makeCollection(fn, ".vtp"); // make also a pvd file
1407 }
1408 
1409 template<class T>
1410 void gsWriteParaviewPoints(gsMatrix<T> const& X,
1411  gsMatrix<T> const& Y,
1412  gsMatrix<T> const& Z,
1413  gsMatrix<T> const& V,
1414  std::string const & fn)
1415 {
1416  GISMO_ASSERT(X.cols() == Y.cols() && X.cols() == Z.cols(),
1417  "X, Y and Z must have the same size of columns!");
1418  GISMO_ASSERT(X.rows() == 1 && Y.rows() == 1 && Z.cols(),
1419  "X, Y and Z must be row matrices!");
1420  index_t np = X.cols();
1421 
1422  std::string mfn(fn);
1423  mfn.append(".vtp");
1424  std::ofstream file(mfn.c_str());
1425 
1426  if (!file.is_open())
1427  {
1428  gsWarn << "Problem opening " << fn << " Aborting..." << std::endl;
1429  return;
1430  }
1431 
1432  file << std::fixed; // no exponents
1433  file << std::setprecision (PLOT_PRECISION);
1434 
1435  file <<"<?xml version=\"1.0\"?>\n";
1436  file <<"<VTKFile type=\"PolyData\" version=\"0.1\" byte_order=\"LittleEndian\">\n";
1437  file <<"<PolyData>\n";
1438  file <<"<Piece NumberOfPoints=\""<<np<<"\" NumberOfVerts=\"1\" NumberOfLines=\"0\" NumberOfStrips=\"0\" NumberOfPolys=\"0\">\n";
1439  //---------
1440  file <<"<PointData "<< "Scalars=\"PointInfo\">\n";
1441  file <<"<DataArray type=\"Float32\" Name=\"PointInfo\" format=\"ascii\" NumberOfComponents=\"1\">\n";
1442  for ( index_t j=0; j<np; ++j)
1443  file<< V(0,j) <<" ";
1444  file <<"</DataArray>\n";
1445  file <<"</PointData>\n";
1446  //---------
1447  file <<"<CellData>\n";
1448  file <<"</CellData>\n";
1449  file <<"<Points>\n";
1450  file <<"<DataArray type=\"Float32\" Name=\"Points\" NumberOfComponents=\"3\" format=\"ascii\" RangeMin=\""<<X.minCoeff()<<"\" RangeMax=\""<<X.maxCoeff()<<"\">\n";
1451 
1452  for (index_t i = 0; i < np; ++i)
1453  {
1454  file << X(0, i) << " " << Y(0, i) << " " << Z(0, i) << "\n";
1455  }
1456 
1457  file <<"\n</DataArray>\n";
1458  file <<"</Points>\n";
1459  file <<"<Verts>\n";
1460  file <<"<DataArray type=\"Int64\" Name=\"connectivity\" format=\"ascii\" RangeMin=\""<<0<<"\" RangeMax=\""<<np-1<<"\">\n";
1461 
1462  for (index_t i=0; i< np; ++i )
1463  {
1464  file << i << " ";
1465  }
1466 
1467  file <<"\n</DataArray>\n";
1468  file <<"<DataArray type=\"Int64\" Name=\"offsets\" format=\"ascii\" RangeMin=\""<<np<<"\" RangeMax=\""<<np<<"\">\n"<<np<<"\n";
1469  file <<"</DataArray>\n";
1470  file <<"</Verts>\n";
1471  file <<"<Lines>\n";
1472  file <<"<DataArray type=\"Int64\" Name=\"connectivity\" format=\"ascii\" RangeMin=\"0\" RangeMax=\""<<np-1<<"\">\n";
1473  file <<"</DataArray>\n";
1474  file <<"<DataArray type=\"Int64\" Name=\"offsets\" format=\"ascii\" RangeMin=\""<<np<<"\" RangeMax=\""<<np<<"\">\n";
1475  file <<"</DataArray>\n";
1476  file <<"</Lines>\n";
1477  file <<"<Strips>\n";
1478  file <<"<DataArray type=\"Int64\" Name=\"connectivity\" format=\"ascii\" RangeMin=\"0\" RangeMax=\""<<np-1<<"\">\n";
1479  file <<"</DataArray>\n";
1480  file <<"<DataArray type=\"Int64\" Name=\"offsets\" format=\"ascii\" RangeMin=\""<<np<<"\" RangeMax=\""<<np<<"\">\n";
1481  file <<"</DataArray>\n";
1482  file <<"</Strips>\n";
1483  file <<"<Polys>\n";
1484  file <<"<DataArray type=\"Int64\" Name=\"connectivity\" format=\"ascii\" RangeMin=\"0\" RangeMax=\""<<np-1<<"\">\n";
1485  file <<"</DataArray>\n";
1486  file <<"<DataArray type=\"Int64\" Name=\"offsets\" format=\"ascii\" RangeMin=\""<<np<<"\" RangeMax=\""<<np<<"\">\n";
1487  file <<"</DataArray>\n";
1488  file <<"</Polys>\n";
1489  file <<"</Piece>\n";
1490  file <<"</PolyData>\n";
1491  file <<"</VTKFile>\n";
1492  file.close();
1493 
1494  makeCollection(fn, ".vtp"); // make also a pvd file
1495 }
1496 
1497 template<class T>
1498 void gsWriteParaviewPoints(gsMatrix<T> const& points, std::string const & fn)
1499 {
1500  const index_t rows = points.rows();
1501  switch (rows)
1502  {
1503  case 1:
1504  gsWriteParaviewPoints<T>(points.row(0), gsMatrix<T>::Zero(1, points.cols()), fn);
1505  break;
1506  case 2:
1507  gsWriteParaviewPoints<T>(points.row(0), points.row(1), fn);
1508  break;
1509  case 3:
1510  gsWriteParaviewPoints<T>(points.row(0), points.row(1), points.row(2), fn);
1511  break;
1512  case 4:
1513  gsWriteParaviewPoints<T>(points.row(0), points.row(1), points.row(2), points.row(3), fn);
1514  break;
1515  default:
1516  GISMO_ERROR("Point plotting is implemented just for 2D and 3D (rows== 1, 2 or 3).");
1517  }
1518 }
1519 
1520 // Depicting edge graph of each volume of one gsSolid with a segmenting loop
1521 // INPUTS:
1522 // \param eloop: a vector of ID numbers of vertices, often for representing a segmenting loop
1523 template <class T>
1524 void gsWriteParaview(gsSolid<T> const& sl, std::string const & fn, unsigned numPoints_for_eachCurve, int vol_Num,
1525  T edgeThick, gsVector3d<T> const & translate, int color_convex,
1526  int color_nonconvex, int color_eloop, std::vector<unsigned> const & eloop)
1527 {
1528  // options
1529  int color=color_convex;
1530 
1531  gsSolidHalfFace<T>* face;
1532  int numOfCurves;
1533  int numOfPoints = numPoints_for_eachCurve;
1534 
1535  T faceThick = edgeThick;
1536 // T camera1 = 1;
1537 // T camera2 = 1;
1538 // T camera3 = 1;
1539 
1540  std::string mfn(fn);
1541  mfn.append(".vtp");
1542  std::ofstream file(mfn.c_str());
1543  if ( ! file.is_open() )
1544  gsWarn<<"gsWriteParaview: Problem opening file \""<<fn<<"\""<<std::endl;
1545  file << std::fixed; // no exponents
1546  file << std::setprecision (PLOT_PRECISION);
1547  file <<"<?xml version=\"1.0\"?>\n";
1548  file <<"<VTKFile type=\"PolyData\" version=\"0.1\" byte_order=\"LittleEndian\">\n";
1549  file <<"<PolyData>\n";
1550 
1551 
1552  // collect HEs representing the edge loop
1553  numOfCurves = eloop.size();
1554  gsSolidHalfEdge<T>* he;
1555  std::vector< typename gsSolid<T>::gsSolidHalfEdgeHandle > heSet;
1556  typename gsSolid<T>::gsSolidHeVertexHandle source,target;
1557  if (eloop.size()>0){
1558  for (int iedge=0; iedge!= numOfCurves; iedge++)
1559  {
1560  source = sl.vertex[eloop[iedge]];
1561  target = sl.vertex[eloop[(iedge+1)%numOfCurves]];
1562  he = source->getHalfEdge(target);
1563  heSet.push_back(he);
1564  face = he->face;
1565  }}
1566 
1567 
1568  //gsDebug<<"\n ------------------------------------- number of hafl faces: "<< sl.nHalfFaces();
1569  for (int iface=0;iface!= sl.nHalfFaces();iface++)
1570  {
1571  face = sl.getHalfFaceFromID(iface);
1572  //gsDebug<<"\n ------------------------------------- vol of face:"<< face->vol->getId()<< " :for face: "<< iface <<"\n";
1573  //gsDebug << std::flush;
1574  if (face->vol->getId()==vol_Num)
1575  {
1576  numOfCurves=face->nCurvesOfOneLoop(0);
1577  //gsDebug<<"\n -----------INSIDE-------------------- vol of face:"<< face->vol->getId()<< " :for face: "<< iface <<"\n";
1578 
1579  for (int iedge=0; iedge!= numOfCurves; iedge++)
1580  {
1581  he = face->getHalfEdgeFromBoundaryOrder(iedge);
1582  // search if he is in heSet
1583  bool isMember(false);
1584  for (size_t iheSet=0;iheSet<heSet.size();iheSet++)
1585  {
1586  if ( he->isEquiv(heSet.at(iheSet))==true || he->mate->isEquiv(heSet.at(iheSet))==true)
1587  {isMember=true;
1588  break;}
1589  }
1590  gsMatrix<T> curvePoints = face->surf->sampleBoundaryCurve(iedge, numPoints_for_eachCurve);
1591  if (iedge==0) assert( numOfPoints == curvePoints.cols());
1592  color=color_convex;
1593  if (isMember==true) color=color_eloop;
1594  if (face->getHalfEdgeFromBoundaryOrder(iedge)->is_convex==false){color = color_nonconvex;}
1596  file <<"<Piece NumberOfPoints=\""<< 2*numOfPoints <<"\" NumberOfVerts=\"0\" NumberOfLines=\""<< 0
1597  <<"\" NumberOfStrips=\"0\" NumberOfPolys=\""<< numOfPoints-1 << "\">\n";
1598 
1600  file <<"<Points>\n";
1601  file <<"<DataArray type=\"Float32\" NumberOfComponents=\"3\" format=\"ascii\">\n";
1602  // translate the volume towards the *translate* vector
1603  for (index_t iCol = 0;iCol!=curvePoints.cols();iCol++)
1604  {
1605  file << curvePoints(0,iCol) + translate(0) << " " << curvePoints(1,iCol) + translate(1) << " " << curvePoints(2,iCol) + translate(2) << " \n";
1606  // translate the vertex about along the vector (faceThick,0,0)
1607  file << curvePoints(0,iCol) + faceThick + translate(0) << " " << curvePoints(1,iCol) + faceThick + translate(1)
1608  << " " << curvePoints(2,iCol) +faceThick + translate(2) << " \n";
1609  };
1610  file << "\n";
1611  file <<"</DataArray>\n";
1612  file <<"</Points>\n";
1613 
1615  file << "<CellData Scalars=\"cell_scalars\">\n";
1616  file << "<DataArray type=\"Int32\" Name=\"cell_scalars\" format=\"ascii\">\n";
1618  for (index_t iCol = 0;iCol!=curvePoints.cols()-1;iCol++)
1619  {
1620  file << color << " ";
1621  }
1622  file << "\n";
1623  file << "</DataArray>\n";
1624  file << "</CellData>\n";
1625 
1627  file << "<Polys>\n";
1628  file << "<DataArray type=\"Int32\" Name=\"connectivity\" format=\"ascii\">\n";
1629  for (index_t iCol = 0;iCol<=curvePoints.cols()-2;iCol++)
1630  {
1631  //file << iCol << " " << iCol+1 << " "<< iCol+1 << " " << iCol << " ";
1632  file << 2*iCol << " " << 2*iCol+1 << " "<< 2*iCol+3 << " " << 2*iCol+2 << " ";
1633  }
1634  //file << curvePoints.cols()-1 << " " << 0 << " "<< 0 << " "<< curvePoints.cols()-1 << " ";
1635  file << "\n";
1636  file << "</DataArray>\n";
1637  file << "<DataArray type=\"Int32\" Name=\"offsets\" format=\"ascii\">\n";
1638  unsigned offsets(0);
1639  for (index_t iCol = 0;iCol!=curvePoints.cols()-1;iCol++)
1640  {
1641  offsets +=4;
1642  file << offsets << " ";
1643  }
1644  file << "\n";
1645  file << "</DataArray>\n";
1646  file << "</Polys>\n";
1647 
1648  file << "</Piece>\n";
1649 
1651  file << "\n";
1652  file << "\n";
1653  }
1654  }
1655  }
1656 
1657  file <<"</PolyData>\n";
1658  file <<"</VTKFile>\n";
1659  file.close();
1660 
1661  makeCollection(fn, ".vtp"); // make also a pvd file
1662 }
1663 
1664 template <class T>
1666  std::string const & fn,
1667  unsigned numSamples)
1668 {
1669  const size_t n = sl.numHalfFaces;
1670  gsParaviewCollection collection(fn);
1671 
1672  // for( typename gsSolid<T>::const_face_iterator it = sl.begin();
1673  // it != sl.end(); ++it)
1674 
1675  for ( size_t i=0; i<n ; i++)
1676  {
1677  std::string fnBase = fn + util::to_string(i);
1678  std::string fnBase_nopath = gsFileManager::getFilename(fnBase);
1679  writeSingleTrimSurface(*sl.face[i]->surf, fnBase, numSamples);
1680  collection.addPart(fnBase_nopath + ".vtp");
1681  }
1682 
1683  // Write out the collection file
1684  collection.save();
1685 }
1686 
1687 
1689 template <class T>
1690 void gsWriteParaview(gsMesh<T> const& sl, std::string const & fn, bool pvd)
1691 {
1692  std::string mfn(fn);
1693  mfn.append(".vtp");
1694  std::ofstream file(mfn.c_str());
1695  if ( ! file.is_open() )
1696  gsWarn<<"gsWriteParaview: Problem opening file \""<<fn<<"\""<<std::endl;
1697  file << std::fixed; // no exponents
1698  file << std::setprecision (PLOT_PRECISION);
1699 
1700  file <<"<?xml version=\"1.0\"?>\n";
1701  file <<"<VTKFile type=\"PolyData\" version=\"0.1\" byte_order=\"LittleEndian\">\n";
1702  file <<"<PolyData>\n";
1703 
1705  file <<"<Piece NumberOfPoints=\""<< sl.numVertices() <<"\" NumberOfVerts=\"0\" NumberOfLines=\""
1706  << sl.numEdges()<<"\" NumberOfStrips=\"0\" NumberOfPolys=\""<< sl.numFaces() << "\">\n";
1707 
1709  file <<"<Points>\n";
1710  file <<"<DataArray type=\"Float32\" NumberOfComponents=\"3\" format=\"ascii\">\n";
1711  for (typename std::vector< gsVertex<T>* >::const_iterator it=sl.vertices().begin(); it!=sl.vertices().end(); ++it)
1712  {
1713  const gsVertex<T>& vertex = **it;
1714  file << vertex[0] << " ";
1715  file << vertex[1] << " ";
1716  file << vertex[2] << " \n";
1717  }
1718 
1719  file << "\n";
1720  file <<"</DataArray>\n";
1721  file <<"</Points>\n";
1722 
1723  // Scalar field attached to each face
1724  // file << "<PointData Scalars=\"point_scalars\">\n";
1725  // file << "<DataArray type=\"Int32\" Name=\"point_scalars\" format=\"ascii\">\n";
1726  // for (typename std::vector< gsVertex<T>* >::const_iterator it=sl.vertex.begin();
1727  // it!=sl.vertex.end(); ++it)
1728  // {
1729  // file << 0 << " ";
1730  // }
1731  // file << "\n";
1732  // file << "</DataArray>\n";
1733  // file << "</PointData>\n";
1734 
1735  // Write out edges
1736  file << "<Lines>\n";
1737  file << "<DataArray type=\"Int32\" Name=\"connectivity\" format=\"ascii\">\n";
1738  for (typename std::vector< gsEdge<T> >::const_iterator it=sl.edges().begin();
1739  it!=sl.edges().end(); ++it)
1740  {
1741  file << it->source->getId() << " " << it->target->getId() << "\n";
1742  }
1743  file << "</DataArray>\n";
1744  file << "<DataArray type=\"Int32\" Name=\"offsets\" format=\"ascii\">\n";
1745  int count=0;
1746  for (typename std::vector< gsEdge<T> >::const_iterator it=sl.edges().begin();
1747  it!=sl.edges().end(); ++it)
1748  {
1749  count+=2;
1750  file << count << " ";
1751  }
1752  file << "\n";
1753  file << "</DataArray>\n";
1754  file << "</Lines>\n";
1755 
1756  // Scalar field attached to each face (* if edges exists, this has a problem)
1757  // file << "<CellData Scalars=\"cell_scalars\">\n";
1758  // file << "<DataArray type=\"Int32\" Name=\"cell_scalars\" format=\"ascii\">\n";
1759  // for (typename std::vector< gsFace<T>* >::const_iterator it=sl.face.begin();
1760  // it!=sl.face.end(); ++it)
1761  // {
1762  // file << 1 << " ";
1763  // }
1764  // file << "\n";
1765  // file << "</DataArray>\n";
1766  // file << "</CellData>\n";
1767 
1769  file << "<Polys>\n";
1770  file << "<DataArray type=\"Int32\" Name=\"connectivity\" format=\"ascii\">\n";
1771  for (typename std::vector< gsFace<T>* >::const_iterator it=sl.faces().begin();
1772  it!=sl.faces().end(); ++it)
1773  {
1774  for (typename std::vector< gsVertex<T>* >::const_iterator vit= (*it)->vertices.begin();
1775  vit!=(*it)->vertices.end(); ++vit)
1776  {
1777  file << (*vit)->getId() << " ";
1778  }
1779  file << "\n";
1780  }
1781  file << "</DataArray>\n";
1782  file << "<DataArray type=\"Int32\" Name=\"offsets\" format=\"ascii\">\n";
1783  count=0;
1784  for (typename std::vector< gsFace<T>* >::const_iterator it=sl.faces().begin();
1785  it!=sl.faces().end(); ++it)
1786  {
1787  count += (*it)->vertices.size();
1788  file << count << " ";
1789  }
1790  file << "\n";
1791  file << "</DataArray>\n";
1792  file << "</Polys>\n";
1793 
1794  file << "</Piece>\n";
1795  file <<"</PolyData>\n";
1796  file <<"</VTKFile>\n";
1797  file.close();
1798 
1799  if( pvd ) // make also a pvd file
1800  makeCollection(fn, ".vtp");
1801 }
1802 
1803 template <class T>
1804 void gsWriteParaview(gsMesh<T> const& sl, std::string const & fn, const gsMatrix<T>& params)
1805 {
1806  GISMO_ASSERT((index_t)sl.numVertices()==params.cols(),
1807  "Incorrect number of data: "<< params.cols() <<" != "<< sl.numVertices() );
1808 
1809  std::string mfn(fn);
1810  mfn.append(".vtk");
1811  std::ofstream file(mfn.c_str());
1812  if ( ! file.is_open() )
1813  gsWarn<<"gsWriteParaview: Problem opening file \""<<fn<<"\""<<std::endl;
1814  file << std::fixed; // no exponents
1815  file << std::setprecision (PLOT_PRECISION);
1816 
1817  file << "# vtk DataFile Version 4.2\n";
1818  file << "vtk output\n";
1819  file << "ASCII\n";
1820  file << "DATASET POLYDATA\n";
1821 
1822  // Vertices
1823  file << "POINTS " << sl.numVertices() << " float\n";
1824  for (typename std::vector< gsVertex<T>* >::const_iterator it=sl.vertices().begin(); it!=sl.vertices().end(); ++it)
1825  {
1826  const gsVertex<T>& vertex = **it;
1827  file << vertex[0] << " ";
1828  file << vertex[1] << " ";
1829  file << vertex[2] << " \n";
1830  }
1831  file << "\n";
1832 
1833  // Triangles or quads
1834  file << "POLYGONS " << sl.numFaces() << " " <<
1835  (sl.faces().front()->vertices.size()+1) * sl.numFaces() << std::endl;
1836  for (typename std::vector< gsFace<T>* >::const_iterator it=sl.faces().begin();
1837  it!=sl.faces().end(); ++it)
1838  {
1839  file << (*it)->vertices.size() <<" "; //3: triangles, 4: quads
1840  for (typename std::vector< gsVertex<T>* >::const_iterator vit=
1841  (*it)->vertices.begin(); vit!=(*it)->vertices.end(); ++vit)
1842  {
1843  file << (*vit)->getId() << " ";
1844  }
1845  file << "\n";
1846  }
1847  file << "\n";
1848 
1849  // Data
1850  file << "POINT_DATA " << sl.numVertices() << std::endl;
1851  //file << "TEXTURE_COORDINATES parameters "<<params.rows()<<" float\n";
1852  if ( 3 == params.rows() )
1853  file << "VECTORS Data float\n";
1854  else
1855  file << "SCALARS Data float "<<params.rows()<<"\nLOOKUP_TABLE default\n";
1856 
1857  for(index_t j=0; j<params.cols(); j++)
1858  {
1859  for(index_t i=0; i<params.rows(); i++)
1860  file << params(i,j) << " ";
1861  file << "\n";
1862  }
1863 
1864  file.close();
1865 }
1866 
1867 template <typename T>
1868 void gsWriteParaview(const std::vector<gsMesh<T> >& meshes,
1869  const std::string& fn)
1870 {
1871  for (unsigned index = 0; index < meshes.size(); index++)
1872  {
1873  std::string file = fn + "Level" + util::to_string(index);
1874  gsWriteParaview(meshes[index], file, false);
1875  }
1876 }
1877 
1878 template<class T>
1879 void gsWriteParaview(gsPlanarDomain<T> const & pdomain, std::string const & fn, unsigned npts)
1880 {
1881  std::vector<gsGeometry<T> *> all_curves;
1882  for(index_t i =0; i<pdomain.numLoops();i++)
1883  for(index_t j =0; j< pdomain.loop(i).numCurves() ; j++)
1884  all_curves.push_back( const_cast<gsCurve<T> *>(&pdomain.loop(i).curve(j)) );
1885 
1886  gsWriteParaview( all_curves, fn, npts);
1887 }
1888 
1889 template<class T>
1890 void gsWriteParaview(const gsTrimSurface<T> & surf, std::string const & fn,
1891  unsigned npts, bool trimCurves)
1892 {
1893  gsParaviewCollection collection(fn);
1894 
1895  writeSingleTrimSurface(surf, fn, npts);
1896  std::string fn_nopath = gsFileManager::getFilename(fn);
1897  collection.addPart(fn_nopath + ".vtp");
1898 
1899  if ( trimCurves )
1900  {
1901  gsWarn<<"trimCurves: To do.\n";
1902  }
1903 
1904  // Write out the collection file
1905  collection.save();
1906 }
1907 
1908 template<typename T>
1909 void gsWriteParaview(const gsVolumeBlock<T>& volBlock,
1910  std::string const & fn,
1911  unsigned npts)
1912 {
1913  using util::to_string;
1914 
1915  gsParaviewCollection collection(fn);
1916 
1917  // for each face
1918  for (unsigned idFace = 0; idFace != volBlock.face.size(); idFace++)
1919  {
1920  typename gsVolumeBlock<T>::HalfFace* face = volBlock.face[idFace];
1921  gsPlanarDomain<T>& domain = face->surf->domain();
1922 
1923  // for each curve loop (boundary + holes)
1924  unsigned numLoops = static_cast<unsigned>(domain.numLoops());
1925  for (unsigned idLoop = 0; idLoop < numLoops; idLoop++)
1926  {
1927  gsCurveLoop<T>& curveLoop = domain.loop(idLoop);
1928 
1929  unsigned clSize = static_cast<unsigned>(curveLoop.size());
1930 
1931  // for each curve in curve loop
1932  for (unsigned idCurve = 0; idCurve < clSize; idCurve++)
1933  {
1934  // file name is fn_curve_Fface_Lloop_Ccurve
1935  std::string fileName = fn + "_curve_F";
1936  std::string fileName_nopath = gsFileManager::getFilename(fileName);
1937  fileName += to_string(idFace) + "_L" +
1938  to_string(idLoop) + "_C" +
1939  to_string(idCurve);
1940 
1941  gsWriteParaviewTrimmedCurve(*(face->surf), idLoop, idCurve,
1942  fileName, npts);
1943 
1944  collection.addPart(fileName_nopath + ".vts");
1945 
1946  } // for each curve
1947  } // for each curve loop
1948  } // for each face
1949 
1950  collection.save();
1951 }
1952 
1953 template<typename T>
1955  std::string const & fn,
1956  unsigned npts, bool ctrlNet)
1957 {
1958  typename gsMultiPatch<T>::BoundaryRep const & brep = patches.boundaryRep();
1959  GISMO_ENSURE(brep.size()!=0,"Boundary representation is empty. Call gsMultiPatch::constructBoundaryRep first!");
1960  gsMultiPatch<T> bnd_net;
1961  for (auto it = brep.begin(); it!=brep.end(); ++it)
1962  bnd_net.addPatch((*it->second));
1963  gsWriteParaview<T>(bnd_net,fn,npts,false,ctrlNet);
1964 }
1965 
1966 template<typename T>
1968  std::string const & fn,
1969  unsigned npts, bool ctrlNet)
1970 {
1971 
1972  typename gsMultiPatch<T>::InterfaceRep const & irep = patches.interfaceRep();
1973  GISMO_ENSURE(irep.size()!=0,"Interface representation is empty. Call gsMultiPatch::constructInterfaceRep first!");
1974  gsMultiPatch<T> iface_net;
1975  for (auto it = irep.begin(); it!=irep.end(); ++it)
1976  iface_net.addPatch((*it->second));
1977  gsWriteParaview<T>(iface_net,fn,npts,false,ctrlNet);
1978 }
1979 
1980 template<typename T>
1981 void gsWriteParaview(gsMultiPatch<T> const & patches,
1982  typename gsBoundaryConditions<T>::bcContainer const & bcs,
1983  std::string const & fn, unsigned npts, bool ctrlNet)
1984 {
1985  gsMultiPatch<T> bc_net;
1986  for (typename gsBoundaryConditions<T>::const_iterator bc=bcs.begin(); bc!=bcs.end(); bc++)
1987  bc_net.addPatch(patches[bc->patch()].boundary(bc->side()));
1988  gsWriteParaview<T>(bc_net,fn,npts,false,ctrlNet);
1989 }
1990 
1991 template<typename T>
1993  const unsigned idLoop,
1994  const unsigned idCurve,
1995  const std::string fn,
1996  unsigned npts)
1997 {
1998  // computing parameters and points
1999 
2000  int idL = static_cast<int>(idLoop);
2001  int idC = static_cast<int>(idCurve);
2002 
2003  gsCurve<T>& curve = surf.getCurve(idL, idC);
2004 
2005  gsMatrix<T> ab = curve.parameterRange() ;
2006  gsVector<T> a = ab.col(0);
2007  gsVector<T> b = ab.col(1);
2008 
2009  gsVector<unsigned> np = uniformSampleCount(a, b, npts);
2010  gsMatrix<T> param = gsPointGrid(a, b, np);
2011 
2012  gsMatrix<T> points;
2013  surf.evalCurve_into(idLoop, idCurve, param, points);
2014 
2015  np.conservativeResize(3);
2016  np.bottomRows(3 - 1).setOnes();
2017 
2018 
2019  // writing to the file
2020 
2021  std::string myFile(fn);
2022  myFile.append(".vts");
2023 
2024  std::ofstream file(myFile.c_str());
2025  if (!file.is_open())
2026  {
2027  gsWarn << "Problem opening " << fn << " Aborting..." << std::endl;
2028  return;
2029  }
2030 
2031  file << std::fixed; // no exponents
2032  file << std::setprecision (PLOT_PRECISION);
2033 
2034  file << "<?xml version=\"1.0\"?>\n";
2035  file << "<VTKFile type=\"StructuredGrid\" version=\"0.1\">\n";
2036  file << "<StructuredGrid WholeExtent=\"0 "<< np(0) - 1 <<
2037  " 0 " << np(1) - 1 << " 0 " << np(2) - 1 << "\">\n";
2038 
2039  file << "<Piece Extent=\"0 " << np(0) - 1 << " 0 " << np(1) - 1 << " 0 "
2040  << np(2) - 1 << "\">\n";
2041 
2042  file << "<Points>\n";
2043  file << "<DataArray type=\"Float32\" NumberOfComponents=\"" << points.rows()
2044  << "\">\n";
2045 
2046  for (index_t j = 0; j < points.cols(); ++j)
2047  {
2048  for (index_t i = 0; i < points.rows(); ++i)
2049  {
2050  file << points(i, j) << " ";
2051  }
2052  file << "\n";
2053  }
2054 
2055  file << "</DataArray>\n";
2056  file << "</Points>\n";
2057  file << "</Piece>\n";
2058  file << "</StructuredGrid>\n";
2059  file << "</VTKFile>\n";
2060  file.close();
2061 
2062 }
2063 
2064 } // namespace gismo
2065 
2066 
2067 #undef PLOT_PRECISION
index_t addPatch(typename gsGeometry< T >::uPtr g)
Add a patch from a gsGeometry&lt;T&gt;::uPtr.
Definition: gsMultiPatch.hpp:210
T projectedErrorRef() const
The error contribution of *this when it is refined.
Definition: gsHBox.hpp:307
void evaluateMesh(gsMesh< T > &mesh) const
Definition: gsGeometry.hpp:255
Abstract base class representing a geometry map.
Definition: gsGeometry.h:92
A fixed-size, statically allocated 3D vector.
Definition: gsVector.h:218
gsCurve< T > & getCurve(int loopNumber, int curveNumber) const
Returns curveNumber-th curve in loopNumber-th loop.
Definition: gsTrimSurface.h:103
void controlNet(gsMesh< T > &mesh) const
Return the control net of the geometry.
Definition: gsGeometry.hpp:524
Class for a trim surface.
Definition: gsTrimSurface.h:33
void gsWriteParaview_basisFnct(int i, gsBasis< T > const &basis, std::string const &fn, unsigned npts=NS)
Export i-th Basis function to paraview file.
Definition: gsWriteParaview.hpp:984
Abstract base class representing a curve.
Definition: gsCurve.h:30
gsMatrix< T > parameterRange() const
Returns the range of parameters as a matrix with two columns, [lower upper].
Definition: gsGeometry.hpp:198
#define gsDebug
Definition: gsDebug.h:61
A scalar of vector field defined on a m_parametric geometry.
Definition: gsField.h:54
const gsFunction< T > & function(int i=0) const
Returns the gsFunction of patch i.
Definition: gsField.h:231
#define short_t
Definition: gsConfig.h:35
void writeSingleBasisMesh(const gsBasis< T > &basis, std::string const &fn)
Export a parametric mesh.
Definition: gsWriteParaview.hpp:218
const gsFunction< T > & function(const index_t k) const
Helper which casts and returns the k-th piece of this function set as a gsFunction.
Definition: gsFunctionSet.hpp:25
std::string to_string(const C &value)
Converts value to string, assuming &quot;operator&lt;&lt;&quot; defined on C.
Definition: gsUtils.h:56
const_iterator begin(const std::string &label) const
Returns a const-iterator to the beginning of the Bc container of type label.
Definition: gsBoundaryConditions.h:471
void gsWriteParaviewIfc(gsMultiPatch< T > const &patches, std::string const &fn, unsigned npts, bool ctrlNet)
Writes the interfaces of a multipatch to paraview.
Definition: gsWriteParaview.hpp:1967
This class provides a Hierarchical Box (gsHBox)
Definition: gsHBox.h:54
Provides interface of gsTrimSurface class. Represents a trimmed surface (= spline &quot;master surface&quot; in...
index_t level() const
Gets the level of the object.
Definition: gsHBox.hpp:287
virtual index_t size() const
size
Definition: gsFunctionSet.h:578
gsMatrix< T > eval(const gsMatrix< T > &u) const
Evaluate the function,.
Definition: gsFunctionSet.hpp:120
Provides declaration of Geometry abstract interface.
const gsMatrix< T > & getCoordinates() const
Gets the coordinates of the box (first column lower corner, second column higher corner).
Definition: gsHBox.hpp:231
#define index_t
Definition: gsConfig.h:32
#define GISMO_ENSURE(cond, message)
Definition: gsDebug.h:102
A function from a n-dimensional domain to an m-dimensional image.
Definition: gsFunction.h:59
void computeCoordinates() const
Computes the parametric coordinates of this.
Definition: gsHBox.hpp:633
static std::string getFilename(std::string const &fn)
Returns the filename without the path of fn.
Definition: gsFileManager.cpp:597
void gsWriteParaviewPoints(gsMatrix< T > const &X, gsMatrix< T > const &Y, std::string const &fn)
Export 2D Point set to Paraview file.
Definition: gsWriteParaview.hpp:1267
bool isParametrized() const
Definition: gsField.h:257
This file contains the debugging and messaging system of G+Smo.
#define GISMO_ASSERT(cond, message)
Definition: gsDebug.h:89
Input and output Utilities.
virtual short_t targetDim() const
Dimension of the target space.
Definition: gsFunctionSet.h:560
virtual const gsFunctionSet & piece(const index_t) const
Returns the piece(s) of the function(s) at subdomain k.
Definition: gsFunctionSet.h:239
Class Representing a triangle mesh with 3D vertices.
Definition: gsMesh.h:31
index_t size() const
size
Definition: gsMultiPatch.h:129
std::string to_string(const unsigned &i)
Helper to convert small unsigned to string.
Definition: gsXml.cpp:74
#define gsWarn
Definition: gsDebug.h:50
Holds a set of patch-wise bases and their topology information.
Definition: gsMultiBasis.h:36
void writeSingleGeometry(gsFunction< T > const &func, gsMatrix< T > const &supp, std::string const &fn, unsigned npts)
Export a geometry represented by func.
Definition: gsWriteParaview.hpp:469
gsMatrix< T > evalSingle(index_t i, const gsMatrix< T > &u) const
Evaluate a single basis function i at points u.
Definition: gsBasis.h:122
bool isParametric() const
Definition: gsField.h:252
Provides declaration of the MultiPatch class.
gsGeometry< T > & patch(size_t i) const
Return the i-th patch.
Definition: gsMultiPatch.h:226
void gsWriteParaviewTrimmedCurve(const gsTrimSurface< T > &surf, const unsigned idLoop, const unsigned idCurve, const std::string fn, unsigned npts=NS)
Export a boundary/hole curve in trimmed surface.
Definition: gsWriteParaview.hpp:1992
void gsWriteParaviewSolid(gsSolid< T > const &sl, std::string const &fn, unsigned numSamples=NS)
Export a gsSolid to Paraview file.
Definition: gsWriteParaview.hpp:1665
virtual short_t domainDim() const
Dimension d of the parameter domain (overriding gsFunction::domainDim()).
Definition: gsGeometry.hpp:184
size_t nPatches() const
Number of patches.
Definition: gsMultiPatch.h:208
Provides a helper class to write Paraview collection (.pvd) files.
const_iterator end(const std::string &label) const
Returns a const-iterator to the end of the Bc container of type label.
Definition: gsBoundaryConditions.h:477
gsMatrix< T > gsPointGrid(gsVector< T > const &a, gsVector< T > const &b, gsVector< unsigned > const &np)
Construct a Cartesian grid of uniform points in a hypercube, using np[i] points in direction i...
Definition: gsPointGrid.hpp:82
const_iterator end() const
Definition: gsMultiPatch.h:108
void save()
Definition: gsParaviewCollection.h:203
virtual short_t domainDim() const =0
Dimension of the (source) domain.
gsGeometrySlice is a class representing an iso parametric slice of a geometry object. It stores a pointer to the geometry object, which is only valid as long as this object is alive. Methods for printing to paraview are available in gsWriteToParaview.h
Definition: gsGeometrySlice.h:27
Interface for the set of functions defined on a domain (the total number of functions in the set equa...
Definition: gsFuncData.h:23
Container class for a set of geometry patches and their topology, that is, the interface connections ...
Definition: gsMultiPatch.h:33
This class is used to create a Paraview .pvd (collection) file.
Definition: gsParaviewCollection.h:76
void addPart(String const &fn, real_t tStep=-1, std::string name="", index_t part=-1)
Appends a file to the Paraview collection (.pvd file).
Definition: gsParaviewCollection.h:114
short_t parDim() const
Dimension d of the parameter domain (same as domainDim()).
Definition: gsGeometry.hpp:190
virtual void eval_into(const gsMatrix< T > &u, gsMatrix< T > &result) const =0
Evaluate the function at points u into result.
void evalCurve_into(int loopNumber, int curveNumber, const gsMatrix< T > &u, gsMatrix< T > &result) const
Definition: gsTrimSurface.h:133
void writeSingleCompMesh(const gsBasis< T > &basis, const gsGeometry< T > &Geo, std::string const &fn, unsigned resolution=8)
Export a computational mesh.
Definition: gsWriteParaview.hpp:232
Class representing a Planar domain with an outer boundary and a number of holes.
Definition: gsPlanarDomain.h:43
void gsWriteParaviewBdr(gsMultiPatch< T > const &patches, std::string const &fn, unsigned npts, bool ctrlNet)
Writes the boundaries of a multipatch to paraview.
Definition: gsWriteParaview.hpp:1954
const gsBasis< T > & basis(const size_t i) const
Return the i-th basis block.
Definition: gsMultiBasis.h:267
Provides a container for gsHBox.
void writeSingleHBox(gsHBox< 2, T > &box, std::string const &fn)
Export a gsHBox.
Definition: gsWriteParaview.hpp:1180
virtual index_t nPieces() const
Number of pieces in the domain of definition.
Definition: gsFunctionSet.h:584
size_t nBases() const
Number of patch-wise bases.
Definition: gsMultiBasis.h:264
Class for representing a solid made up of vertices, edges, faces, and volumes.
Definition: gsSolid.h:32
#define GISMO_ERROR(message)
Definition: gsDebug.h:118
int nPieces() const
Returns the number of pieces.
Definition: gsField.h:200
const_iterator begin() const
Definition: gsMultiPatch.h:103
A closed loop given by a collection of curves.
Definition: gsCurveLoop.h:36
void makeCollection(std::string const &fn, std::string const &ext, int n=0)
Definition: gsParaviewCollection.h:258
virtual const gsBasis< T > & basis() const =0
Returns a const reference to the basis of the geometry.
void writeSingleCurve(gsFunction< T > const &func, gsMatrix< T > const &supp, std::string const &fn, unsigned npts)
Export a curve geometry represented by func.
Definition: gsWriteParaview.hpp:556
void writeSingleControlNet(const gsGeometry< T > &Geo, std::string const &fn)
Export a control net.
Definition: gsWriteParaview.hpp:248
virtual gsMatrix< T > support() const
Returns (a bounding box for) the domain of the whole basis.
Definition: gsBasis.hpp:431
Provides declaration of the gsGeometrySlice class.
short_t geoDim() const
Dimension n of the absent physical space.
Definition: gsGeometry.h:292
const gsGeometry< T > & patch(int i=0) const
Returns the gsGeometry of patch i.
Definition: gsField.h:221
A basis represents a family of scalar basis functions defined over a common parameter domain...
Definition: gsBasis.h:78
Provides declaration of the Field class.
gsMatrix< T > & coefs()
Definition: gsGeometry.h:340
gsVertex class that represents a 3D vertex for a gsMesh.
Definition: gsVertex.h:26
const gsGeometry< T > & igaFunction(int i=0) const
Attempts to return an Isogeometric function for patch i.
Definition: gsField.h:239
Provides declaration of gsSolid class, a boundary-represented solid.
T error() const
Gets the error stored in the object.
Definition: gsHBox.hpp:304