Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
campvis-public
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Locked Files
Issues
9
Issues
9
List
Boards
Labels
Service Desk
Milestones
Iterations
Merge Requests
1
Merge Requests
1
Requirements
Requirements
List
Security & Compliance
Security & Compliance
Dependency List
License Compliance
Operations
Operations
Incidents
Analytics
Analytics
Code Review
Insights
Issue
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
CAMP
campvis-public
Commits
eb24cfdd
Commit
eb24cfdd
authored
Dec 15, 2017
by
Jakob Weiss
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Basic files for Visualization assignment
parent
5889d2b8
Changes
12
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
999 additions
and
0 deletions
+999
-0
modules/cppcourse/cppcourse.cmake
modules/cppcourse/cppcourse.cmake
+37
-0
modules/cppcourse/cppcourse.cpp
modules/cppcourse/cppcourse.cpp
+13
-0
modules/cppcourse/glsl/verysimpleraycaster.frag
modules/cppcourse/glsl/verysimpleraycaster.frag
+144
-0
modules/cppcourse/pipelines/cppcourse.cpp
modules/cppcourse/pipelines/cppcourse.cpp
+3
-0
modules/cppcourse/pipelines/cppcourse.h
modules/cppcourse/pipelines/cppcourse.h
+3
-0
modules/cppcourse/processors/EDFhandler.cpp
modules/cppcourse/processors/EDFhandler.cpp
+233
-0
modules/cppcourse/processors/EDFhandler.h
modules/cppcourse/processors/EDFhandler.h
+33
-0
modules/cppcourse/processors/IOutilities.h
modules/cppcourse/processors/IOutilities.h
+313
-0
modules/cppcourse/processors/verysimpleraycaster.cpp
modules/cppcourse/processors/verysimpleraycaster.cpp
+102
-0
modules/cppcourse/processors/verysimpleraycaster.h
modules/cppcourse/processors/verysimpleraycaster.h
+60
-0
modules/cppcourse/processors/volume.cpp
modules/cppcourse/processors/volume.cpp
+29
-0
modules/cppcourse/processors/volume.h
modules/cppcourse/processors/volume.h
+29
-0
No files found.
modules/cppcourse/cppcourse.cmake
0 → 100644
View file @
eb24cfdd
# modules/cppcourse/cppcourse.cmake
# CMake file for the Module for the Cpp Course in WS 17
# Set module status (valid values are STABLE, TESTING and EXPERIMENTAL)
SET
(
ThisModStatus EXPERIMENTAL
)
# Set whether this module has external dependencies that are not shipped with CAMPVis.
SET
(
ThisModExternalDependencies TRUE
)
# The files and assignments need only to be parsed if the module is enabled
IF
(
ModuleEnabled
)
# Source files:
FILE
(
GLOB ThisModSources RELATIVE
${
ModulesDir
}
modules/cppcourse/pipelines/*.cpp
modules/cppcourse/processors/*.cpp
modules/cppcourse/datastructures/*.cpp
modules/cppcourse/properties/*.cpp
modules/cppcourse/*.cpp
)
# Header files (including GLSL files so that they'll appear in VS projects)
FILE
(
GLOB ThisModHeaders RELATIVE
${
ModulesDir
}
modules/cppcourse/glsl/*.frag
modules/cppcourse/glsl/*.geom
modules/cppcourse/glsl/*.vert
modules/cppcourse/pipelines/*.h
modules/cppcourse/processors/*.h
modules/cppcourse/datastructures/*.h
modules/cppcourse/properties/*.h
)
# Define the GLSL shader path, so that all needed shaders will be deployed to target directory
SET
(
ThisModShaderDirectories
"modules/cppcourse/glsl"
)
# Define dependency modules (the pipelines in the vis modules use processors from io)
#SET(ThisModDependencies io)
ENDIF
(
ModuleEnabled
)
modules/cppcourse/cppcourse.cpp
0 → 100644
View file @
eb24cfdd
#include "core/pipeline/pipelinefactory.h"
#include "core/pipeline/processorfactory.h"
#include "modules/cppcourse/pipelines/cppcourse.h"
#include "modules/cppcourse/processors/verysimpleraycaster.h"
namespace
campvis
{
// explicitly instantiate templates to register the pipelines to make them available in the prototyping GUI
//template class PipelineRegistrar<CPPCourse>;
template
class
SmartProcessorRegistrar
<
VerySimpleRaycaster
>;
}
modules/cppcourse/glsl/verysimpleraycaster.frag
0 → 100644
View file @
eb24cfdd
// ================================================================================================
//
// This file is part of the CAMPVis Software Framework.
//
// If not explicitly stated otherwise: Copyright (C) 2012-2015, all rights reserved,
// Christian Schulte zu Berge <christian.szb@in.tum.de>
// Chair for Computer Aided Medical Procedures
// Technische Universitaet Muenchen
// Boltzmannstr. 3, 85748 Garching b. Muenchen, Germany
//
// For a full list of authors and contributors, please refer to the file "AUTHORS.txt".
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
// except in compliance with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software distributed under the
// License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// either express or implied. See the License for the specific language governing permissions
// and limitations under the License.
//
// ================================================================================================
layout
(
location
=
0
)
out
vec4
FragData0
;
///< outgoing fragment color
#include "tools/gradient.frag"
#include "tools/raycasting.frag"
#include "tools/shading.frag"
#include "tools/texture2d.frag"
#include "tools/texture3d.frag"
#include "tools/transferfunction.frag"
uniform
vec2
_viewportSizeRCP
;
uniform
float
_jitterStepSizeMultiplier
;
// ray entry points
uniform
sampler2D
_entryPoints
;
uniform
sampler2D
_entryPointsDepth
;
uniform
TextureParameters2D
_entryParams
;
// ray exit points
uniform
sampler2D
_exitPoints
;
uniform
sampler2D
_exitPointsDepth
;
uniform
TextureParameters2D
_exitParams
;
// DVR volume
uniform
sampler3D
_volume
;
uniform
TextureParameters3D
_volumeTextureParams
;
// Transfer function
uniform
sampler1D
_transferFunction
;
uniform
TFParameters1D
_transferFunctionParams
;
uniform
LightSource
_lightSource
;
uniform
vec3
_cameraPosition
;
uniform
float
_samplingStepSize
;
const
float
SAMPLING_BASE_INTERVAL_RCP
=
200
.
0
;
// The compositing mode that gets passed through from the p_compositingMode property
uniform
int
_compositingMode
;
/**
* Performs the raycasting and returns the final fragment color.
*/
vec4
performRaycasting
(
in
vec3
entryPoint
,
in
vec3
exitPoint
,
in
vec2
texCoords
)
{
vec4
result
=
vec4
(
0
.
0
);
float
firstHitT
=
-
1
.
0
;
// calculate ray start and endpoint
vec3
direction
=
exitPoint
.
rgb
-
entryPoint
.
rgb
;
float
t
=
0
.
0
;
float
tend
=
length
(
direction
);
direction
=
normalize
(
direction
);
// This applies a small random offset to avoid banding artifacts
// Uncomment to see the effect ;)
jitterEntryPoint
(
entryPoint
,
direction
,
_samplingStepSize
*
_jitterStepSizeMultiplier
);
while
(
t
<
tend
)
{
// compute sample position - next step
vec3
samplePosition
=
entryPoint
.
rgb
+
t
*
direction
;
// get the intensity of our sample from the volume
float
intensity
=
texture
(
_volume
,
samplePosition
).
r
;
// use the transfer function to transform from
vec4
color
=
lookupTF
(
_transferFunction
,
_transferFunctionParams
,
intensity
);
if
(
_compositingMode
==
0
)
{
// accomodate for variable sampling rates
color
.
a
=
1
.
0
-
pow
(
1
.
0
-
color
.
a
,
_samplingStepSize
*
SAMPLING_BASE_INTERVAL_RCP
);
// perform compositing
// Alpha-blend the new sample with the color accumulated so far
blendUnder
(
result
,
color
);
}
else
if
(
_compositingMode
==
1
)
{
//TODO
result
=
vec4
(
entryPoint
,
1
.
0
);
}
// else if...
// save first hit ray parameter for depth value calculation
if
(
firstHitT
<
0
.
0
&&
result
.
a
>
0
.
0
)
{
firstHitT
=
t
;
}
// advance to the next evaluation point along the ray
t
+=
_samplingStepSize
;
}
// calculate depth value from ray parameter
gl_FragDepth
=
1
.
0
;
if
(
firstHitT
>=
0
.
0
)
{
float
depthEntry
=
texture
(
_entryPointsDepth
,
texCoords
).
z
;
float
depthExit
=
texture
(
_exitPointsDepth
,
texCoords
).
z
;
gl_FragDepth
=
calculateDepthValue
(
firstHitT
/
tend
,
depthEntry
,
depthExit
);
}
return
result
;
}
/***
* The main method.
***/
void
main
()
{
vec2
p
=
gl_FragCoord
.
xy
*
_viewportSizeRCP
;
vec3
frontPos
=
texture
(
_entryPoints
,
p
).
rgb
;
vec3
backPos
=
texture
(
_exitPoints
,
p
).
rgb
;
//determine whether the ray has to be casted
if
(
frontPos
==
backPos
)
{
//background needs no raycasting
discard
;
}
else
{
//fragCoords are lying inside the boundingbox
FragData0
=
performRaycasting
(
frontPos
,
backPos
,
p
);
}
}
modules/cppcourse/pipelines/cppcourse.cpp
0 → 100644
View file @
eb24cfdd
#include "cppcourse.h"
// TODO
modules/cppcourse/pipelines/cppcourse.h
0 → 100644
View file @
eb24cfdd
#pragma once
// TODO
modules/cppcourse/processors/EDFhandler.cpp
0 → 100644
View file @
eb24cfdd
#include "EDFhandler.h"
#include <fstream>
#include <map>
#include <exception>
#include "IOutilities.h"
Volume
EDFHandler
::
read
(
const
std
::
string
&
filename
)
{
// open the file
std
::
ifstream
file
(
filename
,
std
::
ios
::
binary
);
if
(
!
file
.
good
())
throw
std
::
invalid_argument
(
"EDFHandler::read: error opening "
+
filename
+
" for reading"
);
// read a single character and make sure that a header is opened
if
(
file
.
eof
()
||
file
.
get
()
!=
'{'
)
throw
std
::
invalid_argument
(
"EDFHandler::read: failed reading header opening marker"
);
std
::
map
<
std
::
string
,
std
::
string
>
attributes
;
// --- read header data
while
(
!
file
.
eof
())
{
// skip whitespace
while
(
!
file
.
eof
())
{
const
int
chr
=
file
.
peek
();
if
(
chr
!=
'\r'
&&
chr
!=
'\n'
&&
chr
!=
' '
&&
chr
!=
'\t'
)
break
;
file
.
ignore
(
1
);
}
// abort if the header is closed
if
(
file
.
eof
()
||
file
.
peek
()
==
'}'
)
break
;
// extract the attribute assignment
bool
quotesSingle
=
false
,
quotesDouble
=
false
;
std
::
string
assignment
=
""
;
while
(
!
file
.
eof
())
{
const
int
chr
=
file
.
get
();
// abort on end-of-assignment
if
(
chr
==
';'
&&
!
(
quotesSingle
||
quotesDouble
))
break
;
// check for quote characters
if
(
chr
==
'\''
)
quotesSingle
=
!
quotesSingle
;
if
(
chr
==
'\"'
)
quotesDouble
=
!
quotesDouble
;
assignment
+=
chr
;
}
// split the assignment, and remove quotes (if they exist)
auto
delim
=
assignment
.
find
(
'='
);
if
(
delim
==
std
::
string
::
npos
)
throw
std
::
invalid_argument
(
"EDFHandler::read: failed reading name/value delimiter"
);
std
::
string
name
=
assignment
.
substr
(
0
,
delim
);
StringUtils
::
trim
(
name
);
std
::
string
value
=
assignment
.
substr
(
delim
+
1
);
StringUtils
::
trim
(
value
);
if
(
value
[
0
]
==
value
[
value
.
size
()
-
1
]
&&
(
value
[
0
]
==
'\''
||
value
[
0
]
==
'\"'
))
value
=
value
.
substr
(
1
,
value
.
size
()
-
2
);
StringUtils
::
tolower
(
name
);
attributes
[
name
]
=
value
;
}
file
.
ignore
(
2
);
// end of header marker
// --- now parse the header data
// read the dimensions
std
::
vector
<
int
>
dim
;
for
(
int
i
=
1
;
;
++
i
)
{
// assemble the attribute name
std
::
stringstream
aux
;
aux
<<
"dim_"
<<
i
;
// try to find the attribute
auto
dimIt
=
attributes
.
find
(
aux
.
str
());
if
(
dimIt
==
attributes
.
end
())
break
;
dim
.
push_back
(
StringUtils
::
parseString
<
int
>
(
dimIt
->
second
));
}
const
int
nDims
=
dim
.
size
();
if
(
!
nDims
)
throw
std
::
runtime_error
(
"EDFHandler::read: dimension information not found"
);
// parse the (non-standard) spacing tag
std
::
vector
<
float
>
spacing
;
auto
spacingIt
=
attributes
.
find
(
"spacing"
);
if
(
spacingIt
!=
attributes
.
end
())
StringUtils
::
parseString
<
float
>
(
spacingIt
->
second
,
spacing
);
// check for a byte order tag, but fall back to the default value
ByteOrder
::
ByteOrderEnum
byteorder
=
ByteOrder
::
DEFAULT
;
auto
byteorderIt
=
attributes
.
find
(
"byteorder"
);
if
(
byteorderIt
!=
attributes
.
end
())
{
std
::
string
byteorderValue
=
byteorderIt
->
second
;
StringUtils
::
tolower
(
byteorderValue
);
if
(
byteorderValue
==
"highbytefirst"
)
byteorder
=
ByteOrder
::
HIGH_BYTE_FIRST
;
else
if
(
byteorderValue
==
"lowbytefirst"
)
byteorder
=
ByteOrder
::
LOW_BYTE_FIRST
;
else
throw
std
::
runtime_error
(
"invalid byte order value"
);
}
// check for the 'element type' value
DataTypes
::
DataTypeEnum
datatype
;
auto
datatypeIt
=
attributes
.
find
(
"datatype"
);
if
(
datatypeIt
!=
attributes
.
end
())
{
std
::
string
datatypeValue
=
datatypeIt
->
second
;
StringUtils
::
tolower
(
datatypeValue
);
if
(
datatypeValue
==
"signedbyte"
)
datatype
=
DataTypes
::
INT8
;
else
if
(
datatypeValue
==
"unsignedbyte"
)
datatype
=
DataTypes
::
UINT8
;
else
if
(
datatypeValue
==
"signedshort"
)
datatype
=
DataTypes
::
INT16
;
else
if
(
datatypeValue
==
"unsignedshort"
)
datatype
=
DataTypes
::
UINT16
;
else
if
(
datatypeValue
==
"float"
||
datatypeValue
==
"floatvalue"
||
datatypeValue
==
"real"
)
datatype
=
DataTypes
::
FLOAT32
;
else
if
(
datatypeValue
==
"double"
||
datatypeValue
==
"doublevalue"
)
datatype
=
DataTypes
::
FLOAT64
;
// todo: add further data types
else
throw
std
::
runtime_error
(
"EDFHandler::read: invalid/unsupported data type"
);
}
else
throw
std
::
runtime_error
(
"EDFHandler::read: data type not found"
);
auto
compressionIt
=
attributes
.
find
(
"compression"
);
if
(
compressionIt
!=
attributes
.
end
())
throw
std
::
runtime_error
(
"compression not supported"
);
int
size
=
0
;
auto
sizeIt
=
attributes
.
find
(
"size"
);
if
(
sizeIt
!=
attributes
.
end
())
size
=
StringUtils
::
parseString
<
int
>
(
sizeIt
->
second
);
auto
imageIt
=
attributes
.
find
(
"image"
);
if
(
imageIt
!=
attributes
.
end
()
&&
StringUtils
::
parseString
<
int
>
(
imageIt
->
second
)
!=
1
)
throw
std
::
runtime_error
(
"EDFHandler::read: image not set to 1"
);
// convert size
Eigen
::
VectorXi
dimSizes
(
nDims
);
for
(
int
i
=
0
;
i
<
nDims
;
++
i
)
dimSizes
[
i
]
=
dim
[
i
];
if
(
dimSizes
.
prod
()
*
DataTypes
::
getSizeForType
(
datatype
)
!=
size
)
throw
std
::
runtime_error
(
"EDFHandler::read: size inconsistency"
);
// convert spacing
Eigen
::
VectorXf
dimSpacing
=
Eigen
::
VectorXf
::
Ones
(
nDims
);
if
(
spacing
.
size
()
>
0
)
{
if
(
spacing
.
size
()
!=
nDims
)
throw
std
::
runtime_error
(
"EDFHandler::read: spacing inconsistency"
);
for
(
int
i
=
0
;
i
<
nDims
;
++
i
)
dimSpacing
[
i
]
=
spacing
[
i
];
}
// compute the byte shuffling flag
const
bool
byteShuffle
=
(
byteorder
!=
ByteOrder
::
DEFAULT
);
// --- read in the image data
Eigen
::
VectorXf
data
=
DataTypes
::
parseData
<
float
>
(
file
,
datatype
,
dimSizes
.
prod
(),
byteShuffle
);
file
.
close
();
// --- setup the volume
Eigen
::
Vector3f
lowerLeft
=
Eigen
::
Vector3f
::
Zero
();
Eigen
::
Vector3f
upperRight
=
lowerLeft
+
(
dimSizes
.
cast
<
float
>
().
array
()
*
dimSpacing
.
array
()
).
matrix
();
Volume
vol
(
lowerLeft
,
upperRight
,
dimSpacing
);
vol
.
setContent
(
data
);
return
vol
;
}
void
EDFHandler
::
write
(
const
std
::
string
&
filename
,
const
Volume
&
vol
)
{
// open the EDF file
std
::
ofstream
file
(
filename
,
std
::
ios
::
binary
);
if
(
!
file
.
good
())
throw
std
::
invalid_argument
(
"EDFHandler::write: cannot open "
+
filename
+
" for writing"
);
// open the header
file
<<
"{
\n
"
;
file
<<
"HeaderID = EH:000001:000000:000000;
\n
"
;
file
<<
"Image = "
<<
1
<<
";
\n
"
;
if
(
ByteOrder
::
DEFAULT
==
ByteOrder
::
HIGH_BYTE_FIRST
)
file
<<
"ByteOrder = HighByteFirst;
\n
"
;
else
file
<<
"ByteOrder = LowByteFirst;
\n
"
;
file
<<
"DataType = "
<<
TYPE_FLOAT
<<
";
\n
"
;
// write dimension and size
for
(
int
i
=
0
;
i
<
3
;
++
i
)
file
<<
"Dim_"
<<
(
i
+
1
)
<<
" = "
<<
vol
.
getNumVoxels
()[
i
]
<<
";
\n
"
;
file
<<
"Size = "
<<
vol
.
getNumVoxels
().
prod
()
*
sizeof
(
float
)
<<
";
\n
"
;
// write spacing
file
<<
"Spacing ="
;
for
(
int
i
=
0
;
i
<
3
;
++
i
)
file
<<
' '
<<
vol
.
getSpacing
()[
i
];
file
<<
";
\n
"
;
// pad the header by adding spaces such that the header ends on a kilobyte boundary
std
::
size_t
n
=
1024
;
while
(
n
<
(
static_cast
<
std
::
size_t
>
(
file
.
tellp
())
+
3
))
n
+=
1024
;
n
-=
static_cast
<
std
::
size_t
>
(
file
.
tellp
())
+
3
;
while
(
n
>
0
)
{
file
.
put
(
' '
);
n
--
;
}
// close the header
file
<<
"
\n
}
\n
"
;
// write the volume data
file
.
write
(
reinterpret_cast
<
const
char
*>
(
vol
.
getContent
().
data
()),
vol
.
getNumVoxels
().
prod
()
*
sizeof
(
float
)
);
file
.
close
();
}
modules/cppcourse/processors/EDFhandler.h
0 → 100644
View file @
eb24cfdd
#ifndef EDFHANDLER_H
#define EDFHANDLER_H
#include <string>
#include "volume.h"
/**
* \brief EDFHandler reads and writes EDF files.
*/
class
EDFHandler
{
public:
/* \brief read an EDF file into a Volume
* \param[in] filename - filename of the EDF file to be read
* \return volume containing the data
*/
static
Volume
read
(
const
std
::
string
&
filename
);
/* \brief write out a Volume into an EDF file
* \param[in] filename - filename of the EDF file to be written
* \param[in] vol - volume to be written
*/
static
void
write
(
const
std
::
string
&
filename
,
const
Volume
&
vol
);
private:
static
constexpr
auto
TYPE_FLOAT
=
"FloatValue"
;
};
#endif // EDFHANDLER_H
modules/cppcourse/processors/IOutilities.h
0 → 100644
View file @
eb24cfdd
#ifndef IOUTILITIES_H
#define IOUTILITIES_H
#include <algorithm>
#include <regex>
#include <string>
#include <vector>
#include <Eigen/Dense>
/**
* \brief StringUtils provides common string utilities for file parsing.
*/
struct
StringUtils
{
/* \brief remove whitespace at front and back of string
* \param[in,out] str - string to be trimmed
*/
static
void
trim
(
std
::
string
&
str
);
/* \brief convert string to lower case
* \param[in,out] str - string to be converted
*/
static
void
tolower
(
std
::
string
&
str
);
/* \brief convert string to upper case
* \param[in,out] str - string to be converted
*/
static
void
toupper
(
std
::
string
&
str
);
/* \brief convert string to arbitrary datatype using stringstream
* \param[in] str - string to be converted
* \return converted datatype
*/
template
<
typename
Type
>
static
Type
parseString
(
const
std
::
string
&
str
);
/* \brief convert string to vector of arbitrary data type using stringstream
* \param[in] str - string to be converted
* \param[out] vec - vector of converted datatypes
* \return number of converted datatypes
*/
template
<
typename
Type
>
static
int
parseString
(
const
std
::
string
&
str
,
std
::
vector
<
Type
>&
vec
);
};
/**
* \brief ByteOrder supplies helper routines to cope with byte order conversions.
*/
struct
ByteOrder
{
/// byte order enum
enum
ByteOrderEnum
{
LOW_BYTE_FIRST
,
// little endian (e.g. x86)
HIGH_BYTE_FIRST
// big endian (e.g. PowerPC)
};
/// attempt to determine endianness (works on Mac at least..), default to little endian
static
const
ByteOrderEnum
DEFAULT
=
#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && BYTE_ORDER == BIG_ENDIAN
HIGH_BYTE_FIRST
;
#else
LOW_BYTE_FIRST
;
#endif
/* \brief shuffle the bytes of the data pointed to by ptr to switch endianness
* \tparam _DataType - data type underlying the pointer
* \param[in,out] ptr - pointer to the data
* \param[in] elements - number of elements of _DataType
*/
template
<
typename
_DataType
>
static
void
shuffleBytes
(
void
*
ptr
,
long
elements
);
};
/**
* \brief DataTypes supplies helper enums and routines for type conversions.
*/
struct
DataTypes
{
/// data type enum
enum
DataTypeEnum
{
INT8
,
UINT8
,
INT16
,
UINT16
,
INT32
,
UINT32
,
FLOAT32
,
FLOAT64
};
/* \brief return the size in bytes for the specified data type
* \param[in] dataType - type for which to return the size in bytes
* \return size of dataType in bytes
*/
static
int
getSizeForType
(
const
DataTypeEnum
&
dataType
);
/* \brief parse data of type dataType from stream in into an Eigen::Vector
* (dispatches to parseData<_DataType, _Scalar> internally)
* \tparam _Scalar - scalar type of Eigen::Vector to return
* \param[in] in - stream from which to read
* \param[in] dataType - dataType of elements to be read from stream
* \param[in] sizeInElements - number of elements (of type dataType) to read from stream
* \param[in] shuffleBytes - flag whether to shuffle bytes around to account for endianness change
* \return vector of _Scalar containing the read in values
*/
template
<
typename
_Scalar
>
static
Eigen
::
Matrix
<
_Scalar
,
Eigen
::
Dynamic
,
1
>
parseData
(
std
::
istream
&
in
,
const
DataTypeEnum
&
dataType
,
long
sizeInElements
,
bool
shuffleBytes
);
private:
/* \brief parse data of type _DataType from stream in into an Eigen::Vector
* \tparam _DataType - data type of elements to be read from stream
* \tparam _Scalar - scalar type of Eigen::Vector to return
* \param[in] in - stream from which to read
* \param[in] sizeInElements - number of elements (of type _DataType) to read from stream
* \param[in] shuffleBytes - flag whether to shuffle bytes around to account for endianness change
* \return vector of _Scalar containing the read in values
*/
template
<
typename
_DataType
,
typename
_Scalar
>
static
Eigen
::
Matrix
<
_Scalar
,
Eigen
::
Dynamic
,
1
>
parseData
(
std
::
istream
&
in
,
long
sizeInElements
,
bool
shuffleBytes
);
};
// --------- Implementations -----------
inline
void
StringUtils
::
trim
(
std
::
string
&
str
)
{
str
=
std
::
regex_replace
(
str
,
std
::
regex
(
"^
\\
s+|
\\
s+$"
),
std
::
string
(
""
));
}
inline
void
StringUtils
::
tolower
(
std
::
string
&
str
)
{
std
::
transform
(
str
.
begin
(),
str
.
end
(),
str
.
begin
(),
::
tolower
);
}
inline
void
StringUtils
::
toupper
(
std
::
string
&
str
)
{
std
::
transform
(
str
.
begin
(),
str
.
end
(),
str
.
begin
(),
::
toupper
);
}
template
<
typename
Type
>
inline
Type
StringUtils
::
parseString
(
const
std
::
string
&
str
)
{
Type
value
;
std
::
stringstream
convert
(
str
);