mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
ENH: add colour for x3d surface writer (#1057)
- can be used for outputing sampled surfaces in x3d format for direct import in other rendering tools.
This commit is contained in:
committed by
Andrew Heather
parent
3089a11647
commit
23e5d43e4e
3
applications/test/colourTables/Make/files
Normal file
3
applications/test/colourTables/Make/files
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
Test-colourTables.C
|
||||||
|
|
||||||
|
EXE = $(FOAM_USER_APPBIN)/Test-colourTables
|
||||||
5
applications/test/colourTables/Make/options
Normal file
5
applications/test/colourTables/Make/options
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
EXE_INC = \
|
||||||
|
-I$(LIB_SRC)/fileFormats/lnInclude
|
||||||
|
|
||||||
|
EXE_LIBS = \
|
||||||
|
-lfileFormats
|
||||||
66
applications/test/colourTables/Test-colourTables.C
Normal file
66
applications/test/colourTables/Test-colourTables.C
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | Copyright (C) 2019 OpenCFD Ltd.
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "colourTable.H"
|
||||||
|
#include "IOstreams.H"
|
||||||
|
|
||||||
|
using namespace Foam;
|
||||||
|
|
||||||
|
void dumpTable(const colourTable& tbl, const label n=128)
|
||||||
|
{
|
||||||
|
Info<< tbl.table(n) << nl;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void dumpTable(const colourTable* tbl, const label n=128)
|
||||||
|
{
|
||||||
|
if (tbl)
|
||||||
|
{
|
||||||
|
Info<< tbl->table(n) << nl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
// Main program:
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
// dumpTable(colourTable::ptr(colourTable::RAINBOW));
|
||||||
|
dumpTable(colourTable::ptr(colourTable::COOL_WARM));
|
||||||
|
|
||||||
|
// forAllConstIters(colourTable::tables(), iter)
|
||||||
|
// {
|
||||||
|
// Info<< nl << iter.key() << nl;
|
||||||
|
// dumpTable(iter.val());
|
||||||
|
// }
|
||||||
|
|
||||||
|
Info<< "\nDone\n";
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
96
etc/colourTables
Normal file
96
etc/colourTables
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
/*--------------------------------*- C++ -*----------------------------------*\
|
||||||
|
| ========= | |
|
||||||
|
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||||
|
| \\ / O peration | Version: v1812 |
|
||||||
|
| \\ / A nd | Web: www.OpenFOAM.com |
|
||||||
|
| \\/ M anipulation | |
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
// An OpenFOAM dictionary of colourTables.
|
||||||
|
// The names should match those in the colourTables class.
|
||||||
|
|
||||||
|
6
|
||||||
|
(
|
||||||
|
|
||||||
|
coolToWarm
|
||||||
|
{
|
||||||
|
// ParaView: "Cool To Warm"
|
||||||
|
interpolate diverging;
|
||||||
|
|
||||||
|
table
|
||||||
|
(
|
||||||
|
( 0.0 ( 0.231372 0.298039 0.752941 ) )
|
||||||
|
( 0.5 ( 0.865003 0.865003 0.865003 ) )
|
||||||
|
( 1.0 ( 0.705882 0.0156863 0.14902 ) )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
coldAndHot
|
||||||
|
{
|
||||||
|
// ParaView : "Cold and Hot"
|
||||||
|
interpolate diverging;
|
||||||
|
|
||||||
|
table
|
||||||
|
(
|
||||||
|
( 0 ( 0 1 1 ) )
|
||||||
|
( 0.45 ( 0 0 1 ) )
|
||||||
|
( 0.5 ( 0 0 0.5019608) )
|
||||||
|
( 0.55 ( 1 0 0 ) )
|
||||||
|
( 1 ( 1 1 0 ) )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fire
|
||||||
|
{
|
||||||
|
// ParaView: Black-Body Radiation
|
||||||
|
interpolate rbg;
|
||||||
|
|
||||||
|
table
|
||||||
|
(
|
||||||
|
( 0 ( 0 0 0 ) )
|
||||||
|
( 0.4 ( 0.901961 0 0 ) )
|
||||||
|
( 0.8 ( 0.901961 0.901961 0 ) )
|
||||||
|
( 1 ( 1 1 1 ) )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
rainbow
|
||||||
|
{
|
||||||
|
interpolate hsv;
|
||||||
|
|
||||||
|
table
|
||||||
|
(
|
||||||
|
( 0 ( 0 0 1 ) )
|
||||||
|
( 0.5 ( 0 1 0 ) )
|
||||||
|
( 1 ( 1 0 0 ) )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
greyscale
|
||||||
|
{
|
||||||
|
// ParaView: grayscale
|
||||||
|
interpolate rbg;
|
||||||
|
|
||||||
|
table
|
||||||
|
(
|
||||||
|
( 0 ( 0 0 0 ) )
|
||||||
|
( 1 ( 1 1 1 ) )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
xray
|
||||||
|
{
|
||||||
|
// ParaView: "X ray"
|
||||||
|
interpolate rbg;
|
||||||
|
|
||||||
|
table
|
||||||
|
(
|
||||||
|
( 0 ( 1 1 1 ) )
|
||||||
|
( 1 ( 0 0 0 ) )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -1,3 +1,7 @@
|
|||||||
|
colours/colourTable.C
|
||||||
|
colours/colourTables.C
|
||||||
|
colours/colourTools.C
|
||||||
|
|
||||||
ensight/file/ensightCase.C
|
ensight/file/ensightCase.C
|
||||||
ensight/file/ensightCaseOptions.C
|
ensight/file/ensightCaseOptions.C
|
||||||
ensight/file/ensightFile.C
|
ensight/file/ensightFile.C
|
||||||
|
|||||||
182
src/fileFormats/colours/colourTable.C
Normal file
182
src/fileFormats/colours/colourTable.C
Normal file
@ -0,0 +1,182 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | Copyright (C) 2019 OpenCFD Ltd.
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "colourTable.H"
|
||||||
|
#include "colourTools.H"
|
||||||
|
#include "ListOps.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
const Foam::Enum
|
||||||
|
<
|
||||||
|
Foam::colourTable::interpolationType
|
||||||
|
>
|
||||||
|
Foam::colourTable::interpolationTypeNames
|
||||||
|
({
|
||||||
|
{ interpolationType::RGB, "rgb" },
|
||||||
|
{ interpolationType::HSV, "hsv" },
|
||||||
|
{ interpolationType::DIVERGING, "diverging" },
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::colourTable::colourTable
|
||||||
|
(
|
||||||
|
const List<Tuple2<scalar, vector>>& values,
|
||||||
|
const interpolationType interp
|
||||||
|
)
|
||||||
|
:
|
||||||
|
table_(values),
|
||||||
|
interp_(interp)
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::colourTable::colourTable
|
||||||
|
(
|
||||||
|
List<Tuple2<scalar, vector>>&& values,
|
||||||
|
const interpolationType interp
|
||||||
|
)
|
||||||
|
:
|
||||||
|
table_(std::move(values)),
|
||||||
|
interp_(interp)
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::colourTable::colourTable
|
||||||
|
(
|
||||||
|
const dictionary& dict,
|
||||||
|
const interpolationType interp
|
||||||
|
)
|
||||||
|
:
|
||||||
|
table_(),
|
||||||
|
interp_(interp)
|
||||||
|
{
|
||||||
|
dict.readEntry("table", table_);
|
||||||
|
interpolationTypeNames.readIfPresent("interpolate", dict, interp_);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::autoPtr<Foam::colourTable> Foam::colourTable::New(Istream& is)
|
||||||
|
{
|
||||||
|
return autoPtr<colourTable>::New(dictionary(is));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::vector Foam::colourTable::value(const scalar x) const
|
||||||
|
{
|
||||||
|
if (x <= 0)
|
||||||
|
{
|
||||||
|
return table_.first().second();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (x >= 1)
|
||||||
|
{
|
||||||
|
return table_.last().second();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
label idx = findLower
|
||||||
|
(
|
||||||
|
table_, x, 0,
|
||||||
|
[](const pair_type& pr, const scalar& val)
|
||||||
|
{
|
||||||
|
// Test first element
|
||||||
|
return (pr.first() <= val);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
if (idx == -1)
|
||||||
|
{
|
||||||
|
// Use first element only
|
||||||
|
return table_.first().second();
|
||||||
|
}
|
||||||
|
else if (idx == table_.size()-1)
|
||||||
|
{
|
||||||
|
// Use last element only
|
||||||
|
return table_.last().second();
|
||||||
|
}
|
||||||
|
|
||||||
|
const scalar t0 = table_[idx].first();
|
||||||
|
const scalar t1 = table_[idx+1].first();
|
||||||
|
|
||||||
|
const scalar s = (x - t0)/(t1 - t0);
|
||||||
|
|
||||||
|
const vector& rgb0 = table_[idx].second();
|
||||||
|
const vector& rgb1 = table_[idx+1].second();
|
||||||
|
|
||||||
|
if (interp_ == DIVERGING)
|
||||||
|
{
|
||||||
|
return colourTools::interpolateDiverging(s, rgb0, rgb1);
|
||||||
|
}
|
||||||
|
else if (interp_ == HSV)
|
||||||
|
{
|
||||||
|
return colourTools::interpolateHSV(s, rgb0, rgb1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return colourTools::interpolateRGB(s, rgb0, rgb1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::List<Foam::Tuple2<Foam::scalar, Foam::vector>>
|
||||||
|
Foam::colourTable::table(const label nColours) const
|
||||||
|
{
|
||||||
|
List<Tuple2<scalar, vector>> lut(nColours);
|
||||||
|
|
||||||
|
for (label i=0; i < nColours; ++i)
|
||||||
|
{
|
||||||
|
const scalar x = scalar(i)/scalar(nColours-1);
|
||||||
|
|
||||||
|
lut[i] = pair_type(x, value(x));
|
||||||
|
}
|
||||||
|
|
||||||
|
return lut;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::Ostream& Foam::colourTable::writeDict(Ostream& os) const
|
||||||
|
{
|
||||||
|
os.beginBlock();
|
||||||
|
os.writeEntry("interpolate", interpolationTypeNames[interp_]);
|
||||||
|
os.writeEntry("table", table_);
|
||||||
|
os.endBlock();
|
||||||
|
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::Ostream& Foam::operator<<(Ostream& os, const colourTable& tbl)
|
||||||
|
{
|
||||||
|
tbl.writeDict(os);
|
||||||
|
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
207
src/fileFormats/colours/colourTable.H
Normal file
207
src/fileFormats/colours/colourTable.H
Normal file
@ -0,0 +1,207 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | Copyright (C) 2019 OpenCFD Ltd.
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
Class
|
||||||
|
Foam::colourTable
|
||||||
|
|
||||||
|
Description
|
||||||
|
Base class for generating a colour table from node points.
|
||||||
|
|
||||||
|
Dictionary definition
|
||||||
|
\table
|
||||||
|
Property | Description | Required | Default
|
||||||
|
interpolate | rgb/hsv/diverging | no | rgb
|
||||||
|
table | Node points for the colour table | yes |
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
Predefined colour tables (in "etc/colourTables") include
|
||||||
|
"coolToWarm", "coldAndHot", "fire", "rainbow", "greyscale", "xray".
|
||||||
|
|
||||||
|
SourceFiles
|
||||||
|
colourTable.C
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef colourTable_H
|
||||||
|
#define colourTable_H
|
||||||
|
|
||||||
|
#include "Enum.H"
|
||||||
|
#include "List.H"
|
||||||
|
#include "Tuple2.H"
|
||||||
|
#include "vector.H"
|
||||||
|
#include "HashPtrTable.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
Class colourTable Declaration
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
class colourTable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
//- Internal interpolation type
|
||||||
|
enum interpolationType
|
||||||
|
{
|
||||||
|
RGB,
|
||||||
|
HSV,
|
||||||
|
DIVERGING
|
||||||
|
};
|
||||||
|
|
||||||
|
//- Enumeration of commonly used colour tables.
|
||||||
|
// The indices must match those in "etc/colourTables"
|
||||||
|
enum predefinedType
|
||||||
|
{
|
||||||
|
COOL_WARM, //!< "coolToWarm"
|
||||||
|
COLD_HOT, //!< "coldAndHot"
|
||||||
|
FIRE, //!< "fire" - ParaView "Black-Body Radiation"
|
||||||
|
RAINBOW, //!< "rainbow"
|
||||||
|
GREYSCALE, //!< greyscale - ParaView "Grayscale"
|
||||||
|
XRAY //!< "xray" - ParaView "X Ray"
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//- Enumeration names for interpolationType
|
||||||
|
static const Enum<interpolationType> interpolationTypeNames;
|
||||||
|
|
||||||
|
//- Enumeration names for predefinedType
|
||||||
|
static const Enum<predefinedType> predefinedNames;
|
||||||
|
|
||||||
|
//- The data lookup type
|
||||||
|
typedef Tuple2<scalar, vector> pair_type;
|
||||||
|
|
||||||
|
|
||||||
|
// Lookup Colour Tables
|
||||||
|
|
||||||
|
//- Look up pointer to colourTable by name, or nullptr on failure.
|
||||||
|
static const colourTable* ptr(const word& tableName);
|
||||||
|
|
||||||
|
//- Look up pointer to colourTable by type, or nullptr on failure.
|
||||||
|
static const colourTable* ptr(const predefinedType tbl);
|
||||||
|
|
||||||
|
//- Look up pointer to colourTable by name. Fatal on failure
|
||||||
|
static const colourTable& ref(const word& tableName);
|
||||||
|
|
||||||
|
//- Look up pointer to colourTable by type. Fatal on failure
|
||||||
|
static const colourTable& ref(const predefinedType tbl);
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
// Private Static Data
|
||||||
|
|
||||||
|
//- Predefined tables
|
||||||
|
static HashPtrTable<colourTable> tables_;
|
||||||
|
|
||||||
|
|
||||||
|
// Private Data
|
||||||
|
|
||||||
|
//- The table control points
|
||||||
|
List<pair_type> table_;
|
||||||
|
|
||||||
|
//- Interpolator type
|
||||||
|
interpolationType interp_;
|
||||||
|
|
||||||
|
|
||||||
|
// Private Member Functions
|
||||||
|
|
||||||
|
//- Construct from central "etc/colourTables" file.
|
||||||
|
static void constructTables();
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
|
||||||
|
//- Copy construct from table values
|
||||||
|
explicit colourTable
|
||||||
|
(
|
||||||
|
const List<Tuple2<scalar, vector>>& values,
|
||||||
|
const interpolationType interp = interpolationType::RGB
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Copy construct from table values
|
||||||
|
explicit colourTable
|
||||||
|
(
|
||||||
|
List<Tuple2<scalar, vector>>&& values,
|
||||||
|
const interpolationType interp = interpolationType::RGB
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Read construct from dictionary
|
||||||
|
explicit colourTable
|
||||||
|
(
|
||||||
|
const dictionary& dict,
|
||||||
|
const interpolationType interp = interpolationType::RGB
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
// Selectors
|
||||||
|
|
||||||
|
//- Read as dictionary content
|
||||||
|
static autoPtr<colourTable> New(Istream& is);
|
||||||
|
|
||||||
|
|
||||||
|
//- Destructor
|
||||||
|
virtual ~colourTable() = default;
|
||||||
|
|
||||||
|
|
||||||
|
// Member Functions
|
||||||
|
|
||||||
|
// Access
|
||||||
|
|
||||||
|
//- Predefined tables
|
||||||
|
static const HashPtrTable<colourTable>& tables();
|
||||||
|
|
||||||
|
//- Return the colour at x (within 0-1 range)
|
||||||
|
vector value(const scalar x) const;
|
||||||
|
|
||||||
|
//- Return a discrete lookup table of colours
|
||||||
|
List<Tuple2<scalar, vector>> table(const label nColours) const;
|
||||||
|
|
||||||
|
|
||||||
|
// IO
|
||||||
|
|
||||||
|
//- Write as dictionary format
|
||||||
|
Ostream& writeDict(Ostream& os) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//- Write as dictionary format
|
||||||
|
Ostream& operator<<(Ostream& os, const colourTable& tbl);
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
132
src/fileFormats/colours/colourTables.C
Normal file
132
src/fileFormats/colours/colourTables.C
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | Copyright (C) 2019 OpenCFD Ltd.
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "colourTable.H"
|
||||||
|
#include "etcFiles.H"
|
||||||
|
#include "IFstream.H"
|
||||||
|
#include "HashSet.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::HashPtrTable<Foam::colourTable> Foam::colourTable::tables_;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const Foam::Enum
|
||||||
|
<
|
||||||
|
Foam::colourTable::predefinedType
|
||||||
|
>
|
||||||
|
Foam::colourTable::predefinedNames
|
||||||
|
({
|
||||||
|
{ predefinedType::COOL_WARM, "coolToWarm" },
|
||||||
|
{ predefinedType::COLD_HOT, "coldAndHot" },
|
||||||
|
{ predefinedType::FIRE, "fire" },
|
||||||
|
{ predefinedType::RAINBOW, "rainbow" },
|
||||||
|
{ predefinedType::GREYSCALE, "greyscale" },
|
||||||
|
{ predefinedType::XRAY, "xray" },
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
void Foam::colourTable::constructTables()
|
||||||
|
{
|
||||||
|
if (tables_.size())
|
||||||
|
{
|
||||||
|
FatalErrorInFunction
|
||||||
|
<< "attempt to re-construct colourTables when they already exist"
|
||||||
|
<< exit(FatalError);
|
||||||
|
}
|
||||||
|
|
||||||
|
IFstream is(findEtcFile("colourTables", true)); // Mandatory file
|
||||||
|
|
||||||
|
HashPtrTable<colourTable> newEntries(is);
|
||||||
|
tables_.swap(newEntries);
|
||||||
|
|
||||||
|
Info<< "loaded " << tables_.sortedToc()
|
||||||
|
<< " from etc/colourTable" << endl;
|
||||||
|
|
||||||
|
Info<< "== " << tables_ << nl;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const Foam::HashPtrTable<Foam::colourTable>& Foam::colourTable::tables()
|
||||||
|
{
|
||||||
|
if (tables_.empty())
|
||||||
|
{
|
||||||
|
constructTables();
|
||||||
|
}
|
||||||
|
|
||||||
|
return tables_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const Foam::colourTable* Foam::colourTable::ptr(const word& tableName)
|
||||||
|
{
|
||||||
|
if (tables_.empty())
|
||||||
|
{
|
||||||
|
constructTables();
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto iter = tables_.cfind(tableName);
|
||||||
|
|
||||||
|
if (iter.good())
|
||||||
|
{
|
||||||
|
const colourTable* p = iter.val();
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const Foam::colourTable* Foam::colourTable::ptr(const predefinedType tbl)
|
||||||
|
{
|
||||||
|
return ptr(predefinedNames[tbl]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const Foam::colourTable& Foam::colourTable::ref(const word& tableName)
|
||||||
|
{
|
||||||
|
const colourTable* p = ptr(tableName);
|
||||||
|
|
||||||
|
if (!p)
|
||||||
|
{
|
||||||
|
FatalErrorInFunction
|
||||||
|
<< "No such colourTable: " << tableName
|
||||||
|
<< exit(FatalError);
|
||||||
|
}
|
||||||
|
|
||||||
|
return *p;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const Foam::colourTable& Foam::colourTable::ref(const predefinedType tbl)
|
||||||
|
{
|
||||||
|
return ref(predefinedNames[tbl]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
501
src/fileFormats/colours/colourTools.C
Normal file
501
src/fileFormats/colours/colourTools.C
Normal file
@ -0,0 +1,501 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | Copyright (C) 2019 OpenCFD Ltd.
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
Note
|
||||||
|
Some implementation details from VTK vtkColorTransferFunction.cxx
|
||||||
|
vtkMath.cxx
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "colourTools.H"
|
||||||
|
#include "mathematicalConstants.H"
|
||||||
|
|
||||||
|
using namespace Foam::constant;
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
|
||||||
|
static constexpr scalar oneThird = 1.0 / 3.0;
|
||||||
|
static constexpr scalar oneSixth = 1.0 / 6.0;
|
||||||
|
static constexpr scalar twoThird = 2.0 / 3.0;
|
||||||
|
static constexpr scalar fiveSixth = 5.0 / 6.0;
|
||||||
|
|
||||||
|
|
||||||
|
// Compute HSV from RGB
|
||||||
|
static inline void RGB_to_HSV
|
||||||
|
(
|
||||||
|
const scalar r, const scalar g, const scalar b,
|
||||||
|
scalar& h, scalar& s, scalar& v
|
||||||
|
)
|
||||||
|
{
|
||||||
|
scalar cmin = r, cmax = r;
|
||||||
|
|
||||||
|
if (g > cmax)
|
||||||
|
{
|
||||||
|
cmax = g;
|
||||||
|
}
|
||||||
|
else if (g < cmin)
|
||||||
|
{
|
||||||
|
cmin = g;
|
||||||
|
}
|
||||||
|
if (b > cmax)
|
||||||
|
{
|
||||||
|
cmax = b;
|
||||||
|
}
|
||||||
|
else if (b < cmin)
|
||||||
|
{
|
||||||
|
cmin = b;
|
||||||
|
}
|
||||||
|
|
||||||
|
v = cmax;
|
||||||
|
s = (v > 0.0) ? ((cmax - cmin) / cmax) : 0.0;
|
||||||
|
|
||||||
|
if (s > 0.0)
|
||||||
|
{
|
||||||
|
if (r == cmax)
|
||||||
|
{
|
||||||
|
h = oneSixth * (g - b) / (cmax - cmin);
|
||||||
|
}
|
||||||
|
else if (g == cmax)
|
||||||
|
{
|
||||||
|
h = oneThird + oneSixth * (b - r) / (cmax - cmin);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
h = twoThird + oneSixth * (r - g) / (cmax - cmin);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (h < 0.0)
|
||||||
|
{
|
||||||
|
h += 1.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
h = 0.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Compute HSV to RGB
|
||||||
|
static inline void HSV_to_RGB
|
||||||
|
(
|
||||||
|
const scalar h, const scalar s, const scalar v,
|
||||||
|
scalar& r, scalar& g, scalar& b
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (h > oneSixth && h <= oneThird)
|
||||||
|
{
|
||||||
|
// green/red
|
||||||
|
g = 1.0;
|
||||||
|
r = (oneThird - h) / oneSixth;
|
||||||
|
b = 0.0;
|
||||||
|
}
|
||||||
|
else if (h > oneThird && h <= 0.5)
|
||||||
|
{
|
||||||
|
// green/blue
|
||||||
|
g = 1.0;
|
||||||
|
b = (h - oneThird) / oneSixth;
|
||||||
|
r = 0.0;
|
||||||
|
}
|
||||||
|
else if (h > 0.5 && h <= twoThird)
|
||||||
|
{
|
||||||
|
// blue/green
|
||||||
|
b = 1.0;
|
||||||
|
g = (twoThird - h) / oneSixth;
|
||||||
|
r = 0.0;
|
||||||
|
}
|
||||||
|
else if (h > twoThird && h <= fiveSixth)
|
||||||
|
{
|
||||||
|
// blue/red
|
||||||
|
b = 1.0;
|
||||||
|
r = (h - twoThird) / oneSixth;
|
||||||
|
g = 0.0;
|
||||||
|
}
|
||||||
|
else if (h > fiveSixth && h <= 1.0)
|
||||||
|
{
|
||||||
|
// red/blue
|
||||||
|
r = 1.0;
|
||||||
|
b = (1.0 - h) / oneSixth;
|
||||||
|
g = 0.0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// red/green
|
||||||
|
r = 1.0;
|
||||||
|
g = h / oneSixth;
|
||||||
|
b = 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add saturation
|
||||||
|
r = (s * r + (1.0 - s));
|
||||||
|
g = (s * g + (1.0 - s));
|
||||||
|
b = (s * b + (1.0 - s));
|
||||||
|
|
||||||
|
r *= v;
|
||||||
|
g *= v;
|
||||||
|
b *= v;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Intermediate calculation to XYZ
|
||||||
|
static inline scalar to_XYZ(scalar val)
|
||||||
|
{
|
||||||
|
const scalar p3 = pow3(val);
|
||||||
|
return (p3 > 0.008856 ? p3 : (val - 16.0 / 116.0) / 7.787);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Intermediate calculation from XYZ
|
||||||
|
static inline scalar from_XYZ(scalar val)
|
||||||
|
{
|
||||||
|
return (val > 0.008856) ? cbrt(val) : (7.787 * val) + (16.0 / 116.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Observer= 2 deg Illuminant= D65
|
||||||
|
static constexpr scalar ref_X = 0.9505;
|
||||||
|
static constexpr scalar ref_Y = 1.000;
|
||||||
|
static constexpr scalar ref_Z = 1.089;
|
||||||
|
|
||||||
|
static inline void LAB_to_XYZ
|
||||||
|
(
|
||||||
|
const scalar L, const scalar a, const scalar b,
|
||||||
|
scalar& x, scalar& y, scalar& z
|
||||||
|
)
|
||||||
|
{
|
||||||
|
const scalar var_Y = (L + 16.0) / 116.0;
|
||||||
|
const scalar var_X = a / 500 + var_Y;
|
||||||
|
const scalar var_Z = var_Y - b / 200;
|
||||||
|
|
||||||
|
x = ref_X * to_XYZ(var_X);
|
||||||
|
y = ref_Y * to_XYZ(var_Y);
|
||||||
|
z = ref_Z * to_XYZ(var_Z);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static inline void XYZ_to_LAB
|
||||||
|
(
|
||||||
|
const scalar x, const scalar y, const scalar z,
|
||||||
|
scalar& L, scalar& a, scalar& b
|
||||||
|
)
|
||||||
|
{
|
||||||
|
const scalar var_X = from_XYZ(x / ref_X);
|
||||||
|
const scalar var_Y = from_XYZ(y / ref_Y);
|
||||||
|
const scalar var_Z = from_XYZ(z / ref_Z);
|
||||||
|
|
||||||
|
L = (116 * var_Y) - 16;
|
||||||
|
a = 500 * (var_X - var_Y);
|
||||||
|
b = 200 * (var_Y - var_Z);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// "Gamma correction" specified by the sRGB color space.
|
||||||
|
|
||||||
|
static inline scalar gamma_from_xyz(const scalar val)
|
||||||
|
{
|
||||||
|
return
|
||||||
|
(
|
||||||
|
val > 0.0031308
|
||||||
|
? (1.055 * (pow(val, 1.0/2.4)) - 0.055)
|
||||||
|
: 12.92 * val
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static inline scalar gamma_to_xyz(const scalar val)
|
||||||
|
{
|
||||||
|
return
|
||||||
|
(
|
||||||
|
val > 0.04045
|
||||||
|
? (pow((val + 0.055) / 1.055, 2.4))
|
||||||
|
: val / 12.92
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static inline void XYZ_to_RGB
|
||||||
|
(
|
||||||
|
const scalar x, const scalar y, const scalar z,
|
||||||
|
scalar& r, scalar& g, scalar& b
|
||||||
|
)
|
||||||
|
{
|
||||||
|
r = gamma_from_xyz(x * 3.2406 + y * -1.5372 + z * -0.4986);
|
||||||
|
g = gamma_from_xyz(x * -0.9689 + y * 1.8758 + z * 0.0415);
|
||||||
|
b = gamma_from_xyz(x * 0.0557 + y * -0.2040 + z * 1.0570);
|
||||||
|
|
||||||
|
// Clip colour range
|
||||||
|
scalar cmax = r;
|
||||||
|
if (cmax < g) cmax = g;
|
||||||
|
if (cmax < b) cmax = b;
|
||||||
|
if (cmax > 1.0)
|
||||||
|
{
|
||||||
|
r /= cmax;
|
||||||
|
g /= cmax;
|
||||||
|
b /= cmax;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (r < 0) r = 0;
|
||||||
|
if (g < 0) g = 0;
|
||||||
|
if (b < 0) b = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static inline void RGB_to_XYZ
|
||||||
|
(
|
||||||
|
scalar r, scalar g, scalar b,
|
||||||
|
scalar& x, scalar& y, scalar& z
|
||||||
|
)
|
||||||
|
{
|
||||||
|
r = gamma_to_xyz(r);
|
||||||
|
g = gamma_to_xyz(g);
|
||||||
|
b = gamma_to_xyz(b);
|
||||||
|
|
||||||
|
x = r * 0.4124 + g * 0.3576 + b * 0.1805;
|
||||||
|
y = r * 0.2126 + g * 0.7152 + b * 0.0722;
|
||||||
|
z = r * 0.0193 + g * 0.1192 + b * 0.9505;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//- Convert to special polar version of CIELAB
|
||||||
|
// (for creating continuous diverging color maps).
|
||||||
|
inline void labToMsh(const vector& lab, vector& msh)
|
||||||
|
{
|
||||||
|
const scalar& L = lab[0];
|
||||||
|
const scalar& a = lab[1];
|
||||||
|
const scalar& b = lab[2];
|
||||||
|
|
||||||
|
msh[0] = sqrt(L*L + a*a + b*b);
|
||||||
|
msh[1] = (msh[0] > 0.001) ? acos(L / msh[0]) : 0.0;
|
||||||
|
msh[2] = (msh[1] > 0.001) ? atan2(b,a) : 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//- Convert from special polar version of CIELAB
|
||||||
|
inline void mshToLab(const vector& msh, vector& lab)
|
||||||
|
{
|
||||||
|
lab[0] = msh[0]*cos(msh[1]);
|
||||||
|
lab[1] = msh[0]*sin(msh[1])*cos(msh[2]);
|
||||||
|
lab[2] = msh[0]*sin(msh[1])*sin(msh[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Return the smallest angle between the two
|
||||||
|
static inline scalar angleDiff(scalar angle1, scalar angle2)
|
||||||
|
{
|
||||||
|
scalar adiff = angle1 - angle1;
|
||||||
|
if (adiff < 0.0) adiff = -adiff;
|
||||||
|
|
||||||
|
while (adiff >= mathematical::twoPi) adiff -= mathematical::twoPi;
|
||||||
|
if (adiff > mathematical::pi) adiff = (mathematical::twoPi - adiff);
|
||||||
|
return adiff;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// For the case when interpolating from a saturated color to an unsaturated
|
||||||
|
// color, find a hue for the unsaturated color that makes sense.
|
||||||
|
static inline scalar adjustHue(const vector& msh, scalar unsatM)
|
||||||
|
{
|
||||||
|
if (msh[0] >= unsatM - 0.1)
|
||||||
|
{
|
||||||
|
// The best we can do is hold hue constant.
|
||||||
|
return msh[2];
|
||||||
|
}
|
||||||
|
|
||||||
|
// This equation is designed to make the perceptual change of the
|
||||||
|
// interpolation to be close to constant.
|
||||||
|
const scalar hueSpin =
|
||||||
|
msh[1]*sqrt(unsatM*unsatM - msh[0]*msh[0]) / (msh[0]*sin(msh[1]));
|
||||||
|
|
||||||
|
// Spin hue away from 0 except in purple hues.
|
||||||
|
if (msh[2] > -0.3*mathematical::pi)
|
||||||
|
{
|
||||||
|
return msh[2] + hueSpin;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return msh[2] - hueSpin;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
void Foam::colourTools::rgbToHsv(const vector& rgb, vector& hsv)
|
||||||
|
{
|
||||||
|
RGB_to_HSV(rgb[0], rgb[1], rgb[2], hsv[0], hsv[1], hsv[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Foam::colourTools::hsvToRgb(const vector& hsv, vector& rgb)
|
||||||
|
{
|
||||||
|
HSV_to_RGB(hsv[0], hsv[1], hsv[2], rgb[0], rgb[1], rgb[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::colourTools::rgbToXyz(const vector& rgb, vector& xyz)
|
||||||
|
{
|
||||||
|
RGB_to_XYZ(rgb[0], rgb[1], rgb[2], xyz[0], xyz[1], xyz[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Foam::colourTools::xyzToRgb(const vector& xyz, vector& rgb)
|
||||||
|
{
|
||||||
|
XYZ_to_RGB(xyz[0], xyz[1], xyz[2], rgb[0], rgb[1], rgb[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::colourTools::labToXyz(const vector& lab, vector& xyz)
|
||||||
|
{
|
||||||
|
LAB_to_XYZ(lab[0], lab[1], lab[2], xyz[0], xyz[1], xyz[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::colourTools::xyzToLab(const vector& xyz, vector& lab)
|
||||||
|
{
|
||||||
|
XYZ_to_LAB(xyz[0], xyz[1], xyz[2], lab[0], lab[1], lab[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::colourTools::rgbToLab(const vector& rgb, vector& lab)
|
||||||
|
{
|
||||||
|
vector xyz;
|
||||||
|
RGB_to_XYZ(rgb[0], rgb[1], rgb[2], xyz[0], xyz[1], xyz[2]);
|
||||||
|
XYZ_to_LAB(xyz[0], xyz[1], xyz[2], lab[0], lab[1], lab[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::colourTools::labToRgb(const vector& lab, vector& rgb)
|
||||||
|
{
|
||||||
|
vector xyz;
|
||||||
|
labToXyz(lab, xyz);
|
||||||
|
xyzToRgb(xyz, rgb);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::colourTools::interpolateDiverging
|
||||||
|
(
|
||||||
|
scalar s,
|
||||||
|
const vector& rgb1,
|
||||||
|
const vector& rgb2,
|
||||||
|
vector& result
|
||||||
|
)
|
||||||
|
{
|
||||||
|
vector lab1, lab2;
|
||||||
|
rgbToLab(rgb1, lab1);
|
||||||
|
rgbToLab(rgb2, lab2);
|
||||||
|
|
||||||
|
vector msh1, msh2;
|
||||||
|
labToMsh(lab1, msh1);
|
||||||
|
labToMsh(lab2, msh2);
|
||||||
|
|
||||||
|
// If the endpoints are distinct saturated colors,
|
||||||
|
// then place white in between them.
|
||||||
|
if
|
||||||
|
(
|
||||||
|
msh1[1] > 0.05
|
||||||
|
&& msh2[1] > 0.05
|
||||||
|
&& angleDiff(msh1[2], msh2[2]) > mathematical::pi/3.0
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// Insert the white midpoint by setting one end to white and
|
||||||
|
// adjusting the scalar value.
|
||||||
|
|
||||||
|
scalar Mmid = std::max(msh1[0], msh2[0]);
|
||||||
|
Mmid = std::max(88.0, Mmid);
|
||||||
|
if (s < 0.5)
|
||||||
|
{
|
||||||
|
msh2[0] = Mmid; msh2[1] = 0; msh2[2] = 0;
|
||||||
|
s = 2.0*s;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
msh1[0] = Mmid; msh1[1] = 0; msh1[2] = 0;
|
||||||
|
s = 2.0*s - 1.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If one color has no saturation, then its hue value is invalid.
|
||||||
|
// In this case, we want to set it to something logical so the
|
||||||
|
// interpolation of hue makes sense.
|
||||||
|
if ((msh1[1] < 0.05) && (msh2[1] > 0.05))
|
||||||
|
{
|
||||||
|
msh1[2] = adjustHue(msh2, msh1[0]);
|
||||||
|
}
|
||||||
|
else if ((msh2[1] < 0.05) && (msh1[1] > 0.05))
|
||||||
|
{
|
||||||
|
msh2[2] = adjustHue(msh1, msh2[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Msh tmp
|
||||||
|
vector mshTmp((1-s)*msh1 + s*msh2);
|
||||||
|
|
||||||
|
// Convert back to RGB
|
||||||
|
vector lab;
|
||||||
|
mshToLab(mshTmp, lab);
|
||||||
|
labToRgb(lab, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::colourTools::interpolateHSV
|
||||||
|
(
|
||||||
|
scalar s,
|
||||||
|
const vector& rgb1,
|
||||||
|
const vector& rgb2,
|
||||||
|
vector& result
|
||||||
|
)
|
||||||
|
{
|
||||||
|
vector hsv1, hsv2;
|
||||||
|
rgbToHsv(rgb1, hsv1);
|
||||||
|
rgbToHsv(rgb2, hsv2);
|
||||||
|
|
||||||
|
// Wrap HSV?
|
||||||
|
if (hsv1[0] - hsv2[0] > 0.5 || hsv2[0] - hsv1[0] > 0.5)
|
||||||
|
{
|
||||||
|
if (hsv1[0] > hsv2[0])
|
||||||
|
{
|
||||||
|
hsv1[0] -= 1.0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
hsv2[0] -= 1.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
vector hsvTmp((1-s)*hsv1 + s*hsv2);
|
||||||
|
|
||||||
|
if (hsvTmp[0] < 0.0)
|
||||||
|
{
|
||||||
|
hsvTmp[0] += 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert back to RGB
|
||||||
|
hsvToRgb(hsvTmp, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
214
src/fileFormats/colours/colourTools.H
Normal file
214
src/fileFormats/colours/colourTools.H
Normal file
@ -0,0 +1,214 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | Copyright (C) 2019 OpenCFD Ltd.
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
Namespace
|
||||||
|
Foam::colourTools
|
||||||
|
|
||||||
|
Description
|
||||||
|
Utility methods for colours and colour spaces
|
||||||
|
|
||||||
|
SourceFiles
|
||||||
|
colourTools.C
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef colourTools_H
|
||||||
|
#define colourTools_H
|
||||||
|
|
||||||
|
#include "vector.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
namespace colourTools
|
||||||
|
{
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
Namespace colourTools
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
//- Convert RGB to HSV
|
||||||
|
void rgbToHsv(const vector& rgb, vector& hsv);
|
||||||
|
|
||||||
|
//- Convert RGB to HSV
|
||||||
|
inline vector rgbToHsv(const vector& rgb)
|
||||||
|
{
|
||||||
|
vector hsv;
|
||||||
|
rgbToHsv(rgb, hsv);
|
||||||
|
return hsv;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//- Convert HSV to RGB
|
||||||
|
void hsvToRgb(const vector& hsv, vector& rgb);
|
||||||
|
|
||||||
|
//- Convert HSV to RGB
|
||||||
|
inline vector hsvToRgb(const vector& hsv)
|
||||||
|
{
|
||||||
|
vector rgb;
|
||||||
|
hsvToRgb(hsv, rgb);
|
||||||
|
return rgb;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//- Convert RGB to XYZ
|
||||||
|
void rgbToXyz(const vector& rgb, vector& xyz);
|
||||||
|
|
||||||
|
//- Convert RGB to XYZ
|
||||||
|
inline vector rgbToXyz(const vector& rgb)
|
||||||
|
{
|
||||||
|
vector xyz;
|
||||||
|
rgbToXyz(rgb, xyz);
|
||||||
|
return xyz;
|
||||||
|
}
|
||||||
|
|
||||||
|
//- Convert XYZ to RGB
|
||||||
|
void xyzToRgb(const vector& xyz, vector& rgb);
|
||||||
|
|
||||||
|
//- Convert XYZ to RGB
|
||||||
|
inline vector xyzToRgb(const vector& xyz)
|
||||||
|
{
|
||||||
|
vector rgb;
|
||||||
|
xyzToRgb(xyz, rgb);
|
||||||
|
return rgb;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//- Convert LAB to XYZ
|
||||||
|
void labToXyz(const vector& lab, vector& xyz);
|
||||||
|
|
||||||
|
//- Convert LAB to XYZ
|
||||||
|
inline vector labToXyz(const vector& lab)
|
||||||
|
{
|
||||||
|
vector xyz;
|
||||||
|
labToXyz(lab, xyz);
|
||||||
|
return xyz;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//- Convert XYZ to LAB
|
||||||
|
void xyzToLab(const vector& xyz, vector& lab);
|
||||||
|
|
||||||
|
//- Convert XYZ to LAB
|
||||||
|
inline vector xyzToLab(const vector& xyz)
|
||||||
|
{
|
||||||
|
vector lab;
|
||||||
|
xyzToLab(xyz, lab);
|
||||||
|
return lab;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//- Convert RGB to LAB
|
||||||
|
void rgbToLab(const vector& rgb, vector& lab);
|
||||||
|
|
||||||
|
//- Convert RGB to LAB
|
||||||
|
inline vector rgbToLab(const vector& rgb)
|
||||||
|
{
|
||||||
|
vector lab;
|
||||||
|
rgbToLab(rgb, lab);
|
||||||
|
return lab;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//- Convert LAB to RGB
|
||||||
|
void labToRgb(const vector& lab, vector& rgb);
|
||||||
|
|
||||||
|
//- Convert LAB to RGB
|
||||||
|
inline vector labToRgb(const vector& lab)
|
||||||
|
{
|
||||||
|
vector rgb;
|
||||||
|
labToRgb(lab, rgb);
|
||||||
|
return rgb;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//- Interpolate RGB values with diverging color map
|
||||||
|
void interpolateDiverging
|
||||||
|
(
|
||||||
|
scalar s,
|
||||||
|
const vector& rgb1,
|
||||||
|
const vector& rgb2,
|
||||||
|
vector& result
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Interpolate RGB values with diverging color map
|
||||||
|
inline vector interpolateDiverging
|
||||||
|
(
|
||||||
|
scalar s,
|
||||||
|
const vector& rgb1,
|
||||||
|
const vector& rgb2
|
||||||
|
)
|
||||||
|
{
|
||||||
|
vector result;
|
||||||
|
interpolateDiverging(s, rgb1, rgb2, result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//- Interpolate RGB values in HSV colourspace
|
||||||
|
void interpolateHSV
|
||||||
|
(
|
||||||
|
scalar s,
|
||||||
|
const vector& rgb1,
|
||||||
|
const vector& rgb2,
|
||||||
|
vector& result
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Interpolate RGB values in HSV colourspace
|
||||||
|
inline vector interpolateHSV
|
||||||
|
(
|
||||||
|
scalar s,
|
||||||
|
const vector& rgb1,
|
||||||
|
const vector& rgb2
|
||||||
|
)
|
||||||
|
{
|
||||||
|
vector result;
|
||||||
|
interpolateHSV(s, rgb1, rgb2, result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//- Interpolate RGB values in RGB colourspace
|
||||||
|
inline vector interpolateRGB
|
||||||
|
(
|
||||||
|
scalar s,
|
||||||
|
const vector& rgb1,
|
||||||
|
const vector& rgb2
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return ((1-s)*rgb1 + s*rgb2);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace colourTools
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -70,7 +70,7 @@ $(writers)/proxy/proxySurfaceWriter.C
|
|||||||
$(writers)/raw/rawSurfaceWriter.C
|
$(writers)/raw/rawSurfaceWriter.C
|
||||||
$(writers)/starcd/starcdSurfaceWriter.C
|
$(writers)/starcd/starcdSurfaceWriter.C
|
||||||
$(writers)/vtk/vtkSurfaceWriter.C
|
$(writers)/vtk/vtkSurfaceWriter.C
|
||||||
/* $(writers)/x3d/x3dSurfaceWriter.C */
|
$(writers)/x3d/x3dSurfaceWriter.C
|
||||||
|
|
||||||
|
|
||||||
LIB = $(FOAM_LIBBIN)/libsurfMesh
|
LIB = $(FOAM_LIBBIN)/libsurfMesh
|
||||||
|
|||||||
@ -61,14 +61,9 @@ void Foam::fileFormats::X3DsurfaceFormat<Face>::write
|
|||||||
}
|
}
|
||||||
|
|
||||||
writeHeader(os);
|
writeHeader(os);
|
||||||
|
beginGroup(os);
|
||||||
os << "\n"
|
|
||||||
"<Group>\n"
|
|
||||||
" <Shape>\n";
|
|
||||||
|
|
||||||
writeAppearance(os);
|
writeAppearance(os);
|
||||||
|
|
||||||
|
|
||||||
// NOTE: we could provide an optimized IndexedTriangleSet output for
|
// NOTE: we could provide an optimized IndexedTriangleSet output for
|
||||||
// triangulated surfaces too
|
// triangulated surfaces too
|
||||||
|
|
||||||
@ -109,20 +104,15 @@ void Foam::fileFormats::X3DsurfaceFormat<Face>::write
|
|||||||
}
|
}
|
||||||
|
|
||||||
os <<
|
os <<
|
||||||
"' >\n"
|
"' >\n";
|
||||||
" <Coordinate point='\n";
|
|
||||||
|
|
||||||
for (const point& p : pointLst)
|
writePoints(os, pointLst);
|
||||||
{
|
|
||||||
os << p.x() << ' ' << p.y() << ' ' << p.z() << nl;
|
|
||||||
}
|
|
||||||
|
|
||||||
os <<
|
os <<
|
||||||
"' />\n" // end Coordinate
|
" </IndexedFaceSet>\n";
|
||||||
" </IndexedFaceSet>\n"
|
|
||||||
" </Shape>\n"
|
endGroup(os);
|
||||||
" </Group>\n"
|
writeFooter(os);
|
||||||
"</X3D>\n";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
========= |
|
========= |
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
\\ / O peration |
|
\\ / O peration |
|
||||||
\\ / A nd |
|
\\ / A nd | Copyright (C) 2019 OpenCFD Ltd.
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
| Copyright (C) 2011-2016 OpenFOAM Foundation
|
| Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||||
@ -26,7 +26,7 @@ License
|
|||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#include "X3DsurfaceFormatCore.H"
|
#include "X3DsurfaceFormatCore.H"
|
||||||
#include "clock.H"
|
#include "Ostream.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
|
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
@ -49,6 +49,38 @@ void Foam::fileFormats::X3DsurfaceFormatCore::writeHeader
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::fileFormats::X3DsurfaceFormatCore::writeFooter
|
||||||
|
(
|
||||||
|
Ostream& os
|
||||||
|
)
|
||||||
|
{
|
||||||
|
os <<
|
||||||
|
"</X3D>\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::fileFormats::X3DsurfaceFormatCore::beginGroup
|
||||||
|
(
|
||||||
|
Ostream& os
|
||||||
|
)
|
||||||
|
{
|
||||||
|
os <<
|
||||||
|
"<Group>\n"
|
||||||
|
" <Shape>\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::fileFormats::X3DsurfaceFormatCore::endGroup
|
||||||
|
(
|
||||||
|
Ostream& os
|
||||||
|
)
|
||||||
|
{
|
||||||
|
os <<
|
||||||
|
" </Shape>\n"
|
||||||
|
" </Group>\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Foam::fileFormats::X3DsurfaceFormatCore::writeAppearance
|
void Foam::fileFormats::X3DsurfaceFormatCore::writeAppearance
|
||||||
(
|
(
|
||||||
Ostream& os
|
Ostream& os
|
||||||
@ -57,13 +89,34 @@ void Foam::fileFormats::X3DsurfaceFormatCore::writeAppearance
|
|||||||
os <<
|
os <<
|
||||||
" <Appearance>\n"
|
" <Appearance>\n"
|
||||||
" <Material"
|
" <Material"
|
||||||
" diffuseColor='0.8 0.8 0.8'"
|
" ambientIntensity='0'"
|
||||||
" specularColor='1.0 1.0 1.0'"
|
" diffuseColor='1 1 1'" // Default: '0.8 0.8 0.8'
|
||||||
" shininess='0.5'"
|
// Default: " emissiveColor='0 0 0'"
|
||||||
" transparency='0.0'"
|
// Default: " specularColor='0 0 0'"
|
||||||
" />\n" // end material
|
" shininess='0.8'" // Default: 0.2
|
||||||
|
" transparency='0'"
|
||||||
|
" />\n" // Material
|
||||||
" </Appearance>\n";
|
" </Appearance>\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::fileFormats::X3DsurfaceFormatCore::writePoints
|
||||||
|
(
|
||||||
|
Ostream& os,
|
||||||
|
const UList<point>& pts
|
||||||
|
)
|
||||||
|
{
|
||||||
|
os <<
|
||||||
|
" <Coordinate point='\n";
|
||||||
|
|
||||||
|
for (const point& p : pts)
|
||||||
|
{
|
||||||
|
os << p.x() << ' ' << p.y() << ' ' << p.z() << ',' << nl;
|
||||||
|
}
|
||||||
|
|
||||||
|
os <<
|
||||||
|
"' />\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
// ************************************************************************* //
|
||||||
|
|||||||
@ -37,7 +37,7 @@ SourceFiles
|
|||||||
#ifndef X3DsurfaceFormatCore_H
|
#ifndef X3DsurfaceFormatCore_H
|
||||||
#define X3DsurfaceFormatCore_H
|
#define X3DsurfaceFormatCore_H
|
||||||
|
|
||||||
#include "Ostream.H"
|
#include "pointField.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
@ -59,9 +59,20 @@ protected:
|
|||||||
//- Write file header
|
//- Write file header
|
||||||
static void writeHeader(Ostream& os);
|
static void writeHeader(Ostream& os);
|
||||||
|
|
||||||
|
//- Write file header
|
||||||
|
static void writeFooter(Ostream& os);
|
||||||
|
|
||||||
|
//- Begin Group/Shape node
|
||||||
|
static void beginGroup(Ostream& os);
|
||||||
|
|
||||||
|
//- End Group/Shape node
|
||||||
|
static void endGroup(Ostream& os);
|
||||||
|
|
||||||
//- Write appearance node
|
//- Write appearance node
|
||||||
static void writeAppearance(Ostream& os);
|
static void writeAppearance(Ostream& os);
|
||||||
|
|
||||||
|
//- Write points (Coordinate)
|
||||||
|
static void writePoints(Ostream& os, const UList<point>& pts);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
342
src/surfMesh/writers/x3d/x3dSurfaceWriter.C
Normal file
342
src/surfMesh/writers/x3d/x3dSurfaceWriter.C
Normal file
@ -0,0 +1,342 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | Copyright (C) 2019 OpenCFD Ltd.
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "x3dSurfaceWriter.H"
|
||||||
|
#include "OFstream.H"
|
||||||
|
#include "OSspecific.H"
|
||||||
|
#include "MeshedSurfaceProxy.H"
|
||||||
|
#include "surfaceWriterMethods.H"
|
||||||
|
#include "addToRunTimeSelectionTable.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
namespace surfaceWriters
|
||||||
|
{
|
||||||
|
defineTypeName(x3dWriter);
|
||||||
|
addToRunTimeSelectionTable(surfaceWriter, x3dWriter, word);
|
||||||
|
addToRunTimeSelectionTable(surfaceWriter, x3dWriter, wordDict);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
|
||||||
|
//- A (0-1) range for colouring
|
||||||
|
template<class Type>
|
||||||
|
static inline scalar rangex(const scalarMinMax& range, const Type& val)
|
||||||
|
{
|
||||||
|
scalar x = Foam::mag(val);
|
||||||
|
|
||||||
|
return (x - range.min()) / (range.max() - range.min());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//- A (0-1) range for colouring
|
||||||
|
template<>
|
||||||
|
inline scalar rangex(const scalarMinMax& range, const scalar& val)
|
||||||
|
{
|
||||||
|
scalar x = val;
|
||||||
|
return (x - range.min()) / (range.max() - range.min());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//- A (0-1) range for colouring
|
||||||
|
template<>
|
||||||
|
inline scalar rangex(const scalarMinMax& range, const label& val)
|
||||||
|
{
|
||||||
|
scalar x = val;
|
||||||
|
return (x - range.min()) / (range.max() - range.min());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static inline void printColour(Ostream& os, const vector& rgb)
|
||||||
|
{
|
||||||
|
os << rgb[0] << ' ' << rgb[1] << ' ' << rgb[2] << ',' << nl;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::surfaceWriters::x3dWriter::x3dWriter()
|
||||||
|
:
|
||||||
|
surfaceWriter(),
|
||||||
|
range_(),
|
||||||
|
colourTablePtr_(nullptr)
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::surfaceWriters::x3dWriter::x3dWriter
|
||||||
|
(
|
||||||
|
const dictionary& options
|
||||||
|
)
|
||||||
|
:
|
||||||
|
surfaceWriter(options),
|
||||||
|
range_(),
|
||||||
|
colourTablePtr_(nullptr)
|
||||||
|
{
|
||||||
|
verbose_ = true;
|
||||||
|
|
||||||
|
options.readIfPresent("range", range_);
|
||||||
|
|
||||||
|
word tableName;
|
||||||
|
if (options.readIfPresent("colourMap", tableName))
|
||||||
|
{
|
||||||
|
colourTablePtr_ = colourTable::ptr(tableName);
|
||||||
|
if (!colourTablePtr_)
|
||||||
|
{
|
||||||
|
WarningInFunction
|
||||||
|
<< "No colourMap " << tableName << " using default" << nl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!colourTablePtr_)
|
||||||
|
{
|
||||||
|
tableName = colourTable::predefinedNames[colourTable::COOL_WARM];
|
||||||
|
colourTablePtr_ = colourTable::ptr(colourTable::COOL_WARM);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (verbose_)
|
||||||
|
{
|
||||||
|
Info<< "X3D with colourMap '" << tableName << "' and range ";
|
||||||
|
|
||||||
|
if (range_.valid())
|
||||||
|
{
|
||||||
|
Info<< range_;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Info<< "auto";
|
||||||
|
}
|
||||||
|
Info<< nl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::surfaceWriters::x3dWriter::x3dWriter
|
||||||
|
(
|
||||||
|
const meshedSurf& surf,
|
||||||
|
const fileName& outputPath,
|
||||||
|
bool parallel,
|
||||||
|
const dictionary& options
|
||||||
|
)
|
||||||
|
:
|
||||||
|
x3dWriter(options)
|
||||||
|
{
|
||||||
|
open(surf, outputPath, parallel);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::surfaceWriters::x3dWriter::x3dWriter
|
||||||
|
(
|
||||||
|
const pointField& points,
|
||||||
|
const faceList& faces,
|
||||||
|
const fileName& outputPath,
|
||||||
|
bool parallel,
|
||||||
|
const dictionary& options
|
||||||
|
)
|
||||||
|
:
|
||||||
|
x3dWriter(options)
|
||||||
|
{
|
||||||
|
open(points, faces, outputPath, parallel);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::fileName Foam::surfaceWriters::x3dWriter::write()
|
||||||
|
{
|
||||||
|
checkOpen();
|
||||||
|
|
||||||
|
// Geometry: rootdir/<TIME>/surfaceName.x3d
|
||||||
|
|
||||||
|
fileName outputFile = outputPath_;
|
||||||
|
if (useTimeDir() && !timeName().empty())
|
||||||
|
{
|
||||||
|
// Splice in time-directory
|
||||||
|
outputFile = outputPath_.path() / timeName() / outputPath_.name();
|
||||||
|
}
|
||||||
|
outputFile.ext("x3d");
|
||||||
|
|
||||||
|
if (verbose_)
|
||||||
|
{
|
||||||
|
Info<< "Writing geometry to " << outputFile << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
const meshedSurf& surf = surface();
|
||||||
|
|
||||||
|
if (Pstream::master() || !parallel_)
|
||||||
|
{
|
||||||
|
if (!isDir(outputFile.path()))
|
||||||
|
{
|
||||||
|
mkDir(outputFile.path());
|
||||||
|
}
|
||||||
|
|
||||||
|
MeshedSurfaceProxy<face>
|
||||||
|
(
|
||||||
|
surf.points(),
|
||||||
|
surf.faces()
|
||||||
|
).write(outputFile, "x3d");
|
||||||
|
}
|
||||||
|
|
||||||
|
wroteGeom_ = true;
|
||||||
|
return outputFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
Foam::fileName Foam::surfaceWriters::x3dWriter::writeTemplate
|
||||||
|
(
|
||||||
|
const word& fieldName,
|
||||||
|
const Field<Type>& localValues
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (!colourTablePtr_)
|
||||||
|
{
|
||||||
|
// Write geometry only if there are no colours to use
|
||||||
|
WarningInFunction
|
||||||
|
<< "No output colours set" << endl;
|
||||||
|
|
||||||
|
return this->write();
|
||||||
|
}
|
||||||
|
|
||||||
|
checkOpen();
|
||||||
|
|
||||||
|
// Field: rootdir/<TIME>/<field>_surfaceName.x3d
|
||||||
|
|
||||||
|
fileName outputFile = outputPath_.path();
|
||||||
|
if (useTimeDir() && !timeName().empty())
|
||||||
|
{
|
||||||
|
// Splice in time-directory
|
||||||
|
outputFile /= timeName();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Append <field>_surfaceName.usr
|
||||||
|
outputFile /= fieldName + '_' + outputPath_.name();
|
||||||
|
outputFile.ext("x3d");
|
||||||
|
|
||||||
|
if (verbose_)
|
||||||
|
{
|
||||||
|
Info<< "Writing field " << fieldName << " to " << outputFile << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
const meshedSurf& surf = surface();
|
||||||
|
|
||||||
|
// geometry merge() implicit
|
||||||
|
tmp<Field<Type>> tfield = mergeField(localValues);
|
||||||
|
|
||||||
|
if (Pstream::master() || !parallel_)
|
||||||
|
{
|
||||||
|
const auto& values = tfield();
|
||||||
|
|
||||||
|
scalarMinMax range(range_);
|
||||||
|
|
||||||
|
if (!range.valid())
|
||||||
|
{
|
||||||
|
range = minMaxMag(values);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isDir(outputFile.path()))
|
||||||
|
{
|
||||||
|
mkDir(outputFile.path());
|
||||||
|
}
|
||||||
|
|
||||||
|
OFstream os(outputFile);
|
||||||
|
|
||||||
|
writeHeader(os);
|
||||||
|
beginGroup(os);
|
||||||
|
writeAppearance(os);
|
||||||
|
|
||||||
|
// For point field: "colorPerVetex=true"
|
||||||
|
os << " <IndexedFaceSet"
|
||||||
|
<< " colorPerVertex='" << Switch(this->isPointData()) << "'"
|
||||||
|
<< " coordIndex='" << nl;
|
||||||
|
|
||||||
|
for (const auto& f : surf.faces())
|
||||||
|
{
|
||||||
|
for (const label vrti : f)
|
||||||
|
{
|
||||||
|
os << vrti << ' ';
|
||||||
|
}
|
||||||
|
os << "-1\n";
|
||||||
|
}
|
||||||
|
os << "'";
|
||||||
|
|
||||||
|
// Colour indices for face fields
|
||||||
|
if (!this->isPointData())
|
||||||
|
{
|
||||||
|
const label nFaces = surf.faces().size();
|
||||||
|
|
||||||
|
os << " colorIndex='";
|
||||||
|
|
||||||
|
for (label i=0; i < nFaces; ++i)
|
||||||
|
{
|
||||||
|
os << i << ' ';
|
||||||
|
}
|
||||||
|
os << "'";
|
||||||
|
}
|
||||||
|
|
||||||
|
os << " >\n"; // IndexedFaceSet
|
||||||
|
|
||||||
|
writePoints(os, surf.points());
|
||||||
|
|
||||||
|
os << "<Color color='" << nl;
|
||||||
|
|
||||||
|
// writeColours(os, values, range, colorBar);
|
||||||
|
|
||||||
|
for (const Type& val : values)
|
||||||
|
{
|
||||||
|
const scalar x = rangex(range, val);
|
||||||
|
vector rgb = colourTablePtr_->value(x);
|
||||||
|
printColour(os, rgb);
|
||||||
|
}
|
||||||
|
|
||||||
|
os << "' />" << nl; // Color
|
||||||
|
|
||||||
|
os <<
|
||||||
|
" </IndexedFaceSet>\n";
|
||||||
|
|
||||||
|
endGroup(os);
|
||||||
|
writeFooter(os);
|
||||||
|
}
|
||||||
|
|
||||||
|
wroteGeom_ = true;
|
||||||
|
return outputFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Field writing methods
|
||||||
|
defineSurfaceWriterWriteFields(Foam::surfaceWriters::x3dWriter);
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
169
src/surfMesh/writers/x3d/x3dSurfaceWriter.H
Normal file
169
src/surfMesh/writers/x3d/x3dSurfaceWriter.H
Normal file
@ -0,0 +1,169 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | Copyright (C) 2019 OpenCFD Ltd.
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
Class
|
||||||
|
Foam::surfaceWriters::x3dWriter
|
||||||
|
|
||||||
|
Description
|
||||||
|
A surfaceWriter for X3D files.
|
||||||
|
|
||||||
|
The formatOptions for x3d:
|
||||||
|
\table
|
||||||
|
Property | Description | Required | Default
|
||||||
|
range | The min/max range for colour table | no | automatic
|
||||||
|
colourMap | The colour map for rendering | no | coolToWarm
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
\heading Output file locations
|
||||||
|
|
||||||
|
The \c rootdir normally corresponds to something like
|
||||||
|
\c postProcessing/\<name\>
|
||||||
|
|
||||||
|
\subheading Geometry
|
||||||
|
\verbatim
|
||||||
|
rootdir
|
||||||
|
`-- timeName
|
||||||
|
`-- surfaceName.x3d
|
||||||
|
\endverbatim
|
||||||
|
|
||||||
|
\subheading Fields
|
||||||
|
\verbatim
|
||||||
|
rootdir
|
||||||
|
`-- timeName
|
||||||
|
|-- <field0>_surfaceName.x3d
|
||||||
|
`-- <field1>_surfaceName.x3d
|
||||||
|
\endverbatim
|
||||||
|
|
||||||
|
SourceFiles
|
||||||
|
x3dSurfaceWriter.C
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef x3dSurfaceWriter_H
|
||||||
|
#define x3dSurfaceWriter_H
|
||||||
|
|
||||||
|
#include "surfaceWriter.H"
|
||||||
|
#include "X3DsurfaceFormatCore.H"
|
||||||
|
#include "colourTable.H"
|
||||||
|
#include "MinMax.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
namespace surfaceWriters
|
||||||
|
{
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
Class x3dWriter Declaration
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
class x3dWriter
|
||||||
|
:
|
||||||
|
public surfaceWriter,
|
||||||
|
protected fileFormats::X3DsurfaceFormatCore
|
||||||
|
{
|
||||||
|
// Private Data
|
||||||
|
|
||||||
|
//- Range of values
|
||||||
|
// The lower/upper limits for the colour table output
|
||||||
|
// Undefined means calculate from the data
|
||||||
|
scalarMinMax range_;
|
||||||
|
|
||||||
|
//- Selected colour table
|
||||||
|
const colourTable* colourTablePtr_;
|
||||||
|
|
||||||
|
|
||||||
|
// Private Member Functions
|
||||||
|
|
||||||
|
//- Templated write operation
|
||||||
|
template<class Type>
|
||||||
|
fileName writeTemplate
|
||||||
|
(
|
||||||
|
const word& fieldName, //!< Name of field
|
||||||
|
const Field<Type>& localValues //!< Local field values to write
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
//- Runtime type information
|
||||||
|
TypeNameNoDebug("x3d");
|
||||||
|
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
|
||||||
|
//- Construct null
|
||||||
|
x3dWriter();
|
||||||
|
|
||||||
|
//- Construct with some output options
|
||||||
|
explicit x3dWriter(const dictionary& options);
|
||||||
|
|
||||||
|
//- Construct from components
|
||||||
|
x3dWriter
|
||||||
|
(
|
||||||
|
const meshedSurf& surf,
|
||||||
|
const fileName& outputPath,
|
||||||
|
bool parallel = Pstream::parRun(),
|
||||||
|
const dictionary& options = dictionary()
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Construct from components
|
||||||
|
x3dWriter
|
||||||
|
(
|
||||||
|
const pointField& points,
|
||||||
|
const faceList& faces,
|
||||||
|
const fileName& outputPath,
|
||||||
|
bool parallel = Pstream::parRun(),
|
||||||
|
const dictionary& options = dictionary()
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
//- Destructor
|
||||||
|
virtual ~x3dWriter() = default;
|
||||||
|
|
||||||
|
|
||||||
|
// Member Functions
|
||||||
|
|
||||||
|
//- Write surface geometry to file.
|
||||||
|
virtual fileName write(); // override
|
||||||
|
|
||||||
|
declareSurfaceWriterWriteMethod(label);
|
||||||
|
declareSurfaceWriterWriteMethod(scalar);
|
||||||
|
declareSurfaceWriterWriteMethod(vector);
|
||||||
|
declareSurfaceWriterWriteMethod(sphericalTensor);
|
||||||
|
declareSurfaceWriterWriteMethod(symmTensor);
|
||||||
|
declareSurfaceWriterWriteMethod(tensor);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace surfaceWriters
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
Reference in New Issue
Block a user