x3dSurfaceWriter.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | www.openfoam.com
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8  Copyright (C) 2019-2020 OpenCFD Ltd.
9 -------------------------------------------------------------------------------
10 License
11  This file is part of OpenFOAM.
12 
13  OpenFOAM is free software: you can redistribute it and/or modify it
14  under the terms of the GNU General Public License as published by
15  the Free Software Foundation, either version 3 of the License, or
16  (at your option) any later version.
17 
18  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
19  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21  for more details.
22 
23  You should have received a copy of the GNU General Public License
24  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
25 
26 \*---------------------------------------------------------------------------*/
27 
28 #include "x3dSurfaceWriter.H"
29 #include "OFstream.H"
30 #include "OSspecific.H"
31 #include "MeshedSurfaceProxy.H"
32 #include "surfaceWriterMethods.H"
34 
35 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
36 
37 namespace Foam
38 {
39 namespace surfaceWriters
40 {
41  defineTypeName(x3dWriter);
42  addToRunTimeSelectionTable(surfaceWriter, x3dWriter, word);
43  addToRunTimeSelectionTable(surfaceWriter, x3dWriter, wordDict);
44 }
45 }
46 
47 
48 // * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
49 
50 namespace Foam
51 {
52 
53 //- A (0-1) range for colouring
54 inline scalar srange01(const scalarMinMax& range, scalar x)
55 {
56  if (x >= range.max())
57  {
58  return 1;
59  }
60 
61  x -= range.min();
62 
63  if (x < VSMALL)
64  {
65  return 0;
66  }
67 
68  return x / (range.max() - range.min());
69 }
70 
71 
72 //- A (0-1) range for colouring
73 template<class Type>
74 static inline scalar rangex(const scalarMinMax& range, const Type& val)
75 {
76  return srange01(range, Foam::mag(val));
77 }
78 
79 
80 //- A (0-1) range for colouring
81 template<>
82 inline scalar rangex(const scalarMinMax& range, const scalar& val)
83 {
84  return srange01(range, val);
85 }
86 
87 
88 //- A (0-1) range for colouring
89 template<>
90 inline scalar rangex(const scalarMinMax& range, const label& val)
91 {
92  return srange01(range, val);
93 }
94 
95 
96 static inline void printColour(Ostream& os, const vector& rgb)
97 {
98  os << rgb[0] << ' ' << rgb[1] << ' ' << rgb[2] << ',' << nl;
99 }
100 
101 } // End namespace Foam
102 
103 
104 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
105 
107 :
108  surfaceWriter(),
109  streamOpt_(),
110  range_(),
111  colourTablePtr_(nullptr)
112 {}
113 
114 
116 (
117  const dictionary& options
118 )
119 :
120  surfaceWriter(options),
121  streamOpt_
122  (
124  IOstream::compressionEnum("compression", options)
125  ),
126  range_(),
127  colourTablePtr_(nullptr)
128 {
129  verbose_ = true;
130 
131  options.readIfPresent("range", range_);
132 
133  word tableName;
134  if (options.readIfPresent("colourMap", tableName))
135  {
136  colourTablePtr_ = colourTable::ptr(tableName);
137  if (!colourTablePtr_)
138  {
140  << "No colourMap " << tableName << " using default" << nl;
141  }
142  }
143 
144  if (!colourTablePtr_)
145  {
147  colourTablePtr_ = colourTable::ptr(colourTable::COOL_WARM);
148  }
149 
150  if (verbose_)
151  {
152  Info<< "X3D with colourMap '" << tableName << "' and range ";
153 
154  if (range_.valid())
155  {
156  Info<< range_;
157  }
158  else
159  {
160  Info<< "auto";
161  }
162  Info<< nl;
163  }
164 }
165 
166 
168 (
169  const meshedSurf& surf,
170  const fileName& outputPath,
171  bool parallel,
172  const dictionary& options
173 )
174 :
175  x3dWriter(options)
176 {
177  open(surf, outputPath, parallel);
178 }
179 
180 
182 (
183  const pointField& points,
184  const faceList& faces,
185  const fileName& outputPath,
186  bool parallel,
187  const dictionary& options
188 )
189 :
190  x3dWriter(options)
191 {
192  open(points, faces, outputPath, parallel);
193 }
194 
195 
196 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
197 
199 {
200  checkOpen();
201 
202  // Geometry: rootdir/<TIME>/surfaceName.x3d
203 
204  fileName outputFile = outputPath_;
205  if (useTimeDir() && !timeName().empty())
206  {
207  // Splice in time-directory
208  outputFile = outputPath_.path() / timeName() / outputPath_.name();
209  }
210  outputFile.ext("x3d");
211 
212  if (verbose_)
213  {
214  Info<< "Writing geometry to " << outputFile << endl;
215  }
216 
217  const meshedSurf& surf = surface();
218 
219  if (Pstream::master() || !parallel_)
220  {
221  if (!isDir(outputFile.path()))
222  {
223  mkDir(outputFile.path());
224  }
225 
227  (
228  outputFile,
229  "x3d",
230  streamOpt_
231  );
232  }
233 
234  wroteGeom_ = true;
235  return outputFile;
236 }
237 
238 
239 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
240 
241 template<class Type>
242 Foam::fileName Foam::surfaceWriters::x3dWriter::writeTemplate
243 (
244  const word& fieldName,
245  const Field<Type>& localValues
246 )
247 {
248  if (!colourTablePtr_)
249  {
250  // Write geometry only if there are no colours to use
252  << "No output colours set" << endl;
253 
254  return this->write();
255  }
256 
257  checkOpen();
258 
259  // Field: rootdir/<TIME>/<field>_surfaceName.x3d
260 
261  fileName outputFile = outputPath_.path();
262  if (useTimeDir() && !timeName().empty())
263  {
264  // Splice in time-directory
265  outputFile /= timeName();
266  }
267 
268  // Append <field>_surfaceName.x3d
269  outputFile /= fieldName + '_' + outputPath_.name();
270  outputFile.ext("x3d");
271 
272  if (verbose_)
273  {
274  Info<< "Writing field " << fieldName << " to " << outputFile << endl;
275  }
276 
277  const meshedSurf& surf = surface();
278 
279  // Implicit geometry merge()
280  tmp<Field<Type>> tfield = mergeField(localValues);
281 
282  if (Pstream::master() || !parallel_)
283  {
284  const auto& values = tfield();
285 
286  scalarMinMax range(range_);
287 
288  if (!range.valid())
289  {
291 
292  if (equal(range.mag(), 0))
293  {
294  range.add(range.centre());
295  }
296  }
297 
298  // Slight rounding
299  range.min() -= VSMALL;
300  range.max() += VSMALL;
301 
302  if (!isDir(outputFile.path()))
303  {
304  mkDir(outputFile.path());
305  }
306 
307  OFstream os(outputFile, streamOpt_);
308 
309  writeHeader(os);
310  beginGroup(os);
311  writeAppearance(os);
312 
313  // For point field: "colorPerVetex=true"
314  os << " <IndexedFaceSet"
315  << " colorPerVertex='" << Switch(this->isPointData()) << "'"
316  << " coordIndex='" << nl;
317 
318  for (const auto& f : surf.faces())
319  {
320  for (const label vrti : f)
321  {
322  os << vrti << ' ';
323  }
324  os << "-1\n";
325  }
326  os << "'";
327 
328  // Colour indices for face fields
329  if (!this->isPointData())
330  {
331  const label nFaces = surf.faces().size();
332 
333  os << " colorIndex='";
334 
335  for (label i=0; i < nFaces; ++i)
336  {
337  os << i << ' ';
338  }
339  os << "'";
340  }
341 
342  os << " >\n"; // IndexedFaceSet
343 
344  writePoints(os, surf.points());
345 
346  os << "<Color color='" << nl;
347 
348  // writeColours(os, values, range, colorBar);
349 
350  for (const Type& val : values)
351  {
352  const scalar x = rangex(range, val);
353  vector rgb = colourTablePtr_->value(x);
354  printColour(os, rgb);
355  }
356 
357  os << "' />" << nl; // Color
358 
359  os <<
360  " </IndexedFaceSet>\n";
361 
362  endGroup(os);
363  writeFooter(os);
364  }
365 
366  wroteGeom_ = true;
367  return outputFile;
368 }
369 
370 
371 // Field writing methods
373 
374 
375 // ************************************************************************* //
Foam::colourTable::predefinedNames
static const Enum< predefinedType > predefinedNames
Enumeration names for predefinedType.
Definition: colourTable.H:108
Foam::surfaceWriters::x3dWriter
A surfaceWriter for X3D files.
Definition: x3dSurfaceWriter.H:103
OSspecific.H
Functions used by OpenFOAM that are specific to POSIX compliant operating systems and need to be repl...
MeshedSurfaceProxy.H
Foam::Switch
A simple wrapper around bool so that it can be read as a word: true/false, on/off,...
Definition: Switch.H:77
Foam::colourTable::ptr
static const colourTable * ptr(const word &tableName)
Look up pointer to colourTable by name, or nullptr on failure.
Definition: colourTables.C:88
Foam::srange01
scalar srange01(const scalarMinMax &range, scalar x)
A (0-1) range for colouring.
Definition: x3dSurfaceWriter.C:54
Foam::word
A class for handling words, derived from Foam::string.
Definition: word.H:65
Foam::surfaceWriter
Base class for surface writers.
Definition: surfaceWriter.H:114
Foam::fileName
A class for handling file names.
Definition: fileName.H:73
Foam::surfaceWriters::defineTypeName
defineTypeName(abaqusWriter)
Foam::fileName::path
static std::string path(const std::string &str)
Return directory path name (part before last /)
Definition: fileNameI.H:176
Foam::tmp
A class for managing temporary objects.
Definition: PtrList.H:61
Foam::HashTableOps::values
List< T > values(const HashTable< T, Key, Hash > &tbl, const bool doSort=false)
List of values from HashTable, optionally sorted.
Definition: HashOps.H:149
Foam::meshedSurf::faces
virtual const faceList & faces() const =0
The faces used for the surface.
Foam::meshedSurf
Abstract definition of a meshed surface defined by faces and points.
Definition: meshedSurf.H:49
x3dSurfaceWriter.H
Foam::UPstream::master
static bool master(const label communicator=worldComm)
Am I the master process.
Definition: UPstream.H:457
Foam::rangex
static scalar rangex(const scalarMinMax &range, const Type &val)
A (0-1) range for colouring.
Definition: x3dSurfaceWriter.C:74
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:369
Foam::writeHeader
static void writeHeader(Ostream &os, const word &fieldName)
Definition: rawSurfaceWriterImpl.C:66
surfaceWriterMethods.H
Convenience macros for instantiating surfaceWriter methods.
Foam::MeshedSurfaceProxy
A proxy for writing MeshedSurface, UnsortedMeshedSurface and surfMesh to various file formats.
Definition: MeshedSurface.H:82
OFstream.H
Foam::surfaceWriters::addToRunTimeSelectionTable
addToRunTimeSelectionTable(surfaceWriter, abaqusWriter, word)
Foam::Field< vector >
Foam::Info
messageStream Info
Information stream (stdout output on master, null elsewhere)
Foam::surfaceWriters::x3dWriter::x3dWriter
x3dWriter()
Default construct.
Definition: x3dSurfaceWriter.C:106
Foam::printColour
static void printColour(Ostream &os, const vector &rgb)
Definition: x3dSurfaceWriter.C:96
Foam::meshedSurf::points
virtual const pointField & points() const =0
The points used for the surface.
timeName
word timeName
Definition: getTimeIndex.H:3
Foam::IOstreamOption::compressionEnum
static compressionType compressionEnum(const word &compName, const compressionType deflt=compressionType::UNCOMPRESSED)
The compression enum corresponding to the string.
Definition: IOstreamOption.C:92
Foam::dictionary
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition: dictionary.H:123
Foam::minMaxMag
dimensioned< scalarMinMax > minMaxMag(const DimensionedField< Type, GeoMesh > &df)
Definition: DimensionedFieldFunctions.C:330
os
OBJstream os(runTime.globalPath()/outputName)
addToRunTimeSelectionTable.H
Macros for easy insertion into run-time selection tables.
Foam::colourTable::COOL_WARM
"coolToWarm"
Definition: colourTable.H:95
Foam::fileName::ext
word ext() const
Return file name extension (part after last .)
Definition: fileNameI.H:218
Foam
Namespace for OpenFOAM.
Definition: atmBoundaryLayer.C:33
Foam::OFstream
Output to file stream, using an OSstream.
Definition: OFstream.H:53
Foam::IOstreamOption::ASCII
"ascii" (normal default)
Definition: IOstreamOption.H:72
range
scalar range
Definition: LISASMDCalcMethod1.H:12
Foam::nl
constexpr char nl
Definition: Ostream.H:404
f
labelList f(nPoints)
Foam::surfaceWriters::x3dWriter::write
virtual fileName write()
Write surface geometry to file.
Definition: x3dSurfaceWriter.C:198
Foam::Vector< scalar >
Foam::List< face >
Foam::mag
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
points
const pointField & points
Definition: gmvOutputHeader.H:1
x
x
Definition: LISASMDCalcMethod2.H:52
Foam::vtk::write
void write(vtk::formatter &fmt, const Type &val, const label n=1)
Component-wise write of a value (N times)
Definition: foamVtkOutputTemplates.C:36
Foam::Ostream
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition: Ostream.H:56
Foam::mkDir
bool mkDir(const fileName &pathName, mode_t mode=0777)
Make a directory and return an error if it could not be created.
Definition: MSwindows.C:507
Foam::equal
bool equal(const T &s1, const T &s2)
Compare two values for equality.
Definition: doubleFloat.H:46
WarningInFunction
#define WarningInFunction
Report a warning using Foam::Warning.
Definition: messageStream.H:328
Foam::MinMax
A min/max value pair with additional methods. In addition to conveniently storing values,...
Definition: HashSet.H:76
defineSurfaceWriterWriteFields
defineSurfaceWriterWriteFields(Foam::surfaceWriters::x3dWriter)
Foam::dictionary::readIfPresent
bool readIfPresent(const word &keyword, T &val, enum keyType::option matchOpt=keyType::REGEX) const
Definition: dictionaryTemplates.C:405
Foam::isDir
bool isDir(const fileName &name, const bool followLink=true)
Does the name exist as a DIRECTORY in the file system?
Definition: MSwindows.C:643