Removal of unused files

This commit is contained in:
Paul Egberts
2023-03-10 14:20:57 +01:00
committed by Markus Blatt
parent 7b0156f6cc
commit 22a7a81597
64 changed files with 3 additions and 13515 deletions

View File

@@ -967,7 +967,6 @@ if(ENABLE_ECL_INPUT)
external/resinsight/CommonCode/cvfStructGrid.h
external/resinsight/LibCore/cvfArray.h
external/resinsight/LibCore/cvfArrayWrapperConst.h
external/resinsight/LibCore/cvfArrayWrapperToEdit.h
external/resinsight/LibCore/cvfAssert.h
external/resinsight/LibCore/cvfAtomicCounter.h
external/resinsight/LibCore/cvfBase.h
@@ -983,20 +982,13 @@ if(ENABLE_ECL_INPUT)
external/resinsight/LibCore/cvfFunctorRange.h
external/resinsight/LibCore/cvfLibCore.h
external/resinsight/LibCore/cvfLogDestination.h
external/resinsight/LibCore/cvfLogDestinationConsole.h
external/resinsight/LibCore/cvfLogDestinationFile.h
external/resinsight/LibCore/cvfLogEvent.h
external/resinsight/LibCore/cvfLogManager.h
external/resinsight/LibCore/cvfLogger.h
external/resinsight/LibCore/cvfMath.h
external/resinsight/LibCore/cvfMatrix3.h
external/resinsight/LibCore/cvfMatrix4.h
external/resinsight/LibCore/cvfMutex.h
external/resinsight/LibCore/cvfObject.h
external/resinsight/LibCore/cvfPlane.h
external/resinsight/LibCore/cvfProgramOptions.h
external/resinsight/LibCore/cvfPropertySet.h
external/resinsight/LibCore/cvfPropertySetCollection.h
external/resinsight/LibCore/cvfQuat.h
external/resinsight/LibCore/cvfRect.h
external/resinsight/LibCore/cvfString.h
@@ -1005,39 +997,21 @@ if(ENABLE_ECL_INPUT)
external/resinsight/LibCore/cvfTimer.h
external/resinsight/LibCore/cvfTrace.h
external/resinsight/LibCore/cvfValueArray.h
external/resinsight/LibCore/cvfVariant.h
external/resinsight/LibCore/cvfVector2.h
external/resinsight/LibCore/cvfVector3.h
external/resinsight/LibCore/cvfVector4.h
external/resinsight/LibCore/cvfVersion.h
external/resinsight/LibGeometry/cvfArrowGenerator.h
external/resinsight/LibGeometry/cvfBoundingBox.h
external/resinsight/LibGeometry/cvfBoundingBoxTree.h
external/resinsight/LibGeometry/cvfBoxGenerator.h
external/resinsight/LibGeometry/cvfEdgeKey.h
external/resinsight/LibGeometry/cvfFrustum.h
external/resinsight/LibGeometry/cvfGeometryBuilder.h
external/resinsight/LibGeometry/cvfGeometryBuilderFaceList.h
external/resinsight/LibGeometry/cvfGeometryBuilderTriangles.h
external/resinsight/LibGeometry/cvfGeometryUtils.h
external/resinsight/LibGeometry/cvfLibGeometry.h
external/resinsight/LibGeometry/cvfMeshEdgeExtractor.h
external/resinsight/LibGeometry/cvfOutlineEdgeExtractor.h
external/resinsight/LibGeometry/cvfPatchGenerator.h
external/resinsight/LibGeometry/cvfPrimitiveTests.h
external/resinsight/LibGeometry/cvfRay.h
external/resinsight/LibGeometry/cvfTriangleMeshEdgeExtractor.h
external/resinsight/LibGeometry/cvfTriangleVertexSplitter.h
external/resinsight/LibGeometry/cvfVertexCompactor.h
external/resinsight/LibGeometry/cvfVertexWelder.h
external/resinsight/ReservoirDataModel/RigCellGeometryTools.h
external/resinsight/ReservoirDataModel/RigEclipseCaseData.h
#external/resinsight/ReservoirDataModel/RigEclipseCaseData.h
external/resinsight/ReservoirDataModel/RigHexIntersectionTools.h
external/resinsight/ReservoirDataModel/RigMainGrid.h
#external/resinsight/ReservoirDataModel/RigMainGrid.h
external/resinsight/ReservoirDataModel/RigWellLogExtractionTools.h
external/resinsight/ReservoirDataModel/RigWellLogExtractor.h
external/resinsight/ReservoirDataModel/RigWellPath.h
external/resinsight/ReservoirDataModel/RigWellPathIntersectionTools.h
#external/resinsight/ReservoirDataModel/RigWellPathIntersectionTools.h
external/resinsight/ReservoirDataModel/cvfGeometryTools.h
external/resinsight/cafHexGridIntersectionTools/cafHexGridIntersectionTools.h
external/resinsight/cafPdmCore/cafAppEnum.h

View File

@@ -1,135 +0,0 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) Ceetron Solutions AS
//
// This library may be used under the terms of either the GNU General Public License or
// the GNU Lesser General Public License as follows:
//
// GNU General Public License Usage
// This library 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.
//
// This library 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 at <<http://www.gnu.org/licenses/gpl.html>>
// for more details.
//
// GNU Lesser General Public License Usage
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library 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 Lesser General Public License at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
// for more details.
//
//##################################################################################################
#pragma once
namespace external {
namespace cvf {
//--------------------------------------------------------------------------------------------------
///
/// \class cvf::ArrayWrapperToEdit
/// \ingroup Core
///
/// A wrapper class to make it possible to use different array types with
/// different element types in the same algorithms.
///
/// The implementation has a specialization for bare pointer arrays.
/// The reason for the bare pointer specialization is the [] access implementation
/// which is different. (*array)[] vs array[]
///
/// The convenience functions wrapArrayToEdit() are available to simplify wrapping of your data making it
/// possible to do:
/// myFunction (wrapArrayToEdit(myNodeArray), wrapArrayToEdit(myIndexArray), ...);
/// when calling a template function using ArrayWrapperToEdit's as input.
///
//--------------------------------------------------------------------------------------------------
template < typename ArrayType, typename ElmType >
class ArrayWrapperToEdit
{
public:
ArrayWrapperToEdit(ArrayType* array, size_t size) : m_array(array), m_size(size) { }
inline size_t size() const { return m_size; }
inline ElmType& operator[](const size_t index) { return (*m_array)[index]; }
inline const ElmType& operator[](const size_t index) const { return (*m_array)[index]; }
private:
ArrayType * m_array;
size_t m_size;
};
//--------------------------------------------------------------------------------------------------
/// Bare-pointer array wrapper specialization
//--------------------------------------------------------------------------------------------------
template < typename ElmType >
class ArrayWrapperToEdit <ElmType*, ElmType>
{
public:
ArrayWrapperToEdit(ElmType* array, size_t size) : m_array(array), m_size(size) { }
inline size_t size() const { return m_size; }
inline ElmType& operator[](const size_t index) { return m_array[index]; }
inline const ElmType& operator[](const size_t index) const { return m_array[index]; }
private:
ElmType * m_array;
size_t m_size;
};
#include "cvfArray.h"
#include <vector>
//--------------------------------------------------------------------------------------------------
/// cvf::Array specialization
//--------------------------------------------------------------------------------------------------
template <typename ElmType>
inline ArrayWrapperToEdit< cvf::Array<ElmType>, ElmType > wrapArrayToEdit(cvf::Array<ElmType>* array )
{
ArrayWrapperToEdit<cvf::Array<ElmType>, ElmType> warr(array, array->size());
return warr;
}
//--------------------------------------------------------------------------------------------------
/// std::vector specialization
//--------------------------------------------------------------------------------------------------
template <typename ElmType>
inline ArrayWrapperToEdit< std::vector<ElmType>, ElmType > wrapArrayToEdit(std::vector<ElmType>* array )
{
ArrayWrapperToEdit<std::vector<ElmType>, ElmType> warr(array, array->size());
return warr;
}
//--------------------------------------------------------------------------------------------------
/// Bare-pointer specialization
//--------------------------------------------------------------------------------------------------
template <typename ElmType>
inline ArrayWrapperToEdit< ElmType*, ElmType > wrapArrayToEdit(ElmType* array, size_t size )
{
ArrayWrapperToEdit<ElmType*, ElmType> warr(array, size);
return warr;
}
}
} //namespace external

View File

@@ -1,240 +0,0 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2013 Ceetron AS
//
// This library may be used under the terms of either the GNU General Public License or
// the GNU Lesser General Public License as follows:
//
// GNU General Public License Usage
// This library 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.
//
// This library 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 at <<http://www.gnu.org/licenses/gpl.html>>
// for more details.
//
// GNU Lesser General Public License Usage
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library 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 Lesser General Public License at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
// for more details.
//
//##################################################################################################
#include "cvfBase.h"
#include "cvfBase64.h"
#ifdef WIN32
#pragma warning (disable: 4242 4244 4267 4365)
#endif
CVF_GCC_DIAGNOSTIC_IGNORE("-Wconversion")
CVF_GCC_DIAGNOSTIC_IGNORE("-Wunused-parameter")
#ifdef CVF_LINUX
#include <stdio.h>
#include <stdlib.h>
#endif
namespace external
{
// Doxygen conditional section to hide contents of the cvf_base64 namespace
/// \cond CVF_NEVER_INCLUDE
namespace cvf_base64
{
//## START -- base64.cpp
//////////////////////////////////////////////////////////////////////////
// start include
// base64.h
//////////////////////////////////////////////////////////////////////////
/*
base64.cpp and base64.h
Copyright (C) 2004-2008 Rene Nyffenegger
This source code is provided 'as-is', without any express or implied
warranty. In no event will the author be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this source code must not be misrepresented; you must not
claim that you wrote the original source code. If you use this source code
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original source code.
3. This notice may not be removed or altered from any source distribution.
Rene Nyffenegger rene.nyffenegger@adp-gmbh.ch
*/
// Commented out by Ceetron
//#include "base64.h"
//#include <iostream>
static const std::string base64_chars =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789+/";
static inline bool is_base64(unsigned char c) {
return (isalnum(c) || (c == '+') || (c == '/'));
}
std::string base64_encode(unsigned char const* bytes_to_encode, unsigned int in_len) {
std::string ret;
int i = 0;
int j = 0;
unsigned char char_array_3[3];
unsigned char char_array_4[4];
while (in_len--) {
char_array_3[i++] = *(bytes_to_encode++);
if (i == 3) {
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
char_array_4[3] = char_array_3[2] & 0x3f;
for(i = 0; (i <4) ; i++)
ret += base64_chars[char_array_4[i]];
i = 0;
}
}
if (i)
{
for(j = i; j < 3; j++)
char_array_3[j] = '\0';
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
char_array_4[3] = char_array_3[2] & 0x3f;
for (j = 0; (j < i + 1); j++)
ret += base64_chars[char_array_4[j]];
while((i++ < 3))
ret += '=';
}
return ret;
}
std::string base64_decode(std::string const& encoded_string) {
int in_len = encoded_string.size();
int i = 0;
int j = 0;
int in_ = 0;
unsigned char char_array_4[4], char_array_3[3];
std::string ret;
while (in_len-- && ( encoded_string[in_] != '=') && is_base64(encoded_string[in_])) {
char_array_4[i++] = encoded_string[in_]; in_++;
if (i ==4) {
for (i = 0; i <4; i++)
char_array_4[i] = base64_chars.find(char_array_4[i]);
char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
for (i = 0; (i < 3); i++)
ret += char_array_3[i];
i = 0;
}
}
if (i) {
for (j = i; j <4; j++)
char_array_4[j] = 0;
for (j = 0; j <4; j++)
char_array_4[j] = base64_chars.find(char_array_4[j]);
char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
for (j = 0; (j < i - 1); j++) ret += char_array_3[j];
}
return ret;
}
//## END -- base64.cpp
} // namespace cvf_base64
// End of Doxygen conditional section
/// \endcond
namespace cvf {
//==================================================================================================
///
/// \class cvf::Base64
/// \ingroup Core
///
/// Base64 encoding and decoding for representing binary data in an ASCII string format by
/// translating it into a radix-64 representation.
///
//==================================================================================================
//--------------------------------------------------------------------------------------------------
/// Encode a binary buffer
//--------------------------------------------------------------------------------------------------
std::string Base64::encode(const cvf::UByteArray& data)
{
return (data.size() > 0) ? cvf_base64::base64_encode(data.ptr(), data.size()) : "";
}
//--------------------------------------------------------------------------------------------------
/// Decode already encoded data. Array returned is NULL if unable to decode
//--------------------------------------------------------------------------------------------------
cvf::ref<cvf::UByteArray> Base64::decode(const std::string& encodedData)
{
if (encodedData.size() < 1) return NULL;
std::string decodedData = cvf_base64::base64_decode(encodedData);
size_t numDecodedBytes = decodedData.length();
if (numDecodedBytes == 0) return NULL;
cvf::UByteArray* data = new cvf::UByteArray;
data->resize(numDecodedBytes);
data->copyData(reinterpret_cast<const unsigned char*>(decodedData.c_str()), numDecodedBytes, 0);
return data;
}
} // namespace cvf
} //namespace external

View File

@@ -1,183 +0,0 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2013 Ceetron AS
//
// This library may be used under the terms of either the GNU General Public License or
// the GNU Lesser General Public License as follows:
//
// GNU General Public License Usage
// This library 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.
//
// This library 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 at <<http://www.gnu.org/licenses/gpl.html>>
// for more details.
//
// GNU Lesser General Public License Usage
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library 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 Lesser General Public License at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
// for more details.
//
//##################################################################################################
#include "cvfBase.h"
#include "cvfCodeLocation.h"
#include <algorithm>
#include <cstring>
namespace external {
namespace cvf {
//==================================================================================================
///
/// \class cvf::CodeLocation
/// \ingroup Core
///
/// Represents a source code location.
///
/// Typically used with logging, asserts etc. Typically initialized using built-in compiler macros
/// such as __FILE__ and __LINE__.
///
/// Note that the strings parameters for file name and function must be a static strings with a
/// lifetime that's longer than the lifetime of the CodeLocation object
///
//==================================================================================================
static const char* const EMPTY_STRING = "";
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
CodeLocation::CodeLocation()
: m_fileName(EMPTY_STRING),
m_functionName(EMPTY_STRING),
m_lineNumber(-1)
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
CodeLocation::CodeLocation(const char* fileName, const char* functionName, int lineNumber)
: m_fileName(fileName),
m_functionName(functionName),
m_lineNumber(lineNumber)
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
CodeLocation::CodeLocation(const CodeLocation& other)
: m_fileName(other.m_fileName),
m_functionName(other.m_functionName),
m_lineNumber(other.m_lineNumber)
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const CodeLocation& CodeLocation::operator=(CodeLocation rhs)
{
// Copy-and-swap (copy already done since parameter is passed by value)
rhs.swap(*this);
return *this;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const char* CodeLocation::fileName() const
{
return m_fileName ? m_fileName : EMPTY_STRING;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const char* CodeLocation::shortFileName() const
{
if (m_fileName)
{
const char* ptrToLastSlash = strrchr(m_fileName, '/');
#ifdef WIN32
const char* ptrToLastBwdSlash = strrchr(m_fileName, '\\');
if (ptrToLastBwdSlash > ptrToLastSlash)
{
ptrToLastSlash = ptrToLastBwdSlash;
}
#endif
if (ptrToLastSlash)
{
return ptrToLastSlash + 1;
}
else
{
return m_fileName;
}
}
else
{
return EMPTY_STRING;
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const char* CodeLocation::functionName() const
{
return m_functionName ? m_functionName : EMPTY_STRING;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
int CodeLocation::lineNumber() const
{
return m_lineNumber;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void CodeLocation::swap(CodeLocation& other)
{
std::swap(m_fileName, other.m_fileName);
std::swap(m_functionName, other.m_functionName);
std::swap(m_lineNumber, other.m_lineNumber);
}
} // namespace cvf
} //namespace external

View File

@@ -1,453 +0,0 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2013 Ceetron AS
//
// This library may be used under the terms of either the GNU General Public License or
// the GNU Lesser General Public License as follows:
//
// GNU General Public License Usage
// This library 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.
//
// This library 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 at <<http://www.gnu.org/licenses/gpl.html>>
// for more details.
//
// GNU Lesser General Public License Usage
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library 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 Lesser General Public License at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
// for more details.
//
//##################################################################################################
#include "cvfBase.h"
#include "cvfColor3.h"
#include "cvfMath.h"
namespace external {
namespace cvf {
//==================================================================================================
///
/// \class cvf::Color3
/// \ingroup Core
///
/// Abstract base class for 3-component RGB colors.
///
/// Currently, this class only contains the ColorIdent enums,
//==================================================================================================
//==================================================================================================
///
/// \class cvf::Color3f
/// \ingroup Core
///
/// Class for storing and manipulating 3-component RGB floating point colors
///
//==================================================================================================
//--------------------------------------------------------------------------------------------------
/// Default constructor, initializes all color components to 0.0
//--------------------------------------------------------------------------------------------------
Color3f::Color3f()
{
m_rgb[0] = 0.0f;
m_rgb[1] = 0.0f;
m_rgb[2] = 0.0f;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
Color3f::Color3f(float r, float g, float b)
{
m_rgb[0] = r;
m_rgb[1] = g;
m_rgb[2] = b;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
Color3f::Color3f(const Color3f& other)
{
m_rgb[0] = other.m_rgb[0];
m_rgb[1] = other.m_rgb[1];
m_rgb[2] = other.m_rgb[2];
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
Color3f::Color3f(ColorIdent colorIdent)
{
Color3ub byteColor(colorIdent);
*this = Color3f::fromByteColor(byteColor.r(), byteColor.g(), byteColor.b());
}
//--------------------------------------------------------------------------------------------------
/// Explicit conversion constructor from byte color
//--------------------------------------------------------------------------------------------------
Color3f::Color3f(const Color3ub& byteColor)
{
*this = Color3f::fromByteColor(byteColor.r(), byteColor.g(), byteColor.b());
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
Color3f& Color3f::operator=(const Color3f& rhs)
{
m_rgb[0] = rhs.m_rgb[0];
m_rgb[1] = rhs.m_rgb[1];
m_rgb[2] = rhs.m_rgb[2];
return *this;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
Color3f& Color3f::operator=(ColorIdent colorIdent)
{
return operator=(Color3f(colorIdent));
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool Color3f::operator==(const Color3f& rhs) const
{
if (m_rgb[0] == rhs.m_rgb[0] &&
m_rgb[1] == rhs.m_rgb[1] &&
m_rgb[2] == rhs.m_rgb[2])
{
return true;
}
else
{
return false;
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool Color3f::operator!=(const Color3f& rhs) const
{
return !operator==(rhs);
}
//--------------------------------------------------------------------------------------------------
/// Sets all color components
//--------------------------------------------------------------------------------------------------
void Color3f::set(float r, float g, float b)
{
m_rgb[0] = r;
m_rgb[1] = g;
m_rgb[2] = b;
}
//--------------------------------------------------------------------------------------------------
/// Query whether this color is valid
///
/// For a color to be considered valid, all the component values must be in the range 0.0 to 1.0
//--------------------------------------------------------------------------------------------------
bool Color3f::isValid() const
{
if (!Math::valueInRange(m_rgb[0], 0.0f, 1.0f)) return false;
if (!Math::valueInRange(m_rgb[1], 0.0f, 1.0f)) return false;
if (!Math::valueInRange(m_rgb[2], 0.0f, 1.0f)) return false;
return true;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const float* Color3f::ptr() const
{
return m_rgb;
}
//--------------------------------------------------------------------------------------------------
/// Get red component as byte color (unsigned char)
//--------------------------------------------------------------------------------------------------
unsigned char Color3f::rByte() const
{
int val = static_cast<int>(m_rgb[0]*255.0f + 0.5f);
if (val < 0) return 0;
else if (val > 255) return 255;
else return static_cast<unsigned char>(val);
}
//--------------------------------------------------------------------------------------------------
/// Get green component as byte color (unsigned char)
//--------------------------------------------------------------------------------------------------
unsigned char Color3f::gByte() const
{
int val = static_cast<int>(m_rgb[1]*255.0f + 0.5f);
if (val < 0) return 0;
else if (val > 255) return 255;
else return static_cast<unsigned char>(val);
}
//--------------------------------------------------------------------------------------------------
/// Get blue component as a byte color (unsigned char)
//--------------------------------------------------------------------------------------------------
unsigned char Color3f::bByte() const
{
int val = static_cast<int>(m_rgb[2]*255.0f + 0.5f);
if (val < 0) return 0;
else if (val > 255) return 255;
else return static_cast<unsigned char>(val);
}
//--------------------------------------------------------------------------------------------------
/// Static function to construct a Color3f object from byte RGB values.
///
/// All the values parameter values should be in the range 0-255. The returned object will always
/// have its components clamped to the range 0.0 to 1.0
//--------------------------------------------------------------------------------------------------
Color3f Color3f::fromByteColor(ubyte r, ubyte g, ubyte b)
{
// Constructor sets all elements to 0
Color3f c;
c.m_rgb[0] = static_cast<float>(r)/255.0f;
c.m_rgb[1] = static_cast<float>(g)/255.0f;
c.m_rgb[2] = static_cast<float>(b)/255.0f;
return c;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool operator < (const Color3f& color1, const Color3f& color2)
{
for (int i = 0; i < 3; i++)
{
if (color1.m_rgb[i] > color2.m_rgb[i])
return false;
else if (color1.m_rgb[i] < color2.m_rgb[i])
return true;
}
return false;
}
//==================================================================================================
///
/// \class cvf::Color3ub
/// \ingroup Core
///
/// Class for storing unsigned byte RGB colors
///
//==================================================================================================
//--------------------------------------------------------------------------------------------------
/// Default constructor, initializes all color components to 0
//--------------------------------------------------------------------------------------------------
Color3ub::Color3ub()
{
m_rgb[0] = 0;
m_rgb[1] = 0;
m_rgb[2] = 0;
}
//--------------------------------------------------------------------------------------------------
/// Constructor with initialization of all components
//--------------------------------------------------------------------------------------------------
Color3ub::Color3ub(ubyte r, ubyte g, ubyte b)
{
m_rgb[0] = r;
m_rgb[1] = g;
m_rgb[2] = b;
}
//--------------------------------------------------------------------------------------------------
/// Copy constructor
//--------------------------------------------------------------------------------------------------
Color3ub::Color3ub(const Color3ub& other)
{
m_rgb[0] = other.m_rgb[0];
m_rgb[1] = other.m_rgb[1];
m_rgb[2] = other.m_rgb[2];
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
Color3ub::Color3ub(ColorIdent colorIdent)
{
switch (colorIdent)
{
case RED: set(255, 0, 0); break;
case GREEN: set( 0, 255, 0); break;
case BLUE: set( 0, 0, 255); break;
case YELLOW: set(255, 255, 0); break;
case CYAN: set( 0, 255, 255); break;
case MAGENTA: set(255, 0, 255); break;
case WHITE: set(255, 255, 255); break;
case BLACK: set( 0, 0, 0); break;
case LIGHT_GRAY: set(192, 192, 192); break;
case GRAY: set(128, 128, 128); break;
case DARK_GRAY: set( 64, 64, 64); break;
case BROWN: set(165, 42, 42); break;
case CRIMSON: set(220, 20, 60); break;
case DARK_BLUE: set( 0, 0, 139); break;
case DARK_YELLOW: set(139, 139, 0); break;
case DARK_CYAN: set( 0, 139, 139); break;
case DARK_GREEN: set( 0, 100, 0); break;
case DARK_MAGENTA: set(139, 0, 139); break;
case DARK_ORANGE: set(255, 140, 0); break;
case DARK_RED: set(139, 0, 0); break;
case DARK_VIOLET: set(148, 0, 211); break;
case DEEP_PINK: set(255, 20, 147); break;
case FOREST_GREEN: set( 34, 139, 34); break;
case GOLD: set(255, 215, 0); break;
case GREEN_YELLOW: set(173, 255, 47); break;
case INDIGO: set( 75, 0, 130); break;
case OLIVE: set(128, 128, 0); break;
case ORANGE: set(255, 165, 0); break;
case ORANGE_RED: set(255, 69, 0); break;
case ORCHID: set(218, 112, 214); break;
case PINK: set(255, 192, 203); break;
case PURPLE: set(128, 0, 128); break;
case SEA_GREEN: set( 46, 139, 87); break;
case SKY_BLUE: set(135, 206, 235); break;
case VIOLET: set(238, 130, 238); break;
case YELLOW_GREEN: set(154, 205, 50); break;
case CEETRON: set( 81, 134, 148); break;
default: set(0, 0, 0);
CVF_FAIL_MSG("Unknown ColorIdent");
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
Color3ub::Color3ub(const Color3f& other)
{
m_rgb[0] = static_cast<ubyte>(other.r()*255.0f);
m_rgb[1] = static_cast<ubyte>(other.g()*255.0f);
m_rgb[2] = static_cast<ubyte>(other.b()*255.0f);
}
//--------------------------------------------------------------------------------------------------
/// Assignment operator
//--------------------------------------------------------------------------------------------------
Color3ub& Color3ub::operator=(const Color3ub& rhs)
{
m_rgb[0] = rhs.m_rgb[0];
m_rgb[1] = rhs.m_rgb[1];
m_rgb[2] = rhs.m_rgb[2];
return *this;
}
//--------------------------------------------------------------------------------------------------
/// Assignment from ColorIdent
//--------------------------------------------------------------------------------------------------
Color3ub& Color3ub::operator=(ColorIdent colorIdent)
{
return operator=(Color3ub(colorIdent));
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool Color3ub::operator==(const Color3ub& rhs) const
{
if (m_rgb[0] == rhs.m_rgb[0] &&
m_rgb[1] == rhs.m_rgb[1] &&
m_rgb[2] == rhs.m_rgb[2])
{
return true;
}
else
{
return false;
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool Color3ub::operator!=(const Color3ub& rhs) const
{
return !operator==(rhs);
}
//--------------------------------------------------------------------------------------------------
/// Sets all color components
//--------------------------------------------------------------------------------------------------
void Color3ub::set(ubyte r, ubyte g, ubyte b)
{
m_rgb[0] = r;
m_rgb[1] = g;
m_rgb[2] = b;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const ubyte* Color3ub::ptr() const
{
return m_rgb;
}
} // namespace cvf
} //namespace external

View File

@@ -1,409 +0,0 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2013 Ceetron AS
//
// This library may be used under the terms of either the GNU General Public License or
// the GNU Lesser General Public License as follows:
//
// GNU General Public License Usage
// This library 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.
//
// This library 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 at <<http://www.gnu.org/licenses/gpl.html>>
// for more details.
//
// GNU Lesser General Public License Usage
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library 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 Lesser General Public License at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
// for more details.
//
//##################################################################################################
#include "cvfBase.h"
#include "cvfColor4.h"
#include "cvfColor3.h"
#include "cvfMath.h"
namespace external {
namespace cvf {
//==================================================================================================
///
/// \class cvf::Color4f
/// \ingroup Core
///
/// Class for storing and manipulating 4-component RGBA colors
///
//==================================================================================================
//--------------------------------------------------------------------------------------------------
/// Default constructor, initializes object to RGB=0.0 and Alpha=1.0
//--------------------------------------------------------------------------------------------------
Color4f::Color4f()
{
m_rgba[0] = 0.0f;
m_rgba[1] = 0.0f;
m_rgba[2] = 0.0f;
m_rgba[3] = 1.0f;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
Color4f::Color4f(float r, float g, float b, float alpha)
{
m_rgba[0] = r;
m_rgba[1] = g;
m_rgba[2] = b;
m_rgba[3] = alpha;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
Color4f::Color4f(const Color4f& other)
{
m_rgba[0] = other.m_rgba[0];
m_rgba[1] = other.m_rgba[1];
m_rgba[2] = other.m_rgba[2];
m_rgba[3] = other.m_rgba[3];
}
//--------------------------------------------------------------------------------------------------
/// Construct from 3 component RGB color. Alpha value will be set to 1.0
//--------------------------------------------------------------------------------------------------
Color4f::Color4f(const Color3f& rgbColor)
{
m_rgba[0] = rgbColor.r();
m_rgba[1] = rgbColor.g();
m_rgba[2] = rgbColor.b();
m_rgba[3] = 1.0f;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
Color4f::Color4f(const Color3f& rgbColor, float alpha)
{
m_rgba[0] = rgbColor.r();
m_rgba[1] = rgbColor.g();
m_rgba[2] = rgbColor.b();
m_rgba[3] = alpha;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
Color4f::Color4f(Color3::ColorIdent colorIdent)
{
Color3f rgb(colorIdent);
m_rgba[0] = rgb.r();
m_rgba[1] = rgb.g();
m_rgba[2] = rgb.b();
m_rgba[3] = 1.0f;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
Color4f::Color4f(const Color4ub& other)
{
m_rgba[0] = static_cast<float>(other.r())/255.0f;
m_rgba[1] = static_cast<float>(other.g())/255.0f;
m_rgba[2] = static_cast<float>(other.b())/255.0f;
m_rgba[3] = static_cast<float>(other.a())/255.0f;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
Color4f& Color4f::operator=(const Color4f& rhs)
{
m_rgba[0] = rhs.m_rgba[0];
m_rgba[1] = rhs.m_rgba[1];
m_rgba[2] = rhs.m_rgba[2];
m_rgba[3] = rhs.m_rgba[3];
return *this;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool Color4f::operator==(const Color4f& rhs) const
{
if (m_rgba[0] == rhs.m_rgba[0] &&
m_rgba[1] == rhs.m_rgba[1] &&
m_rgba[2] == rhs.m_rgba[2] &&
m_rgba[3] == rhs.m_rgba[3])
{
return true;
}
else
{
return false;
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool Color4f::operator!=(const Color4f& rhs) const
{
return !operator==(rhs);
}
//--------------------------------------------------------------------------------------------------
/// Sets all color components
//--------------------------------------------------------------------------------------------------
void Color4f::set(float r, float g, float b, float alpha)
{
m_rgba[0] = r;
m_rgba[1] = g;
m_rgba[2] = b;
m_rgba[3] = alpha;
}
//--------------------------------------------------------------------------------------------------
/// Set from 3-component RGB color and separate alpha factor
//--------------------------------------------------------------------------------------------------
void Color4f::set(const Color3f& rgbColor, float alpha)
{
m_rgba[0] = rgbColor.r();
m_rgba[1] = rgbColor.g();
m_rgba[2] = rgbColor.b();
m_rgba[3] = alpha;
}
//--------------------------------------------------------------------------------------------------
/// Set from 3-component RGB color. Alpha will be set to 1.0
//--------------------------------------------------------------------------------------------------
void Color4f::set(const Color3f& rgbColor)
{
m_rgba[0] = rgbColor.r();
m_rgba[1] = rgbColor.g();
m_rgba[2] = rgbColor.b();
m_rgba[3] = 1.0f;
}
//--------------------------------------------------------------------------------------------------
/// Query whether this color is valid
///
/// For a color to be considered valid, all the component values must be in the range 0.0 to 1.0
//--------------------------------------------------------------------------------------------------
bool Color4f::isValid() const
{
if (!Math::valueInRange(m_rgba[0], 0.0f, 1.0f)) return false;
if (!Math::valueInRange(m_rgba[1], 0.0f, 1.0f)) return false;
if (!Math::valueInRange(m_rgba[2], 0.0f, 1.0f)) return false;
if (!Math::valueInRange(m_rgba[3], 0.0f, 1.0f)) return false;
return true;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const float* Color4f::ptr() const
{
return m_rgba;
}
//--------------------------------------------------------------------------------------------------
/// Convert to 3-component RGB color by dropping the alpha value
//--------------------------------------------------------------------------------------------------
Color3f Color4f::toColor3f() const
{
return Color3f(m_rgba[0], m_rgba[1], m_rgba[2]);
}
//==================================================================================================
///
/// \class cvf::Color4ub
/// \ingroup Core
///
/// Class for storing unsigned byte RGBA colors
///
//==================================================================================================
//--------------------------------------------------------------------------------------------------
/// Default constructor, initializes object to RGB=0.0 and Alpha=1.0
//--------------------------------------------------------------------------------------------------
Color4ub::Color4ub()
{
m_rgba[0] = 0;
m_rgba[1] = 0;
m_rgba[2] = 0;
m_rgba[3] = 255;
}
//--------------------------------------------------------------------------------------------------
/// Constructor with initialization of all components
//--------------------------------------------------------------------------------------------------
Color4ub::Color4ub(ubyte r, ubyte g, ubyte b, ubyte a)
{
m_rgba[0] = r;
m_rgba[1] = g;
m_rgba[2] = b;
m_rgba[3] = a;
}
//--------------------------------------------------------------------------------------------------
/// Copy constructor
//--------------------------------------------------------------------------------------------------
Color4ub::Color4ub(const Color4ub& other)
{
m_rgba[0] = other.m_rgba[0];
m_rgba[1] = other.m_rgba[1];
m_rgba[2] = other.m_rgba[2];
m_rgba[3] = other.m_rgba[3];
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
Color4ub::Color4ub(const Color3ub& rgbColor, ubyte a)
{
m_rgba[0] = rgbColor.r();
m_rgba[1] = rgbColor.g();
m_rgba[2] = rgbColor.b();
m_rgba[3] = a;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
Color4ub::Color4ub(const Color3ub& rgbColor)
{
m_rgba[0] = rgbColor.r();
m_rgba[1] = rgbColor.g();
m_rgba[2] = rgbColor.b();
m_rgba[3] = 255;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
Color4ub::Color4ub(Color3::ColorIdent colorIdent)
{
Color3ub color3(colorIdent);
set(color3.r(), color3.g(), color3.b(), 255);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
Color4ub::Color4ub(const Color4f& other)
{
m_rgba[0] = static_cast<ubyte>(other.r()*255.0f);
m_rgba[1] = static_cast<ubyte>(other.g()*255.0f);
m_rgba[2] = static_cast<ubyte>(other.b()*255.0f);
m_rgba[3] = static_cast<ubyte>(other.a()*255.0f);
}
//--------------------------------------------------------------------------------------------------
/// Assignment operator
//--------------------------------------------------------------------------------------------------
Color4ub& Color4ub::operator=(const Color4ub& rhs)
{
m_rgba[0] = rhs.m_rgba[0];
m_rgba[1] = rhs.m_rgba[1];
m_rgba[2] = rhs.m_rgba[2];
m_rgba[3] = rhs.m_rgba[3];
return *this;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool Color4ub::operator==(const Color4ub& rhs) const
{
if (m_rgba[0] == rhs.m_rgba[0] &&
m_rgba[1] == rhs.m_rgba[1] &&
m_rgba[2] == rhs.m_rgba[2] &&
m_rgba[3] == rhs.m_rgba[3])
{
return true;
}
else
{
return false;
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool Color4ub::operator!=(const Color4ub& rhs) const
{
return !operator==(rhs);
}
//--------------------------------------------------------------------------------------------------
/// Sets all color components
//--------------------------------------------------------------------------------------------------
void Color4ub::set(ubyte r, ubyte g, ubyte b, ubyte a)
{
m_rgba[0] = r;
m_rgba[1] = g;
m_rgba[2] = b;
m_rgba[3] = a;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const ubyte* Color4ub::ptr() const
{
return m_rgba;
}
} // namespace cvf
} //namespace external

View File

@@ -1,224 +0,0 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2013 Ceetron AS
//
// This library may be used under the terms of either the GNU General Public License or
// the GNU Lesser General Public License as follows:
//
// GNU General Public License Usage
// This library 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.
//
// This library 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 at <<http://www.gnu.org/licenses/gpl.html>>
// for more details.
//
// GNU Lesser General Public License Usage
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library 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 Lesser General Public License at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
// for more details.
//
//##################################################################################################
#include "cvfBase.h"
#include "cvfDebugTimer.h"
#include "cvfTimer.h"
#include "cvfTrace.h"
#include <cstdio>
#include <cstdarg>
namespace external {
namespace cvf {
//==================================================================================================
///
/// \class cvf::DebugTimer
/// \ingroup Core
///
/// Debug timer class for reporting timing info via the static Trace class
///
//==================================================================================================
//--------------------------------------------------------------------------------------------------
/// Constructor, starts the timer
///
/// \param prefix This text will be prepended for all trace outputs. Can be NULL
/// \param operationMode Either NORMAL (the default) or DISABLED. Specifying DISABLED effectively
/// disables all functionality in the class.
//--------------------------------------------------------------------------------------------------
DebugTimer::DebugTimer(const char* prefix, OperationMode operationMode)
: m_timer(NULL),
m_prefix(NULL),
m_messageCount(0)
{
if (operationMode == NORMAL)
{
if (prefix)
{
m_prefix = new String(prefix);
}
m_timer = new Timer();
}
}
//--------------------------------------------------------------------------------------------------
/// Destructor
//--------------------------------------------------------------------------------------------------
DebugTimer::~DebugTimer()
{
delete m_prefix;
delete m_timer;
}
//--------------------------------------------------------------------------------------------------
/// Restart timer.
///
/// If msg is specified this method will show this text as trace output. Else nothing is shown.
//--------------------------------------------------------------------------------------------------
void DebugTimer::restart(const char* msg)
{
if (!m_timer) return;
m_timer->restart();
if (msg)
{
String outputText = makeMessageStartString(msg);
Trace::show(outputText);
}
}
//--------------------------------------------------------------------------------------------------
/// Report elapsed time, in seconds. msg is appended if provided.
//--------------------------------------------------------------------------------------------------
void DebugTimer::reportTime(const char* msg)
{
if (!m_timer) return;
double time = m_timer->time();
String outputText = makeMessageStartString(msg) + ": " + String::number(time, 'f', 6) + " sec";
Trace::show(outputText);
}
//--------------------------------------------------------------------------------------------------
/// Report elapsed time, in milliseconds. msg is appended if provided.
//--------------------------------------------------------------------------------------------------
void DebugTimer::reportTimeMS(const char* msg )
{
if (!m_timer) return;
double timeMS = m_timer->time() * 1000.0;
String outputText = makeMessageStartString(msg) + ": " + String::number(timeMS, 'f', 3) + " ms";
Trace::show(outputText);
}
//--------------------------------------------------------------------------------------------------
/// Report lap time, in seconds. msg is appended if provided.
//--------------------------------------------------------------------------------------------------
void DebugTimer::reportLapTime(const char* msg)
{
if (!m_timer) return;
double lapTime = m_timer->lapTime();
String outputText = makeMessageStartString(msg) + ": " + String::number(lapTime, 'f', 6) + " sec";
Trace::show(outputText);
}
//--------------------------------------------------------------------------------------------------
/// Report lap time, in milliseconds. msg is appended if provided.
//--------------------------------------------------------------------------------------------------
void DebugTimer::reportLapTimeMS(const char* msg)
{
if (!m_timer) return;
double lapTimeMS = m_timer->lapTime() * 1000.0;
String outputText = makeMessageStartString(msg) + ": " + String::number(lapTimeMS, 'f', 3) + " ms";
Trace::show(outputText);
}
//--------------------------------------------------------------------------------------------------
/// Show trace output with message count, optional prefix and provided text.
//--------------------------------------------------------------------------------------------------
void DebugTimer::echoMessage(const char* format, ...)
{
if (!m_timer) return;
// Create the printf-style string and send it to the console and trace file
// TODO! Note: var-arg is solved locally here, but needs to be revisited e.g. in String class
va_list argList;
va_start(argList, format);
const int maxFormatLength = 4000;
char temp[maxFormatLength + 1];
#ifdef WIN32
_vsnprintf_s(temp, maxFormatLength, format, argList);
#else
vsprintf(temp, format, argList);
#endif
va_end(argList);
String outputText = makeMessageStartString(temp);
Trace::show(outputText);
}
//--------------------------------------------------------------------------------------------------
/// Generate message string with message count, optional prefix and optional msg text.
//--------------------------------------------------------------------------------------------------
String DebugTimer::makeMessageStartString(const char* msg)
{
String outputText = String(m_messageCount);
m_messageCount++;
if (m_prefix)
{
outputText += String(": ");
outputText += *m_prefix;
}
if (msg)
{
outputText += ": ";
outputText += msg;
}
return outputText;
}
} // namespace cvf
} //namespace external

View File

@@ -1,161 +0,0 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2013 Ceetron AS
//
// This library may be used under the terms of either the GNU General Public License or
// the GNU Lesser General Public License as follows:
//
// GNU General Public License Usage
// This library 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.
//
// This library 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 at <<http://www.gnu.org/licenses/gpl.html>>
// for more details.
//
// GNU Lesser General Public License Usage
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library 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 Lesser General Public License at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
// for more details.
//
//##################################################################################################
#include "cvfBase.h"
#include "cvfLogDestinationConsole.h"
#include "cvfLogEvent.h"
#ifdef WIN32
#pragma warning (push)
#pragma warning (disable: 4668)
#include <windows.h>
#pragma warning (pop)
#else
#include <cstdio>
#include <cstdarg>
#endif
namespace external {
namespace cvf {
//==================================================================================================
///
/// \class cvf::LogDestinationConsole
/// \ingroup Core
///
///
///
//==================================================================================================
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void LogDestinationConsole::log(const LogEvent& logEvent)
{
String str;
bool addLocationInfo = false;
Logger::Level logEventLevel = logEvent.level();
if (logEventLevel == Logger::LL_ERROR)
{
str = "ERROR: " + logEvent.message();
addLocationInfo = true;
}
else if (logEventLevel == Logger::LL_WARNING)
{
str = "warn: " + logEvent.message();
}
else if (logEventLevel == Logger::LL_INFO)
{
str = "info: " + logEvent.message();
}
else if (logEventLevel == Logger::LL_DEBUG)
{
str = "debug: " + logEvent.message();
}
if (addLocationInfo)
{
str += "\n";
str += String(" -func: %1\n").arg(logEvent.location().functionName());
str += String(" -file: %1(%2)").arg(logEvent.location().shortFileName()).arg(logEvent.location().lineNumber());
}
CharArray charArrMsg = str.toAscii();
const char* szMsg = charArrMsg.ptr();
{
Mutex::ScopedLock lock(m_mutex);
#ifdef WIN32
writeToWindowsConsole(szMsg, true);
#else
writeToStderr(szMsg, true);
#endif
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void LogDestinationConsole::writeToWindowsConsole(const char* theString, bool addNewLine)
{
#ifdef WIN32
CVF_ASSERT(theString);
AllocConsole();
HANDLE hStdOutputHandle = GetStdHandle(STD_OUTPUT_HANDLE);
if (hStdOutputHandle && theString)
{
DWORD stringLength = static_cast<DWORD>(System::strlen(theString));
unsigned long iDum = 0;
WriteConsoleA(hStdOutputHandle, theString, stringLength, &iDum, NULL);
if (addNewLine) WriteConsole(hStdOutputHandle, "\n", 1, &iDum, NULL);
}
#else
CVF_UNUSED(theString);
CVF_UNUSED(addNewLine);
#endif
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void LogDestinationConsole::writeToStderr(const char* theString, bool addNewLine)
{
CVF_ASSERT(theString);
if (theString)
{
fprintf(stderr, "%s", theString);
if (addNewLine)
{
fprintf(stderr, "\n");
}
}
}
} // namespace cvf
} //namespace external

View File

@@ -1,69 +0,0 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2013 Ceetron AS
//
// This library may be used under the terms of either the GNU General Public License or
// the GNU Lesser General Public License as follows:
//
// GNU General Public License Usage
// This library 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.
//
// This library 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 at <<http://www.gnu.org/licenses/gpl.html>>
// for more details.
//
// GNU Lesser General Public License Usage
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library 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 Lesser General Public License at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
// for more details.
//
//##################################################################################################
#pragma once
#include "cvfLogDestination.h"
#include "cvfMutex.h"
namespace external {
namespace cvf {
//==================================================================================================
//
//
//
//==================================================================================================
class LogDestinationConsole : public LogDestination
{
public:
virtual void log(const LogEvent& logEvent);
private:
static void writeToWindowsConsole(const char* theString, bool addNewLine);
static void writeToStderr(const char* theString, bool addNewLine);
private:
Mutex m_mutex;
};
} // cvf
} //namespace external

View File

@@ -1,204 +0,0 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2013 Ceetron AS
//
// This library may be used under the terms of either the GNU General Public License or
// the GNU Lesser General Public License as follows:
//
// GNU General Public License Usage
// This library 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.
//
// This library 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 at <<http://www.gnu.org/licenses/gpl.html>>
// for more details.
//
// GNU Lesser General Public License Usage
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library 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 Lesser General Public License at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
// for more details.
//
//##################################################################################################
#include "cvfBase.h"
#include "cvfLogDestinationFile.h"
#include "cvfLogEvent.h"
#ifdef WIN32
#pragma warning (push)
#pragma warning (disable: 4668)
#include <windows.h>
#pragma warning (pop)
#else
#include <cstdio>
#include <cstdarg>
#endif
namespace external {
namespace cvf {
//==================================================================================================
//
//
//
//==================================================================================================
class FileWrapper
{
public:
FileWrapper(const String& fileName)
: m_fileName(fileName),
m_filePtr(NULL)
{
}
~FileWrapper()
{
if (m_filePtr)
{
fclose(m_filePtr);
}
}
bool open(const String& mode)
{
CVF_ASSERT(m_filePtr == NULL);
#ifdef WIN32
if (_wfopen_s(&m_filePtr, m_fileName.c_str(), mode.c_str()) != 0)
{
m_filePtr = NULL;
}
#else
m_filePtr = ::fopen(m_fileName.toUtf8().ptr(), mode.toUtf8().ptr());
#endif
return m_filePtr != NULL;
}
FILE* filePtr()
{
return m_filePtr;
}
private:
String m_fileName;
FILE* m_filePtr;
};
//==================================================================================================
///
/// \class cvf::LogDestinationFile
/// \ingroup Core
///
///
///
//==================================================================================================
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
LogDestinationFile::LogDestinationFile(const String& fileName)
: m_fileName(fileName)
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void LogDestinationFile::log(const LogEvent& logEvent)
{
String str;
bool addLocationInfo = false;
Logger::Level logEventLevel = logEvent.level();
if (logEventLevel == Logger::LL_ERROR)
{
str = logEvent.source() + "**ERROR**: " + logEvent.message();
addLocationInfo = true;
}
else if (logEventLevel == Logger::LL_WARNING)
{
str = logEvent.source() + "(warn): " + logEvent.message();
}
else if (logEventLevel == Logger::LL_INFO)
{
str = logEvent.source() + "(i): " + logEvent.message();
}
else if (logEventLevel == Logger::LL_DEBUG)
{
str = logEvent.source() + "(d): " + logEvent.message();
}
if (addLocationInfo)
{
str += "\n";
str += String(" -func: %1\n").arg(logEvent.location().functionName());
str += String(" -file: %1(%2)").arg(logEvent.location().shortFileName()).arg(logEvent.location().lineNumber());
}
CharArray charArrMsg = str.toAscii();
const char* szMsg = charArrMsg.ptr();
Mutex::ScopedLock lock(m_mutex);
writeToFile(szMsg, true);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void LogDestinationFile::writeToFile(const char* theString, bool addNewLine)
{
FileWrapper file(m_fileName);
if (m_firstTimeOpen)
{
if (!file.open("wt"))
{
return;
}
m_firstTimeOpen = false;
}
else
{
if (!file.open("at"))
{
return;
}
}
if (file.filePtr() && theString)
{
if (addNewLine)
{
fprintf(file.filePtr(), "%s\n", theString);
}
else
{
fprintf(file.filePtr(), "%s", theString);
}
}
}
} // namespace cvf
} //namespace external

View File

@@ -1,73 +0,0 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2013 Ceetron AS
//
// This library may be used under the terms of either the GNU General Public License or
// the GNU Lesser General Public License as follows:
//
// GNU General Public License Usage
// This library 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.
//
// This library 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 at <<http://www.gnu.org/licenses/gpl.html>>
// for more details.
//
// GNU Lesser General Public License Usage
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library 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 Lesser General Public License at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
// for more details.
//
//##################################################################################################
#pragma once
#include "cvfLogDestination.h"
#include "cvfString.h"
#include "cvfMutex.h"
namespace external {
namespace cvf {
//==================================================================================================
//
//
//
//==================================================================================================
class LogDestinationFile : public LogDestination
{
public:
LogDestinationFile(const String& fileName);
virtual void log(const LogEvent& logEvent);
private:
void writeToFile(const char* theString, bool addNewLine);
private:
String m_fileName;
bool m_firstTimeOpen; // Initialized to true, Will be set to false after first write operation
Mutex m_mutex;
};
} // cvf
} //namespace external

View File

@@ -1,148 +0,0 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2013 Ceetron AS
//
// This library may be used under the terms of either the GNU General Public License or
// the GNU Lesser General Public License as follows:
//
// GNU General Public License Usage
// This library 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.
//
// This library 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 at <<http://www.gnu.org/licenses/gpl.html>>
// for more details.
//
// GNU Lesser General Public License Usage
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library 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 Lesser General Public License at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
// for more details.
//
//##################################################################################################
#include "cvfBase.h"
#include "cvfLogEvent.h"
namespace external {
namespace cvf {
//==================================================================================================
///
/// \class cvf::LogEvent
/// \ingroup Core
///
///
///
//==================================================================================================
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
LogEvent::LogEvent()
: m_level(Logger::LL_ERROR)
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
LogEvent::LogEvent(const String& source, const String& message, Logger::Level level, const CodeLocation& codeLocation)
: m_source(source),
m_message(message),
m_level(level),
m_codeLocation(codeLocation)
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
LogEvent::LogEvent(const LogEvent& other)
: m_source(other.m_source),
m_message(other.m_message),
m_level(other.m_level),
m_codeLocation(other.m_codeLocation)
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const LogEvent& LogEvent::operator=(LogEvent rhs)
{
// Copy-and-swap (copy already done since parameter is passed by value)
rhs.swap(*this);
return *this;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const String& LogEvent::source() const
{
return m_source;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
Logger::Level LogEvent::level() const
{
return m_level;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const String& LogEvent::message() const
{
return m_message;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const CodeLocation& LogEvent::location() const
{
return m_codeLocation;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void LogEvent::swap(LogEvent& other)
{
m_source.swap(other.m_source);
m_message.swap(other.m_message);
std::swap(m_level, other.m_level);
m_codeLocation.swap(other.m_codeLocation);
}
} // namespace cvf
} //namespace external

View File

@@ -1,82 +0,0 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2013 Ceetron AS
//
// This library may be used under the terms of either the GNU General Public License or
// the GNU Lesser General Public License as follows:
//
// GNU General Public License Usage
// This library 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.
//
// This library 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 at <<http://www.gnu.org/licenses/gpl.html>>
// for more details.
//
// GNU Lesser General Public License Usage
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library 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 Lesser General Public License at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
// for more details.
//
//##################################################################################################
#pragma once
#include "cvfObject.h"
#include "cvfString.h"
#include "cvfLogger.h"
namespace external {
namespace cvf {
//==================================================================================================
//
//
//
//==================================================================================================
class LogEvent
{
public:
LogEvent();
LogEvent(const String& source, const String& message, Logger::Level level, const CodeLocation& codeLocation);
LogEvent(const LogEvent& other);
const LogEvent& operator=(LogEvent rhs);
const String& source() const;
Logger::Level level() const;
const String& message() const;
const CodeLocation& location() const;
private:
void swap(LogEvent& other);
private:
String m_source; // Source of the log event, normally name of the logger
String m_message; // The logged message
Logger::Level m_level; // The log level of the event
CodeLocation m_codeLocation; // Source code location of log statement
};
} // cvf
} //namespace external

View File

@@ -1,257 +0,0 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2013 Ceetron AS
//
// This library may be used under the terms of either the GNU General Public License or
// the GNU Lesser General Public License as follows:
//
// GNU General Public License Usage
// This library 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.
//
// This library 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 at <<http://www.gnu.org/licenses/gpl.html>>
// for more details.
//
// GNU Lesser General Public License Usage
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library 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 Lesser General Public License at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
// for more details.
//
//##################################################################################################
#include "cvfBase.h"
#include "cvfLogManager.h"
#include "cvfLogDestinationConsole.h"
namespace external {
namespace cvf {
//==================================================================================================
///
/// \class cvf::LogManager
/// \ingroup Core
///
///
///
//==================================================================================================
cvf::ref<LogManager> LogManager::sm_logManagerInstance;
Mutex LogManager::sm_instanceMutex;
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
LogManager::LogManager()
{
// Create the root logger
ref<Logger> rootLogger = new Logger("", Logger::LL_WARNING, new LogDestinationConsole);
m_loggerMap[""] = rootLogger;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
LogManager::~LogManager()
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
LogManager* LogManager::instance()
{
Mutex::ScopedLock mutexLock(sm_instanceMutex);
if (sm_logManagerInstance.isNull())
{
sm_logManagerInstance = new LogManager;
}
return sm_logManagerInstance.p();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void LogManager::setInstance(LogManager* logManagerInstance)
{
Mutex::ScopedLock mutexLock(sm_instanceMutex);
sm_logManagerInstance = logManagerInstance;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void LogManager::shutdownInstance()
{
Mutex::ScopedLock mutexLock(sm_instanceMutex);
sm_logManagerInstance = NULL;
}
//--------------------------------------------------------------------------------------------------
/// Returns logger with the specified name
///
/// Will create the logger if it doesn't already exist. In this case, the newly created logger will
/// be initialized with the same logging level and appender as its parent.
//--------------------------------------------------------------------------------------------------
Logger* LogManager::logger(const String& loggerName)
{
Mutex::ScopedLock mutexLock(m_mutex);
ref<Logger> theLogger = find(loggerName);
if (theLogger.isNull())
{
// Must create a new logger
// Try and find parent (optionally we'll use the root logger) and use its settings to initialize level and appender
String parentLoggerName = LogManager::nameOfParentLogger(loggerName);
ref<Logger> parentLogger = find(parentLoggerName);
if (parentLogger.isNull())
{
parentLogger = rootLogger();
}
CVF_ASSERT(parentLogger.notNull());
theLogger = new Logger(loggerName, parentLogger->level(), parentLogger->destination());
m_loggerMap[loggerName] = theLogger;
}
return theLogger.p();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
Logger* LogManager::rootLogger()
{
return logger(String());
}
//--------------------------------------------------------------------------------------------------
/// Sets the logging level of the given logger and all its descendants.
///
/// Specify an empty name to set logging level of all current loggers.
//--------------------------------------------------------------------------------------------------
void LogManager::setLevelRecursive(const String& baseLoggerName, int logLevel)
{
Mutex::ScopedLock mutexLock(m_mutex);
const size_t baseNameLength = baseLoggerName.size();
const bool baseNameIsRoot = (baseNameLength == 0);
for (LoggerMap_T::iterator it = m_loggerMap.begin(); it != m_loggerMap.end(); ++it)
{
Logger* logger = it->second.p();
if (baseNameIsRoot)
{
logger->setLevel(logLevel);
}
else
{
const String& loggerName = logger->name();
if (loggerName.startsWith(baseLoggerName) &&
((loggerName.size() == baseNameLength) || (loggerName[baseNameLength] == '.')) )
{
logger->setLevel(logLevel);
}
}
}
}
//--------------------------------------------------------------------------------------------------
/// Sets the log destination for the specified logger and all its children.
//--------------------------------------------------------------------------------------------------
void LogManager::setDestinationRecursive(const String& baseLoggerName, LogDestination* logDestination)
{
Mutex::ScopedLock mutexLock(m_mutex);
const size_t baseNameLength = baseLoggerName.size();
const bool baseNameIsRoot = (baseNameLength == 0);
for (LoggerMap_T::iterator it = m_loggerMap.begin(); it != m_loggerMap.end(); ++it)
{
Logger* logger = it->second.p();
if (baseNameIsRoot)
{
logger->setDestination(logDestination);
}
else
{
const String& loggerName = logger->name();
if (loggerName.startsWith(baseLoggerName) &&
((loggerName.size() == baseNameLength) || (loggerName[baseNameLength] == '.')) )
{
logger->setDestination(logDestination);
}
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
Logger* LogManager::find(const String& loggerName)
{
LoggerMap_T::iterator it = m_loggerMap.find(loggerName);
if (it != m_loggerMap.end())
{
return it->second.p();
}
else
{
return NULL;
}
}
//--------------------------------------------------------------------------------------------------
/// Determine name of the parent logger of \a childLoggerName
//--------------------------------------------------------------------------------------------------
String LogManager::nameOfParentLogger(const String& childLoggerName)
{
std::wstring childName = childLoggerName.toStdWString();
std::wstring::size_type pos = childName.rfind('.');
if (pos != std::wstring::npos)
{
std::wstring parentName = childName.substr(0, pos);
return parentName;
}
else
{
return String();
}
}
} // namespace cvf
} //namespace external

View File

@@ -1,97 +0,0 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2013 Ceetron AS
//
// This library may be used under the terms of either the GNU General Public License or
// the GNU Lesser General Public License as follows:
//
// GNU General Public License Usage
// This library 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.
//
// This library 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 at <<http://www.gnu.org/licenses/gpl.html>>
// for more details.
//
// GNU Lesser General Public License Usage
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library 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 Lesser General Public License at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
// for more details.
//
//##################################################################################################
#pragma once
#include "cvfObject.h"
#include "cvfString.h"
#include "cvfMutex.h"
#include "cvfLogger.h"
#include <map>
namespace external {
namespace cvf {
class LogDestination;
//==================================================================================================
//
//
//
//==================================================================================================
class LogManager : public Object
{
public:
LogManager();
~LogManager();
static LogManager* instance();
static void setInstance(LogManager* logManagerInstance);
static void shutdownInstance();
Logger* logger(const String& loggerName);
Logger* rootLogger();
void setLevelRecursive(const String& baseLoggerName, int logLevel);
void setDestinationRecursive(const String& baseLoggerName, LogDestination* logDestination);
private:
Logger* find(const String& loggerName);
static String nameOfParentLogger(const String& childLoggerName);
private:
typedef std::map<String, cvf::ref<Logger> > LoggerMap_T;
LoggerMap_T m_loggerMap;
Mutex m_mutex;
static cvf::ref<LogManager> sm_logManagerInstance;
static Mutex sm_instanceMutex;
CVF_DISABLE_COPY_AND_ASSIGN(LogManager);
};
// Helper macros for getting or creating a named logger
#define CVF_GET_LOGGER(loggerName) (cvf::LogManager::instance()->logger(loggerName))
} // cvf
} //namespace external

View File

@@ -1,220 +0,0 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2013 Ceetron AS
//
// This library may be used under the terms of either the GNU General Public License or
// the GNU Lesser General Public License as follows:
//
// GNU General Public License Usage
// This library 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.
//
// This library 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 at <<http://www.gnu.org/licenses/gpl.html>>
// for more details.
//
// GNU Lesser General Public License Usage
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library 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 Lesser General Public License at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
// for more details.
//
//##################################################################################################
#include "cvfBase.h"
#include "cvfLogger.h"
#include "cvfLogEvent.h"
#include "cvfLogDestination.h"
namespace external {
namespace cvf {
//==================================================================================================
///
/// \class cvf::Logger
/// \ingroup Core
///
/// Logger class
///
/// Note that in itself, the Logger is not thread safe. This means that logger configuration, such
/// as setting the logging level and specifying the log destination, must be done in a single
/// threaded environment.
///
//==================================================================================================
//--------------------------------------------------------------------------------------------------
/// Constructor
//--------------------------------------------------------------------------------------------------
Logger::Logger(const String& loggerName, int logLevel, LogDestination* logDestination)
: m_name(loggerName),
m_logLevel(logLevel),
m_destination(logDestination)
{
}
//--------------------------------------------------------------------------------------------------
/// Destructor
//--------------------------------------------------------------------------------------------------
Logger::~Logger()
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const String& Logger::name() const
{
return m_name;
}
//--------------------------------------------------------------------------------------------------
/// Sets the logging level of this logger
///
/// Set a level of 0 to disable all logging for this logger.
/// \sa Logger::Level
//--------------------------------------------------------------------------------------------------
void Logger::setLevel(int logLevel)
{
m_logLevel = logLevel;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
int Logger::level() const
{
return m_logLevel;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
LogDestination* Logger::destination()
{
return m_destination.p();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void Logger::setDestination(LogDestination* logDestination)
{
m_destination = logDestination;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void Logger::error(const String& message)
{
error(message, CodeLocation());
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void Logger::error(const String& message, const CodeLocation& location)
{
if (m_logLevel >= LL_ERROR && m_destination.notNull())
{
log(message, LL_ERROR, location);
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void Logger::warning(const String& message)
{
warning(message, CodeLocation());
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void Logger::warning(const String& message, const CodeLocation& location)
{
if (m_logLevel >= LL_WARNING && m_destination.notNull())
{
log(message, LL_WARNING, location);
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void Logger::info(const String& message)
{
info(message, CodeLocation());
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void Logger::info(const String& message, const CodeLocation& location)
{
if (m_logLevel >= LL_INFO && m_destination.notNull())
{
log(message, LL_INFO, location);
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void Logger::debug(const String& message, const CodeLocation& location)
{
if (m_logLevel >= LL_DEBUG && m_destination.notNull())
{
log(message, LL_DEBUG, location);
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void Logger::log(const String& message, Logger::Level messageLevel, const CodeLocation& location)
{
if (m_logLevel >= messageLevel && m_destination.notNull())
{
m_destination->log(LogEvent(m_name, message, messageLevel, location));
}
}
} // namespace cvf
} //namespace external

View File

@@ -1,222 +0,0 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2013 Ceetron AS
//
// This library may be used under the terms of either the GNU General Public License or
// the GNU Lesser General Public License as follows:
//
// GNU General Public License Usage
// This library 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.
//
// This library 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 at <<http://www.gnu.org/licenses/gpl.html>>
// for more details.
//
// GNU Lesser General Public License Usage
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library 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 Lesser General Public License at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
// for more details.
//
//##################################################################################################
#include "cvfBase.h"
#include "cvfMutex.h"
#ifdef WIN32
#pragma warning (push)
#pragma warning (disable: 4668)
#include <windows.h>
#pragma warning (pop)
#endif
#if defined(CVF_LINUX) || defined(CVF_ANDROID) || defined(CVF_OSX)
#include <pthread.h>
#endif
namespace external {
namespace cvf {
//==================================================================================================
//
// Win32 implementation using critical section
//
//==================================================================================================
#ifdef WIN32
class MutexImpl
{
public:
MutexImpl()
{
::InitializeCriticalSection(&m_critSection);
}
~MutexImpl()
{
::DeleteCriticalSection(&m_critSection);
}
void lock()
{
::EnterCriticalSection(&m_critSection);
}
void unlock()
{
::LeaveCriticalSection(&m_critSection);
}
private:
CRITICAL_SECTION m_critSection;
};
#endif
//==================================================================================================
//
// Linux and Android implementation using POSIX/Pthreads
//
//==================================================================================================
#if defined(CVF_LINUX) || defined(CVF_ANDROID) || defined(CVF_IOS) || defined(CVF_OSX)
class MutexImpl
{
public:
MutexImpl()
{
pthread_mutexattr_t mutexAttribs;
int errCode = 0;
CVF_UNUSED(errCode);
errCode = pthread_mutexattr_init(&mutexAttribs);
CVF_ASSERT(errCode == 0);
// Use a recursive mutex to be aligned with Win32 implementation
errCode = pthread_mutexattr_settype(&mutexAttribs, PTHREAD_MUTEX_RECURSIVE);
CVF_ASSERT(errCode == 0);
errCode = pthread_mutex_init(&m_mutex, &mutexAttribs);
CVF_ASSERT(errCode == 0);
// We're done with the attribs object
errCode = pthread_mutexattr_destroy(&mutexAttribs);
CVF_ASSERT(errCode == 0);
}
~MutexImpl()
{
int errCode = pthread_mutex_destroy(&m_mutex);
CVF_UNUSED(errCode);
CVF_TIGHT_ASSERT(errCode == 0);
}
void lock()
{
int errCode = pthread_mutex_lock(&m_mutex);
CVF_UNUSED(errCode);
CVF_TIGHT_ASSERT(errCode == 0);
}
void unlock()
{
int errCode = pthread_mutex_unlock(&m_mutex);
CVF_UNUSED(errCode);
CVF_TIGHT_ASSERT(errCode == 0);
}
private:
pthread_mutex_t m_mutex;
};
#endif
//==================================================================================================
///
/// \class cvf::Mutex
/// \ingroup Core
///
/// Implements a recursive mutex where the same thread can acquire the lock multiple times.
///
/// The mutex is implemented as an recursive mutex since on Windows platforms its implementation
/// is based critical sections. Win32 critical sections are always recursive, and therefore we also
/// make the other platform implementations recursive for consistency.
///
//==================================================================================================
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
Mutex::Mutex()
: m_pimpl(new MutexImpl)
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
Mutex::~Mutex()
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void Mutex::lock()
{
m_pimpl->lock();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void Mutex::unlock()
{
m_pimpl->unlock();
}
//==================================================================================================
///
/// \class cvf::Mutex::ScopedLock
/// \ingroup Core
///
///
///
//==================================================================================================
Mutex::ScopedLock::ScopedLock(Mutex& mutex)
: m_theMutex(mutex)
{
m_theMutex.lock();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
Mutex::ScopedLock::~ScopedLock()
{
m_theMutex.unlock();
}
} // namespace cvf
} //namespace external

View File

@@ -1,80 +0,0 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2013 Ceetron AS
//
// This library may be used under the terms of either the GNU General Public License or
// the GNU Lesser General Public License as follows:
//
// GNU General Public License Usage
// This library 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.
//
// This library 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 at <<http://www.gnu.org/licenses/gpl.html>>
// for more details.
//
// GNU Lesser General Public License Usage
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library 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 Lesser General Public License at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
// for more details.
//
//##################################################################################################
#pragma once
#include <memory>
namespace external {
namespace cvf {
//==================================================================================================
//
//
//
//==================================================================================================
class Mutex
{
public:
Mutex();
~Mutex();
void lock();
void unlock();
class ScopedLock
{
public:
ScopedLock(Mutex& mutex);
~ScopedLock();
private:
Mutex& m_theMutex;
};
private:
std::unique_ptr<class MutexImpl> m_pimpl;
CVF_DISABLE_COPY_AND_ASSIGN(Mutex);
};
} // cvf
} //namespace external

View File

@@ -1,720 +0,0 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) Ceetron Solutions AS
//
// This library may be used under the terms of either the GNU General Public License or
// the GNU Lesser General Public License as follows:
//
// GNU General Public License Usage
// This library 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.
//
// This library 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 at <<http://www.gnu.org/licenses/gpl.html>>
// for more details.
//
// GNU Lesser General Public License Usage
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library 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 Lesser General Public License at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
// for more details.
//
//##################################################################################################
#include "cvfBase.h"
#include "cvfProgramOptions.h"
namespace external {
namespace cvf {
//==================================================================================================
//
//
//
//==================================================================================================
class ProgramOptions::OptionSpec : public Object
{
public:
OptionSpec(const String& name, const String& valueSyntax, const String& descr, ValueReq valReq, OptionFlags optflags)
: m_name(name), m_valueSyntax(valueSyntax), m_descr(descr), m_valueReq(valReq), m_optionFlags(optflags)
{}
public:
const String m_name;
const String m_valueSyntax;
const String m_descr;
const ValueReq m_valueReq;
const OptionFlags m_optionFlags;
};
//==================================================================================================
//
//
//
//==================================================================================================
class ProgramOptions::ParsedOption : public Object
{
public:
ParsedOption(const OptionSpec* optionSpec)
: m_spec(optionSpec)
{}
/// Check if the option has enough actual values compared to the requirements in spec
bool hasEnoughValues() const
{
const size_t numParsedValues = m_values.size();
CVF_ASSERT(m_spec.notNull());
if (m_spec->m_valueReq == NO_VALUE)
{
CVF_ASSERT(numParsedValues == 0);
return true;
}
else if (m_spec->m_valueReq == SINGLE_VALUE)
{
CVF_ASSERT(numParsedValues <= 1);
return (numParsedValues == 1) ? true : false;
}
else if (m_spec->m_valueReq == OPTIONAL_MULTI_VALUE)
{
return true;
}
else
{
return (numParsedValues >= 1) ? true : false;
}
}
// Check if we're full
bool canAcceptMoreValues() const
{
const size_t numParsedValues = m_values.size();
CVF_ASSERT(m_spec.notNull());
if (m_spec->m_valueReq == NO_VALUE)
{
CVF_ASSERT(numParsedValues == 0);
return false;
}
else if (m_spec->m_valueReq == SINGLE_VALUE)
{
CVF_ASSERT(numParsedValues <= 1);
return (numParsedValues == 0) ? true : false;
}
else
{
return true;
}
}
public:
cref<OptionSpec> m_spec;
std::vector<String> m_values;
};
//==================================================================================================
///
/// \class cvf::Option
/// \ingroup Core
///
///
///
//==================================================================================================
//--------------------------------------------------------------------------------------------------
/// Constructs an invalid/empty option
//--------------------------------------------------------------------------------------------------
Option::Option()
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
Option::Option(const String& name, const std::vector<String>& values)
: m_name(name),
m_values(values)
{
CVF_ASSERT(!m_name.isEmpty());
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
String Option::name() const
{
return m_name;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
size_t Option::valueCount() const
{
return m_values.size();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
String Option::value(size_t valueIndex) const
{
CVF_ASSERT(valueIndex < m_values.size());
return m_values[valueIndex];
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
String Option::safeValue(size_t valueIndex) const
{
if (valueIndex < m_values.size())
{
return m_values[valueIndex];
}
else
{
return String();
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<String> Option::values() const
{
return m_values;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
String Option::combinedValues() const
{
String combined;
for (size_t i = 0; i < m_values.size(); i++)
{
if (i > 0) combined += " ";
combined += m_values[i];
}
return combined;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool Option::isValid() const
{
return m_name.isEmpty() ? false : true;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
Option::operator bool_type() const
{
return isValid() ? &Option::this_type_does_not_support_comparisons : 0;
}
//==================================================================================================
///
/// \class cvf::ProgramOptions
/// \ingroup Core
///
///
///
//==================================================================================================
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
ProgramOptions::ProgramOptions()
: m_optionPrefix(DOUBLE_DASH)
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
ProgramOptions::~ProgramOptions()
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void ProgramOptions::setOptionPrefix(OptionPrefix prefix)
{
m_optionPrefix = prefix;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool ProgramOptions::registerOption(const String& optionName, ValueReq valueReq, OptionFlags optionFlags)
{
return registerOption(optionName, "", "", valueReq, optionFlags);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool ProgramOptions::registerOption(const String& optionName, const String& valueSyntax, const String& description, ValueReq valueReq, OptionFlags optionFlags)
{
if (optionName.isEmpty())
{
return false;
}
if (findOptionSpec(optionName))
{
return false;
}
ref<OptionSpec> newOpt = new OptionSpec(optionName, valueSyntax, description, valueReq, optionFlags);
m_optionSpecs.push_back(newOpt.p());
return true;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool ProgramOptions::parse(const std::vector<String>& commandLineArguments)
{
const String prefixStr = prefixString();
const size_t prefixLen = prefixStr.size();
m_parsedOptions.clear();
m_positionalParams.clear();
m_unknownOptions.clear();
m_optionsWithMissingValues.clear();
ref<ParsedOption> currParseOption;
const size_t numCmdLineArgs = commandLineArguments.size();
size_t ia = 1;
while (ia < numCmdLineArgs)
{
String arg = commandLineArguments[ia];
arg = arg.trimmed();
if (arg.isEmpty())
{
ia++;
continue;
}
if (arg.startsWith(prefixStr))
{
// Finish the option currently being parsed if any
if (currParseOption.notNull())
{
if (currParseOption->hasEnoughValues())
{
addNewParsedOption(currParseOption.p());
}
else
{
m_optionsWithMissingValues.push_back(currParseOption->m_spec->m_name);
}
currParseOption = NULL;
}
if (arg.size() > prefixLen)
{
const String optName = arg.subString(prefixLen);
const OptionSpec* optSpec = findOptionSpec(optName);
if (optSpec)
{
currParseOption = new ParsedOption(optSpec);
}
else
{
m_unknownOptions.push_back(optName);
}
}
}
else
{
// Determine if this arg belongs as a value to the option currently being parsed or if it is a positional parameter
if (currParseOption.notNull())
{
// Simple flags should never get here
CVF_ASSERT(currParseOption->m_spec->m_valueReq != NO_VALUE);
CVF_ASSERT(currParseOption->canAcceptMoreValues());
currParseOption->m_values.push_back(arg);
}
else
{
m_positionalParams.push_back(arg);
}
}
if (currParseOption.notNull())
{
if (!currParseOption->canAcceptMoreValues())
{
addNewParsedOption(currParseOption.p());
currParseOption = NULL;
}
}
ia++;
}
// Finish the option currently being parsed if any
if (currParseOption.notNull())
{
if (currParseOption->hasEnoughValues())
{
addNewParsedOption(currParseOption.p());
}
else
{
m_optionsWithMissingValues.push_back(currParseOption->m_spec->m_name);
}
currParseOption = NULL;
}
if (m_unknownOptions.empty() && m_optionsWithMissingValues.empty())
{
return true;
}
else
{
return false;
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void ProgramOptions::addNewParsedOption(ParsedOption* parsedOption)
{
const OptionSpec* optSpec = parsedOption->m_spec.p();
CVF_ASSERT(optSpec);
// Check if option already exists
ref<ParsedOption> existingOption = findParsedOption(optSpec->m_name);
if (existingOption.notNull())
{
if (optSpec->m_optionFlags.testFlag(COMBINE_REPEATED))
{
// Add incoming values to the already existing ones
existingOption->m_values.insert(existingOption->m_values.end(), parsedOption->m_values.begin(), parsedOption->m_values.end());
}
else
{
// Last occurence wins
// Erase existing and add ourselves at the end
m_parsedOptions.erase(existingOption.p());
m_parsedOptions.push_back(parsedOption);
}
}
else
{
// First time we see this option so just add it
m_parsedOptions.push_back(parsedOption);
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool ProgramOptions::hasOption(const String& optionName) const
{
if (findParsedOption(optionName))
{
return true;
}
else
{
return false;
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
Option ProgramOptions::option(const String& optionName) const
{
const ParsedOption* parsedOption = findParsedOption(optionName);
if (parsedOption)
{
return Option(parsedOption->m_spec->m_name, parsedOption->m_values);
}
else
{
return Option();
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
String ProgramOptions::firstValue(const String& optionName) const
{
const ParsedOption* parsedOption = findParsedOption(optionName);
if (parsedOption && parsedOption->m_values.size() > 0)
{
return parsedOption->m_values[0];
}
else
{
return String();
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<String> ProgramOptions::values(const String& optionName) const
{
const ParsedOption* parsedOption = findParsedOption(optionName);
if (parsedOption)
{
return parsedOption->m_values;
}
else
{
return std::vector<String>();
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<String> ProgramOptions::positionalParameters() const
{
return m_positionalParams;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<String> ProgramOptions::unknownOptions() const
{
return m_unknownOptions;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<String> ProgramOptions::optionsWithMissingValues() const
{
return m_optionsWithMissingValues;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
String ProgramOptions::prefixString() const
{
switch (m_optionPrefix)
{
case DOUBLE_DASH: return "--";
case SINGLE_DASH: return "-";
case SLASH: return "/";
default:
CVF_FAIL_MSG("Unhandled option prefix type");
return "UNKNOWN";
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const ProgramOptions::OptionSpec* ProgramOptions::findOptionSpec(const String& optionName) const
{
const String lcName = optionName.toLower();
for (size_t i = 0; i < m_optionSpecs.size(); i++)
{
if (m_optionSpecs[i]->m_name.toLower() == lcName)
{
return m_optionSpecs.at(i);
}
}
return NULL;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const ProgramOptions::ParsedOption* ProgramOptions::findParsedOption(const String& optionName) const
{
const String lcName = optionName.toLower();
for (size_t i = 0; i < m_parsedOptions.size(); i++)
{
if (m_parsedOptions[i]->m_spec->m_name.toLower() == lcName)
{
return m_parsedOptions.at(i);
}
}
return NULL;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
ProgramOptions::ParsedOption* ProgramOptions::findParsedOption(const String& optionName)
{
// Utilize const version
return const_cast<ParsedOption*>( (static_cast<const ProgramOptions*>(this))->findParsedOption(optionName) );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
String ProgramOptions::usageText(int maxWidth, int maxOptionWidth) const
{
if (maxWidth <= 1) maxWidth = 2;
if (maxOptionWidth <= 0) maxOptionWidth = maxWidth/2;
const String prefixStr = prefixString();
std::vector<String> optAndValArr;
std::vector<String> descrArr;
int optAndValMaxLen = 0;
const size_t numOpts = m_optionSpecs.size();
for (size_t i = 0; i < numOpts; i++)
{
const OptionSpec* spec = m_optionSpecs.at(i);
String optAndVal = prefixStr + spec->m_name + String(" ") + spec->m_valueSyntax;
optAndValMaxLen = CVF_MAX(optAndValMaxLen, static_cast<int>(optAndVal.size()));
optAndValArr.push_back(optAndVal);
descrArr.push_back(spec->m_descr);
}
const int firstColWidth = static_cast<int>(CVF_MIN(optAndValMaxLen + 1, maxOptionWidth));
const String firstColBlanks = String("%1").arg("", firstColWidth);
String retStr;
for (size_t iopt = 0; iopt < numOpts; iopt++)
{
const String optAndVal = optAndValArr[iopt];
const int maxDescrWidth = CVF_MAX((maxWidth - firstColWidth), 1);
std::vector<String> descrLines = breakStringIntoLines(descrArr[iopt], static_cast<size_t>(maxDescrWidth));
String s = String("%1 ").arg(optAndValArr[iopt], -(firstColWidth - 1));
if (s.size() > static_cast<size_t>(firstColWidth) && descrLines.size() > 0)
{
s += "\n" + firstColBlanks;
}
for (size_t i = 0; i < descrLines.size(); i++)
{
if (i > 0)
{
s += "\n" + firstColBlanks;
}
s += descrLines[i];
}
retStr += s + String("\n");
}
return retStr;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<String> ProgramOptions::breakStringIntoLines(const String& str, size_t maxCharsPerLine)
{
std::vector<String> words = str.split();
if (words.size() < 1)
{
return std::vector<String>();
}
std::vector<String> lines;
String currLine = words[0];
const size_t numWords = words.size();
for (size_t i = 1; i < numWords; i++)
{
const String& thisWord = words[i];
const size_t thisWordLen = thisWord.size();
if (currLine.size() + 1 + thisWordLen <= maxCharsPerLine)
{
currLine += String(" ") + thisWord;
}
else
{
lines.push_back(currLine);
currLine = thisWord;
}
}
lines.push_back(currLine);
return lines;
}
} // namespace cvf
} //namespace external

View File

@@ -1,155 +0,0 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) Ceetron Solutions AS
//
// This library may be used under the terms of either the GNU General Public License or
// the GNU Lesser General Public License as follows:
//
// GNU General Public License Usage
// This library 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.
//
// This library 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 at <<http://www.gnu.org/licenses/gpl.html>>
// for more details.
//
// GNU Lesser General Public License Usage
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library 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 Lesser General Public License at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
// for more details.
//
//##################################################################################################
#pragma once
#include "cvfFlags.h"
#include "cvfString.h"
#include "cvfCollection.h"
namespace external {
namespace cvf {
//==================================================================================================
//
//
//
//==================================================================================================
class Option
{
public:
Option();
Option(const String& name, const std::vector<String>& values);
String name() const;
size_t valueCount() const;
String value(size_t valueIndex) const;
String safeValue(size_t valueIndex) const;
std::vector<String> values() const;
String combinedValues() const;
bool isValid() const;
// Safe bool idiom, internally calls isValid()
typedef void (Option::*bool_type)() const;
operator bool_type() const;
private:
const String m_name;
const std::vector<String> m_values;
private:
void this_type_does_not_support_comparisons() const {}
};
//==================================================================================================
//
//
//
//==================================================================================================
class ProgramOptions
{
public:
enum OptionPrefix
{
DOUBLE_DASH,
SINGLE_DASH,
SLASH
};
enum ValueReq
{
NO_VALUE, // A flag option that does not accept any values
SINGLE_VALUE, // Option requires exactly one single value, no more, no less
MULTI_VALUE, // Option requires one or more values
OPTIONAL_MULTI_VALUE // Option can have none, one or more values
};
enum OptionFlag
{
COMBINE_REPEATED = 0x01, // When this flag is specified and an option occurs multiple times, the values will be combined. Default is for the last occurrence to win
UNDOCUMENTED = 0x02 // Will not be output in help text
};
typedef cvf::Flags<OptionFlag> OptionFlags;
public:
ProgramOptions();
~ProgramOptions();
void setOptionPrefix(OptionPrefix prefix);
bool registerOption(const String& optionName, ValueReq valueReq = NO_VALUE, OptionFlags optionFlags = OptionFlags());
bool registerOption(const String& optionName, const String& valueSyntax, const String& description, ValueReq valueReq = NO_VALUE, OptionFlags optionFlags = OptionFlags());
bool parse(const std::vector<String>& commandLineArguments);
bool hasOption(const String& optionName) const;
Option option(const String& optionName) const;
std::vector<String> values(const String& optionName) const;
String firstValue(const String& optionName) const;
std::vector<String> positionalParameters() const;
std::vector<String> unknownOptions() const;
std::vector<String> optionsWithMissingValues() const;
String usageText(int maxWidth, int maxOptionWidth = -1) const;
private:
class OptionSpec;
class ParsedOption;
String prefixString() const;
const OptionSpec* findOptionSpec(const String& optionName) const;
const ParsedOption* findParsedOption(const String& optionName) const;
ParsedOption* findParsedOption(const String& optionName);
void addNewParsedOption(ParsedOption* parsedOption);
static std::vector<String> breakStringIntoLines(const String& str, size_t maxCharsPerLine);
private:
OptionPrefix m_optionPrefix; // The prefix to use to identify options
Collection<OptionSpec> m_optionSpecs; // Collection of legal registered options
Collection<ParsedOption> m_parsedOptions; // The options we have successfully parsed
std::vector<String> m_positionalParams; // Array of positional parameters
std::vector<String> m_unknownOptions; // Unrecognized options
std::vector<String> m_optionsWithMissingValues; // Options that failed during parsing due to missing values
};
}
} //namespace external

View File

@@ -1,177 +0,0 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2013 Ceetron AS
//
// This library may be used under the terms of either the GNU General Public License or
// the GNU Lesser General Public License as follows:
//
// GNU General Public License Usage
// This library 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.
//
// This library 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 at <<http://www.gnu.org/licenses/gpl.html>>
// for more details.
//
// GNU Lesser General Public License Usage
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library 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 Lesser General Public License at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
// for more details.
//
//##################################################################################################
#include "cvfBase.h"
#include "cvfPropertySetCollection.h"
namespace external {
namespace cvf {
//==================================================================================================
///
/// \class cvf::PropertySetCollection
/// \ingroup Core
///
///
///
//==================================================================================================
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
PropertySetCollection::PropertySetCollection()
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
PropertySetCollection::~PropertySetCollection()
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
size_t PropertySetCollection::count() const
{
return m_propertySets.size();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
PropertySet* PropertySetCollection::propertySet(size_t index)
{
CVF_ASSERT(index < m_propertySets.size());
return m_propertySets.at(index);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const PropertySet* PropertySetCollection::propertySet(size_t index) const
{
CVF_ASSERT(index < m_propertySets.size());
return m_propertySets.at(index);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void PropertySetCollection::addPropertySet(PropertySet* propertySet)
{
CVF_ASSERT(propertySet);
m_propertySets.push_back(propertySet);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
size_t PropertySetCollection::countOfType(const String& classType) const
{
size_t classCount = 0;
const size_t totNumSets = m_propertySets.size();
for (size_t i = 0; i < totNumSets; i++)
{
const PropertySet* ps = m_propertySets.at(i);
if (ps->classType() == classType)
{
classCount++;
}
}
return classCount;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
PropertySet* PropertySetCollection::propertySetOfType(const String& classType, size_t index)
{
size_t classCount = 0;
const size_t totNumSets = m_propertySets.size();
for (size_t i = 0; i < totNumSets; i++)
{
PropertySet* ps = m_propertySets.at(i);
if (ps->classType() == classType)
{
if (classCount == index)
{
return ps;
}
classCount++;
}
}
CVF_FAIL_MSG("Specified index is of of range");
return NULL;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
PropertySet* PropertySetCollection::firstPropertySetOfType(const String& classType)
{
const size_t totNumSets = m_propertySets.size();
for (size_t i = 0; i < totNumSets; i++)
{
PropertySet* ps = m_propertySets.at(i);
if (ps->classType() == classType)
{
return ps;
}
}
return NULL;
}
} // namespace gc
} //namespace external

View File

@@ -1,76 +0,0 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2013 Ceetron AS
//
// This library may be used under the terms of either the GNU General Public License or
// the GNU Lesser General Public License as follows:
//
// GNU General Public License Usage
// This library 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.
//
// This library 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 at <<http://www.gnu.org/licenses/gpl.html>>
// for more details.
//
// GNU Lesser General Public License Usage
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library 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 Lesser General Public License at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
// for more details.
//
//##################################################################################################
#pragma once
#include "cvfObject.h"
#include "cvfPropertySet.h"
#include "cvfCollection.h"
#include <map>
namespace external {
namespace cvf {
//==================================================================================================
//
//
//
//==================================================================================================
class PropertySetCollection : public Object
{
public:
PropertySetCollection();
~PropertySetCollection();
size_t count() const;
PropertySet* propertySet(size_t index);
const PropertySet* propertySet(size_t index) const;
void addPropertySet(PropertySet* propertySet);
size_t countOfType(const String& classType) const;
PropertySet* propertySetOfType(const String& classType, size_t index);
PropertySet* firstPropertySetOfType(const String& classType);
private:
Collection<PropertySet> m_propertySets;
};
} // namespace cvf
} //namespace external

View File

@@ -1,88 +0,0 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2013 Ceetron AS
//
// This library may be used under the terms of either the GNU General Public License or
// the GNU Lesser General Public License as follows:
//
// GNU General Public License Usage
// This library 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.
//
// This library 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 at <<http://www.gnu.org/licenses/gpl.html>>
// for more details.
//
// GNU Lesser General Public License Usage
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library 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 Lesser General Public License at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
// for more details.
//
//##################################################################################################
#include "cvfBase.h"
#include "cvfTBBControl.h"
namespace external {
namespace cvf {
//==================================================================================================
///
/// \class cvf::TBBControl
/// \ingroup Core
///
/// Static class used to enable or disable the use of Intel TBB inside the libraries.
/// Only relevant if the libraries are being built with TBB support, in which case the default
/// enable setting will be true. If no TBB support is compiled in, the default enable state is false.
///
//==================================================================================================
#ifdef CVF_USE_TBB
bool TBBControl::sm_useTBB = true;
#else
bool TBBControl::sm_useTBB = false;
#endif
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void TBBControl::enable(bool enableTBB)
{
#ifdef CVF_USE_TBB
sm_useTBB = enableTBB;
#else
CVF_UNUSED(enableTBB);
#endif
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool TBBControl::isEnabled()
{
return sm_useTBB;
}
} // namespace cvf
} //namespace external

View File

@@ -1,276 +0,0 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2013 Ceetron AS
//
// This library may be used under the terms of either the GNU General Public License or
// the GNU Lesser General Public License as follows:
//
// GNU General Public License Usage
// This library 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.
//
// This library 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 at <<http://www.gnu.org/licenses/gpl.html>>
// for more details.
//
// GNU Lesser General Public License Usage
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library 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 Lesser General Public License at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
// for more details.
//
//##################################################################################################
#include "cvfBase.h"
#include "cvfTimer.h"
#ifdef WIN32
#pragma warning (push)
#pragma warning (disable: 4668)
#include <windows.h>
#pragma warning (pop)
#endif
#if defined(CVF_LINUX) || defined(CVF_ANDROID)
#include <time.h>
#endif
#if defined(CVF_IOS) || defined(CVF_OSX)
#include "mach/mach_time.h"
#endif
namespace external {
namespace cvf {
//=================================================================================================
//
// PrivateTimerState
//
//=================================================================================================
#ifdef WIN32
class PrivateTimerState
{
public:
PrivateTimerState()
{
m_ticksPerSecond = 0;
m_startTick = 0;
m_lastLapTick = 0;
LARGE_INTEGER freq;
if (QueryPerformanceFrequency(&freq))
{
m_ticksPerSecond = freq.QuadPart;
}
}
__int64 m_ticksPerSecond;
__int64 m_startTick;
__int64 m_lastLapTick;
};
#endif //WIN32
#if defined(CVF_LINUX) || defined(CVF_ANDROID)
class PrivateTimerState
{
public:
PrivateTimerState()
{
m_timeStart.tv_sec = 0;
m_timeStart.tv_nsec = 0;
m_timeMark.tv_sec = 0;
m_timeMark.tv_nsec = 0;
}
timespec m_timeStart;
timespec m_timeMark;
};
#endif // CVF_LINUX || CVF_ANDROID
#if defined(CVF_IOS) || defined(CVF_OSX)
class PrivateTimerState
{
public:
PrivateTimerState()
{
mach_timebase_info(&m_info);
m_startTime = 0;
m_lastLapTime = 0;
}
mach_timebase_info_data_t m_info;
uint64_t m_startTime;
uint64_t m_lastLapTime;
};
#endif // CVF_IOS || CVF_OSX
//--------------------------------------------------------------------------------------------------
/// Static helper on Linux to compute difference between two timespecs
//--------------------------------------------------------------------------------------------------
#if defined(CVF_LINUX) || defined(CVF_ANDROID)
static timespec ComputeTimespecDiff(const timespec start, const timespec end)
{
timespec temp;
if ((end.tv_nsec - start.tv_nsec) < 0)
{
temp.tv_sec = end.tv_sec - start.tv_sec - 1;
temp.tv_nsec = 1000000000 + end.tv_nsec-start.tv_nsec;
}
else
{
temp.tv_sec = end.tv_sec - start.tv_sec;
temp.tv_nsec = end.tv_nsec - start.tv_nsec;
}
return temp;
}
#endif
//==================================================================================================
///
/// \class cvf::Timer
/// \ingroup Core
///
/// Timer class
///
//==================================================================================================
//--------------------------------------------------------------------------------------------------
/// Start the timer.
//--------------------------------------------------------------------------------------------------
Timer::Timer()
{
m_timerState = new PrivateTimerState;
restart();
}
//--------------------------------------------------------------------------------------------------
/// Cleanup
//--------------------------------------------------------------------------------------------------
Timer::~Timer()
{
delete m_timerState;
}
//--------------------------------------------------------------------------------------------------
/// Restart timer and laptime
//--------------------------------------------------------------------------------------------------
void Timer::restart()
{
CVF_ASSERT(m_timerState);
#ifdef WIN32
LARGE_INTEGER tick;
QueryPerformanceCounter(&tick);
m_timerState->m_startTick = tick.QuadPart;
m_timerState->m_lastLapTick = m_timerState->m_startTick;
#elif defined(CVF_LINUX) || defined(CVF_ANDROID)
clock_gettime(CLOCK_MONOTONIC, &m_timerState->m_timeStart);
m_timerState->m_timeMark = m_timerState->m_timeStart;
#elif defined(CVF_IOS) || defined(CVF_OSX)
m_timerState->m_startTime = mach_absolute_time();
m_timerState->m_lastLapTime = m_timerState->m_startTime;
#endif
}
//--------------------------------------------------------------------------------------------------
/// Get the time elapsed since the start, in seconds
//--------------------------------------------------------------------------------------------------
double Timer::time() const
{
#ifdef WIN32
if (m_timerState->m_ticksPerSecond == 0) return 0.0;
LARGE_INTEGER nowTick;
QueryPerformanceCounter(&nowTick);
return static_cast<double>((nowTick.QuadPart - m_timerState->m_startTick))/static_cast<double>(m_timerState->m_ticksPerSecond);
#elif defined(CVF_LINUX) || defined(CVF_ANDROID)
timespec timeNow;
clock_gettime(CLOCK_MONOTONIC, &timeNow);
timespec timeDiff = ComputeTimespecDiff(m_timerState->m_timeStart, timeNow);
double timeUsedSec = static_cast<double>(timeDiff.tv_sec) + static_cast<double>(timeDiff.tv_nsec)/1000000000.0;
return timeUsedSec;
#elif defined(CVF_IOS) || defined(CVF_OSX)
uint64_t timeNow = mach_absolute_time();
uint64_t timeUsed = timeNow - m_timerState->m_startTime;
timeUsed *= m_timerState->m_info.numer;
uint64_t timeUsedNanoSec = timeUsed/m_timerState->m_info.denom;
double timeUsedSec = timeUsedNanoSec/1.0e9;
return timeUsedSec;
#endif
}
//--------------------------------------------------------------------------------------------------
/// Get elapsed time since last lap, in seconds
//--------------------------------------------------------------------------------------------------
double Timer::lapTime()
{
#ifdef WIN32
if (m_timerState->m_ticksPerSecond == 0) return 0.0;
LARGE_INTEGER nowTick;
QueryPerformanceCounter(&nowTick);
double lapTime = static_cast<double>((nowTick.QuadPart - m_timerState->m_lastLapTick))/static_cast<double>(m_timerState->m_ticksPerSecond);
m_timerState->m_lastLapTick = nowTick.QuadPart;
#elif defined(CVF_LINUX) || defined(CVF_ANDROID)
timespec timeNow;
clock_gettime(CLOCK_MONOTONIC, &timeNow);
timespec timeDiff = ComputeTimespecDiff(m_timerState->m_timeMark, timeNow);
m_timerState->m_timeMark = timeNow;
double lapTime = static_cast<double>(timeDiff.tv_sec) + static_cast<double>(timeDiff.tv_nsec)/1000000000.0;
#elif defined(CVF_IOS) || defined(CVF_OSX)
uint64_t timeNow = mach_absolute_time();
uint64_t timeUsed = timeNow - m_timerState->m_lastLapTime;
timeUsed *= m_timerState->m_info.numer;
uint64_t timeUsedNanoSec = timeUsed/m_timerState->m_info.denom;
double lapTime = timeUsedNanoSec/1.0e9;
m_timerState->m_lastLapTime = timeNow;
#endif
return lapTime;
}
} // namespace cvf
} //namespace external

View File

@@ -1,165 +0,0 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2013 Ceetron AS
//
// This library may be used under the terms of either the GNU General Public License or
// the GNU Lesser General Public License as follows:
//
// GNU General Public License Usage
// This library 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.
//
// This library 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 at <<http://www.gnu.org/licenses/gpl.html>>
// for more details.
//
// GNU Lesser General Public License Usage
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library 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 Lesser General Public License at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
// for more details.
//
//##################################################################################################
#include "cvfBase.h"
#include "cvfTrace.h"
#include "cvfSystem.h"
#ifdef WIN32
#pragma warning (push)
#pragma warning (disable: 4668)
#include <windows.h>
#pragma warning (pop)
#else
#include <cstdio>
#include <cstdarg>
#endif
#ifdef CVF_ANDROID
#include <android/log.h>
#endif
namespace external {
namespace cvf {
//==================================================================================================
///
/// \class cvf::Trace
/// \ingroup Core
///
/// Class for writing debug text to console, DevStudio output window and file (future)
///
/// TODO: Create file output.
///
//==================================================================================================
//--------------------------------------------------------------------------------------------------
/// Write debug text to console, DevStudio output window and file (future)
//--------------------------------------------------------------------------------------------------
void Trace::show(String message)
{
showTraceOutput(message, true);
}
//--------------------------------------------------------------------------------------------------
/// Write printf formatted debug text to console, DevStudio output window and file (future)
//--------------------------------------------------------------------------------------------------
void Trace::show(const char* format, ...)
{
// Create the printf-style string and send it to the console and trace file
// TODO! Note: var-arg is solved locally here, but needs to be revisited e.g. in String class
va_list argList;
va_start(argList, format);
const int maxFormatLength = 4000;
char temp[maxFormatLength + 1];
#ifdef WIN32
_vsnprintf_s(temp, maxFormatLength, format, argList);
#elif defined(CVF_ANDROID)
__android_log_print(ANDROID_LOG_DEBUG, "CVF_TAG", format, argList);
#else
vsprintf(temp, format, argList);
#endif
va_end(argList);
showTraceOutput(temp, true);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void Trace::showFileLineNumber(const String& file, int line, const String& message)
{
String tmp = file + "(" + String(line) + ")";
if (!message.isEmpty())
{
tmp += ": msg: " + message;
}
Trace::show(tmp);
}
//--------------------------------------------------------------------------------------------------
/// Show the trace output in console and DevStudio output window
//--------------------------------------------------------------------------------------------------
void Trace::showTraceOutput(String text, bool addNewLine)
{
#ifdef WIN32
AllocConsole();
HANDLE hStdOutputHandle = GetStdHandle(STD_OUTPUT_HANDLE);
if (hStdOutputHandle)
{
unsigned long iDum = 0;
CharArray ascii = text.toAscii();
DWORD stringLength = static_cast<DWORD>(System::strlen(ascii.ptr()));
WriteConsoleA(hStdOutputHandle, ascii.ptr(), stringLength, &iDum, NULL);
if (addNewLine) WriteConsole(hStdOutputHandle, "\n", 1, &iDum, NULL);
}
#elif defined(CVF_ANDROID)
__android_log_print(ANDROID_LOG_DEBUG, "CVF_TAG", "%s", text.toAscii().ptr());
#else
fprintf(stderr, "%s", text.toAscii().ptr());
if (addNewLine)
{
fprintf(stderr, "\n");
}
#endif
// Show output in "Output window" in Visual Studio
#if defined(WIN32) && defined(_DEBUG)
// Alternativly use OutputDebugStringA(text.toAscii().ptr()); if this does not work on some platforms
_RPT0(_CRT_WARN, text.toAscii().ptr());
if (addNewLine)
{
_RPT0(_CRT_WARN, "\n");
}
#endif
}
} // namespace cvf
} //namespace external

View File

@@ -1,454 +0,0 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2013 Ceetron AS
//
// This library may be used under the terms of either the GNU General Public License or
// the GNU Lesser General Public License as follows:
//
// GNU General Public License Usage
// This library 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.
//
// This library 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 at <<http://www.gnu.org/licenses/gpl.html>>
// for more details.
//
// GNU Lesser General Public License Usage
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library 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 Lesser General Public License at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
// for more details.
//
//##################################################################################################
#include "cvfBase.h"
#include "cvfVariant.h"
namespace external {
namespace cvf {
//==================================================================================================
///
/// \class cvf::Variant
/// \ingroup Core
///
///
///
//==================================================================================================
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
Variant::Variant()
: m_type(INVALID)
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
Variant::Variant(const Variant& other)
: m_type(other.m_type),
m_data(other.m_data),
m_arrayData(other.m_arrayData)
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
Variant::~Variant()
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
Variant& Variant::operator=(Variant rhs)
{
// Copy-and-swap (copy already done since parameter is passed by value)
rhs.swap(*this);
return *this;
}
//--------------------------------------------------------------------------------------------------
/// Compares two variants and returns true if they are equal
//--------------------------------------------------------------------------------------------------
bool Variant::operator==(const Variant& rhs) const
{
if (m_type != rhs.m_type)
{
return false;
}
switch (m_type)
{
case INVALID: return true;
case INT: return getInt() == rhs.getInt();
case UINT: return getUInt() == rhs.getUInt();
case DOUBLE: return getDouble() == rhs.getDouble();
case FLOAT: return getFloat() == rhs.getFloat();
case BOOL: return getBool() == rhs.getBool();
case VEC3D: return getVec3d() == rhs.getVec3d();
case COLOR3F: return getColor3f() == rhs.getColor3f();
case STRING: return getString() == rhs.getString();
case ARRAY: return getArray() == rhs.getArray();
}
CVF_FAIL_MSG("Unhandled variant type");
return false;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
Variant::Type Variant::type() const
{
return m_type;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool Variant::isValid() const
{
return (m_type != INVALID);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
Variant::Variant(int val)
: m_type(INT)
{
assignData(&val, sizeof(val));
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
int Variant::getInt() const
{
CVF_ASSERT(m_type == INT);
CVF_ASSERT(m_data.size() == sizeof(int));
const ubyte* rawPtr = m_data.empty() ? 0 : &m_data.front();
if (rawPtr)
{
const int* valPtr = reinterpret_cast<const int*>(rawPtr);
return *valPtr;
}
else
{
return 0;
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
Variant::Variant(uint val)
: m_type(UINT)
{
assignData(&val, sizeof(val));
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
uint Variant::getUInt() const
{
CVF_ASSERT(m_type == UINT);
CVF_ASSERT(m_data.size() == sizeof(uint));
const ubyte* rawPtr = m_data.empty() ? 0 : &m_data.front();
if (rawPtr)
{
const uint* valPtr = reinterpret_cast<const uint*>(rawPtr);
return *valPtr;
}
else
{
return 0;
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
Variant::Variant(double val)
: m_type(DOUBLE)
{
assignData(&val, sizeof(val));
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double Variant::getDouble() const
{
CVF_ASSERT(m_type == DOUBLE);
CVF_ASSERT(m_data.size() == sizeof(double));
const ubyte* rawPtr = m_data.empty() ? 0 : &m_data.front();
if (rawPtr)
{
const double* valPtr = reinterpret_cast<const double*>(rawPtr);
return *valPtr;
}
else
{
return 0;
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
Variant::Variant(float val)
: m_type(FLOAT)
{
assignData(&val, sizeof(val));
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
float Variant::getFloat() const
{
CVF_ASSERT(m_type == FLOAT);
CVF_ASSERT(m_data.size() == sizeof(float));
const ubyte* rawPtr = m_data.empty() ? 0 : &m_data.front();
if (rawPtr)
{
const float* valPtr = reinterpret_cast<const float*>(rawPtr);
return *valPtr;
}
else
{
return 0;
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
Variant::Variant(bool val)
: m_type(BOOL)
{
ubyte tmpVal = val ? 1u : 0;
assignData(&tmpVal, 1);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool Variant::getBool() const
{
CVF_ASSERT(m_type == BOOL);
CVF_ASSERT(m_data.size() == 1);
const ubyte* rawPtr = m_data.empty() ? 0 : &m_data.front();
if (rawPtr)
{
if (*rawPtr == 1u)
{
return true;
}
else
{
return false;
}
}
else
{
return false;
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
Variant::Variant(const Vec3d& val)
: m_type(VEC3D)
{
assignData(val.ptr(), 3*sizeof(double));
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
Vec3d Variant::getVec3d() const
{
CVF_ASSERT(m_type == VEC3D);
CVF_ASSERT(m_data.size() == 3*sizeof(double));
const ubyte* rawPtr = m_data.empty() ? 0 : &m_data.front();
if (rawPtr)
{
const double* valPtr = reinterpret_cast<const double*>(rawPtr);
return Vec3d(valPtr[0], valPtr[1], valPtr[2]);
}
else
{
return Vec3d(0, 0, 0);
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
Variant::Variant(const Color3f& val)
: m_type(COLOR3F)
{
assignData(val.ptr(), 3*sizeof(float));
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
Color3f Variant::getColor3f() const
{
CVF_ASSERT(m_type == COLOR3F);
CVF_ASSERT(m_data.size() == 3*sizeof(float));
const ubyte* rawPtr = m_data.empty() ? 0 : &m_data.front();
if (rawPtr)
{
const float* valPtr = reinterpret_cast<const float*>(rawPtr);
return Color3f(valPtr[0], valPtr[1], valPtr[2]);
}
else
{
return Color3f(0, 0, 0);
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
Variant::Variant(const String& val)
: m_type(STRING)
{
size_t strSize = val.size();
if (strSize > 0)
{
assignData(val.c_str(), strSize*sizeof(wchar_t));
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
Variant::Variant(const char* val)
: m_type(STRING)
{
String strVal(val);
size_t strSize = strVal.size();
if (strSize > 0)
{
assignData(strVal.c_str(), strSize*sizeof(wchar_t));
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
Variant::Variant(const std::vector<Variant>& arr)
: m_type(ARRAY),
m_arrayData(arr)
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<Variant> Variant::getArray() const
{
CVF_ASSERT(m_type == ARRAY);
return m_arrayData;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
String Variant::getString() const
{
CVF_ASSERT(m_type == STRING);
// Array must contain at least one wchar_t
const ubyte* rawPtr = m_data.empty() ? 0 : &m_data.front();
const size_t numWideCars = m_data.size()/sizeof(wchar_t);
if (rawPtr && numWideCars > 0)
{
const wchar_t* valPtr = reinterpret_cast<const wchar_t*>(rawPtr);
std::wstring tmpWideString(valPtr, numWideCars);
return String(tmpWideString);
}
else
{
return String();
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void Variant::swap(Variant& other)
{
std::swap(m_type, other.m_type);
m_data.swap(other.m_data);
m_arrayData.swap(other.m_arrayData);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void Variant::assignData(const void* pointerToData, size_t dataSizeInBytes)
{
CVF_ASSERT(m_arrayData.size() == 0);
m_data.assign(reinterpret_cast<const ubyte*>(pointerToData), reinterpret_cast<const ubyte*>(pointerToData) + dataSizeInBytes);
CVF_ASSERT(m_data.size() == dataSizeInBytes);
}
} // namespace gc
} //namespace external

View File

@@ -1,118 +0,0 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2013 Ceetron AS
//
// This library may be used under the terms of either the GNU General Public License or
// the GNU Lesser General Public License as follows:
//
// GNU General Public License Usage
// This library 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.
//
// This library 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 at <<http://www.gnu.org/licenses/gpl.html>>
// for more details.
//
// GNU Lesser General Public License Usage
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library 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 Lesser General Public License at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
// for more details.
//
//##################################################################################################
#pragma once
#include "cvfVector3.h"
#include "cvfColor3.h"
#include "cvfString.h"
#include <string>
#include <vector>
namespace external {
namespace cvf {
//==================================================================================================
//
//
//
//==================================================================================================
class Variant
{
public:
enum Type
{
INVALID,
INT,
UINT,
DOUBLE,
FLOAT,
BOOL,
VEC3D,
COLOR3F,
STRING,
ARRAY
};
public:
Variant();
Variant(const Variant& other);
~Variant();
Variant(int val);
Variant(uint val);
Variant(double val);
Variant(float val);
Variant(bool val);
Variant(const Vec3d& val);
Variant(const Color3f& val);
Variant(const String& val);
Variant(const char* val);
Variant(const std::vector<Variant>& arr);
Variant& operator=(Variant rhs);
bool operator==(const Variant& rhs) const;
Type type() const;
bool isValid() const;
int getInt() const;
uint getUInt() const;
double getDouble() const;
float getFloat() const;
bool getBool() const;
Vec3d getVec3d() const;
Color3f getColor3f() const;
cvf::String getString() const;
std::vector<Variant> getArray() const;
void swap(Variant& other);
private:
void assignData(const void* pointerToData, size_t dataSizeInBytes);
private:
Type m_type; // Type of for this variant
std::vector<ubyte> m_data; // Data payload for single values
std::vector<Variant> m_arrayData;// Data payload when storing an array (of variants)
};
} // namespace cvf
} //namespace external

View File

@@ -1,52 +0,0 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2013 Ceetron AS
//
// This library may be used under the terms of either the GNU General Public License or
// the GNU Lesser General Public License as follows:
//
// GNU General Public License Usage
// This library 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.
//
// This library 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 at <<http://www.gnu.org/licenses/gpl.html>>
// for more details.
//
// GNU Lesser General Public License Usage
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library 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 Lesser General Public License at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
// for more details.
//
//##################################################################################################
#include "cvfBase.h"
#include "cvfVector2.h"
namespace external {
namespace cvf {
template<> Vector2<double> const Vector2<double>::UNDEFINED(UNDEFINED_DOUBLE, UNDEFINED_DOUBLE);
template<> Vector2<float> const Vector2<float>::UNDEFINED(UNDEFINED_FLOAT, UNDEFINED_FLOAT);
template<> Vector2<int> const Vector2<int>::UNDEFINED(UNDEFINED_INT, UNDEFINED_INT);
} // namespace cvf
} //namespace external

View File

@@ -1,52 +0,0 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2013 Ceetron AS
//
// This library may be used under the terms of either the GNU General Public License or
// the GNU Lesser General Public License as follows:
//
// GNU General Public License Usage
// This library 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.
//
// This library 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 at <<http://www.gnu.org/licenses/gpl.html>>
// for more details.
//
// GNU Lesser General Public License Usage
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library 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 Lesser General Public License at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
// for more details.
//
//##################################################################################################
#include "cvfBase.h"
#include "cvfVector4.h"
#include "cvfMath.h"
namespace external {
namespace cvf {
template<> Vector4<double> const Vector4<double>::UNDEFINED(UNDEFINED_DOUBLE, UNDEFINED_DOUBLE, UNDEFINED_DOUBLE, UNDEFINED_DOUBLE);
template<> Vector4<float> const Vector4<float>::UNDEFINED(UNDEFINED_FLOAT, UNDEFINED_FLOAT, UNDEFINED_FLOAT, UNDEFINED_FLOAT);
template<> Vector4<int> const Vector4<int>::UNDEFINED(UNDEFINED_INT, UNDEFINED_INT, UNDEFINED_INT, UNDEFINED_INT);
} // namespace cvf
} //namespace external

View File

@@ -1,120 +0,0 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2013 Ceetron AS
//
// This library may be used under the terms of either the GNU General Public License or
// the GNU Lesser General Public License as follows:
//
// GNU General Public License Usage
// This library 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.
//
// This library 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 at <<http://www.gnu.org/licenses/gpl.html>>
// for more details.
//
// GNU Lesser General Public License Usage
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library 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 Lesser General Public License at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
// for more details.
//
//##################################################################################################
#include "cvfBase.h"
#include "cvfArrowGenerator.h"
#include "cvfGeometryUtils.h"
namespace external {
namespace cvf {
//==================================================================================================
///
/// \class cvf::ArrowGenerator
/// \ingroup Geometry
///
/// Creates an arrow starting in origin and pointing in the direction of the +Z axis
///
//==================================================================================================
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
ArrowGenerator::ArrowGenerator()
: m_shaftRelativeRadius(0.025f),
m_headRelativeRadius(0.085f),
m_headRelativeLength(0.25f),
m_numSlices(20)
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void ArrowGenerator::setShaftRelativeRadius(float shaftRelativeRadius)
{
m_shaftRelativeRadius = shaftRelativeRadius;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void ArrowGenerator::setHeadRelativeRadius(float headRelativeRadius)
{
m_headRelativeRadius = headRelativeRadius;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void ArrowGenerator::setHeadRelativeLength(float headRelativeLength)
{
m_headRelativeLength = headRelativeLength;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void ArrowGenerator::setNumSlices(uint numSlices)
{
m_numSlices = numSlices;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void ArrowGenerator::generate(GeometryBuilder* builder)
{
const uint numPolysZDir = 1;
GeometryUtils::createObliqueCylinder(m_shaftRelativeRadius, m_shaftRelativeRadius, 1.0f - m_headRelativeLength, 0, 0, m_numSlices, true, true, false, numPolysZDir, builder);
uint startIdx = builder->vertexCount();
GeometryUtils::createCone(m_headRelativeRadius, m_headRelativeLength, m_numSlices, true, true, true, builder);
uint endIdx = builder->vertexCount() - 1;
Mat4f mat = Mat4f::fromTranslation(Vec3f(0, 0, 1.0f - m_headRelativeLength));
builder->transformVertexRange(startIdx, endIdx, mat);
}
} // namespace cvf
} //namespace external

View File

@@ -1,72 +0,0 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2013 Ceetron AS
//
// This library may be used under the terms of either the GNU General Public License or
// the GNU Lesser General Public License as follows:
//
// GNU General Public License Usage
// This library 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.
//
// This library 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 at <<http://www.gnu.org/licenses/gpl.html>>
// for more details.
//
// GNU Lesser General Public License Usage
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library 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 Lesser General Public License at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
// for more details.
//
//##################################################################################################
#pragma once
namespace external {
namespace cvf {
class GeometryBuilder;
//==================================================================================================
//
// Generates an arrow with base in origin and pointing in the +Z direction
//
//==================================================================================================
class ArrowGenerator
{
public:
ArrowGenerator();
void setShaftRelativeRadius(float shaftRelativeRadius);
void setHeadRelativeRadius(float headRelativeRadius);
void setHeadRelativeLength(float headRelativeLength);
void setNumSlices(uint numSlices);
void generate(GeometryBuilder* builder);
private:
float m_shaftRelativeRadius;
float m_headRelativeRadius;
float m_headRelativeLength;
uint m_numSlices;
};
}
} //namespace external

View File

@@ -1,193 +0,0 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2013 Ceetron AS
//
// This library may be used under the terms of either the GNU General Public License or
// the GNU Lesser General Public License as follows:
//
// GNU General Public License Usage
// This library 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.
//
// This library 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 at <<http://www.gnu.org/licenses/gpl.html>>
// for more details.
//
// GNU Lesser General Public License Usage
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library 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 Lesser General Public License at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
// for more details.
//
//##################################################################################################
#include "cvfBase.h"
#include "cvfBoxGenerator.h"
#include "cvfPatchGenerator.h"
#include "cvfGeometryUtils.h"
namespace external {
namespace cvf {
//==================================================================================================
///
/// \class cvf::BoxGenerator
/// \ingroup Geometry
///
/// Generates axis aligned box
///
//==================================================================================================
//--------------------------------------------------------------------------------------------------
/// Default constructor
///
/// Will generate a box with one corner in (0,0,0) and the other corner in (1,1,1).
/// Tesselation will be done using one quad for each of the box's six faces.
//--------------------------------------------------------------------------------------------------
BoxGenerator::BoxGenerator()
: m_minCoord(0, 0, 0),
m_maxCoord(1, 1, 1),
m_subdivisions(1, 1, 1)
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void BoxGenerator::setMinMax(const Vec3d& minCoord, const Vec3d& maxCoord)
{
m_minCoord = minCoord;
m_maxCoord = maxCoord;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void BoxGenerator::setOriginAndExtent(const Vec3d& origin, const Vec3d& extent)
{
m_minCoord = origin;
m_maxCoord = origin + extent;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void BoxGenerator::setCenterAndExtent(const Vec3d& center, const Vec3d& extent)
{
m_minCoord = center - extent/2;
m_maxCoord = center + extent/2;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void BoxGenerator::setSubdivisions(uint subdivX, uint subdivY, uint subdivZ)
{
CVF_ASSERT(subdivX > 0);
CVF_ASSERT(subdivY > 0);
CVF_ASSERT(subdivZ > 0);
m_subdivisions.set(subdivX, subdivY, subdivZ);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void BoxGenerator::generate(GeometryBuilder* builder)
{
uint cellCountX = m_subdivisions.x();
uint cellCountY = m_subdivisions.y();
uint cellCountZ = m_subdivisions.z();
CVF_ASSERT(cellCountX > 0);
CVF_ASSERT(cellCountY > 0);
CVF_ASSERT(cellCountZ > 0);
if (cellCountX == 1 && cellCountY == 1 && cellCountZ == 1)
{
GeometryUtils::createBox(Vec3f(m_minCoord), Vec3f(m_maxCoord), builder);
return;
}
// Face ordering is
//
// *---------* Faces:
// /| /| |z 0 bottom
// / | / | | /y 1 top
// *---------* | |/ 2 front
// | 3------|--* *---x 3 right
// | / | / 4 back
// |/ |/ 5 left
// *---------*
const Vec3d extent(m_maxCoord - m_minCoord);
PatchGenerator patchGen;
// Bottom
patchGen.setOrigin(Vec3d(m_minCoord.x(), m_minCoord.y(), m_minCoord.z()));
patchGen.setAxes(Vec3d::Y_AXIS, Vec3d::X_AXIS);
patchGen.setExtent(extent.y(), extent.x());
patchGen.setSubdivisions(cellCountY, cellCountX);
patchGen.generate(builder);
// Top
patchGen.setOrigin(Vec3d(m_minCoord.x(), m_minCoord.y(), m_maxCoord.z()));
patchGen.setAxes(Vec3d::X_AXIS, Vec3d::Y_AXIS);
patchGen.setExtent(extent.x(), extent.y());
patchGen.setSubdivisions(cellCountX, cellCountY);
patchGen.generate(builder);
// Front
patchGen.setOrigin(Vec3d(m_minCoord.x(), m_minCoord.y(), m_minCoord.z()));
patchGen.setAxes(Vec3d::X_AXIS, Vec3d::Z_AXIS);
patchGen.setExtent(extent.x(), extent.z());
patchGen.setSubdivisions(cellCountX, cellCountZ);
patchGen.generate(builder);
// Right
patchGen.setOrigin(Vec3d(m_maxCoord.x(), m_minCoord.y(), m_minCoord.z()));
patchGen.setAxes(Vec3d::Y_AXIS, Vec3d::Z_AXIS);
patchGen.setExtent(extent.y(), extent.z());
patchGen.setSubdivisions(cellCountY, cellCountZ);
patchGen.generate(builder);
// Back
patchGen.setOrigin(Vec3d(m_maxCoord.x(), m_maxCoord.y(), m_minCoord.z()));
patchGen.setAxes(-Vec3d::X_AXIS, Vec3d::Z_AXIS);
patchGen.setExtent(extent.x(), extent.z());
patchGen.setSubdivisions(cellCountX, cellCountZ);
patchGen.generate(builder);
// Left
patchGen.setOrigin(Vec3d(m_minCoord.x(), m_maxCoord.y(), m_minCoord.z()));
patchGen.setAxes(-Vec3d::Y_AXIS, Vec3d::Z_AXIS);
patchGen.setExtent(extent.y(), extent.z());
patchGen.setSubdivisions(cellCountY, cellCountZ);
patchGen.generate(builder);
}
} // namespace cvf
} //namespace external

View File

@@ -1,74 +0,0 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2013 Ceetron AS
//
// This library may be used under the terms of either the GNU General Public License or
// the GNU Lesser General Public License as follows:
//
// GNU General Public License Usage
// This library 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.
//
// This library 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 at <<http://www.gnu.org/licenses/gpl.html>>
// for more details.
//
// GNU Lesser General Public License Usage
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library 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 Lesser General Public License at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
// for more details.
//
//##################################################################################################
#pragma once
#include "cvfVector3.h"
namespace external {
namespace cvf {
class GeometryBuilder;
//==================================================================================================
//
// Generates an axis aligned box
//
//==================================================================================================
class BoxGenerator
{
public:
BoxGenerator();
void setMinMax(const Vec3d& minCoord, const Vec3d& maxCoord);
void setOriginAndExtent(const Vec3d& origin, const Vec3d& extent);
void setCenterAndExtent(const Vec3d& center, const Vec3d& extent);
void setSubdivisions(uint subdivX, uint subdivY, uint subdivZ);
void generate(GeometryBuilder* builder);
private:
Vec3d m_minCoord;
Vec3d m_maxCoord;
Vec3ui m_subdivisions; // Number of cells/quads in each direction. Default (1, 1, 1)
};
}
} //namespace external

View File

@@ -1,132 +0,0 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2013 Ceetron AS
//
// This library may be used under the terms of either the GNU General Public License or
// the GNU Lesser General Public License as follows:
//
// GNU General Public License Usage
// This library 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.
//
// This library 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 at <<http://www.gnu.org/licenses/gpl.html>>
// for more details.
//
// GNU Lesser General Public License Usage
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library 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 Lesser General Public License at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
// for more details.
//
//##################################################################################################
#include "cvfBase.h"
#include "cvfEdgeKey.h"
namespace external {
namespace cvf {
//==================================================================================================
///
/// \class cvf::EdgeKey
/// \ingroup Geometry
///
///
///
//==================================================================================================
EdgeKey::EdgeKey(uint vertexIdx1, uint vertexIdx2)
{
if (vertexIdx1 <= vertexIdx2)
{
m_vertexIdx1 = vertexIdx1;
m_vertexIdx2 = vertexIdx2;
}
else
{
m_vertexIdx1 = vertexIdx2;
m_vertexIdx2 = vertexIdx1;
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool EdgeKey::operator==(const EdgeKey& rhs) const
{
if (m_vertexIdx1 == rhs.m_vertexIdx1 && m_vertexIdx2 == rhs.m_vertexIdx2)
{
return true;
}
else
{
return false;
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool EdgeKey::operator<(const EdgeKey& rhs) const
{
if (m_vertexIdx1 == rhs.m_vertexIdx1)
{
return (m_vertexIdx2 < rhs.m_vertexIdx2);
}
else
{
return (m_vertexIdx1 < rhs.m_vertexIdx1);
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
int64 EdgeKey::toKeyVal() const
{
int64 edgeKey = m_vertexIdx1;
edgeKey <<= 32;
edgeKey += m_vertexIdx2;
return edgeKey;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
EdgeKey EdgeKey::fromkeyVal(int64 edgeKeyVal)
{
uint vertexIdx2 = static_cast<uint>(edgeKeyVal);
edgeKeyVal >>= 32;
uint vertexIdx1 = static_cast<uint>(edgeKeyVal);
return EdgeKey(vertexIdx1, vertexIdx2);
}
} // namespace cvf
} //namespace external

View File

@@ -1,73 +0,0 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2013 Ceetron AS
//
// This library may be used under the terms of either the GNU General Public License or
// the GNU Lesser General Public License as follows:
//
// GNU General Public License Usage
// This library 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.
//
// This library 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 at <<http://www.gnu.org/licenses/gpl.html>>
// for more details.
//
// GNU Lesser General Public License Usage
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library 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 Lesser General Public License at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
// for more details.
//
//##################################################################################################
#pragma once
namespace external {
namespace cvf {
//==================================================================================================
//
//
//
//==================================================================================================
class EdgeKey
{
public:
EdgeKey(uint vertexIdx1, uint vertexIdx2);
bool operator==(const EdgeKey& rhs) const;
bool operator<(const EdgeKey& rhs) const;
uint index1() const { return m_vertexIdx1; }
uint index2() const { return m_vertexIdx2; }
int64 toKeyVal() const;
static EdgeKey fromkeyVal(int64 edgeKeyVal);
private:
uint m_vertexIdx1; // The constructor ensures that index 1 is always the smallest
uint m_vertexIdx2; // of the two indices
};
}
} //namespace external

View File

@@ -1,233 +0,0 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2013 Ceetron AS
//
// This library may be used under the terms of either the GNU General Public License or
// the GNU Lesser General Public License as follows:
//
// GNU General Public License Usage
// This library 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.
//
// This library 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 at <<http://www.gnu.org/licenses/gpl.html>>
// for more details.
//
// GNU Lesser General Public License Usage
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library 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 Lesser General Public License at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
// for more details.
//
//##################################################################################################
#include "cvfBase.h"
#include "cvfBoundingBox.h"
#include "cvfFrustum.h"
namespace external {
namespace cvf {
//==================================================================================================
///
/// \class cvf::Frustum
/// \ingroup Geometry
///
/// Class defining a frustum
///
/// The frustum consists of 6 \link Plane Planes\endlink
///
//==================================================================================================
//--------------------------------------------------------------------------------------------------
/// Default constructor
//--------------------------------------------------------------------------------------------------
Frustum::Frustum()
{
}
//--------------------------------------------------------------------------------------------------
/// Copy constructor
//--------------------------------------------------------------------------------------------------
Frustum::Frustum(const Frustum& other)
: Object()
{
*this = other;
}
//--------------------------------------------------------------------------------------------------
/// Destructor
//--------------------------------------------------------------------------------------------------
Frustum::~Frustum()
{
}
//--------------------------------------------------------------------------------------------------
/// Assignment operator
//--------------------------------------------------------------------------------------------------
const Frustum& Frustum::operator=(const Frustum& rhs)
{
m_planes.clear();
std::map<int, Plane>::const_iterator it;
for (it = rhs.m_planes.begin(); it != rhs.m_planes.end(); it++)
{
m_planes[it->first] = it->second;
}
return *this;
}
//--------------------------------------------------------------------------------------------------
/// Equality operator
//--------------------------------------------------------------------------------------------------
bool Frustum::operator==(const Frustum& rhs) const
{
if (m_planes.size() != rhs.m_planes.size()) return false;
std::map<int, Plane>::const_iterator thisIt, rhsIt;
size_t i;
for (i = 0; i < m_planes.size(); i++)
{
int sideIdx = static_cast<int>(i);
thisIt = m_planes.find(sideIdx);
rhsIt = rhs.m_planes.find(sideIdx);
if (thisIt->first != rhsIt->first) return false;
if (thisIt->second != rhsIt->second) return false;
}
return true;
}
//--------------------------------------------------------------------------------------------------
/// Inequality operator
//--------------------------------------------------------------------------------------------------
bool Frustum::operator!=(const Frustum& rhs) const
{
return !operator==(rhs);
}
//--------------------------------------------------------------------------------------------------
/// Set one of the planes building up the frustum
//--------------------------------------------------------------------------------------------------
void Frustum::setPlane(Side side, const Plane& plane)
{
CVF_ASSERT(side < COUNT);
CVF_ASSERT(plane.isValid());
m_planes[side] = plane;
}
//--------------------------------------------------------------------------------------------------
/// Get one given Plane of the frustum.
///
/// \return The Plane queried or an invalid Plane if it does not exist.
//--------------------------------------------------------------------------------------------------
Plane Frustum::plane(Side side) const
{
std::map<int, Plane>::const_iterator it = m_planes.find(side);
return (it != m_planes.end()) ? it->second : Plane();
}
//--------------------------------------------------------------------------------------------------
/// Transforms all planes in the frustum with the given matrix
//--------------------------------------------------------------------------------------------------
void Frustum::transform(const Mat4d& matrix)
{
std::map<int, Plane>::iterator it;
for (it = m_planes.begin(); it != m_planes.end(); it++)
{
it->second.transform(matrix);
}
}
//--------------------------------------------------------------------------------------------------
/// Test point to see if it's outside the frustum or not
///
/// \return true if outside or exactly on the boundary. false if inside.
//--------------------------------------------------------------------------------------------------
bool Frustum::isOutside(const Vec3d& point) const
{
CVF_ASSERT(m_planes.size() == 6);
std::map<int, Plane>::const_iterator it;
for (it = m_planes.begin(); it != m_planes.end(); it++)
{
if (it->second.distanceSquared(point) < 0.0)
{
return true;
}
}
return false;
}
//--------------------------------------------------------------------------------------------------
/// Test bounding box to see if it's outside the frustum or not
///
/// \return true if outside or exactly on the boundary. false if inside.
//--------------------------------------------------------------------------------------------------
bool Frustum::isOutside(const BoundingBox& bbox) const
{
CVF_ASSERT(m_planes.size() == 6);
const Vec3d& boxMin = bbox.min();
const Vec3d& boxMax = bbox.max();
Vec3d point;
Vec3d planeNormal;
std::map<int, Plane>::const_iterator it;
for (it = m_planes.begin(); it != m_planes.end(); it++)
{
planeNormal = it->second.normal();
point.x() = (planeNormal.x() <= 0.0) ? boxMin.x() : boxMax.x();
point.y() = (planeNormal.y() <= 0.0) ? boxMin.y() : boxMax.y();
point.z() = (planeNormal.z() <= 0.0) ? boxMin.z() : boxMax.z();
if (it->second.distanceSquared(point) < 0.0)
{
return true;
}
}
return false;
}
} // namespace cvf
} //namespace external

View File

@@ -1,93 +0,0 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2013 Ceetron AS
//
// This library may be used under the terms of either the GNU General Public License or
// the GNU Lesser General Public License as follows:
//
// GNU General Public License Usage
// This library 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.
//
// This library 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 at <<http://www.gnu.org/licenses/gpl.html>>
// for more details.
//
// GNU Lesser General Public License Usage
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library 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 Lesser General Public License at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
// for more details.
//
//##################################################################################################
#pragma once
#include "cvfObject.h"
#include "cvfPlane.h"
#include <map>
namespace external {
namespace cvf {
class BoundingBox;
//=================================================================================================
//
// Frustum class
//
//=================================================================================================
class Frustum : public Object
{
public:
/// Sides of the frustum
enum Side
{
BOTTOM = 0, // Index based -> Must start with zero
TOP,
LEFT,
RIGHT,
FRONT,
BACK,
COUNT ///< Number of sides
};
public:
Frustum();
Frustum(const Frustum& other);
~Frustum();
const Frustum& operator=(const Frustum& other);
bool operator==(const Frustum& other) const;
bool operator!=(const Frustum& other) const;
void setPlane(Side side, const Plane& plane);
Plane plane(Side side) const;
void transform(const Mat4d& matrix);
bool isOutside(const Vec3d& point) const;
bool isOutside(const BoundingBox& bbox) const;
private:
std::map<int, Plane> m_planes;
};
}
} //namespace external

View File

@@ -1,367 +0,0 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2013 Ceetron AS
//
// This library may be used under the terms of either the GNU General Public License or
// the GNU Lesser General Public License as follows:
//
// GNU General Public License Usage
// This library 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.
//
// This library 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 at <<http://www.gnu.org/licenses/gpl.html>>
// for more details.
//
// GNU Lesser General Public License Usage
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library 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 Lesser General Public License at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
// for more details.
//
//##################################################################################################
#include "cvfBase.h"
#include "cvfGeometryBuilder.h"
namespace external {
namespace cvf {
//==================================================================================================
///
/// \class cvf::GeometryBuilder
/// \ingroup Geometry
///
/// Abstract base class for building geometry using the Builder pattern.
/// \sa GeometryUtils
///
//==================================================================================================
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void GeometryBuilder::setTotalVertexCountHint(size_t totalVertexCountHint)
{
CVF_UNUSED(totalVertexCountHint);
// Nothing here, may be used in derived classes
}
//--------------------------------------------------------------------------------------------------
/// \fn virtual int GeometryBuilder::addVertices(const Vec3fArray& vertices) = 0;
///
/// Add vertex coordinates
///
/// \return The resulting index of the first vertex in the \a vertices array.
//--------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------
/// \fn virtual int GeometryBuilder::addTriangle(int i0, int i1, int i2) = 0;
///
/// Add a single triangle by specifying the indices into the vertex array.
///
/// \sa addTriangles()
//--------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------
/// Add multiple triangles
///
/// \remarks There must be at least 3 entries in the \a indices array, and the total number of
/// entries must be a multiple of 3.
//--------------------------------------------------------------------------------------------------
void GeometryBuilder::addTriangles(const UIntArray& indices)
{
size_t numIndices = indices.size();
CVF_ASSERT(numIndices >= 3);
CVF_ASSERT(numIndices % 3 == 0);
size_t numTriangles = numIndices/3;
CVF_ASSERT(numTriangles >= 1);
CVF_ASSERT(3*numTriangles == numIndices);
size_t i;
for (i = 0; i < numTriangles; i++)
{
addTriangle(indices[3*i], indices[3*i + 1], indices[3*i + 2]);
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void GeometryBuilder::addTriangles(const IntArray& indices)
{
size_t numIndices = indices.size();
CVF_ASSERT(numIndices >= 3);
CVF_ASSERT(numIndices % 3 == 0);
size_t numTriangles = numIndices/3;
CVF_ASSERT(numTriangles >= 1);
CVF_ASSERT(3*numTriangles == numIndices);
size_t i;
for (i = 0; i < numTriangles; i++)
{
CVF_ASSERT(indices[3*i] >= 0 && indices[3*i + 1] && indices[3*i + 2]);
addTriangle(static_cast<uint>(indices[3*i]), static_cast<uint>(indices[3*i + 1]), static_cast<uint>(indices[3*i + 2]));
}
}
//--------------------------------------------------------------------------------------------------
/// Add a triangle fan
///
/// Vertex ordering for triangle fans:
/// <PRE>
/// v4 *-------* v3 Resulting triangles:
/// \ / \ t1: v0, v1, v2
/// \ / \ t2: v0, v2, v3
/// \ / \ t3: v0, v3, v4
/// v0 *-------* v2
/// \ /
/// \ /
/// \ /
/// * v1 </PRE>
///
/// \remarks The number of entries in the \a indices array must be at least 3.
//--------------------------------------------------------------------------------------------------
void GeometryBuilder::addTriangleFan(const UIntArray& indices)
{
size_t numIndices = indices.size();
CVF_ASSERT(numIndices >= 3);
size_t numTriangles = numIndices - 2;
CVF_ASSERT(numTriangles >= 1);
size_t i;
for (i = 0; i < numTriangles; i++)
{
addTriangle(indices[0], indices[i + 1], indices[i + 2]);
}
}
//--------------------------------------------------------------------------------------------------
/// Add a triangle strip
///
/// Vertex ordering for triangle strips:
/// <PRE>
/// v0 v2 v4 Resulting triangles:
/// *-------*-------* t1: v0, v1, v2
/// \ / \ / \ t2: v2, v1, v3
/// \ / \ / \ t3: v2, v3, v4
/// \ / \ / \ t4: v4, v3, v5
/// *-------*-------*
/// v1 v3 v5 </PRE>
///
/// \remarks The number of entries in the \a indices array must be at least 3.
//--------------------------------------------------------------------------------------------------
void GeometryBuilder::addTriangleStrip(const UIntArray& indices)
{
size_t numIndices = indices.size();
CVF_ASSERT(numIndices >= 3);
size_t numTriangles = numIndices - 2;
CVF_ASSERT(numTriangles >= 1);
size_t i;
for (i = 0; i < numTriangles; i++)
{
if (i % 2 == 0)
{
addTriangle(indices[i], indices[i + 1], indices[i + 2]);
}
else
{
addTriangle(indices[i + 1], indices[i], indices[i + 2]);
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void GeometryBuilder::addTriangleByVertices(const Vec3f& v0, const Vec3f& v1, const Vec3f& v2)
{
Vec3fArray verts;
verts.resize(3);
verts[0] = v0;
verts[1] = v1;
verts[2] = v2;
uint firstVertexIdx = addVertices(verts);
addTriangle(firstVertexIdx, firstVertexIdx + 1, firstVertexIdx + 2);
}
//--------------------------------------------------------------------------------------------------
/// Add a single quad by specifying the indices into the vertex array
///
/// The default implementation will split the quad into two triangles (i0,i1,i2 and i0,i2,i3) and
/// add them using addTriangle().
///
/// \sa addTriangle(), addQuads()
//--------------------------------------------------------------------------------------------------
void GeometryBuilder::addQuad(uint i0, uint i1, uint i2, uint i3)
{
addTriangle(i0, i1, i2);
addTriangle(i0, i2, i3);
}
//--------------------------------------------------------------------------------------------------
/// Add multiple quads
///
/// The default implementation utilizes addQuad() to add each quad separately.
///
/// \remarks There must be at least 4 entries in the \a indices array, and the total number of
/// entries must be a multiple of 4.
//--------------------------------------------------------------------------------------------------
void GeometryBuilder::addQuads(const UIntArray& indices)
{
size_t numIndices = indices.size();
CVF_ASSERT(numIndices >= 4);
CVF_ASSERT(numIndices % 4 == 0);
size_t numQuads = numIndices/4;
CVF_ASSERT(numQuads >= 1);
CVF_ASSERT(4*numQuads == numIndices);
size_t i;
for (i = 0; i < numQuads; i++)
{
addQuad(indices[4*i], indices[4*i + 1], indices[4*i + 2], indices[4*i + 3]);
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void GeometryBuilder::addQuads(const IntArray& indices)
{
size_t numIndices = indices.size();
CVF_ASSERT(numIndices >= 4);
CVF_ASSERT(numIndices % 4 == 0);
size_t numQuads = numIndices/4;
CVF_ASSERT(numQuads >= 1);
CVF_ASSERT(4*numQuads == numIndices);
size_t i;
for (i = 0; i < numQuads; i++)
{
CVF_ASSERT(indices[4*i] >= 0 && indices[4*i + 1] && indices[4*i + 2] && indices[4*i + 3]);
addQuad(static_cast<uint>(indices[4*i]), static_cast<uint>(indices[4*i + 1]), static_cast<uint>(indices[4*i + 2]), static_cast<uint>(indices[4*i + 3]));
}
}
//--------------------------------------------------------------------------------------------------
/// Add a quad strip
///
/// Vertex ordering for quad strips:
/// <PRE>
/// v0 v2 v4 v6 Resulting quads:
/// *-----*-----*-----* q1: v0, v1, v3, v2
/// | | | | q2: v2, v3, v5, v4
/// | | | | q3: v4, v5, v7, v6
/// | | | |
/// *-----*-----*-----*
/// v1 v3 v5 v7 </PRE>
///
/// \remarks There must be at least 4 entries in the \a indices array, and the total number of
/// entries must be a multiple of 2.
//--------------------------------------------------------------------------------------------------
void GeometryBuilder::addQuadStrip(const UIntArray& indices)
{
size_t numIndices = indices.size();
CVF_ASSERT(numIndices >= 4);
CVF_ASSERT(numIndices % 2 == 0);
size_t numQuads = (numIndices - 2)/2;
CVF_ASSERT(numQuads >= 1);
size_t i;
for (i = 0; i < numQuads; i++)
{
addQuad(indices[2*i], indices[2*i + 1], indices[2*i + 3], indices[2*i + 2]);
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void GeometryBuilder::addQuadByVertices(const Vec3f& v0, const Vec3f& v1, const Vec3f& v2, const Vec3f& v3)
{
Vec3fArray verts;
verts.resize(4);
verts[0] = v0;
verts[1] = v1;
verts[2] = v2;
verts[3] = v3;
uint firstVertexIdx = addVertices(verts);
addQuad(firstVertexIdx, firstVertexIdx + 1, firstVertexIdx + 2, firstVertexIdx + 3);
}
//--------------------------------------------------------------------------------------------------
/// Add one face
///
/// The type of primitive added will be determined from the number of indices passed in \a indices
///
/// \remarks Currently, points and lines are not supported. Faces with more than 4 indices will
/// be triangulated using fanning
//--------------------------------------------------------------------------------------------------
void GeometryBuilder::addFace(const UIntArray& indices)
{
size_t numIndices = indices.size();
CVF_ASSERT(numIndices >= 3);
if (numIndices == 3)
{
addTriangle(indices[0], indices[1], indices[2]);
}
else if (numIndices == 4)
{
addQuad(indices[0], indices[1], indices[2], indices[3]);
}
else
{
size_t numTriangles = numIndices - 2;
size_t i;
for (i = 0; i < numTriangles; i++)
{
addTriangle(indices[0], indices[i + 1], indices[i + 2]);
}
}
}
} // namespace cvf
} //namespace external

View File

@@ -1,81 +0,0 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2013 Ceetron AS
//
// This library may be used under the terms of either the GNU General Public License or
// the GNU Lesser General Public License as follows:
//
// GNU General Public License Usage
// This library 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.
//
// This library 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 at <<http://www.gnu.org/licenses/gpl.html>>
// for more details.
//
// GNU Lesser General Public License Usage
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library 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 Lesser General Public License at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
// for more details.
//
//##################################################################################################
#pragma once
#include "cvfObject.h"
#include "cvfArray.h"
#include "cvfMatrix4.h"
namespace external {
namespace cvf {
//==================================================================================================
//
// Abstract base class for building geometry using the Builder pattern
//
//==================================================================================================
class GeometryBuilder : public Object
{
public:
virtual void setTotalVertexCountHint(size_t totalVertexCountHint);
virtual uint addVertices(const Vec3fArray& vertices) = 0;
virtual uint vertexCount() const = 0;
virtual void transformVertexRange(uint startIdx, uint endIdx, const Mat4f& mat) = 0;
virtual void addTriangle(uint i0, uint i1, uint i2) = 0;
virtual void addTriangles(const UIntArray& indices);
virtual void addTriangles(const IntArray& indices);
virtual void addTriangleFan(const UIntArray& indices);
virtual void addTriangleStrip(const UIntArray& indices);
virtual void addTriangleByVertices(const Vec3f& v0, const Vec3f& v1, const Vec3f& v2);
virtual void addQuad(uint i0, uint i1, uint i2, uint i3);
virtual void addQuads(const UIntArray& indices);
virtual void addQuads(const IntArray& indices);
virtual void addQuadStrip(const UIntArray& indices);
virtual void addQuadByVertices(const Vec3f& v0, const Vec3f& v1, const Vec3f& v2, const Vec3f& v3);
virtual void addFace(const UIntArray& indices);
};
}
} //namespace external

View File

@@ -1,165 +0,0 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2013 Ceetron AS
//
// This library may be used under the terms of either the GNU General Public License or
// the GNU Lesser General Public License as follows:
//
// GNU General Public License Usage
// This library 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.
//
// This library 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 at <<http://www.gnu.org/licenses/gpl.html>>
// for more details.
//
// GNU Lesser General Public License Usage
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library 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 Lesser General Public License at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
// for more details.
//
//##################################################################################################
#include "cvfBase.h"
#include "cvfGeometryBuilderFaceList.h"
namespace external {
namespace cvf {
//==================================================================================================
///
/// \class cvf::GeometryBuilderFaceList
/// \ingroup Geometry
///
/// Builds geometry represented as a face list.
///
/// A face list is an array of integers. The first integer is the number of connectivity indices for
/// the first face, followed by an integer for each vertex int the face, which are indices into
/// the vertex array. For example, if the face list contains (3 0 1 2), then a triangle is formed
/// from the first three points in the vertex array. The next entry in the face list starts another
/// face, and so on.
///
/// A face list representing a geometry with two triangles, one quad and finally one line would
/// look something like this:
/// \code
/// 3, 0, 1, 2,
/// 3, 0, 2, 3,
/// 4, 4, 5, 6, 7,
/// 2, 8, 9
/// \endcode
//==================================================================================================
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
GeometryBuilderFaceList::GeometryBuilderFaceList()
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
uint GeometryBuilderFaceList::addVertices(const Vec3fArray& vertices)
{
uint numExistingVerts = static_cast<uint>(m_vertices.size());
uint numNewVerts = static_cast<uint>(vertices.size());
uint i;
for (i = 0; i < numNewVerts; i++)
{
m_vertices.push_back(vertices[i]);
}
return numExistingVerts;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
uint GeometryBuilderFaceList::vertexCount() const
{
return static_cast<uint>(m_vertices.size());
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void GeometryBuilderFaceList::transformVertexRange(uint startIdx, uint endIdx, const Mat4f& mat)
{
uint i;
for (i = startIdx; i <= endIdx; i++)
{
m_vertices[i].transformPoint(mat);
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void GeometryBuilderFaceList::addTriangle(uint i0, uint i1, uint i2)
{
m_faceList.push_back(3);
m_faceList.push_back(i0);
m_faceList.push_back(i1);
m_faceList.push_back(i2);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void GeometryBuilderFaceList::addQuad(uint i0, uint i1, uint i2, uint i3)
{
m_faceList.push_back(4);
m_faceList.push_back(i0);
m_faceList.push_back(i1);
m_faceList.push_back(i2);
m_faceList.push_back(i3);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
ref<Vec3fArray> GeometryBuilderFaceList::vertices() const
{
ref<Vec3fArray> verts = new Vec3fArray(m_vertices);
return verts;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
ref<UIntArray> GeometryBuilderFaceList::faceList() const
{
ref<UIntArray> fList = new UIntArray(m_faceList);
return fList;
}
} // namespace cvf
} //namespace external

View File

@@ -1,73 +0,0 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2013 Ceetron AS
//
// This library may be used under the terms of either the GNU General Public License or
// the GNU Lesser General Public License as follows:
//
// GNU General Public License Usage
// This library 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.
//
// This library 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 at <<http://www.gnu.org/licenses/gpl.html>>
// for more details.
//
// GNU Lesser General Public License Usage
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library 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 Lesser General Public License at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
// for more details.
//
//##################################################################################################
#pragma once
#include "cvfGeometryBuilder.h"
namespace external {
namespace cvf {
//==================================================================================================
//
// Concrete geometry builder class for building geometry to a face lists
//
//==================================================================================================
class GeometryBuilderFaceList : public GeometryBuilder
{
public:
GeometryBuilderFaceList();
virtual uint addVertices(const Vec3fArray& vertices);
virtual uint vertexCount() const;
virtual void transformVertexRange(uint startIdx, uint endIdx, const Mat4f& mat);
virtual void addTriangle(uint i0, uint i1, uint i2);
virtual void addQuad(uint i0, uint i1, uint i2, uint i3);
ref<Vec3fArray> vertices() const;
ref<UIntArray> faceList() const;
private:
std::vector<Vec3f> m_vertices;
std::vector<uint> m_faceList;
};
}
} //namespace external

View File

@@ -1,957 +0,0 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2013 Ceetron AS
//
// This library may be used under the terms of either the GNU General Public License or
// the GNU Lesser General Public License as follows:
//
// GNU General Public License Usage
// This library 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.
//
// This library 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 at <<http://www.gnu.org/licenses/gpl.html>>
// for more details.
//
// GNU Lesser General Public License Usage
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library 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 Lesser General Public License at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
// for more details.
//
//##################################################################################################
#include "cvfBase.h"
#include "cvfGeometryBuilder.h"
#include "cvfGeometryUtils.h"
#include "cvfMatrix4.h"
#include <map>
namespace external {
namespace cvf {
//==================================================================================================
///
/// \class cvf::GeometryUtils
/// \ingroup Geometry
///
/// Static helper class for creating geometries from primitive shapes.
///
//==================================================================================================
//--------------------------------------------------------------------------------------------------
/// Create a 2D patch
///
/// \param origin The start point of the patch
/// \param uUnit Direction vector u. First point 'to the right of' origin is origin + uUnit.
/// \param vUnit Direction vector v. Coordinates of first point 'above' origin is origin + vunit.
/// \param uCellCount The number of cells/quads to generate along the uUnit dimension.
/// \param vCellCount The number of cells/quads to generate along the vUnit dimension.
/// \param builder Geometry builder to use when creating geometry
///
/// The figure below illustrates how the patch is constructed from the specified parameters.
///
/// <PRE>
/// v8-----v9----v10----v11 Parameters: Resulting vertices:
/// | | | | origin = (10,20,0) v0 = (10,20,0)
/// origin | | | | uUnit = (2,0,0) v1 = (12,20,0)
/// + vunit v4-----v5-----v6-----v7 |y vUnit = (0,1,0) v2 = (14,20,0)
/// | | | | | uCellCount = 3 v3 = (16,20,0)
/// | | | | | vCellCount = 2 v4 = (10,21,0)
/// v0-----v1-----v2-----v3 *----x v5 = (12,21,0)
/// origin origin :
/// + uUnit </PRE>
///
/// The following quad connectivities will be produced:\n
/// <TT> &nbsp; &nbsp; (v4,v0,v1,v5) (v5,v1,v2,v6) (v6,v2,v3,v5) ... (v10,v6,v7,v11)</TT>
//--------------------------------------------------------------------------------------------------
void GeometryUtils::createPatch(const Vec3f& origin, const Vec3f& uUnit, const Vec3f& vUnit, uint uCellCount, uint vCellCount, GeometryBuilder* builder)
{
CVF_ASSERT(uCellCount > 0);
CVF_ASSERT(vCellCount > 0);
uint numVertices = (uCellCount + 1)*(vCellCount + 1);
uint numQuads = uCellCount*vCellCount;
Vec3fArray vertices;
vertices.reserve(numVertices);
uint u, v;
for (v = 0; v <= vCellCount; v++)
{
for (u = 0; u <= uCellCount; u++)
{
vertices.add(origin + static_cast<float>(u)*uUnit + static_cast<float>(v)*vUnit);
}
}
uint baseNodeIdx = builder->addVertices(vertices);
UIntArray conn;
conn.reserve(4*numQuads);
for (v = 0; v < vCellCount; v++)
{
for (u = 0; u < uCellCount; u++)
{
conn.add(baseNodeIdx + u + (v + 1)*(uCellCount + 1));
conn.add(baseNodeIdx + u + v*(uCellCount + 1));
conn.add(baseNodeIdx + u + 1 + v*(uCellCount + 1));
conn.add(baseNodeIdx + u + 1 + (v + 1)*(uCellCount + 1));
}
}
builder->addQuads(conn);
}
//--------------------------------------------------------------------------------------------------
/// Create a 3D solid box spanning diagonally from min to max
///
/// \param min The coordinate that represent one corner of the box.
/// \param max The coordinate that lie diagonal from max on the opposite face of the box
/// \param builder Geometry builder to use when creating geometry
///
/// This method creates a box with no shared vertices resulting in sharp corners during shading.
//--------------------------------------------------------------------------------------------------
void GeometryUtils::createBox(const Vec3f& min, const Vec3f& max, GeometryBuilder* builder)
{
// The ordering of the faces is consistent with GLviewAPI's hexahedron element.
// Note that the vertex ordering within a face is not consistent
//
// 7---------6 Faces:
// /| /| |z 0 bottom 0, 3, 2, 1
// / | / | | /y 1 top 4, 5, 6, 7
// 4---------5 | |/ 2 front 4, 0, 1, 5
// | 3------|--2 *---x 3 right 5, 1, 2, 6
// | / | / 4 back 6, 2, 3, 7
// |/ |/ 5 left 7, 3, 0, 4
// 0---------1
Vec3f v0(min.x(), min.y(), min.z());
Vec3f v1(max.x(), min.y(), min.z());
Vec3f v2(max.x(), max.y(), min.z());
Vec3f v3(min.x(), max.y(), min.z());
Vec3f v4(min.x(), min.y(), max.z());
Vec3f v5(max.x(), min.y(), max.z());
Vec3f v6(max.x(), max.y(), max.z());
Vec3f v7(min.x(), max.y(), max.z());
builder->addQuadByVertices(v0, v3, v2, v1);
builder->addQuadByVertices(v4, v5, v6, v7);
builder->addQuadByVertices(v4, v0, v1, v5);
builder->addQuadByVertices(v5, v1, v2, v6);
builder->addQuadByVertices(v6, v2, v3, v7);
builder->addQuadByVertices(v7, v3, v0, v4);
}
//--------------------------------------------------------------------------------------------------
/// Create a 3D solid box at the specified position and with the given total extents
///
/// \param centerPos Position of center of box
/// \param extentX Total extent of box along x-axis
/// \param extentY Total extent of box along y-axis
/// \param extentZ Total extent of box along z-axis
/// \param builder Geometry builder to use when creating geometry
//--------------------------------------------------------------------------------------------------
void GeometryUtils::createBox(const Vec3f& centerPos, float extentX, float extentY, float extentZ, GeometryBuilder* builder)
{
Vec3f halfExtent(extentX/2, extentY/2, extentZ/2);
Vec3f min(centerPos - halfExtent);
Vec3f max(centerPos + halfExtent);
createBox(min, max, builder);
}
//--------------------------------------------------------------------------------------------------
/// Create a disc centered at origin with its normal along positive z-axis
///
/// \param radius Outer radius of the disc
/// \param numSlices The number of subdivisions around the z-axis. Must be >= 4
/// \param builder Geometry builder to use when creating geometry
///
/// Creates a disc on the z = 0 plane, centered at origin and with its surface normal pointing
/// along the positive z-axis.
///
/// The disk is subdivided around the z axis into numSlices (as in pizza slices).
///
/// The sourceNodes that will be produced by this method:
/// <PRE>
/// 1
/// /-----\ 8
/// 2/\ | /\ |y
/// / \ | / \ |
/// | \|/ | |
/// 3|----0----|7 |
/// | /|\ | *-----x
/// \ / | \ / /
/// 4\/ | \/6 /z
/// \-----/
/// 5 </PRE>
///
/// The following triangle connectivities will be produced:\n
/// <TT> &nbsp; &nbsp; (0,1,2) (0,2,3) (0,3,4) ... (0,8,1)</TT>
//--------------------------------------------------------------------------------------------------
void GeometryUtils::createDisc(double radius, uint numSlices, GeometryBuilder* builder)
{
CVF_ASSERT(numSlices >= 4);
CVF_ASSERT(builder);
double da = 2*PI_D/numSlices;
Vec3fArray verts;
verts.reserve(numSlices + 1);
// Center of disc
verts.add(Vec3f::ZERO);
Vec3f point = Vec3f::ZERO;
uint i;
for (i = 0; i < numSlices; i++)
{
// Precompute this one (A = i*da;)
double sinA = Math::sin(i*da);
double cosA = Math::cos(i*da);
point.x() = static_cast<float>(-sinA*radius);
point.y() = static_cast<float>( cosA*radius);
verts.add(point);
}
uint baseNodeIdx = builder->addVertices(verts);
// Vec3fArray myArray;
// myArray.resize(10);
// generatePointsOnCircle(radius, numSlices, &myArray);
uint conn[3] = { baseNodeIdx, 0, 0};
for (i = numSlices; i > 0; i--)
{
conn[1] = baseNodeIdx + i + 1;
conn[2] = baseNodeIdx + i + 0;
if (i == numSlices) conn[1] = baseNodeIdx + 1;
builder->addTriangle(conn[0], conn[1], conn[2]);
}
}
//--------------------------------------------------------------------------------------------------
/// Create a disk with a hole in the middle
//--------------------------------------------------------------------------------------------------
void GeometryUtils::createDisc(double outerRadius, double innerRadius, uint numSlices, GeometryBuilder* builder)
{
CVF_ASSERT(numSlices >= 4);
CVF_ASSERT(builder);
double da = 2*PI_D/numSlices;
Vec3fArray verts;
verts.reserve(2*numSlices);
Vec3f point = Vec3f::ZERO;
uint i;
for (i = 0; i < numSlices; i++)
{
// Precompute this one (A = i*da;)
double sinA = Math::sin(i*da);
double cosA = Math::cos(i*da);
point.x() = static_cast<float>(-sinA*innerRadius);
point.y() = static_cast<float>( cosA*innerRadius);
verts.add(point);
point.x() = static_cast<float>(-sinA*outerRadius);
point.y() = static_cast<float>( cosA*outerRadius);
verts.add(point);
}
uint baseNodeIdx = builder->addVertices(verts);
uint conn[3] = { baseNodeIdx, 0, 0};
for (i = 0; i < numSlices - 1; ++i)
{
uint startIdx = baseNodeIdx + 2*i;
conn[0] = startIdx + 0;
conn[1] = startIdx + 3;
conn[2] = startIdx + 1;
builder->addTriangle(conn[0], conn[1], conn[2]);
conn[0] = startIdx + 2;
conn[1] = startIdx + 3;
conn[2] = startIdx + 0;
builder->addTriangle(conn[0], conn[1], conn[2]);
}
builder->addTriangle(baseNodeIdx + 0, baseNodeIdx + 1, baseNodeIdx + numSlices*2 - 1);
builder->addTriangle(baseNodeIdx + 0, baseNodeIdx + numSlices*2 - 1, baseNodeIdx + numSlices*2 - 2);
}
// void GeometryUtils::generatePointsOnCircle(double radius, int numPoints, Vec3fArray* generatedPoints)
// {
// CVF_ASSERT(generatedPoints);
// generatedPoints->reserve(generatedPoints->size() + numPoints);
//
// double da = 2*PI_D/numPoints;
//
// Vec3f point = Vec3f::ZERO;
//
// int i;
// for (i = 0; i < numPoints; i++)
// {
// // Precompute this one (A = i*da;)
// double sinA = sin(i*da);
// double cosA = cos(i*da);
//
// point.x() = static_cast<float>(-sinA*radius);
// point.y() = static_cast<float>( cosA*radius);
//
// generatedPoints->add(point);
// }
// }
//
// void GeometryUtils::createDiscUsingFan(double radius, int numSlices, GeometryBuilder* geometryBuilder)
// {
// CVF_ASSERT(numSlices >= 4);
// CVF_ASSERT(geometryBuilder);
//
//
// double da = 2*PI_D/numSlices;
//
// Vec3fArray verts;
// verts.preAllocBuffer(numSlices + 1);
//
// // Center of disc
// verts.addToPreAlloc(Vec3f::ZERO);
//
//
// Vec3f point = Vec3f::ZERO;
//
// int i;
// for (i = 0; i < numSlices; i++)
// {
// // Precompute this one (A = i*da;)
// double sinA = sin(i*da);
// double cosA = cos(i*da);
//
// point.x() = static_cast<float>(-sinA*radius);
// point.y() = static_cast<float>( cosA*radius);
//
// verts.addToPreAlloc(point);
// }
//
// int baseNodeIdx = geometryBuilder->addVertices(verts);
//
//
// IntArray conns;
// conns.resize(numSlices + 2);
//
// for (i = 0; i < numSlices + 1; i++)
// {
// conns[i] = baseNodeIdx + i;
// }
//
// conns[numSlices + 1] = baseNodeIdx + 1;
//
// geometryBuilder->addTriangleFan(conns);
// }
//--------------------------------------------------------------------------------------------------
/// Create a sphere with center in origin
///
/// \param radius Radius of sphere
/// \param numSlices The number of subdivisions around the z-axis (similar to lines of longitude).
/// \param numStacks The number of subdivisions along the z-axis (similar to lines of latitude).
/// \param builder Geometry builder to use when creating geometry
//--------------------------------------------------------------------------------------------------
void GeometryUtils::createSphere(double radius, uint numSlices, uint numStacks, GeometryBuilder* builder)
{
// Code is strongly inspired by mesa.
// From GLviewAPI:
// float nsign = bNormalsOutwards ? 1.0f : -1.0f;
// Could be added as a param if needed (e.g. dome)
const double nsign = 1.0;
double rho = PI_D/numStacks;
double theta = 2.0*PI_D/static_cast<double>(numSlices);
// Array to receive the node coordinates
Vec3fArray vertices;
uint vertexCount = 1 + 2*numSlices + (numStacks - 2)*numSlices;
vertices.reserve(vertexCount);
// Create the +Z end as triangles
Vec3d vTop(0.0, 0.0, nsign*radius);
vertices.add(Vec3f(vTop));
ref<UIntArray> triangleFan = new UIntArray;
triangleFan->reserve(numSlices + 2);
triangleFan->add(0);
uint j;
for (j = 0; j < numSlices; j++)
{
double localTheta = j * theta;
Vec3d v;
v.x() = -Math::sin(localTheta) * Math::sin(rho);
v.y() = Math::cos(localTheta) * Math::sin(rho);
v.z() = nsign * Math::cos(rho);
v *= radius;
vertices.add(Vec3f(v));
triangleFan->add(j + 1);
}
// Close top fan
triangleFan->add(1);
builder->addTriangleFan(*triangleFan);
// Intermediate stacks as quad-strips
// First and last stacks are handled separately
ref<UIntArray> quadStrip = new UIntArray;
quadStrip->reserve(numSlices*2 + 2);
uint i;
for (i = 1; i < numStacks - 1; i++)
{
double localRho = i * rho;
quadStrip->setSizeZero();
for (j = 0; j < numSlices; j++)
{
double localTheta = j * theta;
Vec3d v;
v.x() = -Math::sin(localTheta) * Math::sin(localRho + rho);
v.y() = Math::cos(localTheta) * Math::sin(localRho + rho);
v.z() = nsign * Math::cos(localRho + rho);
v *= radius;
vertices.add(Vec3f(v));
uint iC1 = (i*numSlices) + 1 + j;
uint iC0 = iC1 - numSlices;
quadStrip->add(iC0);
quadStrip->add(iC1);
}
// Close quad-strip
uint iStartC1 = (i*numSlices) + 1;
uint iStartC0 = iStartC1 - numSlices;
quadStrip->add(iStartC0);
quadStrip->add(iStartC1);
builder->addQuadStrip(*quadStrip);
}
// Create -Z end as triangles
Vec3d vBot( 0.0, 0.0, -radius*nsign );
vertices.add(Vec3f(vBot));
uint endNodeIndex = static_cast<uint>(vertices.size()) - 1;
triangleFan->setSizeZero();
triangleFan->add(endNodeIndex);
for (j = 0; j < numSlices; j++)
{
triangleFan->add(endNodeIndex - j - 1);
}
// Close bottom fan
triangleFan->add(endNodeIndex - 1);
builder->addTriangleFan(*triangleFan);
builder->addVertices(vertices);
}
//--------------------------------------------------------------------------------------------------
/// Create a (possibly oblique) cylinder oriented along the z-axis
///
/// \param bottomRadius Bottom radius of cylinder
/// \param topRadius Top radius of cylinder
/// \param height Height of cylinder
/// \param topOffsetX Offset top disc relative to bottom in X direction
/// \param topOffsetY Offset top disc relative to bottom in Y direction
/// \param numSlices Number of slices
/// \param normalsOutwards true to generate polygons with outward facing normals.
/// \param closedBot true to close the bottom of the cylinder with a disc
/// \param closedTop true to close the top of the cylinder with a disc
/// \param numPolysZDir Number of (subdivisions) polygons along the Z axis.
/// \param builder Geometry builder to use when creating geometry
///
/// An oblique cylinder is a cylinder with bases that are not aligned one directly above the other
/// The base of the cylinder is placed at z = 0, and the top at z = height.
/// Cylinder is subdivided around the z-axis into slices.
/// Use the cone functions instead of setting one of the radius params to 0
//--------------------------------------------------------------------------------------------------
void GeometryUtils::createObliqueCylinder(float bottomRadius, float topRadius, float height, float topOffsetX, float topOffsetY, uint numSlices, bool normalsOutwards, bool closedBot, bool closedTop, uint numPolysZDir, GeometryBuilder* builder)
{
// Create cylinder...
Vec3f centBot(0, 0, 0);
Vec3f centTop(topOffsetX, topOffsetY, height);
// Create vertices
uint zPoly;
for (zPoly = 0; zPoly <= numPolysZDir; zPoly++)
{
float fT = static_cast<float>((1.0/numPolysZDir)*(zPoly));
float radius = bottomRadius + fT*(topRadius - bottomRadius);
Vec3f center(fT*topOffsetX, fT*topOffsetY, fT*height);
Vec3fArray verts;
verts.reserve(numSlices);
Vec3f point = Vec3f::ZERO;
double da = 2*PI_D/numSlices;
uint i;
for (i = 0; i < numSlices; i++)
{
// Precompute this one (A = i*da;)
double sinA = Math::sin(i*da);
double cosA = Math::cos(i*da);
point.x() = static_cast<float>(-sinA*radius);
point.y() = static_cast<float>( cosA*radius);
point.z() = 0;
point += center;
verts.add(point);
}
uint baseNodeIdx = builder->addVertices(verts);
// First time we only create the sourceNodes
if (zPoly != 0)
{
uint offset = baseNodeIdx - numSlices;
uint piConn[4] = { 0, 0, 0, 0 };
// Normals facing outwards
if (normalsOutwards)
{
uint i;
for (i = 0; i < numSlices; i++)
{
piConn[0] = offset + i;
piConn[1] = offset + i + 1;
piConn[2] = offset + i + numSlices + 1;
piConn[3] = offset + i + numSlices;
if (i == numSlices - 1)
{
piConn[1] = offset;
piConn[2] = offset + numSlices;
}
builder->addQuad(piConn[0], piConn[1], piConn[2], piConn[3]);
}
}
// Normals facing inwards
else
{
uint i;
for (i = 0; i < numSlices; i++)
{
piConn[0] = offset + i + 1;
piConn[1] = offset + i;
piConn[2] = offset + i + numSlices;
piConn[3] = offset + i + numSlices + 1;
if (i == numSlices - 1)
{
piConn[0] = offset;
piConn[3] = offset + numSlices;
}
builder->addQuad(piConn[0], piConn[1], piConn[2], piConn[3]);
}
}
}
}
if (closedBot)
{
createDisc(bottomRadius, numSlices, builder);
}
if (closedTop)
{
uint startIdx = builder->vertexCount();
createDisc(topRadius, numSlices, builder);
uint endIdx = builder->vertexCount() - 1;
// Translate the top disc sourceNodes, also flip it to get the normals the right way
Mat4f mat = Mat4f::fromRotation(Vec3f(1.0f, 0.0f, 0.0f), Math::toRadians(180.0f));
mat.translatePreMultiply(Vec3f(topOffsetX, topOffsetY, height));
builder->transformVertexRange(startIdx, endIdx, mat);
}
}
//--------------------------------------------------------------------------------------------------
/// Create a cone oriented along the z-axis
///
/// \param bottomRadius Bottom radius of cone
/// \param height Height of cone
/// \param numSlices Number of slices
/// \param normalsOutwards true to generate polygons with outward facing normals.
/// \param closedBot true to close the bottom of the cone with a disc
/// \param singleTopNode Specify if a single top node should be used, or if each side triangle
/// should have its own top node.
/// \param builder Geometry builder to use when creating geometry
///
//--------------------------------------------------------------------------------------------------
void GeometryUtils::createCone(float bottomRadius, float height, uint numSlices, bool normalsOutwards, bool closedBot, bool singleTopNode, GeometryBuilder* builder)
{
Vec3fArray verts;
if (singleTopNode)
{
verts.reserve(numSlices + 1);
}
else
{
verts.reserve(numSlices*2);
}
Vec3f point = Vec3f::ZERO;
double da = 2*PI_D/numSlices;
uint i;
for (i = 0; i < numSlices; i++)
{
// Precompute this one (A = i*da;)
double sinA = Math::sin(i*da);
double cosA = Math::cos(i*da);
point.x() = static_cast<float>(-sinA*bottomRadius);
point.y() = static_cast<float>( cosA*bottomRadius);
verts.add(point);
}
if (singleTopNode)
{
verts.add(Vec3f(0, 0, height));
}
else
{
// Unique sourceNodes at apex of cone
Vec3f topNode(0, 0, height);
uint i;
for (i = 0; i < numSlices; i++)
{
verts.add(topNode);
}
}
uint baseNodeIdx = builder->addVertices(verts);
uint piConn[3] = { 0, 0, 0 };
// Normals facing outwards
if (normalsOutwards)
{
uint i;
for (i = 0; i < numSlices; i++)
{
piConn[0] = baseNodeIdx + i;
piConn[1] = baseNodeIdx + i + 1;
piConn[2] = singleTopNode ? baseNodeIdx + numSlices : baseNodeIdx + i + numSlices;
if (i == numSlices - 1)
{
piConn[1] = baseNodeIdx;
}
if (normalsOutwards)
{
builder->addTriangle(piConn[0], piConn[1], piConn[2]);
}
else
{
builder->addTriangle(piConn[1], piConn[0], piConn[2]);
}
}
}
if (closedBot)
{
createDisc(bottomRadius, numSlices, builder);
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void GeometryUtils::tesselatePatchAsQuads(uint pointCountU, uint pointCountV, uint indexOffset, bool windingCCW, UIntArray* indices)
{
CVF_ASSERT(pointCountU >= 2);
CVF_ASSERT(pointCountV >= 2);
uint uCellCount = pointCountU - 1;
uint vCellCount = pointCountV - 1;
uint numQuads = uCellCount*vCellCount;
indices->reserve(indices->size() + 4*numQuads);
uint u, v;
for (v = 0; v < vCellCount; v++)
{
for (u = 0; u < uCellCount; u++)
{
if (windingCCW)
{
indices->add(indexOffset + u + (v+1)*pointCountU);
indices->add(indexOffset + u + v*pointCountU);
indices->add(indexOffset + u+1 + v*pointCountU);
indices->add(indexOffset + u+1 + (v+1)*pointCountU);
}
else
{
indices->add(indexOffset + u + v*pointCountU);
indices->add(indexOffset + u + (v+1)*pointCountU);
indices->add(indexOffset + u+1 + (v+1)*pointCountU);
indices->add(indexOffset + u+1 + v*pointCountU);
}
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void GeometryUtils::tesselatePatchAsTriangles(uint pointCountU, uint pointCountV, uint indexOffset, bool windingCCW, UIntArray* indices)
{
CVF_ASSERT(pointCountU >= 2);
CVF_ASSERT(pointCountV >= 2);
uint uCellCount = pointCountU - 1;
uint vCellCount = pointCountV - 1;
uint numTris = 2*uCellCount*vCellCount;
indices->reserve(indices->size() + 3*numTris);
uint u, v;
for (v = 0; v < vCellCount; v++)
{
for (u = 0; u < uCellCount; u++)
{
if (windingCCW)
{
indices->add(indexOffset + u + (v+1)*pointCountU);
indices->add(indexOffset + u + v*pointCountU);
indices->add(indexOffset + u+1 + v*pointCountU);
indices->add(indexOffset + u + (v+1)*pointCountU);
indices->add(indexOffset + u+1 + v*pointCountU);
indices->add(indexOffset + u+1 + (v+1)*pointCountU);
}
else
{
indices->add(indexOffset + u + v*pointCountU);
indices->add(indexOffset + u + (v+1)*pointCountU);
indices->add(indexOffset + u+1 + (v+1)*pointCountU);
indices->add(indexOffset + u + v*pointCountU);
indices->add(indexOffset + u+1 + (v+1)*pointCountU);
indices->add(indexOffset + u+1 + v*pointCountU);
}
}
}
}
//--------------------------------------------------------------------------------------------------
/// Check if the specified quad is convex
//--------------------------------------------------------------------------------------------------
bool GeometryUtils::isConvexQuad(const Vec3f& a, const Vec3f& b, const Vec3f& c, const Vec3f& d)
{
// From "Real Time Collision Detection", p60
// Quad is nonconvex if dot(cross(bd, ba), cross(bd, bc)) >= 0
const Vec3f bda = (d - b) ^ (a - b);
const Vec3f bdc = (d - b) ^ (c - b);
if (bda*bdc >= 0)
{
return false;
}
// Quad is now convex if dot(cross(ac, ad), cross(ac, ab)) < 0
const Vec3f acd = (c - a) ^ (d - a);
const Vec3f acb = (c - a) ^ (b - a);
if (acd*acb < 0)
{
return true;
}
else
{
return false;
}
}
//--------------------------------------------------------------------------------------------------
/// Compute surface normal for a quad
//--------------------------------------------------------------------------------------------------
Vec3f GeometryUtils::quadNormal(const Vec3f& a, const Vec3f& b, const Vec3f& c, const Vec3f& d)
{
// From "Real Time Collision Detection", p. 495
Vec3f normal = (c - a) ^ (d - b);
normal.normalize();
return normal;
}
//--------------------------------------------------------------------------------------------------
/// Compute polygon normal using Newell's method
//--------------------------------------------------------------------------------------------------
Vec3f GeometryUtils::polygonNormal(const Vec3fValueArray& vertices, const uint* indices, uint indexCount)
{
// From "Real Time Collision Detection", p. 495
// Compute normal as being proportional to projected areas of polygon onto the yz, xz, and xy planes.
Vec3f normal(0, 0, 0);
uint n;
for (n = 0; n < indexCount; n++)
{
uint i = indices[(n > 0) ? n - 1 : indexCount - 1];
uint j = indices[n];
normal.x() += (vertices.val(i).y() - vertices.val(j).y()) * (vertices.val(i).z() + vertices.val(j).z()); // projection on yz
normal.y() += (vertices.val(i).z() - vertices.val(j).z()) * (vertices.val(i).x() + vertices.val(j).x()); // projection on xz
normal.z() += (vertices.val(i).x() - vertices.val(j).x()) * (vertices.val(i).y() + vertices.val(j).y()); // projection on xy
}
normal.normalize();
return normal;
}
//--------------------------------------------------------------------------------------------------
/// Compact an array of vertex indices by removing 'unused' indices
///
/// \param[in] vertexIndices The original vertex indices
/// \param[out] newVertexIndices New compacted vertex indices
/// \param[out] newToOldMapping For each 'new' vertex, will contain its original index
/// \param[in] maxVertexCount The maximum resulting vertex count after removing unused vertices
//--------------------------------------------------------------------------------------------------
void GeometryUtils::removeUnusedVertices(const UIntValueArray& vertexIndices, UIntArray* newVertexIndices, UIntArray* newToOldMapping, uint maxVertexCount)
{
if (vertexIndices.size() == 0 || maxVertexCount == 0)
{
return;
}
std::map<uint, uint> oldToNewVertexIndexMap;
std::map<uint, uint>::const_iterator it;
CVF_ASSERT(newVertexIndices);
CVF_ASSERT(newToOldMapping);
newVertexIndices->reserve(vertexIndices.size());
newToOldMapping->reserve(maxVertexCount);
size_t i;
uint newVertexIndex = 0;
for (i = 0; i < vertexIndices.size(); i++)
{
uint vertexIdx = vertexIndices.val(i);
uint currentIndex = UNDEFINED_UINT;
it = oldToNewVertexIndexMap.find(vertexIdx);
if (it == oldToNewVertexIndexMap.end())
{
currentIndex = newVertexIndex++;
oldToNewVertexIndexMap[vertexIdx] = currentIndex;
newToOldMapping->add(vertexIdx);
}
else
{
currentIndex = it->second;
}
CVF_ASSERT(currentIndex != UNDEFINED_UINT);
newVertexIndices->add(currentIndex);
}
newToOldMapping->squeeze();
}
bool GeometryUtils::project(const Mat4d& projectionMultViewMatrix, const Vec2i& viewportPosition, const Vec2ui& viewportSize, const Vec3d& point, Vec3d* out)
{
CVF_ASSERT(out);
Vec4d v = projectionMultViewMatrix * Vec4d(point, 1.0);
if (v.w() == 0.0f)
{
return false;
}
v.x() /= v.w();
v.y() /= v.w();
v.z() /= v.w();
// map to range 0-1
out->x() = v.x()*0.5 + 0.5;
out->y() = v.y()*0.5 + 0.5;
out->z() = v.z()*0.5 + 0.5;
// map to viewport
out->x() = out->x() * viewportSize.x() + viewportPosition.x();
out->y() = out->y() * viewportSize.y() + viewportPosition.y();
return true;
}
} // namespace cvf
} //namespace external

View File

@@ -1,84 +0,0 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2013 Ceetron AS
//
// This library may be used under the terms of either the GNU General Public License or
// the GNU Lesser General Public License as follows:
//
// GNU General Public License Usage
// This library 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.
//
// This library 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 at <<http://www.gnu.org/licenses/gpl.html>>
// for more details.
//
// GNU Lesser General Public License Usage
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library 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 Lesser General Public License at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
// for more details.
//
//##################################################################################################
#pragma once
#include "cvfVector3.h"
#include "cvfGeometryBuilder.h"
namespace external {
namespace cvf {
//==================================================================================================
//
// Static helper class for building geometry
//
//==================================================================================================
class GeometryUtils
{
public:
static void createPatch(const Vec3f& origin, const Vec3f& uUnit, const Vec3f& vUnit, uint uCellCount, uint vCellCount, GeometryBuilder* builder);
static void createBox(const Vec3f& min, const Vec3f& max, GeometryBuilder* builder);
static void createBox(const Vec3f& centerPos, float extentX, float extentY, float extentZ, GeometryBuilder* builder);
static void createDisc(double radius, uint numSlices, GeometryBuilder* builder);
static void createDisc(double outerRadius, double innerRadius, uint numSlices, GeometryBuilder* builder);
static void createSphere(double radius, uint numSlices, uint numStacks, GeometryBuilder* builder);
// These two should be refactored out into separate generator classes
static void createObliqueCylinder(float bottomRadius, float topRadius, float height, float topOffsetX, float topOffsetY, uint numSlices, bool normalsOutwards, bool closedBot, bool closedTop, uint numPolysZDir, GeometryBuilder* builder);
static void createCone(float bottomRadius, float height, uint numSlices, bool normalsOutwards, bool closedBot, bool singleTopNode, GeometryBuilder* builder);
//static void generatePointsOnCircle(double radius, int numPoints, Vec3fArray* generatedPoints);
static void tesselatePatchAsQuads(uint pointCountU, uint pointCountV, uint indexOffset, bool windingCCW, UIntArray* indices);
static void tesselatePatchAsTriangles(uint pointCountU, uint pointCountV, uint indexOffset, bool windingCCW, UIntArray* indices);
static bool isConvexQuad(const Vec3f& a, const Vec3f& b, const Vec3f& c, const Vec3f& d);
static Vec3f quadNormal(const Vec3f& a, const Vec3f& b, const Vec3f& c, const Vec3f& d);
static Vec3f polygonNormal(const Vec3fValueArray& vertices, const uint* indices, uint indexCount);
static void removeUnusedVertices(const UIntValueArray& vertexIndices, UIntArray* newVertexIndices, UIntArray* newToOldMapping, uint maxVertexCount);
static bool project(const Mat4d& projectionMultViewMatrix, const Vec2i& viewportPosition, const Vec2ui& viewportSize, const Vec3d& point, Vec3d* out);
};
}
} //namespace external

View File

@@ -1,171 +0,0 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2013 Ceetron AS
//
// This library may be used under the terms of either the GNU General Public License or
// the GNU Lesser General Public License as follows:
//
// GNU General Public License Usage
// This library 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.
//
// This library 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 at <<http://www.gnu.org/licenses/gpl.html>>
// for more details.
//
// GNU Lesser General Public License Usage
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library 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 Lesser General Public License at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
// for more details.
//
//##################################################################################################
#include "cvfBase.h"
#include "cvfMeshEdgeExtractor.h"
#include "cvfEdgeKey.h"
namespace external {
namespace cvf {
//==================================================================================================
///
/// \class cvf::MeshEdgeExtractor
/// \ingroup Geometry
///
///
///
//==================================================================================================
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
MeshEdgeExtractor::MeshEdgeExtractor()
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void MeshEdgeExtractor::addPrimitives(uint verticesPerPrimitive, const uint* indices, size_t indexCount)
{
CVF_ASSERT(verticesPerPrimitive > 0);
CVF_ASSERT(indices);
CVF_ASSERT(indexCount > 0);
// Points will never become edges
if (verticesPerPrimitive < 2)
{
return;
}
size_t numPrimitives = indexCount/verticesPerPrimitive;
size_t ip;
for (ip = 0; ip < numPrimitives; ip++)
{
size_t firstIdxInPrimitive = ip*verticesPerPrimitive;
uint i;
for (i = 0; i < verticesPerPrimitive; i++)
{
uint vertexIdx1 = indices[firstIdxInPrimitive + i];
uint vertexIdx2 = (i < verticesPerPrimitive - 1) ? indices[firstIdxInPrimitive + i + 1] : indices[firstIdxInPrimitive];
// Don't add collapsed edges
if (vertexIdx1 != vertexIdx2)
{
int64 edgeKeyVal = EdgeKey(vertexIdx1, vertexIdx2).toKeyVal();
m_edgeSet.insert(edgeKeyVal);
}
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void MeshEdgeExtractor::addPrimitives(uint verticesPerPrimitive, const UIntArray& indices)
{
CVF_ASSERT(verticesPerPrimitive > 0);
size_t indexCount = indices.size();
size_t numPrimitives = indexCount/verticesPerPrimitive;
if (numPrimitives > 0)
{
const uint* indexPtr = indices.ptr();
addPrimitives(verticesPerPrimitive, indexPtr, indexCount);
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void MeshEdgeExtractor::addFaceList(const UIntArray& faceList)
{
size_t numFaceListEntries = faceList.size();
size_t i = 0;
while (i < numFaceListEntries)
{
uint numVerticesInFace = faceList[i++];
CVF_ASSERT(numVerticesInFace > 0);
CVF_ASSERT(i + numVerticesInFace <= numFaceListEntries);
const uint* indexPtr = &faceList[i];
addPrimitives(numVerticesInFace, indexPtr, numVerticesInFace);
i += numVerticesInFace;
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
ref<UIntArray> MeshEdgeExtractor::lineIndices() const
{
ref<UIntArray> indices = new UIntArray;
size_t numEdges = m_edgeSet.size();
if (numEdges == 0)
{
return indices;
}
indices->reserve(2*numEdges);
std::set<cvf::int64>::const_iterator it;
for (it = m_edgeSet.begin(); it != m_edgeSet.end(); ++it)
{
EdgeKey ek = EdgeKey::fromkeyVal(*it);
indices->add(ek.index1());
indices->add(ek.index2());
}
return indices;
}
} // namespace cvf
} //namespace external

View File

@@ -1,71 +0,0 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2013 Ceetron AS
//
// This library may be used under the terms of either the GNU General Public License or
// the GNU Lesser General Public License as follows:
//
// GNU General Public License Usage
// This library 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.
//
// This library 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 at <<http://www.gnu.org/licenses/gpl.html>>
// for more details.
//
// GNU Lesser General Public License Usage
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library 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 Lesser General Public License at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
// for more details.
//
//##################################################################################################
#pragma once
#include "cvfArray.h"
namespace external {
namespace cvf {
//==================================================================================================
//
//
//
//==================================================================================================
class MeshEdgeExtractor
{
public:
MeshEdgeExtractor();
void addPrimitives(uint verticesPerPrimitive, const uint* indices, size_t indexCount);
void addPrimitives(uint verticesPerPrimitive, const UIntArray& indices);
void addFaceList(const UIntArray& faceList);
ref<UIntArray> lineIndices() const;
private:
std::set<cvf::int64> m_edgeSet;
};
}
} //namespace external

View File

@@ -1,292 +0,0 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2013 Ceetron AS
//
// This library may be used under the terms of either the GNU General Public License or
// the GNU Lesser General Public License as follows:
//
// GNU General Public License Usage
// This library 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.
//
// This library 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 at <<http://www.gnu.org/licenses/gpl.html>>
// for more details.
//
// GNU Lesser General Public License Usage
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library 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 Lesser General Public License at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
// for more details.
//
//##################################################################################################
#include "cvfBase.h"
#include "cvfOutlineEdgeExtractor.h"
#include "cvfEdgeKey.h"
#include "cvfGeometryUtils.h"
namespace external {
namespace cvf {
//==================================================================================================
///
/// \class cvf::OutlineEdgeExtractor
/// \ingroup Geometry
///
///
///
//==================================================================================================
static const size_t OEE_OUTLINE_EDGE = cvf::UNDEFINED_SIZE_T; // This is an outline edge
static const size_t OEE_NON_OUTLINE_EDGE = cvf::UNDEFINED_SIZE_T - 1; // Marked as an interior edge
static const size_t OEE_MULTIREF_EDGE = cvf::UNDEFINED_SIZE_T - 2; // An edge with more than two faces connected to it.
//--------------------------------------------------------------------------------------------------
/// Constructor
///
/// creaseAngle is specified in radians
//--------------------------------------------------------------------------------------------------
OutlineEdgeExtractor::OutlineEdgeExtractor(double creaseAngle, const Vec3fValueArray& vertexArray)
: m_creaseAngle(creaseAngle),
m_vertexArray(vertexArray)
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void OutlineEdgeExtractor::addPrimitives(uint verticesPerPrimitive, const uint* indices, size_t indexCount)
{
CVF_ASSERT(verticesPerPrimitive > 0);
CVF_ASSERT(indices);
CVF_ASSERT(indexCount > 0);
// Points will never become edges
if (verticesPerPrimitive < 2)
{
return;
}
size_t numPrimitives = indexCount/verticesPerPrimitive;
size_t ip;
for (ip = 0; ip < numPrimitives; ip++)
{
size_t myFaceIndex = m_faceNormals.size();
size_t firstIdxInPrimitive = ip*verticesPerPrimitive;
// Normal computation accepts points and lines, but in that case returns a zero vector
Vec3f faceNormal = computeFaceNormal(&indices[firstIdxInPrimitive], verticesPerPrimitive);
m_faceNormals.push_back(faceNormal);
uint i;
for (i = 0; i < verticesPerPrimitive; i++)
{
const uint vertexIdx1 = indices[firstIdxInPrimitive + i];
const uint vertexIdx2 = (i < verticesPerPrimitive - 1) ? indices[firstIdxInPrimitive + i + 1] : indices[firstIdxInPrimitive];
// Never add collapsed edges
if (vertexIdx1 == vertexIdx2)
{
continue;
}
int64 edgeKeyVal = EdgeKey(vertexIdx1, vertexIdx2).toKeyVal();
std::map<int64, size_t>::iterator it = m_edgeToFaceIndexMap.find(edgeKeyVal);
if (it == m_edgeToFaceIndexMap.end())
{
// Not found, so add and register face index
m_edgeToFaceIndexMap[edgeKeyVal] = myFaceIndex;
}
else
{
size_t otherFaceIdx = it->second;
if (otherFaceIdx < OEE_MULTIREF_EDGE)
{
// An edge is already there, check angle
if (isFaceAngleAboveThreshold(myFaceIndex, otherFaceIdx))
{
m_edgeToFaceIndexMap[edgeKeyVal] = OEE_OUTLINE_EDGE;
}
else
{
m_edgeToFaceIndexMap[edgeKeyVal] = OEE_NON_OUTLINE_EDGE;
}
}
else
{
// Three or more faces share an edge
m_edgeToFaceIndexMap[edgeKeyVal] = OEE_MULTIREF_EDGE;
}
}
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void OutlineEdgeExtractor::addPrimitives(uint verticesPerPrimitive, const UIntArray& indices)
{
CVF_ASSERT(verticesPerPrimitive > 0);
size_t indexCount = indices.size();
size_t numPrimitives = indexCount/verticesPerPrimitive;
if (numPrimitives > 0)
{
const uint* indexPtr = indices.ptr();
addPrimitives(verticesPerPrimitive, indexPtr, indexCount);
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void OutlineEdgeExtractor::addFaceList(const UIntArray& faceList)
{
size_t numFaceListEntries = faceList.size();
size_t i = 0;
while (i < numFaceListEntries)
{
uint numVerticesInFace = faceList[i++];
CVF_ASSERT(numVerticesInFace > 0);
CVF_ASSERT(i + numVerticesInFace <= numFaceListEntries);
const uint* indexPtr = &faceList[i];
addPrimitives(numVerticesInFace, indexPtr, numVerticesInFace);
i += numVerticesInFace;
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
ref<UIntArray> OutlineEdgeExtractor::lineIndices() const
{
ref<UIntArray> indices = new UIntArray;
size_t numEdges = m_edgeToFaceIndexMap.size();
if (numEdges == 0)
{
return indices;
}
indices->reserve(2*numEdges);
std::map<int64, size_t>::const_iterator it;
for (it = m_edgeToFaceIndexMap.begin(); it != m_edgeToFaceIndexMap.end(); ++it)
{
size_t otherFaceIdx = it->second;
if (otherFaceIdx != OEE_NON_OUTLINE_EDGE)
{
EdgeKey ek = EdgeKey::fromkeyVal(it->first);
indices->add(ek.index1());
indices->add(ek.index2());
}
}
return indices;
}
//--------------------------------------------------------------------------------------------------
/// Returns the worker array with one normal per face (primitive)
//--------------------------------------------------------------------------------------------------
const std::vector<Vec3f>& OutlineEdgeExtractor::faceNormals()
{
return m_faceNormals;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
Vec3f OutlineEdgeExtractor::computeFaceNormal(const uint* faceVertexIndices, uint numVerticesInFace) const
{
// Init to zero so that points and lines return a zero normal
Vec3f normal(Vec3f::ZERO);
if (numVerticesInFace == 3)
{
const Vec3f& v0 = m_vertexArray.val(faceVertexIndices[0]);
Vec3f v1 = m_vertexArray.val(faceVertexIndices[1]) - v0;
Vec3f v2 = m_vertexArray.val(faceVertexIndices[2]) - v0;
normal = v1 ^ v2;
normal.normalize();
}
else if (numVerticesInFace == 4)
{
// Quad surface normal,
// From "Real Time Collision Detection" p 495
const Vec3f& A = m_vertexArray.val(faceVertexIndices[0]);
const Vec3f& B = m_vertexArray.val(faceVertexIndices[1]);
const Vec3f& C = m_vertexArray.val(faceVertexIndices[2]);
const Vec3f& D = m_vertexArray.val(faceVertexIndices[3]);
normal = GeometryUtils::quadNormal(A, B, C, D);
}
else if (numVerticesInFace > 4)
{
normal = GeometryUtils::polygonNormal(m_vertexArray, faceVertexIndices, numVerticesInFace);
}
return normal;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool OutlineEdgeExtractor::isFaceAngleAboveThreshold(size_t faceIdx1, size_t faceIdx2) const
{
const Vec3f& n1 = m_faceNormals[faceIdx1];
const Vec3f& n2 = m_faceNormals[faceIdx2];
// If either vector is 0, the face is probably a line
// Therefore just return true to flag this as an outline edge
if (n1.isZero() || n2.isZero())
{
return true;
}
// Guard acos against out-of-domain input
const double dotProduct = Math::clamp(static_cast<double>(n1*n2), -1.0, 1.0);
const double angle = Math::acos(dotProduct);
if (Math::abs(angle) > m_creaseAngle)
{
return true;
}
else
{
return false;
}
}
} // namespace cvf
} //namespace external

View File

@@ -1,82 +0,0 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2013 Ceetron AS
//
// This library may be used under the terms of either the GNU General Public License or
// the GNU Lesser General Public License as follows:
//
// GNU General Public License Usage
// This library 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.
//
// This library 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 at <<http://www.gnu.org/licenses/gpl.html>>
// for more details.
//
// GNU Lesser General Public License Usage
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library 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 Lesser General Public License at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
// for more details.
//
//##################################################################################################
#pragma once
#include "cvfArray.h"
#include <map>
namespace external {
namespace cvf {
//==================================================================================================
//
//
//
//==================================================================================================
class OutlineEdgeExtractor
{
public:
OutlineEdgeExtractor(double creaseAngle, const Vec3fValueArray& vertexArray);
public:
void addPrimitives(uint verticesPerPrimitive, const uint* indices, size_t indexCount);
void addPrimitives(uint verticesPerPrimitive, const UIntArray& indices);
void addFaceList(const UIntArray& faceList);
ref<UIntArray> lineIndices() const;
const std::vector<Vec3f>& faceNormals(); // Surface normals for the faces, normalized
private:
Vec3f computeFaceNormal(const uint* faceVertexIndices, uint numVerticesInFace) const;
bool isFaceAngleAboveThreshold(size_t faceIdx1, size_t faceIdx2) const;
private:
double m_creaseAngle; // Threshold crease angle in radians
const Vec3fValueArray& m_vertexArray;
std::map<int64, size_t> m_edgeToFaceIndexMap;
std::vector<Vec3f> m_faceNormals; // Surface normals for the faces, normalized
};
}
} //namespace external

View File

@@ -1,108 +0,0 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) Ceetron Solutions AS
//
// This library may be used under the terms of either the GNU General Public License or
// the GNU Lesser General Public License as follows:
//
// GNU General Public License Usage
// This library 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.
//
// This library 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 at <<http://www.gnu.org/licenses/gpl.html>>
// for more details.
//
// GNU Lesser General Public License Usage
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library 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 Lesser General Public License at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
// for more details.
//
//##################################################################################################
#include "cvfBase.h"
#include "cvfPrimitiveTests.h"
#include <limits>
namespace external {
namespace cvf {
//==================================================================================================
///
/// \class cvf::PrimitiveTests
/// \ingroup Geometry
///
///
///
//==================================================================================================
//--------------------------------------------------------------------------------------------------
/// Calculate intersection between the lines p1p2 and p3p4
//--------------------------------------------------------------------------------------------------
bool PrimitiveTests::intersectLines(const Vec2d& p1, const Vec2d& p2, const Vec2d& p3, const Vec2d& p4, Vec2d* isect)
{
// See Paul Bourke, Intersection point of two lines in 2 dimensions
const double epsilon = std::numeric_limits<double>::epsilon();
const double denom = (p4.y()-p3.y())*(p2.x()-p1.x()) - (p4.x()-p3.x())*(p2.y()-p1.y());
const double numera = (p4.x()-p3.x())*(p1.y()-p3.y()) - (p4.y()-p3.y())*(p1.x()-p3.x());
const double numerb = (p2.x()-p1.x())*(p1.y()-p3.y()) - (p2.y()-p1.y())*(p1.x()-p3.x());
// Are the lines coincident?
if (cvf::Math::abs(numera) < epsilon &&
cvf::Math::abs(numerb) < epsilon &&
cvf::Math::abs(denom) < epsilon)
{
isect->x() = (p1.x() + p2.x()) / 2;
isect->y() = (p1.y() + p2.y()) / 2;
return true;
}
// Are the lines parallel?
if (cvf::Math::abs(denom) < epsilon)
{
isect->setZero();
return false;
}
const double ta = numera/denom;
// const double tb = numerb/denom;
//
// // Is the intersection along the the segments ?
// if (ta < 0 || ta > 1 || tb < 0 || tb > 1)
// {
// isect->setZero();
// return false;
// }
isect->x() = p1.x() + ta * (p2.x() - p1.x());
isect->y() = p1.y() + ta * (p2.y() - p1.y());
return true;
}
} // namespace cvf
} //namespace external

View File

@@ -1,58 +0,0 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) Ceetron Solutions AS
//
// This library may be used under the terms of either the GNU General Public License or
// the GNU Lesser General Public License as follows:
//
// GNU General Public License Usage
// This library 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.
//
// This library 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 at <<http://www.gnu.org/licenses/gpl.html>>
// for more details.
//
// GNU Lesser General Public License Usage
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library 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 Lesser General Public License at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
// for more details.
//
//##################################################################################################
#pragma once
#include "cvfVector2.h"
namespace external {
namespace cvf {
//==================================================================================================
//
//
//
//==================================================================================================
class PrimitiveTests
{
public:
static bool intersectLines(const Vec2d& p1, const Vec2d& p2, const Vec2d& p3, const Vec2d& p4, Vec2d* isect);
};
}
} //namespace external

View File

@@ -1,155 +0,0 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2013 Ceetron AS
//
// This library may be used under the terms of either the GNU General Public License or
// the GNU Lesser General Public License as follows:
//
// GNU General Public License Usage
// This library 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.
//
// This library 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 at <<http://www.gnu.org/licenses/gpl.html>>
// for more details.
//
// GNU Lesser General Public License Usage
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library 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 Lesser General Public License at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
// for more details.
//
//##################################################################################################
#include "cvfBase.h"
#include "cvfTriangleMeshEdgeExtractor.h"
namespace external {
namespace cvf {
//==================================================================================================
///
/// \class cvf::TriangleMeshEdgeExtractor
/// \ingroup Geometry
///
///
///
//==================================================================================================
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
TriangleMeshEdgeExtractor::TriangleMeshEdgeExtractor()
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void TriangleMeshEdgeExtractor::addTriangles(const UIntArray& indices, const UIntArray& triangleKeys)
{
size_t index = 0;
size_t numTris = indices.size()/3;
size_t tri;
for (tri = 0; tri < numTris; tri++)
{
uint key = triangleKeys[tri];
uint v1 = indices[index++];
uint v2 = indices[index++];
uint v3 = indices[index++];
addEdge(v1, v2, key);
addEdge(v2, v3, key);
addEdge(v3, v1, key);
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void TriangleMeshEdgeExtractor::addEdge(uint v1, uint v2, uint key)
{
int64 edgeKeyVal = 0;
if (v1 < v2)
{
edgeKeyVal = v2;
edgeKeyVal <<= 32;
edgeKeyVal += v1;
}
else
{
edgeKeyVal = v1;
edgeKeyVal <<= 32;
edgeKeyVal += v2;
}
std::map<int64, uint>::iterator it = m_edgeMap.find(edgeKeyVal);
if (it != m_edgeMap.end())
{
uint foundKey = it->second;
if (foundKey == key)
{
// Remove edge from map and return
m_edgeMap.erase(it);
}
}
else
{
m_edgeMap[edgeKeyVal] = key;
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
ref<UIntArray> TriangleMeshEdgeExtractor::lineIndices() const
{
ref<UIntArray> indices = new UIntArray;
size_t numEdges = m_edgeMap.size();
if (numEdges == 0)
{
return indices;
}
indices->reserve(2*numEdges);
std::map<cvf::int64, uint>::const_iterator it;
for (it = m_edgeMap.begin(); it != m_edgeMap.end(); ++it)
{
int64 edgeKey = it->first;
uint v1 = static_cast<uint>(edgeKey);
uint v2 = static_cast<uint>(edgeKey>>32);
indices->add(v1);
indices->add(v2);
}
return indices;
}
} // namespace cvf
} //namespace external

View File

@@ -1,83 +0,0 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2013 Ceetron AS
//
// This library may be used under the terms of either the GNU General Public License or
// the GNU Lesser General Public License as follows:
//
// GNU General Public License Usage
// This library 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.
//
// This library 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 at <<http://www.gnu.org/licenses/gpl.html>>
// for more details.
//
// GNU Lesser General Public License Usage
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library 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 Lesser General Public License at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
// for more details.
//
//##################################################################################################
#pragma once
#include "cvfArray.h"
#include <map>
namespace external {
namespace cvf {
//==================================================================================================
//
// Extract mesh from triangles with a key per triangle. Mesh edges will not be produced between
// triangles with the same key.
//
//==================================================================================================
class TriangleMeshEdgeExtractor
{
public:
TriangleMeshEdgeExtractor();
void addTriangles(const UIntArray& indices, const UIntArray& triangleKeys);
ref<UIntArray> lineIndices() const;
private:
std::map<int64, uint> m_edgeMap;
inline int64 edgeKey(uint v1, uint v2)
{
if (v1 < v2)
{
int64 key = v2;
key <<= 32;
return key + v1;
}
int64 key = v1;
key <<= 32;
return key + v2;
}
void addEdge(uint v1, uint v2, uint key);
};
}
} //namespace external

View File

@@ -1,330 +0,0 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2013 Ceetron AS
//
// This library may be used under the terms of either the GNU General Public License or
// the GNU Lesser General Public License as follows:
//
// GNU General Public License Usage
// This library 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.
//
// This library 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 at <<http://www.gnu.org/licenses/gpl.html>>
// for more details.
//
// GNU Lesser General Public License Usage
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library 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 Lesser General Public License at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
// for more details.
//
//##################################################################################################
#include "cvfBase.h"
#include "cvfTriangleVertexSplitter.h"
#include "cvfFrustum.h"
#include "cvfOutlineEdgeExtractor.h"
namespace external {
namespace cvf {
//==================================================================================================
///
/// \class cvf::TriangleVertexSplitter
/// \ingroup Geometry
///
/// This class takes a triangle mesh and duplicates nodes on edges where the normal of the two triangles
/// on the edge differ more than the given crease angle.
///
/// The vertices are also compacted, so the returned vertexArray() contains only the vertices
/// referenced by the triangles.
///
//==================================================================================================
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
TriangleVertexSplitter::TriangleVertexSplitter(double creaseAngle, const cvf::UIntValueArray& origTriangleIndices, const cvf::Vec3fValueArray& origVertexArray)
: m_creaseAngle(creaseAngle),
m_origTriangleIndices(origTriangleIndices),
m_origVertexArray(origVertexArray),
m_isComputed(false)
{
}
//--------------------------------------------------------------------------------------------------
/// Returns the new connectivity table for the triangles. Same size as the input origTriangleIndices
/// array
//--------------------------------------------------------------------------------------------------
ref<UIntArray> TriangleVertexSplitter::triangleIndices()
{
if (!m_isComputed)
{
splitVertices();
}
return m_triangleIndices;
}
//--------------------------------------------------------------------------------------------------
/// Returns the new vertex array containg only the referenced nodes in the triangle mesh, but with
/// split nodes wherever needed.
//--------------------------------------------------------------------------------------------------
ref<Vec3fArray> TriangleVertexSplitter::vertexArray()
{
if (!m_isComputed)
{
splitVertices();
}
ref<Vec3fArray> output = new Vec3fArray(m_vertexArray);
return output;
}
//--------------------------------------------------------------------------------------------------
/// Returns an array with vertex indices into the input origVertexArray for each vertex in the
/// output vertexArray(). Used to keep track of the original index of the compacted and split output
/// array.
//--------------------------------------------------------------------------------------------------
ref<UIntArray> TriangleVertexSplitter::perVertexOriginalIndices()
{
if (!m_isComputed)
{
splitVertices();
}
size_t numUsedVertices = m_vertexArray.size();
ref<UIntArray> output = new UIntArray;
if (numUsedVertices == 0)
{
return output;
}
output->resize(numUsedVertices);
output->setAll(UNDEFINED_UINT);
size_t numOrigVertices = m_origVertexArray.size();
size_t i;
for (i = 0; i < numOrigVertices; i++)
{
uint usedIdx = m_origToUsedNodeMap[i];
if (usedIdx != UNDEFINED_UINT)
{
output->set(usedIdx, static_cast<uint>(i));
}
}
for (i = 0; i < numUsedVertices; i++)
{
if (output->get(i) != UNDEFINED_UINT)
{
uint origIndex = output->get(i);
uint nextSplit = m_nextSplitVertexIdx[i];
m_nextSplitVertexIdx[i] = UNDEFINED_UINT;
while (nextSplit != UNDEFINED_UINT)
{
CVF_TIGHT_ASSERT(output->get(nextSplit) == UNDEFINED_UINT);
output->set(nextSplit, origIndex);
uint nextSplitThis = nextSplit;
nextSplit = m_nextSplitVertexIdx[nextSplit];
m_nextSplitVertexIdx[nextSplitThis] = UNDEFINED_UINT;
}
}
}
return output;
}
//--------------------------------------------------------------------------------------------------
/// Returns an array of smooth per vertex normals corresponding to the output vertexArray().
//--------------------------------------------------------------------------------------------------
ref<Vec3fArray> TriangleVertexSplitter::vertexNormals()
{
if (!m_isComputed)
{
splitVertices();
}
size_t numVertices = m_normalArray.size();
ref<Vec3fArray> output = new Vec3fArray;
if (numVertices == 0)
{
return output;
}
output->reserve(numVertices);
size_t i;
for (i = 0; i < numVertices; i++)
{
output->add(m_normalArray[i].getNormalized());
}
return output;
}
//--------------------------------------------------------------------------------------------------
/// Worker. Split the vertices that needs splitting and compact the vertexArray and indices.
//--------------------------------------------------------------------------------------------------
void TriangleVertexSplitter::splitVertices()
{
CVF_ASSERT(!m_isComputed);
m_isComputed = true;
// Handle empty data;
if (m_origTriangleIndices.size() == 0)
{
m_triangleIndices = new UIntArray;
return;
}
size_t origVertexCount = m_origVertexArray.size();
m_triangleIndices = new UIntArray(m_origTriangleIndices);
m_vertexArray.reserve(origVertexCount);
m_normalArray.reserve(origVertexCount);
m_nextSplitVertexIdx.reserve(origVertexCount);
m_origToUsedNodeMap.resize(origVertexCount);
m_origToUsedNodeMap.setAll(UNDEFINED_UINT);
size_t origConnIndex = 0;
size_t numTris = m_triangleIndices->size() / 3;
size_t tri;
for (tri = 0; tri < numTris; tri++)
{
uint c0 = m_origTriangleIndices.val(origConnIndex);
uint c1 = m_origTriangleIndices.val(origConnIndex + 1);
uint c2 = m_origTriangleIndices.val(origConnIndex + 2);
// Compute normal
Vec3f v0 = m_origVertexArray.val(c0);
Vec3f v1 = m_origVertexArray.val(c1);
Vec3f v2 = m_origVertexArray.val(c2);
Vec3f normal = (v1 - v0) ^ (v2 - v0);
normal.normalize();
uint newConn1 = processVertex(c0, normal);
uint newConn2 = processVertex(c1, normal);
uint newConn3 = processVertex(c2, normal);
m_triangleIndices->set(origConnIndex, newConn1);
m_triangleIndices->set(origConnIndex + 1, newConn2);
m_triangleIndices->set(origConnIndex + 2, newConn3);
origConnIndex += 3;
}
}
//--------------------------------------------------------------------------------------------------
/// Returns the new index of the given vertex based on if the vertex will be split or not.
//--------------------------------------------------------------------------------------------------
uint TriangleVertexSplitter::processVertex(uint origVertexIndex, const Vec3f& faceNormal)
{
uint vertexIndex = m_origToUsedNodeMap[origVertexIndex];
if (vertexIndex == UNDEFINED_UINT)
{
vertexIndex = static_cast<uint>(m_vertexArray.size());
m_origToUsedNodeMap[origVertexIndex] = vertexIndex;
m_vertexArray.push_back(m_origVertexArray.val(origVertexIndex));
m_normalArray.push_back(faceNormal);
m_nextSplitVertexIdx.push_back(UNDEFINED_UINT);
return vertexIndex;
}
uint outputIndex = vertexIndex;
for(;;)
{
const Vec3f& vertexNormal = m_normalArray[outputIndex].getNormalized();
if (isNormalDifferenceBelowThreshold(faceNormal, vertexNormal))
{
m_normalArray[outputIndex] += faceNormal;
return outputIndex;
}
else
{
uint nextVertexIndex = m_nextSplitVertexIdx[outputIndex];
if (nextVertexIndex == UNDEFINED_UINT)
{
// Cannot average with any existing normal in orig or new split vertices
uint newVertexIndex = static_cast<uint>(m_vertexArray.size());
m_nextSplitVertexIdx[outputIndex] = newVertexIndex;
outputIndex = newVertexIndex;
m_vertexArray.push_back(m_vertexArray[vertexIndex]);
m_normalArray.push_back(faceNormal);
m_nextSplitVertexIdx.push_back(UNDEFINED_UINT);
return outputIndex;
}
outputIndex = nextVertexIndex;
}
}
}
//--------------------------------------------------------------------------------------------------
/// Return true if the angle between the two normals is below the current crease angle.
//--------------------------------------------------------------------------------------------------
bool TriangleVertexSplitter::isNormalDifferenceBelowThreshold(const Vec3f& n1, const Vec3f& n2)
{
// If either vector is 0, there is probably some trouble with the triangle
// Return false so that it will be split
if (n1.isZero() || n2.isZero())
{
return false;
}
// Guard acos against out-of-domain input
const double dotProduct = Math::clamp(static_cast<double>(n1*n2), -1.0, 1.0);
const double angle = Math::acos(dotProduct);
if (Math::abs(angle) < m_creaseAngle)
{
return true;
}
return false;
}
} // namespace cvf
} //namespace external

View File

@@ -1,79 +0,0 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2013 Ceetron AS
//
// This library may be used under the terms of either the GNU General Public License or
// the GNU Lesser General Public License as follows:
//
// GNU General Public License Usage
// This library 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.
//
// This library 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 at <<http://www.gnu.org/licenses/gpl.html>>
// for more details.
//
// GNU Lesser General Public License Usage
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library 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 Lesser General Public License at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
// for more details.
//
//##################################################################################################
#pragma once
#include "cvfArray.h"
namespace external {
namespace cvf {
//=================================================================================================
//
// Triangle Vertex Splitter Class
//
//=================================================================================================
class TriangleVertexSplitter
{
public:
TriangleVertexSplitter(double creaseAngle, const UIntValueArray& origTriangleIndices, const Vec3fValueArray& origVertexArray);
ref<UIntArray> triangleIndices();
ref<Vec3fArray> vertexArray();
ref<Vec3fArray> vertexNormals();
ref<UIntArray> perVertexOriginalIndices(); // Per vertex (source) indices into origVertexArray
private:
void splitVertices();
uint processVertex(uint origVertexIndex, const Vec3f& faceNormal);
bool isNormalDifferenceBelowThreshold(const Vec3f& n1, const Vec3f& n2);
private:
double m_creaseAngle;
const UIntValueArray& m_origTriangleIndices;
const Vec3fValueArray& m_origVertexArray;
bool m_isComputed;
ref<UIntArray> m_triangleIndices;
UIntArray m_origToUsedNodeMap;
std::vector<uint> m_nextSplitVertexIdx;
std::vector<Vec3f> m_vertexArray;
std::vector<Vec3f> m_normalArray;
};
}
} //namespace external

View File

@@ -1,139 +0,0 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2013 Ceetron AS
//
// This library may be used under the terms of either the GNU General Public License or
// the GNU Lesser General Public License as follows:
//
// GNU General Public License Usage
// This library 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.
//
// This library 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 at <<http://www.gnu.org/licenses/gpl.html>>
// for more details.
//
// GNU Lesser General Public License Usage
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library 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 Lesser General Public License at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
// for more details.
//
//##################################################################################################
#include "cvfBase.h"
#include "cvfVertexCompactor.h"
#include "cvfGeometryUtils.h"
namespace external {
namespace cvf {
//==================================================================================================
///
/// \class cvf::VertexCompactor
/// \ingroup Geometry
///
/// Worker class for creating compact indices based on a "global" index array
///
//==================================================================================================
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
VertexCompactor::VertexCompactor(const UIntValueArray& origIndices, const Vec3fValueArray& origVertexArray)
: m_origIndices(origIndices),
m_origVertexArray(origVertexArray)
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void VertexCompactor::computeCompactedIndices()
{
m_newIndices = new UIntArray;
m_newToOldVertexIndexMapping = new UIntArray;
uint maxNumResultingVertices = static_cast<uint>(m_origVertexArray.size());
GeometryUtils::removeUnusedVertices(m_origIndices, m_newIndices.p(), m_newToOldVertexIndexMapping.p(), maxNumResultingVertices);
}
//--------------------------------------------------------------------------------------------------
/// Get indices into new vertex array
///
/// \return Newly allocated array with the new indices. An array is always returned, but may have zero entries.
//--------------------------------------------------------------------------------------------------
ref<UIntArray> VertexCompactor::indices()
{
if (m_newIndices.isNull())
{
computeCompactedIndices();
}
CVF_ASSERT(m_newIndices.notNull());
return m_newIndices;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
ref<Vec3fArray> VertexCompactor::vertexArray()
{
if (m_newIndices.isNull())
{
computeCompactedIndices();
}
CVF_ASSERT(m_newToOldVertexIndexMapping.notNull());
ref<Vec3fArray> vertices = new Vec3fArray;
size_t numNewVertices = m_newToOldVertexIndexMapping->size();
if (numNewVertices > 0)
{
vertices->reserve(numNewVertices);
size_t i;
for (i = 0; i < numNewVertices; i++)
{
vertices->add(m_origVertexArray.val(m_newToOldVertexIndexMapping->get(i)));
}
}
return vertices;
}
//--------------------------------------------------------------------------------------------------
/// Get array of original indices per new vertex.
///
/// The returned array will be the same size as the array of vertices returned by vertexArray().
/// The indices are the original/source indices of the vertices
//--------------------------------------------------------------------------------------------------
ref<UIntArray> VertexCompactor::perVertexOriginalIndices()
{
if (m_newToOldVertexIndexMapping.isNull())
{
computeCompactedIndices();
}
CVF_ASSERT(m_newToOldVertexIndexMapping.notNull());
return m_newToOldVertexIndexMapping;
}
} // namespace cvf
} //namespace external

View File

@@ -1,72 +0,0 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2013 Ceetron AS
//
// This library may be used under the terms of either the GNU General Public License or
// the GNU Lesser General Public License as follows:
//
// GNU General Public License Usage
// This library 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.
//
// This library 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 at <<http://www.gnu.org/licenses/gpl.html>>
// for more details.
//
// GNU Lesser General Public License Usage
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library 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 Lesser General Public License at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
// for more details.
//
//##################################################################################################
#pragma once
#include "cvfArray.h"
#include "cvfVector3.h"
namespace external {
namespace cvf {
//=================================================================================================
//
// Vertex Compactor class
//
//=================================================================================================
class VertexCompactor
{
public:
VertexCompactor(const UIntValueArray& origIndices, const Vec3fValueArray& origVertexArray);
ref<UIntArray> indices();
ref<Vec3fArray> vertexArray();
ref<UIntArray> perVertexOriginalIndices();
private:
void computeCompactedIndices();
private:
const UIntValueArray& m_origIndices; // Indices into the original vertex array
const Vec3fValueArray& m_origVertexArray; // Original vertex array
ref<UIntArray> m_newIndices; // Indices into new vertex array
ref<UIntArray> m_newToOldVertexIndexMapping; // For each new vertex, this array will store the vertex' original (source) index into origVertexArray
};
}
} //namespace external

View File

@@ -1,280 +0,0 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2013 Ceetron AS
//
// This library may be used under the terms of either the GNU General Public License or
// the GNU Lesser General Public License as follows:
//
// GNU General Public License Usage
// This library 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.
//
// This library 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 at <<http://www.gnu.org/licenses/gpl.html>>
// for more details.
//
// GNU Lesser General Public License Usage
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library 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 Lesser General Public License at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
// for more details.
//
//##################################################################################################
#include "cvfBase.h"
#include "cvfVertexWelder.h"
namespace external {
namespace cvf {
//==================================================================================================
///
/// \class cvf::VertexWelder
/// \ingroup Geometry
///
/// Supports welding of vertices based on vertex distance
///
/// \internal Adapted from the book: "Real time collision detection' by Christer Ericson
//==================================================================================================
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
VertexWelder::VertexWelder()
{
m_weldEpsilon = 0;
m_cellSize = 0;
m_numBuckets = 0;
}
//--------------------------------------------------------------------------------------------------
/// Initialize, must be done before usage of object
///
/// The cell size must be at least 2*weldingDistance, but should normally be much larger. If the
/// specified cell size is too small, it will be set to approximately 2*weldingDistance
//--------------------------------------------------------------------------------------------------
void VertexWelder::initialize(double weldingDistance, double cellSize, uint numBuckets)
{
CVF_ASSERT(weldingDistance >= 0);
CVF_ASSERT(cellSize > 2*weldingDistance);
CVF_ASSERT(numBuckets > 0);
m_weldEpsilon = weldingDistance;
m_cellSize = cellSize;
if (m_cellSize < 2.1*weldingDistance)
{
m_cellSize = 2.1*weldingDistance;
}
m_numBuckets = numBuckets;
m_first.resize(numBuckets);
m_first.setAll(UNDEFINED_UINT);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void VertexWelder::reserveVertices(uint vertexCount)
{
m_vertex.reserve(vertexCount);
m_next.reserve(vertexCount);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
uint VertexWelder::weldVertex(const Vec3f& vertex, bool* wasWelded)
{
// Must be initialized
CVF_ASSERT(m_cellSize > 0 && m_numBuckets > 0);
// Make sure welding distance (epsilon) is not too small for the coordinates used!
// Not sure if we need to handle this case - unsure of what happens if epsilon gets too small.
// Guess the only trouble is that we won't look into neighbor cells, which in turn
// means that we won't be able to weld vertices even if they are closer than epsilon.
//CVF_ASSERT(vertex.x() - m_weldEpsilon != vertex.x() && vertex.x() + m_weldEpsilon != vertex.x());
//CVF_ASSERT(vertex.y() - m_weldEpsilon != vertex.y() && vertex.y() + m_weldEpsilon != vertex.y());
//CVF_ASSERT(vertex.z() - m_weldEpsilon != vertex.z() && vertex.z() + m_weldEpsilon != vertex.z());
// Compute cell coordinates of bounding box of vertex epsilon neighborhood
int left = int((vertex.x() - m_weldEpsilon) / m_cellSize);
int right = int((vertex.x() + m_weldEpsilon) / m_cellSize);
int front = int((vertex.y() - m_weldEpsilon) / m_cellSize);
int back = int((vertex.y() + m_weldEpsilon) / m_cellSize);
int bottom = int((vertex.z() - m_weldEpsilon) / m_cellSize);
int top = int((vertex.z() + m_weldEpsilon) / m_cellSize);
// To lessen effects of worst-case behavior, track previously tested buckets
// 4 in 2D, 8 in 3D
uint prevBucket[8];
int numPrevBuckets = 0;
// Loop over all overlapped cells and test against their buckets
int i;
for (i = left; i <= right; i++)
{
int j;
for (j = front; j <= back; j++)
{
int k;
for (k = bottom; k <= top; k++)
{
uint bucket = getGridCellBucket(i, j, k);
// If this bucket already tested, don't test it again
bool bucketAlreadyTested = false;
for (int b = 0; b < numPrevBuckets; b++)
{
if (bucket == prevBucket[b])
{
bucketAlreadyTested = true;
break;
}
}
if (!bucketAlreadyTested)
{
// Add this bucket to visited list, then test against its contents
CVF_ASSERT(numPrevBuckets < 8);
prevBucket[numPrevBuckets++] = bucket;
// Call function to step through linked list of bucket, testing
// if vertex is within the epsilon of one of the vertices in the bucket
uint indexOfLocatedVertex = locateVertexInBucket(vertex, bucket);
if (indexOfLocatedVertex != UNDEFINED_UINT)
{
if (wasWelded) *wasWelded = true;
return indexOfLocatedVertex;
}
}
}
}
}
// Couldn't locate vertex, so add it to grid
int x = int(vertex.x() / m_cellSize);
int y = int(vertex.y() / m_cellSize);
int z = int(vertex.z() / m_cellSize);
uint indexOfAddedVertex = addVertexToBucket(vertex, getGridCellBucket(x, y, z));
if (wasWelded) *wasWelded = false;
return indexOfAddedVertex;
}
//--------------------------------------------------------------------------------------------------
/// Maps unbounded grid cell coordinates (x, y, z) into an index into a fixed-size array of hash buckets
//--------------------------------------------------------------------------------------------------
uint VertexWelder::getGridCellBucket(int x, int y, int z) const
{
// Large multiplicative constants; here arbitrarily chosen primes
const uint magic1 = 0x8da6b343;
const uint magic2 = 0xd8163841;
const uint magic3 = 0xcb1ab31f;
uint index = magic1*x + magic2*y + z*magic3;
// Bring index into [0, m_numBuckets) range
return index % m_numBuckets;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
uint VertexWelder::locateVertexInBucket(const Vec3f& v, uint bucket) const
{
const double weldEpsilonSqared = m_weldEpsilon*m_weldEpsilon;
// Scan through linked list of vertices at this bucket
uint index = m_first[bucket];
while (index != UNDEFINED_UINT)
{
// Weld this vertex to existing vertex if within given distance tolerance
float sqDistPointPoint = (m_vertex[index] - v).lengthSquared();
if (sqDistPointPoint < weldEpsilonSqared)
{
return index;
}
index = m_next[index];
}
// No vertex found to weld to.
return UNDEFINED_UINT;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
uint VertexWelder::addVertexToBucket(const Vec3f& v, uint bucket)
{
CVF_TIGHT_ASSERT(bucket < m_numBuckets);
CVF_TIGHT_ASSERT(m_numBuckets == m_first.size());
// Fill next available vertex buffer entry and link it into vertex list
m_vertex.push_back(v);
m_next.push_back(m_first[bucket]);
CVF_TIGHT_ASSERT(m_vertex.size() == m_next.size());
uint indexOfAddedVertex = static_cast<uint>(m_vertex.size() - 1);
m_first[bucket] = indexOfAddedVertex;
return indexOfAddedVertex;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
uint VertexWelder::vertexCount() const
{
return static_cast<uint>(m_vertex.size());
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const Vec3f& VertexWelder::vertex(uint index) const
{
return m_vertex[index];
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
ref<Vec3fArray> VertexWelder::createVertexArray() const
{
ref<Vec3fArray> va = new Vec3fArray(m_vertex);
return va;
}
} // namespace cvf
} //namespace external

View File

@@ -1,88 +0,0 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2013 Ceetron AS
//
// This library may be used under the terms of either the GNU General Public License or
// the GNU Lesser General Public License as follows:
//
// GNU General Public License Usage
// This library 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.
//
// This library 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 at <<http://www.gnu.org/licenses/gpl.html>>
// for more details.
//
// GNU Lesser General Public License Usage
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library 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 Lesser General Public License at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
// for more details.
//
//##################################################################################################
#pragma once
#include "cvfArray.h"
namespace external {
namespace cvf {
//==================================================================================================
//
//
//
//==================================================================================================
class VertexWelder
{
public:
VertexWelder();
void initialize(double weldingDistance, double cellSize, uint numBuckets);
void reserveVertices(uint vertexCount);
uint weldVertex(const Vec3f& vertex, bool* wasWelded);
uint vertexCount() const;
const Vec3f& vertex(uint index) const;
ref<Vec3fArray> createVertexArray() const;
private:
uint getGridCellBucket(int x, int y, int z) const;
uint locateVertexInBucket(const Vec3f& v, uint bucket) const;
uint addVertexToBucket(const Vec3f& v, uint bucket);
private:
double m_weldEpsilon; // Welding tolerance, radius around vertex defining welding neighborhood
double m_cellSize; // Grid cell size; must be at least 2*m_weldEpsilon
uint m_numBuckets; // Number of hash buckets to map grid cells into
UIntArray m_first; // Start of linked list for each bucket. Number of buckets long
std::vector<uint> m_next; // Links each vertex to next in linked list. Always numVertices long, will grow as vertices are added
std::vector<Vec3f> m_vertex; // Unique vertices within tolerance
};
}
} //namespace external

View File

@@ -1,845 +0,0 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2017 Statoil ASA
//
// ResInsight 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.
//
// ResInsight 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 at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#include "RigCellGeometryTools.h"
#include "cvfGeometryTools.h"
#include "cvfStructGrid.h"
#include "cafHexGridIntersectionTools/cafHexGridIntersectionTools.h"
#include "cvfBoundingBox.h"
#include "cvfMatrix3.h"
#include "clipper/clipper.hpp"
#include <algorithm>
#include <array>
#include <vector>
namespace external
{
//--------------------------------------------------------------------------------------------------
/// Efficient Computation of Volume of Hexahedral Cells
/// Jeffrey Grandy, Lawrence Livermore National Laboratory
/// https://www.osti.gov/servlets/purl/632793/
///
/// Note that in the paper the following vertex numbering is used
/// 6---------7
/// /| /| |k
/// / | / | | /j
/// 4---------5 | |/
/// | 2------|--3 *---i
/// | / | /
/// |/ |/
/// 0---------1
///
/// While in ResInsight, this is the numbering. Thus we need to swap 2<->3, 6<->7 in the equations.
/// Note the negative k! This causes an additional set of 0<->4, 1<->5, etc. index swaps.
/// 7---------6
/// /| /| |-k
/// / | / | | /j
/// 4---------5 | |/
/// | 3------|--2 *---i
/// | / | /
/// |/ |/
/// 0---------1
//--------------------------------------------------------------------------------------------------
double RigCellGeometryTools::calculateCellVolume( const std::array<cvf::Vec3d, 8>& x )
{
// 6 * 3 flops = 18 flops
// Perform index swap when retrieving corners but keep indices in variable names matching paper.
cvf::Vec3d x3mx0 = x[6] - x[4]; // Swap 3->2, then negate z by 2->6 and 0->4
cvf::Vec3d x5mx0 = x[1] - x[4]; // Negate z by Swap 5->1 and 0->4
cvf::Vec3d x6mx0 = x[3] - x[4]; // Swap 6->7, then negate z by 7->3 and 0->4
cvf::Vec3d x7mx1 = x[2] - x[5]; // Swap 7->6, then negate z by 6->2 and 1->5
cvf::Vec3d x7mx2 = x[2] - x[7]; // Swap 7->6, 2->3, then negate z by 6->2 and 3->7
cvf::Vec3d x7mx4 = x[2] - x[0]; // Swap 7->6 then negate z by 6->2 and 4->0
// 3 flops for summation + 5 for dot product + 9 flops for cross product = 17 flops
double det1 = ( x7mx1 + x6mx0 ) * ( x7mx2 ^ x3mx0 );
// 3 flops for summation + 5 for dot product + 9 flops for cross product = 17 flops
double det2 = x6mx0 * ( ( x7mx2 + x5mx0 ) ^ x7mx4 );
// 3 flops for summation + 5 for dot product + 9 flops for cross product = 17 flops
double det3 = x7mx1 * ( x5mx0 ^ ( x7mx4 + x3mx0 ) );
// 2 flops for summation + 1 for division = 3 flops
double volume = ( det1 + det2 + det3 ) / 12.0;
// In order for this to work in any rotation of the cell, we need the absolute value. 1 flop.
return std::abs( volume ); // Altogether 18 + 3*17 + 3 + 1 flops = 73 flops.
}
//--------------------------------------------------------------------------------------------------
/// A reasonable approximation to the overlap volume
//--------------------------------------------------------------------------------------------------
bool RigCellGeometryTools::estimateHexOverlapWithBoundingBox( const std::array<cvf::Vec3d, 8>& hexCorners,
const cvf::BoundingBox& boundingBox,
std::array<cvf::Vec3d, 8>* overlapElement,
cvf::BoundingBox* overlapBoundingBox )
{
CVF_ASSERT( overlapElement && overlapBoundingBox );
*overlapBoundingBox = cvf::BoundingBox();
std::vector<cvf::Vec3d> uniqueTopPoints = { hexCorners[0], hexCorners[1], hexCorners[2], hexCorners[3] };
auto uniqueTopEnd = std::unique( uniqueTopPoints.begin(), uniqueTopPoints.end() );
if ( uniqueTopEnd - uniqueTopPoints.begin() < 3u ) return false;
cvf::Plane topPlane;
if ( !topPlane.setFromPoints( uniqueTopPoints[0], uniqueTopPoints[1], uniqueTopPoints[2] ) ) return false;
std::vector<cvf::Vec3d> uniqueBottomPoints = { hexCorners[4], hexCorners[5], hexCorners[6], hexCorners[7] };
auto uniqueBottomEnd = std::unique( uniqueBottomPoints.begin(), uniqueBottomPoints.end() );
if ( uniqueBottomEnd - uniqueBottomPoints.begin() < 3u ) return false;
cvf::Plane bottomPlane;
if ( !bottomPlane.setFromPoints( uniqueBottomPoints[0], uniqueBottomPoints[1], uniqueBottomPoints[2] ) )
return false;
const cvf::Vec3d& boundingMin = boundingBox.min();
const cvf::Vec3d& boundingMax = boundingBox.max();
for ( size_t i = 0; i < 4; ++i )
{
const cvf::Vec3d& hexCorner = hexCorners[i];
double x = std::clamp( hexCorner.x(), boundingMin.x(), boundingMax.x() );
double y = std::clamp( hexCorner.y(), boundingMin.y(), boundingMax.y() );
cvf::Vec3d corner;
cvf::Vec3d maxZCorner( x, y, boundingMax.z() );
cvf::Vec3d minZCorner( x, y, boundingMin.z() );
if ( topPlane.intersect( minZCorner, maxZCorner, &corner ) )
{
overlapBoundingBox->add( corner );
std::swap( ( *overlapElement )[i], corner );
}
else
{
double z = std::clamp( hexCorner.z(), boundingMin.z(), boundingMax.z() );
cvf::Vec3d clampedCorner( x, y, z );
overlapBoundingBox->add( clampedCorner );
( *overlapElement )[i] = clampedCorner;
}
}
for ( size_t i = 4; i < 8; ++i )
{
const cvf::Vec3d& hexCorner = hexCorners[i];
double x = std::clamp( hexCorner.x(), boundingMin.x(), boundingMax.x() );
double y = std::clamp( hexCorner.y(), boundingMin.y(), boundingMax.y() );
cvf::Vec3d corner;
cvf::Vec3d maxZCorner( x, y, boundingMax.z() );
cvf::Vec3d minZCorner( x, y, boundingMin.z() );
if ( bottomPlane.intersect( minZCorner, maxZCorner, &corner ) )
{
overlapBoundingBox->add( corner );
std::swap( ( *overlapElement )[i], corner );
}
else
{
double z = std::clamp( hexCorner.z(), boundingMin.z(), boundingMax.z() );
cvf::Vec3d clampedCorner( x, y, z );
overlapBoundingBox->add( clampedCorner );
( *overlapElement )[i] = clampedCorner;
}
}
return true;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RigCellGeometryTools::createPolygonFromLineSegments( std::list<std::pair<cvf::Vec3d, cvf::Vec3d>>& intersectionLineSegments,
std::vector<std::vector<cvf::Vec3d>>& polygons,
double tolerance )
{
bool startNewPolygon = true;
while ( !intersectionLineSegments.empty() )
{
if ( startNewPolygon )
{
std::vector<cvf::Vec3d> polygon;
// Add first line segments to polygon and remove from list
std::pair<cvf::Vec3d, cvf::Vec3d> linesegment = intersectionLineSegments.front();
polygon.push_back( linesegment.first );
polygon.push_back( linesegment.second );
intersectionLineSegments.remove( linesegment );
polygons.push_back( polygon );
startNewPolygon = false;
}
std::vector<cvf::Vec3d>& polygon = polygons.back();
// Search remaining list for next point...
bool isFound = false;
for ( std::list<std::pair<cvf::Vec3d, cvf::Vec3d>>::iterator lIt = intersectionLineSegments.begin();
lIt != intersectionLineSegments.end();
lIt++ )
{
cvf::Vec3d lineSegmentStart = lIt->first;
cvf::Vec3d lineSegmentEnd = lIt->second;
cvf::Vec3d polygonEnd = polygon.back();
double lineSegmentLength = ( lineSegmentStart - lineSegmentEnd ).lengthSquared();
if ( lineSegmentLength < tolerance * tolerance )
{
intersectionLineSegments.erase( lIt );
isFound = true;
break;
}
double lineSegmentStartDiff = ( lineSegmentStart - polygonEnd ).lengthSquared();
if ( lineSegmentStartDiff < tolerance * tolerance )
{
polygon.push_back( lIt->second );
intersectionLineSegments.erase( lIt );
isFound = true;
break;
}
double lineSegmentEndDiff = ( lineSegmentEnd - polygonEnd ).lengthSquared();
if ( lineSegmentEndDiff < tolerance * tolerance )
{
polygon.push_back( lIt->first );
intersectionLineSegments.erase( lIt );
isFound = true;
break;
}
}
if ( isFound )
{
continue;
}
else
{
startNewPolygon = true;
}
}
}
//--------------------------------------------------------------------------------------------------
/// Ramer-Douglas-Peucker simplification algorithm
///
/// https://en.wikipedia.org/wiki/Ramer%E2%80%93Douglas%E2%80%93Peucker_algorithm
//--------------------------------------------------------------------------------------------------
void RigCellGeometryTools::simplifyPolygon( std::vector<cvf::Vec3d>* vertices, double epsilon )
{
CVF_ASSERT( vertices );
if ( vertices->size() < 3 ) return;
std::pair<size_t, double> maxDistPoint( 0u, 0.0 );
for ( size_t i = 1; i < vertices->size() - 1; ++i )
{
cvf::Vec3d v = vertices->at( i );
double u;
cvf::Vec3d v_proj = cvf::GeometryTools::projectPointOnLine( vertices->front(), vertices->back(), v, &u );
double distance = ( v_proj - v ).length();
if ( distance > maxDistPoint.second )
{
maxDistPoint = std::make_pair( i, distance );
}
}
if ( maxDistPoint.second > epsilon )
{
std::vector<cvf::Vec3d> newVertices1( vertices->begin(), vertices->begin() + maxDistPoint.first + 1 );
std::vector<cvf::Vec3d> newVertices2( vertices->begin() + maxDistPoint.first, vertices->end() );
// Recurse
simplifyPolygon( &newVertices1, epsilon );
simplifyPolygon( &newVertices2, epsilon );
std::vector<cvf::Vec3d> newVertices( newVertices1.begin(), newVertices1.end() - 1 );
newVertices.insert( newVertices.end(), newVertices2.begin(), newVertices2.end() );
*vertices = newVertices;
}
else
{
std::vector<cvf::Vec3d> newVertices = { vertices->front(), vertices->back() };
*vertices = newVertices;
}
}
//==================================================================================================
///
//==================================================================================================
void RigCellGeometryTools::findCellLocalXYZ( const std::array<cvf::Vec3d, 8>& hexCorners,
cvf::Vec3d& localXdirection,
cvf::Vec3d& localYdirection,
cvf::Vec3d& localZdirection )
{
cvf::ubyte faceVertexIndices[4];
cvf::StructGridInterface::FaceEnum face;
face = cvf::StructGridInterface::NEG_I;
cvf::StructGridInterface::cellFaceVertexIndices( face, faceVertexIndices );
cvf::Vec3d faceCenterNegI = cvf::GeometryTools::computeFaceCenter( hexCorners[faceVertexIndices[0]],
hexCorners[faceVertexIndices[1]],
hexCorners[faceVertexIndices[2]],
hexCorners[faceVertexIndices[3]] );
// TODO: Should we use face centroids instead of face centers?
face = cvf::StructGridInterface::POS_I;
cvf::StructGridInterface::cellFaceVertexIndices( face, faceVertexIndices );
cvf::Vec3d faceCenterPosI = cvf::GeometryTools::computeFaceCenter( hexCorners[faceVertexIndices[0]],
hexCorners[faceVertexIndices[1]],
hexCorners[faceVertexIndices[2]],
hexCorners[faceVertexIndices[3]] );
face = cvf::StructGridInterface::NEG_J;
cvf::StructGridInterface::cellFaceVertexIndices( face, faceVertexIndices );
cvf::Vec3d faceCenterNegJ = cvf::GeometryTools::computeFaceCenter( hexCorners[faceVertexIndices[0]],
hexCorners[faceVertexIndices[1]],
hexCorners[faceVertexIndices[2]],
hexCorners[faceVertexIndices[3]] );
face = cvf::StructGridInterface::POS_J;
cvf::StructGridInterface::cellFaceVertexIndices( face, faceVertexIndices );
cvf::Vec3d faceCenterPosJ = cvf::GeometryTools::computeFaceCenter( hexCorners[faceVertexIndices[0]],
hexCorners[faceVertexIndices[1]],
hexCorners[faceVertexIndices[2]],
hexCorners[faceVertexIndices[3]] );
cvf::Vec3d faceCenterCenterVectorI = faceCenterPosI - faceCenterNegI;
cvf::Vec3d faceCenterCenterVectorJ = faceCenterPosJ - faceCenterNegJ;
localZdirection.cross( faceCenterCenterVectorI, faceCenterCenterVectorJ );
localZdirection.normalize();
cvf::Vec3d crossPoductJZ;
crossPoductJZ.cross( faceCenterCenterVectorJ, localZdirection );
localXdirection = faceCenterCenterVectorI + crossPoductJZ;
localXdirection.normalize();
cvf::Vec3d crossPoductIZ;
crossPoductIZ.cross( faceCenterCenterVectorI, localZdirection );
localYdirection = faceCenterCenterVectorJ - crossPoductIZ;
localYdirection.normalize();
// TODO: Check if we end up with 0-vectors, and handle this case...
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double RigCellGeometryTools::polygonLengthInLocalXdirWeightedByArea( const std::vector<cvf::Vec3d>& polygonToCalcLengthOf )
{
// Find bounding box
cvf::BoundingBox polygonBBox;
for ( cvf::Vec3d nodeCoord : polygonToCalcLengthOf )
polygonBBox.add( nodeCoord );
cvf::Vec3d bboxCorners[8];
polygonBBox.cornerVertices( bboxCorners );
// Split bounding box in multiple polygons (2D)
int resolutionOfLengthCalc = 20;
double widthOfPolygon = polygonBBox.extent().y() / resolutionOfLengthCalc;
std::vector<double> areasOfPolygonContributions;
std::vector<double> lengthOfPolygonContributions;
cvf::Vec3d directionOfLength( 1, 0, 0 );
for ( int i = 0; i < resolutionOfLengthCalc; i++ )
{
cvf::Vec3d pointOnLine1( bboxCorners[0].x(), bboxCorners[0].y() + i * widthOfPolygon, 0 );
cvf::Vec3d pointOnLine2( bboxCorners[0].x(), bboxCorners[0].y() + ( i + 1 ) * widthOfPolygon, 0 );
std::pair<cvf::Vec3d, cvf::Vec3d> line1 = getLineThroughBoundingBox( directionOfLength, polygonBBox, pointOnLine1 );
std::pair<cvf::Vec3d, cvf::Vec3d> line2 = getLineThroughBoundingBox( directionOfLength, polygonBBox, pointOnLine2 );
std::vector<cvf::Vec3d> polygon;
polygon.push_back( line1.first );
polygon.push_back( line1.second );
polygon.push_back( line2.second );
polygon.push_back( line2.first );
// Use clipper to find overlap between bbpolygon and fracture
std::vector<std::vector<cvf::Vec3d>> clippedPolygons = intersectionWithPolygon( polygonToCalcLengthOf, polygon );
double area = 0;
double length = 0;
cvf::Vec3d areaVector = cvf::Vec3d::ZERO;
// Calculate length (max-min) and area
for ( std::vector<cvf::Vec3d> clippedPolygon : clippedPolygons )
{
areaVector = cvf::GeometryTools::polygonAreaNormal3D( clippedPolygon );
area += areaVector.length();
length += ( getLengthOfPolygonAlongLine( line1, clippedPolygon ) +
getLengthOfPolygonAlongLine( line2, clippedPolygon ) ) /
2;
}
areasOfPolygonContributions.push_back( area );
lengthOfPolygonContributions.push_back( length );
}
// Calculate area-weighted length average.
double totalArea = 0.0;
double totalAreaXlength = 0.0;
for ( size_t i = 0; i < areasOfPolygonContributions.size(); i++ )
{
totalArea += areasOfPolygonContributions[i];
totalAreaXlength += ( areasOfPolygonContributions[i] * lengthOfPolygonContributions[i] );
}
double areaWeightedLength = totalAreaXlength / totalArea;
return areaWeightedLength;
}
double clipperConversionFactor = 10000; // For transform to clipper int
ClipperLib::IntPoint toClipperPoint( const cvf::Vec3d& cvfPoint )
{
int xInt = cvfPoint.x() * clipperConversionFactor;
int yInt = cvfPoint.y() * clipperConversionFactor;
int zInt = cvfPoint.z() * clipperConversionFactor;
return ClipperLib::IntPoint( xInt, yInt, zInt );
}
cvf::Vec3d fromClipperPoint( const ClipperLib::IntPoint& clipPoint )
{
double zDValue;
if ( clipPoint.Z == std::numeric_limits<int>::max() )
{
zDValue = HUGE_VAL;
}
else
{
zDValue = clipPoint.Z;
}
return cvf::Vec3d( clipPoint.X, clipPoint.Y, zDValue ) / clipperConversionFactor;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<std::vector<cvf::Vec3d>>
RigCellGeometryTools::intersectionWithPolygons( const std::vector<cvf::Vec3d>& polygon1,
const std::vector<std::vector<cvf::Vec3d>>& polygonToIntersectWith )
{
std::vector<std::vector<cvf::Vec3d>> clippedPolygons;
// Convert to int for clipper library and store as clipper "path"
ClipperLib::Clipper clpr;
{
ClipperLib::Path polygon1path;
for ( const cvf::Vec3d& v : polygon1 )
{
polygon1path.push_back( toClipperPoint( v ) );
}
clpr.AddPath( polygon1path, ClipperLib::ptSubject, true );
}
for ( const auto& path : polygonToIntersectWith )
{
ClipperLib::Path polygon2path;
for ( const auto& v : path )
{
polygon2path.push_back( toClipperPoint( v ) );
}
clpr.AddPath( polygon2path, ClipperLib::ptClip, true );
}
ClipperLib::Paths solution;
clpr.Execute( ClipperLib::ctIntersection, solution, ClipperLib::pftEvenOdd, ClipperLib::pftEvenOdd );
// Convert back to std::vector<std::vector<cvf::Vec3d> >
for ( ClipperLib::Path pathInSol : solution )
{
std::vector<cvf::Vec3d> clippedPolygon;
for ( ClipperLib::IntPoint IntPosition : pathInSol )
{
clippedPolygon.push_back( fromClipperPoint( IntPosition ) );
}
clippedPolygons.push_back( clippedPolygon );
}
return clippedPolygons;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<std::vector<cvf::Vec3d>>
RigCellGeometryTools::intersectionWithPolygon( const std::vector<cvf::Vec3d>& polygon1,
const std::vector<cvf::Vec3d>& polygon2 )
{
return intersectionWithPolygons( polygon1, { polygon2 } );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<std::vector<cvf::Vec3d>>
RigCellGeometryTools::subtractPolygons( const std::vector<cvf::Vec3d>& sourcePolygon,
const std::vector<std::vector<cvf::Vec3d>>& polygonsToSubtract )
{
ClipperLib::Clipper clpr;
{
// Convert to int for clipper library and store as clipper "path"
ClipperLib::Path polygon1path;
for ( const auto& v : sourcePolygon )
{
polygon1path.push_back( toClipperPoint( v ) );
}
clpr.AddPath( polygon1path, ClipperLib::ptSubject, true );
}
for ( const auto& path : polygonsToSubtract )
{
ClipperLib::Path polygon2path;
for ( const auto& v : path )
{
polygon2path.push_back( toClipperPoint( v ) );
}
clpr.AddPath( polygon2path, ClipperLib::ptClip, true );
}
ClipperLib::Paths solution;
clpr.Execute( ClipperLib::ctDifference, solution, ClipperLib::pftEvenOdd, ClipperLib::pftEvenOdd );
std::vector<std::vector<cvf::Vec3d>> clippedPolygons;
// Convert back to std::vector<std::vector<cvf::Vec3d> >
for ( ClipperLib::Path pathInSol : solution )
{
std::vector<cvf::Vec3d> clippedPolygon;
for ( ClipperLib::IntPoint IntPosition : pathInSol )
{
clippedPolygon.push_back( fromClipperPoint( IntPosition ) );
}
clippedPolygons.push_back( clippedPolygon );
}
return clippedPolygons;
}
std::vector<std::vector<cvf::Vec3d>> RigCellGeometryTools::subtractPolygon( const std::vector<cvf::Vec3d>& sourcePolygon,
const std::vector<cvf::Vec3d>& polygonToSubtract )
{
return subtractPolygons( sourcePolygon, { polygonToSubtract } );
}
//--------------------------------------------------------------------------------------------------
/// Note for cppcheck : First four parameter cannot be const to match the signature of the receiver
//--------------------------------------------------------------------------------------------------
void fillInterpolatedSubjectZ( ClipperLib::IntPoint& e1bot,
ClipperLib::IntPoint& e1top,
ClipperLib::IntPoint& e2bot,
ClipperLib::IntPoint& e2top,
ClipperLib::IntPoint& pt )
{
ClipperLib::IntPoint ePLbot;
ClipperLib::IntPoint ePLtop;
if ( e1top.Z == std::numeric_limits<int>::max() )
{
ePLtop = e2top;
ePLbot = e2bot;
}
else
{
ePLtop = e1top;
ePLbot = e1bot;
}
double ePLXRange = ( ePLtop.X - ePLbot.X );
double ePLYRange = ( ePLtop.Y - ePLbot.Y );
double ePLLength = sqrt( ePLXRange * ePLXRange + ePLYRange * ePLYRange );
if ( ePLLength <= 1 )
{
pt.Z = ePLbot.Z;
return;
}
double ePLBotPtXRange = pt.X - ePLbot.X;
double ePLBotPtYRange = pt.Y - ePLbot.Y;
double ePLBotPtLength = sqrt( ePLBotPtXRange * ePLBotPtXRange + ePLBotPtYRange * ePLBotPtYRange );
double fraction = ePLBotPtLength / ePLLength;
pt.Z = std::nearbyint( ePLbot.Z + fraction * ( ePLtop.Z - ePLbot.Z ) );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void fillUndefinedZ( ClipperLib::IntPoint& e1bot,
ClipperLib::IntPoint& e1top,
ClipperLib::IntPoint& e2bot,
ClipperLib::IntPoint& e2top,
ClipperLib::IntPoint& pt )
{
pt.Z = std::numeric_limits<int>::max();
}
//--------------------------------------------------------------------------------------------------
/// Assumes x.y plane polygon. Polyline might have a Z, and the returned Z is the polyline Z, interpolated if it is
/// clipped.
//--------------------------------------------------------------------------------------------------
std::vector<std::vector<cvf::Vec3d>> RigCellGeometryTools::clipPolylineByPolygon( const std::vector<cvf::Vec3d>& polyLine,
const std::vector<cvf::Vec3d>& polygon,
ZInterpolationType interpolType )
{
std::vector<std::vector<cvf::Vec3d>> clippedPolyline;
// Adjusting polygon to avoid clipper issue with interpolating z-values when lines crosses though polygon vertecies
std::vector<cvf::Vec3d> adjustedPolygon = ajustPolygonToAvoidIntersectionsAtVertex( polyLine, polygon );
// Convert to int for clipper library and store as clipper "path"
ClipperLib::Path polyLinePath;
for ( const cvf::Vec3d& v : polyLine )
{
polyLinePath.push_back( toClipperPoint( v ) );
}
ClipperLib::Path polygonPath;
for ( const cvf::Vec3d& v : adjustedPolygon )
{
ClipperLib::IntPoint intp = toClipperPoint( v );
intp.Z = std::numeric_limits<int>::max();
polygonPath.push_back( intp );
}
ClipperLib::Clipper clpr;
clpr.AddPath( polyLinePath, ClipperLib::ptSubject, false );
clpr.AddPath( polygonPath, ClipperLib::ptClip, true );
if ( interpolType == INTERPOLATE_LINE_Z )
{
clpr.ZFillFunction( &fillInterpolatedSubjectZ );
}
else if ( interpolType == USE_HUGEVAL )
{
clpr.ZFillFunction( &fillUndefinedZ );
}
ClipperLib::PolyTree solution;
clpr.Execute( ClipperLib::ctIntersection, solution, ClipperLib::pftEvenOdd, ClipperLib::pftEvenOdd );
// We only expect open paths from this method (unless the polyline is self intersecting, a condition we do not handle)
ClipperLib::Paths solutionPaths;
ClipperLib::OpenPathsFromPolyTree( solution, solutionPaths );
// Convert back to std::vector<std::vector<cvf::Vec3d> >
for ( ClipperLib::Path pathInSol : solutionPaths )
{
std::vector<cvf::Vec3d> clippedPolygon;
for ( ClipperLib::IntPoint IntPosition : pathInSol )
{
clippedPolygon.push_back( fromClipperPoint( IntPosition ) );
}
clippedPolyline.push_back( clippedPolygon );
}
return clippedPolyline;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::pair<cvf::Vec3d, cvf::Vec3d> RigCellGeometryTools::getLineThroughBoundingBox( const cvf::Vec3d& lineDirection,
const cvf::BoundingBox& polygonBBox,
const cvf::Vec3d& pointOnLine )
{
cvf::Vec3d bboxCorners[8];
polygonBBox.cornerVertices( bboxCorners );
cvf::Vec3d startPoint = pointOnLine;
cvf::Vec3d endPoint = pointOnLine;
cvf::Vec3d lineDir = lineDirection;
// To avoid doing many iterations in loops below linedirection should be quite large.
lineDir.normalize();
lineDir = lineDir * polygonBBox.extent().length() / 5;
// Extend line in positive direction
while ( polygonBBox.contains( startPoint ) )
{
startPoint = startPoint + lineDir;
}
// Extend line in negative direction
while ( polygonBBox.contains( endPoint ) )
{
endPoint = endPoint - lineDir;
}
std::pair<cvf::Vec3d, cvf::Vec3d> line;
line = { startPoint, endPoint };
return line;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double RigCellGeometryTools::getLengthOfPolygonAlongLine( const std::pair<cvf::Vec3d, cvf::Vec3d>& line,
const std::vector<cvf::Vec3d>& polygon )
{
cvf::BoundingBox lineBoundingBox;
for ( cvf::Vec3d polygonPoint : polygon )
{
cvf::Vec3d pointOnLine = cvf::GeometryTools::projectPointOnLine( line.first, line.second, polygonPoint, nullptr );
lineBoundingBox.add( pointOnLine );
}
double length = lineBoundingBox.extent().length();
return length;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<cvf::Vec3d> RigCellGeometryTools::unionOfPolygons( const std::vector<std::vector<cvf::Vec3d>>& polygons )
{
// Convert to int for clipper library and store as clipper "path"
std::vector<ClipperLib::Path> polygonPaths;
for ( const std::vector<cvf::Vec3d>& polygon : polygons )
{
polygonPaths.emplace_back();
auto& p = polygonPaths.back();
for ( const cvf::Vec3d& pp : polygon )
{
p.push_back( toClipperPoint( pp ) );
}
}
ClipperLib::Clipper clpr;
clpr.AddPaths( polygonPaths, ClipperLib::ptSubject, true );
ClipperLib::Paths solution;
clpr.Execute( ClipperLib::ctUnion, solution, ClipperLib::pftEvenOdd, ClipperLib::pftEvenOdd );
// Convert back to std::vector<std::vector<cvf::Vec3d> >
std::vector<cvf::Vec3d> unionPolygon;
for ( ClipperLib::Path pathInSol : solution )
{
for ( ClipperLib::IntPoint IntPosition : pathInSol )
{
unionPolygon.push_back( fromClipperPoint( IntPosition ) );
}
}
return unionPolygon;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<cvf::Vec3d>
RigCellGeometryTools::ajustPolygonToAvoidIntersectionsAtVertex( const std::vector<cvf::Vec3d>& polyLine,
const std::vector<cvf::Vec3d>& polygon )
{
std::vector<cvf::Vec3d> adjustedPolygon;
double treshold = ( 1.0 / 10000.0 ) * 5; // 5 times polygonScaleFactor for converting to int for clipper
for ( cvf::Vec3d polygonPoint : polygon )
{
for ( size_t i = 0; i < polyLine.size() - 1; i++ )
{
cvf::Vec3d linePoint1( polyLine[i].x(), polyLine[i].y(), 0.0 );
cvf::Vec3d linePoint2( polyLine[i + 1].x(), polyLine[i + 1].y(), 0.0 );
double pointDistanceFromLine = cvf::GeometryTools::linePointSquareDist( linePoint1, linePoint2, polygonPoint );
if ( pointDistanceFromLine < treshold )
{
// calculate new polygonPoint
cvf::Vec3d directionOfLineSegment = linePoint2 - linePoint1;
// finding normal to the direction of the line segment in the XY plane (z=0)
cvf::Vec3d normalToLine( -directionOfLineSegment.y(), directionOfLineSegment.x(), 0.0 );
normalToLine.normalize();
polygonPoint = polygonPoint + normalToLine * 0.005;
}
}
adjustedPolygon.push_back( polygonPoint );
}
return adjustedPolygon;
}
//--------------------------------------------------------------------------------------------------
/// tests if a point is Left|On|Right of an infinite line.
/// Input: three points P1, P2, and P3
/// Return: >0 for P3 left of the line through P1 and P2
/// =0 for P3 on the line
/// <0 for P3 right of the line
/// ref. http://geomalgorithms.com/a01-_area.html
//--------------------------------------------------------------------------------------------------
inline double
RigCellGeometryTools::isLeftOfLine2D( const cvf::Vec3d& point1, const cvf::Vec3d& point2, const cvf::Vec3d& point3 )
{
return ( ( point2.x() - point1.x() ) * ( point3.y() - point1.y() ) -
( point3.x() - point1.x() ) * ( point2.y() - point1.y() ) );
}
//--------------------------------------------------------------------------------------------------
/// winding number test for a point in a polygon
/// Input: point = the point to test,
/// polygon[] = vertex points of a closed polygon of size n, where polygon[n-1]=polygon[0]
///
/// Return: true if inside, false if outside)
/// ref. http://geomalgorithms.com/a03-_inclusion.html
//--------------------------------------------------------------------------------------------------
bool RigCellGeometryTools::pointInsidePolygon2D( const cvf::Vec3d point, const std::vector<cvf::Vec3d>& polygon )
{
// Copyright 2000 softSurfer, 2012 Dan Sunday
// This code may be freely used and modified for any purpose
// providing that this copyright notice is included with it.
// SoftSurfer makes no warranty for this code, and cannot be held
// liable for any real or imagined damage resulting from its use.
// Users of this code must verify correctness for their application
int wn = 0; // the winding number counter
size_t N = polygon.size() - 1;
// loop through all edges of the polygon
for ( size_t i = 0; i < N; i++ )
{ // edge from V[i] to V[i+1]
if ( polygon[i].y() <= point.y() )
{ // start y <= P.y
if ( polygon[i + 1].y() > point.y() ) // an upward crossing
if ( isLeftOfLine2D( polygon[i], polygon[i + 1], point ) > 0 ) // P left of edge
++wn; // have a valid up intersect
}
else
{ // start y > P.y
if ( polygon[i + 1].y() <= point.y() ) // a downward crossing
if ( isLeftOfLine2D( polygon[i], polygon[i + 1], point ) < 0 ) // P right of edge
--wn; // have a valid down intersect
}
}
return wn != 0;
}
} //namespace external

View File

@@ -1,779 +0,0 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2011- Statoil ASA
// Copyright (C) 2013- Ceetron Solutions AS
// Copyright (C) 2011-2012 Ceetron AS
//
// ResInsight 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.
//
// ResInsight 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 at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#include "RigEclipseCaseData.h"
#include "RifReaderEclipseOutput.h"
#include "RigActiveCellInfo.h"
#include "RigCaseCellResultsData.h"
#include "RigEquil.h"
#include "RigFormationNames.h"
#include "RigMainGrid.h"
#include "RigResultAccessorFactory.h"
#include "RigSimWellData.h"
#include "RigSimulationWellCenterLineCalculator.h"
#include "RigSimulationWellCoordsAndMD.h"
#include "RigVirtualPerforationTransmissibilities.h"
#include "RigWellPath.h"
#include "RigWellResultPoint.h"
#include <QDebug>
namespace external {
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigEclipseCaseData::RigEclipseCaseData( RimEclipseCase* ownerCase )
: m_hasParsedDeckForEquilData( false )
{
m_mainGrid = new RigMainGrid();
m_ownerCase = ownerCase;
m_matrixModelResults = new RigCaseCellResultsData( this, RiaDefines::PorosityModelType::MATRIX_MODEL );
m_fractureModelResults = new RigCaseCellResultsData( this, RiaDefines::PorosityModelType::FRACTURE_MODEL );
m_activeCellInfo = new RigActiveCellInfo;
m_fractureActiveCellInfo = new RigActiveCellInfo;
m_matrixModelResults->setActiveCellInfo( m_activeCellInfo.p() );
m_fractureModelResults->setActiveCellInfo( m_fractureActiveCellInfo.p() );
m_unitsType = RiaDefines::EclipseUnitSystem::UNITS_METRIC;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigEclipseCaseData::~RigEclipseCaseData()
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigMainGrid* RigEclipseCaseData::mainGrid()
{
return m_mainGrid.p();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const RigMainGrid* RigEclipseCaseData::mainGrid() const
{
return m_mainGrid.p();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RigEclipseCaseData::setMainGrid( RigMainGrid* mainGrid )
{
m_mainGrid = mainGrid;
m_matrixModelResults->setMainGrid( m_mainGrid.p() );
m_fractureModelResults->setMainGrid( m_mainGrid.p() );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RigEclipseCaseData::allGrids( std::vector<RigGridBase*>* grids )
{
CVF_ASSERT( grids );
if ( m_mainGrid.isNull() )
{
return;
}
size_t i;
for ( i = 0; i < m_mainGrid->gridCount(); i++ )
{
grids->push_back( m_mainGrid->gridByIndex( i ) );
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RigEclipseCaseData::allGrids( std::vector<const RigGridBase*>* grids ) const
{
CVF_ASSERT( grids );
if ( m_mainGrid.isNull() )
{
return;
}
size_t i;
for ( i = 0; i < m_mainGrid->gridCount(); i++ )
{
grids->push_back( m_mainGrid->gridByIndex( i ) );
}
}
//--------------------------------------------------------------------------------------------------
/// Get grid by index. The main grid has index 0, so the first lgr has index 1
//--------------------------------------------------------------------------------------------------
const RigGridBase* RigEclipseCaseData::grid( size_t index ) const
{
CVF_ASSERT( m_mainGrid.notNull() );
return m_mainGrid->gridByIndex( index );
}
//--------------------------------------------------------------------------------------------------
/// Get grid by index. The main grid has index 0, so the first lgr has index 1
//--------------------------------------------------------------------------------------------------
RigGridBase* RigEclipseCaseData::grid( size_t index )
{
CVF_ASSERT( m_mainGrid.notNull() );
return m_mainGrid->gridByIndex( index );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const RigGridBase* RigEclipseCaseData::grid( const QString& gridName ) const
{
if ( m_mainGrid.isNull() )
{
return nullptr;
}
if ( gridName.isEmpty() )
{
return m_mainGrid.p();
}
size_t i;
for ( i = 0; i < m_mainGrid->gridCount(); i++ )
{
const RigGridBase* grid = m_mainGrid->gridByIndex( i );
if ( QString::fromStdString( grid->gridName() ) == gridName ) return grid;
}
return nullptr;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
size_t RigEclipseCaseData::gridCount() const
{
CVF_ASSERT( m_mainGrid.notNull() );
return m_mainGrid->gridCount();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RigEclipseCaseData::computeWellCellsPrGrid()
{
// If we have computed this already, return
if ( m_wellCellsInGrid.size() ) return;
std::vector<RigGridBase*> grids;
this->allGrids( &grids );
// Debug code used to display grid names and grid sizes
/*
size_t totCellCount = 0;
for (auto g : grids)
{
qDebug() << g->gridName().data();
qDebug() << g->cellCountI() << " " << g->cellCountJ() << " " << g->cellCountK() << " ";
size_t cellCount = g->cellCount();
totCellCount += cellCount;
qDebug() << cellCount;
qDebug() << "\n";
}
qDebug() << "\nTotal cell count " << totCellCount;
*/
size_t gIdx;
// Allocate and initialize the arrays
m_wellCellsInGrid.resize( grids.size() );
m_gridCellToResultWellIndex.resize( grids.size() );
for ( gIdx = 0; gIdx < grids.size(); ++gIdx )
{
if ( m_wellCellsInGrid[gIdx].isNull() || m_wellCellsInGrid[gIdx]->size() != grids[gIdx]->cellCount() )
{
m_wellCellsInGrid[gIdx] = new cvf::UByteArray;
m_wellCellsInGrid[gIdx]->resize( grids[gIdx]->cellCount() );
m_gridCellToResultWellIndex[gIdx] = new cvf::UIntArray;
m_gridCellToResultWellIndex[gIdx]->resize( grids[gIdx]->cellCount() );
}
m_wellCellsInGrid[gIdx]->setAll( false );
m_gridCellToResultWellIndex[gIdx]->setAll( cvf::UNDEFINED_UINT );
}
// Fill arrays with data
size_t wIdx;
for ( wIdx = 0; wIdx < m_simWellData.size(); ++wIdx )
{
size_t tIdx;
for ( tIdx = 0; tIdx < m_simWellData[wIdx]->m_wellCellsTimeSteps.size(); ++tIdx )
{
RigWellResultFrame& wellCells = m_simWellData[wIdx]->m_wellCellsTimeSteps[tIdx];
// Well result branches
for ( size_t sIdx = 0; sIdx < wellCells.m_wellResultBranches.size(); ++sIdx )
{
RigWellResultBranch& wellSegment = wellCells.m_wellResultBranches[sIdx];
size_t cdIdx;
for ( cdIdx = 0; cdIdx < wellSegment.m_branchResultPoints.size(); ++cdIdx )
{
size_t gridIndex = wellSegment.m_branchResultPoints[cdIdx].m_gridIndex;
size_t gridCellIndex = wellSegment.m_branchResultPoints[cdIdx].m_gridCellIndex;
if ( gridIndex < m_wellCellsInGrid.size() && gridCellIndex < m_wellCellsInGrid[gridIndex]->size() )
{
// NOTE : We do not check if the grid cell is active as we do for well head.
// If we add test for active cell, thorough testing and verification of the new behaviour must
// be adressed
m_wellCellsInGrid[gridIndex]->set( gridCellIndex, true );
m_gridCellToResultWellIndex[gridIndex]->set( gridCellIndex, static_cast<cvf::uint>( wIdx ) );
}
}
}
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RigEclipseCaseData::setSimWellData( const cvf::Collection<RigSimWellData>& data )
{
m_simWellData = data;
m_wellCellsInGrid.clear();
m_gridCellToResultWellIndex.clear();
computeWellCellsPrGrid();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::set<QString> RigEclipseCaseData::findSortedWellNames() const
{
std::set<QString> sortedWellNames;
const cvf::Collection<RigSimWellData>& simWellData = wellResults();
for ( size_t wIdx = 0; wIdx < simWellData.size(); ++wIdx )
{
sortedWellNames.insert( simWellData[wIdx]->m_wellName );
}
return sortedWellNames;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const RigSimWellData* RigEclipseCaseData::findSimWellData( QString wellName ) const
{
for ( size_t wIdx = 0; wIdx < m_simWellData.size(); ++wIdx )
{
if ( m_simWellData[wIdx]->m_wellName == wellName )
{
return m_simWellData[wIdx].p();
}
}
return nullptr;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const cvf::UByteArray* RigEclipseCaseData::wellCellsInGrid( size_t gridIndex )
{
computeWellCellsPrGrid();
CVF_ASSERT( gridIndex < m_wellCellsInGrid.size() );
return m_wellCellsInGrid[gridIndex].p();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const cvf::UIntArray* RigEclipseCaseData::gridCellToResultWellIndex( size_t gridIndex )
{
computeWellCellsPrGrid();
CVF_ASSERT( gridIndex < m_gridCellToResultWellIndex.size() );
return m_gridCellToResultWellIndex[gridIndex].p();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const RigCell& RigEclipseCaseData::cellFromWellResultCell( const RigWellResultPoint& wellResultCell ) const
{
CVF_ASSERT( wellResultCell.isCell() );
size_t gridIndex = wellResultCell.m_gridIndex;
size_t gridCellIndex = wellResultCell.m_gridCellIndex;
std::vector<const RigGridBase*> grids;
allGrids( &grids );
return grids[gridIndex]->cell( gridCellIndex );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RigEclipseCaseData::findSharedSourceFace( cvf::StructGridInterface::FaceType& sharedSourceFace,
const RigWellResultPoint& sourceWellCellResult,
const RigWellResultPoint& otherWellCellResult ) const
{
size_t gridIndex = sourceWellCellResult.m_gridIndex;
size_t gridCellIndex = sourceWellCellResult.m_gridCellIndex;
size_t otherGridIndex = otherWellCellResult.m_gridIndex;
size_t otherGridCellIndex = otherWellCellResult.m_gridCellIndex;
if ( gridIndex != otherGridIndex ) return false;
std::vector<const RigGridBase*> grids;
allGrids( &grids );
const RigGridBase* grid = grids[gridIndex];
size_t i, j, k;
grid->ijkFromCellIndex( gridCellIndex, &i, &j, &k );
size_t faceIdx;
for ( faceIdx = 0; faceIdx < 6; faceIdx++ )
{
cvf::StructGridInterface::FaceType sourceFace = static_cast<cvf::StructGridInterface::FaceType>( faceIdx );
size_t ni, nj, nk;
grid->neighborIJKAtCellFace( i, j, k, sourceFace, &ni, &nj, &nk );
if ( grid->isCellValid( ni, nj, nk ) )
{
size_t neighborCellIndex = grid->cellIndexFromIJK( ni, nj, nk );
if ( neighborCellIndex == otherGridCellIndex )
{
sharedSourceFace = sourceFace;
return true;
}
}
}
return false;
}
//--------------------------------------------------------------------------------------------------
/// Helper class used to find min/max range for valid and active cells
//--------------------------------------------------------------------------------------------------
class CellRangeBB
{
public:
CellRangeBB()
: m_min( cvf::UNDEFINED_SIZE_T, cvf::UNDEFINED_SIZE_T, cvf::UNDEFINED_SIZE_T )
, m_max( cvf::Vec3st::ZERO )
{
}
void add( size_t i, size_t j, size_t k )
{
if ( i < m_min.x() ) m_min.x() = i;
if ( j < m_min.y() ) m_min.y() = j;
if ( k < m_min.z() ) m_min.z() = k;
if ( i > m_max.x() ) m_max.x() = i;
if ( j > m_max.y() ) m_max.y() = j;
if ( k > m_max.z() ) m_max.z() = k;
}
public:
cvf::Vec3st m_min;
cvf::Vec3st m_max;
};
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RigEclipseCaseData::computeActiveCellIJKBBox()
{
if ( m_mainGrid.notNull() && m_activeCellInfo.notNull() && m_fractureActiveCellInfo.notNull() )
{
CellRangeBB matrixModelActiveBB;
CellRangeBB fractureModelActiveBB;
size_t idx;
for ( idx = 0; idx < m_mainGrid->cellCount(); idx++ )
{
size_t i, j, k;
m_mainGrid->ijkFromCellIndex( idx, &i, &j, &k );
if ( m_activeCellInfo->isActive( idx ) )
{
matrixModelActiveBB.add( i, j, k );
}
if ( m_fractureActiveCellInfo->isActive( idx ) )
{
fractureModelActiveBB.add( i, j, k );
}
}
m_activeCellInfo->setIJKBoundingBox( matrixModelActiveBB.m_min, matrixModelActiveBB.m_max );
m_fractureActiveCellInfo->setIJKBoundingBox( fractureModelActiveBB.m_min, fractureModelActiveBB.m_max );
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RigEclipseCaseData::computeActiveCellBoundingBoxes()
{
computeActiveCellIJKBBox();
computeActiveCellsGeometryBoundingBox();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<QString> RigEclipseCaseData::simulationWellNames() const
{
std::vector<QString> wellNames;
for ( const auto& wellResult : wellResults() )
{
wellNames.push_back( wellResult->m_wellName );
}
return wellNames;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RigEclipseCaseData::hasSimulationWell( const QString& simWellName ) const
{
const auto wellNames = simulationWellNames();
return std::find( wellNames.begin(), wellNames.end(), simWellName ) != wellNames.end();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<const RigWellPath*> RigEclipseCaseData::simulationWellBranches( const QString& simWellName,
bool includeAllCellCenters,
bool useAutoDetectionOfBranches ) const
{
std::vector<const RigWellPath*> branches;
if ( simWellName.isEmpty() || simWellName.toUpper() == "NONE" )
{
return branches;
}
const RigSimWellData* simWellData = findSimWellData( simWellName );
if ( !simWellData ) return branches;
std::tuple<QString, bool, bool> simWellSeachItem =
std::make_tuple( simWellName, includeAllCellCenters, useAutoDetectionOfBranches );
if ( m_simWellBranchCache.find( simWellSeachItem ) == m_simWellBranchCache.end() )
{
std::vector<std::vector<cvf::Vec3d>> pipeBranchesCLCoords;
std::vector<std::vector<RigWellResultPoint>> pipeBranchesCellIds;
RigSimulationWellCenterLineCalculator::calculateWellPipeCenterlineFromWellFrame( this,
simWellData,
-1,
useAutoDetectionOfBranches,
includeAllCellCenters,
pipeBranchesCLCoords,
pipeBranchesCellIds );
m_simWellBranchCache.insert( std::make_pair( simWellSeachItem, cvf::Collection<RigWellPath>() ) );
for ( size_t brIdx = 0; brIdx < pipeBranchesCLCoords.size(); ++brIdx )
{
auto wellMdCalculator = RigSimulationWellCoordsAndMD( pipeBranchesCLCoords[brIdx] );
cvf::ref<RigWellPath> newWellPath =
new RigWellPath( wellMdCalculator.wellPathPoints(), wellMdCalculator.measuredDepths() );
m_simWellBranchCache[simWellSeachItem].push_back( newWellPath.p() );
}
}
for ( const auto& branch : m_simWellBranchCache[simWellSeachItem] )
{
branches.push_back( branch.p() );
}
return branches;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RigEclipseCaseData::setVirtualPerforationTransmissibilities(
RigVirtualPerforationTransmissibilities* virtualPerforationTransmissibilities )
{
m_virtualPerforationTransmissibilities = virtualPerforationTransmissibilities;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const RigVirtualPerforationTransmissibilities* RigEclipseCaseData::virtualPerforationTransmissibilities() const
{
return m_virtualPerforationTransmissibilities.p();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RigEclipseCaseData::ensureDeckIsParsedForEquilData( const QString& dataDeckFile,
const QString& includeFileAbsolutePathPrefix )
{
if ( !m_hasParsedDeckForEquilData )
{
RifReaderEclipseOutput::importEquilData( dataDeckFile, includeFileAbsolutePathPrefix, this );
m_hasParsedDeckForEquilData = true;
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<RigEquil> RigEclipseCaseData::equilData() const
{
return m_equil;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RigEclipseCaseData::setEquilData( const std::vector<RigEquil>& equilObjects )
{
m_equil = equilObjects;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigActiveCellInfo* RigEclipseCaseData::activeCellInfo( RiaDefines::PorosityModelType porosityModel )
{
if ( porosityModel == RiaDefines::PorosityModelType::MATRIX_MODEL )
{
return m_activeCellInfo.p();
}
return m_fractureActiveCellInfo.p();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const RigActiveCellInfo* RigEclipseCaseData::activeCellInfo( RiaDefines::PorosityModelType porosityModel ) const
{
if ( porosityModel == RiaDefines::PorosityModelType::MATRIX_MODEL )
{
return m_activeCellInfo.p();
}
return m_fractureActiveCellInfo.p();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RigEclipseCaseData::setActiveCellInfo( RiaDefines::PorosityModelType porosityModel, RigActiveCellInfo* activeCellInfo )
{
if ( porosityModel == RiaDefines::PorosityModelType::MATRIX_MODEL )
{
m_activeCellInfo = activeCellInfo;
m_matrixModelResults->setActiveCellInfo( m_activeCellInfo.p() );
}
else
{
m_fractureActiveCellInfo = activeCellInfo;
m_fractureModelResults->setActiveCellInfo( m_fractureActiveCellInfo.p() );
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RigEclipseCaseData::hasFractureResults() const
{
if ( activeCellInfo( RiaDefines::PorosityModelType::FRACTURE_MODEL ) &&
activeCellInfo( RiaDefines::PorosityModelType::FRACTURE_MODEL )->reservoirActiveCellCount() > 0 )
{
return true;
}
return false;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RigEclipseCaseData::computeActiveCellsGeometryBoundingBox()
{
if ( m_activeCellInfo.isNull() || m_fractureActiveCellInfo.isNull() )
{
return;
}
if ( m_mainGrid.isNull() )
{
cvf::BoundingBox bb;
m_activeCellInfo->setGeometryBoundingBox( bb );
m_fractureActiveCellInfo->setGeometryBoundingBox( bb );
return;
}
RigActiveCellInfo* activeInfos[2];
activeInfos[0] = m_fractureActiveCellInfo.p();
activeInfos[1] = m_activeCellInfo.p(); // Last, to make this bb.min become display offset
cvf::BoundingBox bb;
for ( int acIdx = 0; acIdx < 2; ++acIdx )
{
bb.reset();
if ( m_mainGrid->nodes().size() == 0 )
{
bb.add( cvf::Vec3d::ZERO );
}
else
{
std::array<cvf::Vec3d, 8> hexCorners;
for ( size_t i = 0; i < m_mainGrid->cellCount(); i++ )
{
if ( activeInfos[acIdx]->isActive( i ) )
{
m_mainGrid->cellCornerVertices( i, hexCorners.data() );
for ( const auto& corner : hexCorners )
{
bb.add( corner );
}
}
}
}
activeInfos[acIdx]->setGeometryBoundingBox( bb );
}
m_mainGrid->setDisplayModelOffset( bb.min() );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RigEclipseCaseData::setActiveFormationNames( RigFormationNames* activeFormationNames )
{
m_matrixModelResults->setActiveFormationNames( activeFormationNames );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const RigFormationNames* RigEclipseCaseData::activeFormationNames() const
{
return m_matrixModelResults->activeFormationNames();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const std::vector<QString> RigEclipseCaseData::formationNames() const
{
if ( activeFormationNames() )
{
return activeFormationNames()->formationNames();
}
return {};
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigAllanDiagramData* RigEclipseCaseData::allanDiagramData()
{
return m_matrixModelResults->allanDiagramData();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigCaseCellResultsData* RigEclipseCaseData::results( RiaDefines::PorosityModelType porosityModel )
{
if ( porosityModel == RiaDefines::PorosityModelType::MATRIX_MODEL )
{
return m_matrixModelResults.p();
}
return m_fractureModelResults.p();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const RigCaseCellResultsData* RigEclipseCaseData::results( RiaDefines::PorosityModelType porosityModel ) const
{
if ( porosityModel == RiaDefines::PorosityModelType::MATRIX_MODEL )
{
return m_matrixModelResults.p();
}
return m_fractureModelResults.p();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const std::vector<double>* RigEclipseCaseData::resultValues( RiaDefines::PorosityModelType porosityModel,
RiaDefines::ResultCatType type,
const QString& resultName,
size_t timeStepIndex )
{
RigCaseCellResultsData* gridCellResults = this->results( porosityModel );
const std::vector<double>* swatResults = nullptr;
if ( gridCellResults->ensureKnownResultLoaded( RigEclipseResultAddress( type, resultName ) ) )
{
swatResults = &( gridCellResults->cellScalarResults( RigEclipseResultAddress( type, resultName ), timeStepIndex ) );
}
return swatResults;
}
} //namespace external

View File

@@ -1,161 +0,0 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2011- Statoil ASA
// Copyright (C) 2013- Ceetron Solutions AS
// Copyright (C) 2011-2012 Ceetron AS
//
// ResInsight 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.
//
// ResInsight 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 at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "RifReaderInterface.h"
#include "RiaDefines.h"
#include "cvfArray.h"
#include "cvfAssert.h"
#include "cvfCollection.h"
#include "cvfObject.h"
#include "cvfStructGrid.h"
#include "cvfVector3.h"
#include <map>
#include <set>
#include <vector>
namespace external {
class RigCaseCellResultsData;
class RigFormationNames;
class RigMainGrid;
class RigGridBase;
class RigCaseCellResultsData;
class RigActiveCellInfo;
class RigSimWellData;
class RigCell;
class RigWellPath;
class RimEclipseCase;
class RigVirtualPerforationTransmissibilities;
class RigEquil;
class RigAllanDiagramData;
struct RigWellResultPoint;
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
class RigEclipseCaseData : public cvf::Object
{
public:
explicit RigEclipseCaseData( RimEclipseCase* ownerCase );
~RigEclipseCaseData() override;
RimEclipseCase* ownerCase() const { return m_ownerCase; }
RigMainGrid* mainGrid();
const RigMainGrid* mainGrid() const;
void setMainGrid( RigMainGrid* mainGrid );
void allGrids( std::vector<RigGridBase*>* grids ); // To be removed
void allGrids( std::vector<const RigGridBase*>* grids ) const; // To be removed
const RigGridBase* grid( size_t index ) const;
RigGridBase* grid( size_t index );
size_t gridCount() const;
const RigGridBase* grid( const QString& gridName ) const;
RigCaseCellResultsData* results( RiaDefines::PorosityModelType porosityModel );
const RigCaseCellResultsData* results( RiaDefines::PorosityModelType porosityModel ) const;
const std::vector<double>* resultValues( RiaDefines::PorosityModelType porosityModel,
RiaDefines::ResultCatType type,
const QString& resultName,
size_t timeStepIndex );
RigActiveCellInfo* activeCellInfo( RiaDefines::PorosityModelType porosityModel );
const RigActiveCellInfo* activeCellInfo( RiaDefines::PorosityModelType porosityModel ) const;
void setActiveCellInfo( RiaDefines::PorosityModelType porosityModel, RigActiveCellInfo* activeCellInfo );
bool hasFractureResults() const;
void setActiveFormationNames( RigFormationNames* activeFormationNames );
const std::vector<QString> formationNames() const;
RigAllanDiagramData* allanDiagramData();
void setSimWellData( const cvf::Collection<RigSimWellData>& data );
const cvf::Collection<RigSimWellData>& wellResults() const { return m_simWellData; }
std::set<QString> findSortedWellNames() const;
const RigSimWellData* findSimWellData( QString wellName ) const;
const cvf::UByteArray* wellCellsInGrid( size_t gridIndex );
const cvf::UIntArray* gridCellToResultWellIndex( size_t gridIndex );
const RigCell& cellFromWellResultCell( const RigWellResultPoint& wellResultCell ) const;
bool findSharedSourceFace( cvf::StructGridInterface::FaceType& sharedSourceFace,
const RigWellResultPoint& sourceWellCellResult,
const RigWellResultPoint& otherWellCellResult ) const;
void computeActiveCellBoundingBoxes();
RiaDefines::EclipseUnitSystem unitsType() const { return m_unitsType; }
void setUnitsType( RiaDefines::EclipseUnitSystem unitsType ) { m_unitsType = unitsType; }
std::vector<QString> simulationWellNames() const;
bool hasSimulationWell( const QString& simWellName ) const;
std::vector<const RigWellPath*> simulationWellBranches( const QString& simWellName,
bool includeAllCellCenters,
bool useAutoDetectionOfBranches ) const;
void setVirtualPerforationTransmissibilities( RigVirtualPerforationTransmissibilities* virtualPerforationTransmissibilities );
const RigVirtualPerforationTransmissibilities* virtualPerforationTransmissibilities() const;
void clearWellCellsInGridCache() { m_wellCellsInGrid.clear(); }
void ensureDeckIsParsedForEquilData( const QString& dataDeckFile, const QString& includeFileAbsolutePathPrefix );
std::vector<RigEquil> equilData() const;
void setEquilData( const std::vector<RigEquil>& equilObjects );
private:
void computeActiveCellIJKBBox();
void computeWellCellsPrGrid();
void computeActiveCellsGeometryBoundingBox();
const RigFormationNames* activeFormationNames() const;
private:
cvf::ref<RigMainGrid> m_mainGrid;
RimEclipseCase* m_ownerCase;
cvf::ref<RigActiveCellInfo> m_activeCellInfo;
cvf::ref<RigActiveCellInfo> m_fractureActiveCellInfo;
cvf::ref<RigCaseCellResultsData> m_matrixModelResults;
cvf::ref<RigCaseCellResultsData> m_fractureModelResults;
cvf::ref<RigVirtualPerforationTransmissibilities> m_virtualPerforationTransmissibilities;
cvf::Collection<RigSimWellData> m_simWellData; //< A WellResults object for each well in the reservoir
cvf::Collection<cvf::UByteArray> m_wellCellsInGrid; //< A bool array pr grid with one bool pr cell telling whether
// the cell is a well cell or not
cvf::Collection<cvf::UIntArray> m_gridCellToResultWellIndex; //< Array pr grid with index to well pr cell telling
// which well a cell is in
RiaDefines::EclipseUnitSystem m_unitsType;
bool m_hasParsedDeckForEquilData;
std::vector<RigEquil> m_equil;
mutable std::map<std::tuple<QString, bool, bool>, cvf::Collection<RigWellPath>> m_simWellBranchCache;
};
} //namespace external

View File

@@ -1,929 +0,0 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2011- Statoil ASA
// Copyright (C) 2013- Ceetron Solutions AS
// Copyright (C) 2011-2012 Ceetron AS
//
// ResInsight 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.
//
// ResInsight 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 at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#include "RigMainGrid.h"
#include "RiaLogging.h"
#include "RiaResultNames.h"
#include "RigActiveCellInfo.h"
#include "RigHexIntersectionTools.h"
#include "RigNNCData.h"
#include "cvfAssert.h"
#include "cvfBoundingBoxTree.h"
#ifdef USE_OPENMP
#include <omp.h>
#endif
namespace external {
RigMainGrid::RigMainGrid()
: RigGridBase( this )
{
m_displayModelOffset = cvf::Vec3d::ZERO;
m_gridIndex = 0;
m_gridId = 0;
m_gridIdToIndexMapping.push_back( 0 );
m_flipXAxis = false;
m_flipYAxis = false;
m_useMapAxes = false;
m_mapAxes = defaultMapAxes();
m_dualPorosity = false;
}
RigMainGrid::~RigMainGrid()
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<cvf::Vec3d>& RigMainGrid::nodes()
{
return m_nodes;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const std::vector<cvf::Vec3d>& RigMainGrid::nodes() const
{
return m_nodes;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<RigCell>& RigMainGrid::globalCellArray()
{
return m_cells;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const std::vector<RigCell>& RigMainGrid::globalCellArray() const
{
return m_cells;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigGridBase* RigMainGrid::gridAndGridLocalIdxFromGlobalCellIdx( size_t globalCellIdx, size_t* gridLocalCellIdx )
{
CVF_ASSERT( globalCellIdx < m_cells.size() );
const RigCell& cell = m_cells[globalCellIdx];
RigGridBase* hostGrid = cell.hostGrid();
CVF_ASSERT( hostGrid );
if ( gridLocalCellIdx )
{
*gridLocalCellIdx = cell.gridLocalCellIndex();
}
return hostGrid;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const RigGridBase* RigMainGrid::gridAndGridLocalIdxFromGlobalCellIdx( size_t globalCellIdx, size_t* gridLocalCellIdx ) const
{
CVF_ASSERT( globalCellIdx < m_cells.size() );
const RigCell& cell = m_cells[globalCellIdx];
const RigGridBase* hostGrid = cell.hostGrid();
CVF_ASSERT( hostGrid );
if ( gridLocalCellIdx )
{
*gridLocalCellIdx = cell.gridLocalCellIndex();
}
return hostGrid;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const RigCell& RigMainGrid::cellByGridAndGridLocalCellIdx( size_t gridIdx, size_t gridLocalCellIdx ) const
{
return gridByIndex( gridIdx )->cell( gridLocalCellIdx );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
size_t RigMainGrid::reservoirCellIndexByGridAndGridLocalCellIndex( size_t gridIdx, size_t gridLocalCellIdx ) const
{
return gridByIndex( gridIdx )->reservoirCellIndex( gridLocalCellIdx );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
size_t RigMainGrid::findReservoirCellIndexFromPoint( const cvf::Vec3d& point ) const
{
size_t cellContainingPoint = cvf::UNDEFINED_SIZE_T;
cvf::BoundingBox pointBBox;
pointBBox.add( point );
std::vector<size_t> cellIndices;
m_mainGrid->findIntersectingCells( pointBBox, &cellIndices );
cvf::Vec3d hexCorners[8];
for ( size_t cellIndex : cellIndices )
{
m_mainGrid->cellCornerVertices( cellIndex, hexCorners );
if ( RigHexIntersectionTools::isPointInCell( point, hexCorners ) )
{
cellContainingPoint = cellIndex;
break;
}
}
return cellContainingPoint;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RigMainGrid::addLocalGrid( RigLocalGrid* localGrid )
{
CVF_ASSERT( localGrid && localGrid->gridId() != cvf::UNDEFINED_INT ); // The grid ID must be set.
CVF_ASSERT( localGrid->gridId() >= 0 ); // We cant handle negative ID's if they exist.
m_localGrids.push_back( localGrid );
localGrid->setGridIndex( m_localGrids.size() ); // Maingrid itself has grid index 0
if ( m_gridIdToIndexMapping.size() <= static_cast<size_t>( localGrid->gridId() ) )
{
m_gridIdToIndexMapping.resize( localGrid->gridId() + 1, cvf::UNDEFINED_SIZE_T );
}
m_gridIdToIndexMapping[localGrid->gridId()] = localGrid->gridIndex();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
size_t RigMainGrid::gridCountOnFile() const
{
size_t gridCount = 1;
for ( const auto& grid : m_localGrids )
{
if ( !grid->isTempGrid() )
{
gridCount++;
}
}
return gridCount;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
size_t RigMainGrid::gridCount() const
{
return m_localGrids.size() + 1;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RigMainGrid::initAllSubGridsParentGridPointer()
{
if ( m_localGrids.size() && m_localGrids[0]->parentGrid() == nullptr )
{
initSubGridParentPointer();
size_t i;
for ( i = 0; i < m_localGrids.size(); ++i )
{
m_localGrids[i]->initSubGridParentPointer();
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RigMainGrid::initAllSubCellsMainGridCellIndex()
{
initSubCellsMainGridCellIndex();
size_t i;
for ( i = 0; i < m_localGrids.size(); ++i )
{
m_localGrids[i]->initSubCellsMainGridCellIndex();
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf::Vec3d RigMainGrid::displayModelOffset() const
{
return m_displayModelOffset;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RigMainGrid::setDisplayModelOffset( cvf::Vec3d offset )
{
m_displayModelOffset = offset;
}
//--------------------------------------------------------------------------------------------------
/// Initialize pointers from grid to parent grid
/// Compute cell ranges for active and valid cells
/// Compute bounding box in world coordinates based on node coordinates
//--------------------------------------------------------------------------------------------------
void RigMainGrid::computeCachedData()
{
initAllSubGridsParentGridPointer();
initAllSubCellsMainGridCellIndex();
m_cellSearchTree = nullptr;
buildCellSearchTree();
}
//--------------------------------------------------------------------------------------------------
/// Returns the grid with index \a localGridIndex. Main Grid itself has index 0. First LGR starts on 1
//--------------------------------------------------------------------------------------------------
RigGridBase* RigMainGrid::gridByIndex( size_t localGridIndex )
{
if ( localGridIndex == 0 ) return this;
CVF_ASSERT( localGridIndex - 1 < m_localGrids.size() );
return m_localGrids[localGridIndex - 1].p();
}
//--------------------------------------------------------------------------------------------------
/// Returns the grid with index \a localGridIndex. Main Grid itself has index 0. First LGR starts on 1
//--------------------------------------------------------------------------------------------------
const RigGridBase* RigMainGrid::gridByIndex( size_t localGridIndex ) const
{
if ( localGridIndex == 0 ) return this;
CVF_ASSERT( localGridIndex - 1 < m_localGrids.size() );
return m_localGrids[localGridIndex - 1].p();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RigMainGrid::setFlipAxis( bool flipXAxis, bool flipYAxis )
{
bool needFlipX = false;
bool needFlipY = false;
if ( m_flipXAxis != flipXAxis )
{
needFlipX = true;
}
if ( m_flipYAxis != flipYAxis )
{
needFlipY = true;
}
if ( needFlipX || needFlipY )
{
for ( size_t i = 0; i < m_nodes.size(); i++ )
{
if ( needFlipX )
{
m_nodes[i].x() *= -1.0;
}
if ( needFlipY )
{
m_nodes[i].y() *= -1.0;
}
}
m_flipXAxis = flipXAxis;
m_flipYAxis = flipYAxis;
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigGridBase* RigMainGrid::gridById( int localGridId )
{
CVF_ASSERT( localGridId >= 0 && static_cast<size_t>( localGridId ) < m_gridIdToIndexMapping.size() );
return this->gridByIndex( m_gridIdToIndexMapping[localGridId] );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
size_t RigMainGrid::totalTemporaryGridCellCount() const
{
size_t cellCount = 0;
for ( const auto& grid : m_localGrids )
{
if ( grid->isTempGrid() )
{
cellCount += grid->cellCount();
}
}
return cellCount;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigNNCData* RigMainGrid::nncData()
{
if ( m_nncData.isNull() )
{
m_nncData = new RigNNCData;
}
return m_nncData.p();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RigMainGrid::setFaults( const cvf::Collection<RigFault>& faults )
{
m_faults = faults;
#pragma omp parallel for
for ( int i = 0; i < static_cast<int>( m_faults.size() ); i++ )
{
m_faults[i]->computeFaultFacesFromCellRanges( this->mainGrid() );
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const cvf::Collection<RigFault>& RigMainGrid::faults() const
{
return m_faults;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf::Collection<RigFault>& RigMainGrid::faults()
{
return m_faults;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RigMainGrid::hasFaultWithName( const QString& name ) const
{
for ( auto fault : m_faults )
{
if ( fault->name() == name )
{
return true;
}
}
return false;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RigMainGrid::calculateFaults( const RigActiveCellInfo* activeCellInfo )
{
if ( hasFaultWithName( RiaResultNames::undefinedGridFaultName() ) &&
hasFaultWithName( RiaResultNames::undefinedGridFaultWithInactiveName() ) )
{
// RiaLogging::debug(QString("Calculate faults already run for grid."));
return;
}
m_faultsPrCellAcc = new RigFaultsPrCellAccumulator( m_cells.size() );
// Spread fault idx'es on the cells from the faults
for ( size_t fIdx = 0; fIdx < m_faults.size(); ++fIdx )
{
m_faults[fIdx]->accumulateFaultsPrCell( m_faultsPrCellAcc.p(), static_cast<int>( fIdx ) );
}
// Find the geometrical faults that is in addition: Has no user defined (eclipse) fault assigned.
// Separate the grid faults that has an inactive cell as member
RigFault* unNamedFault = new RigFault;
unNamedFault->setName( RiaResultNames::undefinedGridFaultName() );
int unNamedFaultIdx = static_cast<int>( m_faults.size() );
m_faults.push_back( unNamedFault );
RigFault* unNamedFaultWithInactive = new RigFault;
unNamedFaultWithInactive->setName( RiaResultNames::undefinedGridFaultWithInactiveName() );
int unNamedFaultWithInactiveIdx = static_cast<int>( m_faults.size() );
m_faults.push_back( unNamedFaultWithInactive );
const std::vector<cvf::Vec3d>& vxs = m_mainGrid->nodes();
std::vector<RigFault::FaultFace>& unNamedFaultFaces = unNamedFault->faultFaces();
std::vector<RigFault::FaultFace>& unNamedFaultFacesInactive = unNamedFaultWithInactive->faultFaces();
for ( int gcIdx = 0; gcIdx < static_cast<int>( m_cells.size() ); ++gcIdx )
{
addUnNamedFaultFaces( gcIdx,
activeCellInfo,
vxs,
unNamedFaultIdx,
unNamedFaultWithInactiveIdx,
unNamedFaultFaces,
unNamedFaultFacesInactive,
m_faultsPrCellAcc.p() );
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RigMainGrid::addUnNamedFaultFaces( int gcIdx,
const RigActiveCellInfo* activeCellInfo,
const std::vector<cvf::Vec3d>& vxs,
int unNamedFaultIdx,
int unNamedFaultWithInactiveIdx,
std::vector<RigFault::FaultFace>& unNamedFaultFaces,
std::vector<RigFault::FaultFace>& unNamedFaultFacesInactive,
RigFaultsPrCellAccumulator* faultsPrCellAcc ) const
{
if ( m_cells[gcIdx].isInvalid() )
{
return;
}
size_t neighborReservoirCellIdx;
size_t neighborGridCellIdx;
size_t i = 0;
size_t j = 0;
size_t k = 0;
const RigGridBase* hostGrid = nullptr;
bool firstNO_FAULTFaceForCell = true;
bool isCellActive = true;
char upperLimitForFaceType = cvf::StructGridInterface::FaceType::POS_K;
// Compare only I and J faces
for ( char faceIdx = 0; faceIdx < upperLimitForFaceType; ++faceIdx )
{
cvf::StructGridInterface::FaceType face = cvf::StructGridInterface::FaceType( faceIdx );
// For faces that has no used defined Fault assigned:
if ( m_faultsPrCellAcc->faultIdx( gcIdx, face ) == RigFaultsPrCellAccumulator::NO_FAULT )
{
// Find neighbor cell
if ( firstNO_FAULTFaceForCell ) // To avoid doing this for every face, and only when detecting a NO_FAULT
{
size_t gridLocalCellIndex;
hostGrid = this->gridAndGridLocalIdxFromGlobalCellIdx( gcIdx, &gridLocalCellIndex );
hostGrid->ijkFromCellIndex( gridLocalCellIndex, &i, &j, &k );
isCellActive = activeCellInfo->isActive( gcIdx );
firstNO_FAULTFaceForCell = false;
}
if ( !hostGrid->cellIJKNeighbor( i, j, k, face, &neighborGridCellIdx ) )
{
continue;
}
neighborReservoirCellIdx = hostGrid->reservoirCellIndex( neighborGridCellIdx );
if ( m_cells[neighborReservoirCellIdx].isInvalid() )
{
continue;
}
bool isNeighborCellActive = activeCellInfo->isActive( neighborReservoirCellIdx );
double tolerance = 1e-6;
std::array<size_t, 4> faceIdxs;
m_cells[gcIdx].faceIndices( face, &faceIdxs );
std::array<size_t, 4> nbFaceIdxs;
m_cells[neighborReservoirCellIdx].faceIndices( StructGridInterface::oppositeFace( face ), &nbFaceIdxs );
bool sharedFaceVertices = true;
if ( sharedFaceVertices && vxs[faceIdxs[0]].pointDistance( vxs[nbFaceIdxs[0]] ) > tolerance )
sharedFaceVertices = false;
if ( sharedFaceVertices && vxs[faceIdxs[1]].pointDistance( vxs[nbFaceIdxs[3]] ) > tolerance )
sharedFaceVertices = false;
if ( sharedFaceVertices && vxs[faceIdxs[2]].pointDistance( vxs[nbFaceIdxs[2]] ) > tolerance )
sharedFaceVertices = false;
if ( sharedFaceVertices && vxs[faceIdxs[3]].pointDistance( vxs[nbFaceIdxs[1]] ) > tolerance )
sharedFaceVertices = false;
if ( sharedFaceVertices )
{
continue;
}
// To avoid doing this calculation for the opposite face
int faultIdx = unNamedFaultIdx;
if ( !( isCellActive && isNeighborCellActive ) ) faultIdx = unNamedFaultWithInactiveIdx;
faultsPrCellAcc->setFaultIdx( gcIdx, face, faultIdx );
faultsPrCellAcc->setFaultIdx( neighborReservoirCellIdx, StructGridInterface::oppositeFace( face ), faultIdx );
// Add as fault face only if the grid index is less than the neighbors
if ( static_cast<size_t>( gcIdx ) < neighborReservoirCellIdx )
{
RigFault::FaultFace ff( gcIdx, cvf::StructGridInterface::FaceType( faceIdx ), neighborReservoirCellIdx );
if ( isCellActive && isNeighborCellActive )
{
unNamedFaultFaces.push_back( ff );
}
else
{
unNamedFaultFacesInactive.push_back( ff );
}
}
else
{
CVF_FAIL_MSG( "Found fault with global neighbor index less than the native index. " ); // Should never
// occur. because
// we flag the
// opposite face
// in the
// faultsPrCellAcc
}
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RigMainGrid::distributeNNCsToFaults()
{
if ( m_faultsPrCellAcc.isNull() ) return;
const RigConnectionContainer& nncs = this->nncData()->allConnections();
for ( size_t nncIdx = 0; nncIdx < nncs.size(); ++nncIdx )
{
// Find the fault for each side of the nnc
const RigConnection& conn = nncs[nncIdx];
int fIdx1 = RigFaultsPrCellAccumulator::NO_FAULT;
int fIdx2 = RigFaultsPrCellAccumulator::NO_FAULT;
if ( conn.face() != StructGridInterface::NO_FACE )
{
fIdx1 = m_faultsPrCellAcc->faultIdx( conn.c1GlobIdx(), conn.face() );
fIdx2 = m_faultsPrCellAcc->faultIdx( conn.c2GlobIdx(), StructGridInterface::oppositeFace( conn.face() ) );
}
if ( fIdx1 < 0 && fIdx2 < 0 )
{
cvf::String lgrString( "Same Grid" );
if ( m_cells[conn.c1GlobIdx()].hostGrid() != m_cells[conn.c2GlobIdx()].hostGrid() )
{
lgrString = "Different Grid";
}
// cvf::Trace::show("NNC: No Fault for NNC C1: " + cvf::String((int)conn.m_c1GlobIdx) + " C2: " +
// cvf::String((int)conn.m_c2GlobIdx) + " Grid: " + lgrString);
}
if ( fIdx1 >= 0 )
{
// Add the connection to both, if they are different.
m_faults[fIdx1]->connectionIndices().push_back( nncIdx );
}
if ( fIdx2 != fIdx1 )
{
if ( fIdx2 >= 0 )
{
m_faults[fIdx2]->connectionIndices().push_back( nncIdx );
}
}
}
}
//--------------------------------------------------------------------------------------------------
/// The cell is normally inverted due to Depth becoming -Z at import,
/// but if (only) one of the flipX/Y is done, the cell is back to normal
//--------------------------------------------------------------------------------------------------
bool RigMainGrid::isFaceNormalsOutwards() const
{
for ( int gcIdx = 0; gcIdx < static_cast<int>( m_cells.size() ); ++gcIdx )
{
if ( !m_cells[gcIdx].isInvalid() )
{
cvf::Vec3d cellCenter = m_cells[gcIdx].center();
cvf::Vec3d faceCenter = m_cells[gcIdx].faceCenter( StructGridInterface::POS_I );
cvf::Vec3d faceNormal = m_cells[gcIdx].faceNormalWithAreaLength( StructGridInterface::POS_I );
double typicalIJCellSize = characteristicIJCellSize();
double dummy, dummy2, typicalKSize;
characteristicCellSizes( &dummy, &dummy2, &typicalKSize );
if ( ( faceCenter - cellCenter ).length() > 0.2 * typicalIJCellSize &&
( faceNormal.length() > ( 0.2 * typicalIJCellSize * 0.2 * typicalKSize ) ) )
{
// Cell is assumed ok to use, so calculate whether the normals are outwards or inwards
if ( ( faceCenter - cellCenter ) * faceNormal >= 0 )
{
return true;
}
else
{
return false;
}
}
}
}
return false;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const RigFault* RigMainGrid::findFaultFromCellIndexAndCellFace( size_t reservoirCellIndex,
cvf::StructGridInterface::FaceType face ) const
{
if ( m_faultsPrCellAcc.isNull() ) return nullptr;
if ( face == cvf::StructGridInterface::NO_FACE ) return nullptr;
int faultIdx = m_faultsPrCellAcc->faultIdx( reservoirCellIndex, face );
if ( faultIdx != RigFaultsPrCellAccumulator::NO_FAULT )
{
return m_faults.at( faultIdx );
}
#if 0
for (size_t i = 0; i < m_faults.size(); i++)
{
const RigFault* rigFault = m_faults.at(i);
const std::vector<RigFault::FaultFace>& faultFaces = rigFault->faultFaces();
for (size_t fIdx = 0; fIdx < faultFaces.size(); fIdx++)
{
if (faultFaces[fIdx].m_nativeReservoirCellIndex == cellIndex)
{
if (face == faultFaces[fIdx].m_nativeFace )
{
return rigFault;
}
}
if (faultFaces[fIdx].m_oppositeReservoirCellIndex == cellIndex)
{
if (face == cvf::StructGridInterface::oppositeFace(faultFaces[fIdx].m_nativeFace))
{
return rigFault;
}
}
}
}
#endif
return nullptr;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RigMainGrid::findIntersectingCells( const cvf::BoundingBox& inputBB, std::vector<size_t>* cellIndices ) const
{
CVF_ASSERT( m_cellSearchTree.notNull() );
m_cellSearchTree->findIntersections( inputBB, cellIndices );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RigMainGrid::buildCellSearchTree()
{
if ( m_cellSearchTree.isNull() )
{
// build tree
size_t cellCount = m_cells.size();
std::vector<size_t> cellIndicesForBoundingBoxes;
std::vector<cvf::BoundingBox> cellBoundingBoxes;
#pragma omp parallel
{
size_t threadCellCount = cellCount;
#ifdef USE_OPENMP
threadCellCount = std::ceil( cellCount / static_cast<double>( omp_get_num_threads() ) );
#endif
std::vector<size_t> threadIndicesForBoundingBoxes;
std::vector<cvf::BoundingBox> threadBoundingBoxes;
threadIndicesForBoundingBoxes.reserve( threadCellCount );
threadBoundingBoxes.reserve( threadCellCount );
#pragma omp for
for ( int cIdx = 0; cIdx < (int)cellCount; ++cIdx )
{
if ( m_cells[cIdx].isInvalid() ) continue;
const std::array<size_t, 8>& cellIndices = m_cells[cIdx].cornerIndices();
cvf::BoundingBox cellBB;
cellBB.add( m_nodes[cellIndices[0]] );
cellBB.add( m_nodes[cellIndices[1]] );
cellBB.add( m_nodes[cellIndices[2]] );
cellBB.add( m_nodes[cellIndices[3]] );
cellBB.add( m_nodes[cellIndices[4]] );
cellBB.add( m_nodes[cellIndices[5]] );
cellBB.add( m_nodes[cellIndices[6]] );
cellBB.add( m_nodes[cellIndices[7]] );
if ( cellBB.isValid() )
{
threadIndicesForBoundingBoxes.emplace_back( cIdx );
threadBoundingBoxes.emplace_back( cellBB );
}
}
threadIndicesForBoundingBoxes.shrink_to_fit();
threadBoundingBoxes.shrink_to_fit();
#pragma omp critical
{
cellIndicesForBoundingBoxes.insert( cellIndicesForBoundingBoxes.end(),
threadIndicesForBoundingBoxes.begin(),
threadIndicesForBoundingBoxes.end() );
cellBoundingBoxes.insert( cellBoundingBoxes.end(), threadBoundingBoxes.begin(), threadBoundingBoxes.end() );
}
}
m_cellSearchTree = new cvf::BoundingBoxTree;
m_cellSearchTree->buildTreeFromBoundingBoxes( cellBoundingBoxes, &cellIndicesForBoundingBoxes );
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf::BoundingBox RigMainGrid::boundingBox() const
{
if ( m_boundingBox.isValid() ) return m_boundingBox;
for ( const auto& node : m_nodes )
{
m_boundingBox.add( node );
}
return m_boundingBox;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RigMainGrid::isTempGrid() const
{
return false;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const std::string& RigMainGrid::associatedWellPathName() const
{
static const std::string EMPTY_STRING;
return EMPTY_STRING;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RigMainGrid::setUseMapAxes( bool useMapAxes )
{
m_useMapAxes = useMapAxes;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RigMainGrid::useMapAxes() const
{
return m_useMapAxes;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RigMainGrid::setMapAxes( const std::array<double, 6>& mapAxes )
{
m_mapAxes = mapAxes;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const std::array<double, 6>& RigMainGrid::mapAxes() const
{
return m_mapAxes;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::array<float, 6> RigMainGrid::mapAxesF() const
{
std::array<float, 6> floatAxes;
for ( size_t i = 0; i < 6; ++i )
{
floatAxes[i] = (float)m_mapAxes[i];
}
return floatAxes;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf::Mat4d RigMainGrid::mapAxisTransform() const
{
cvf::Mat4d mapAxisTrans;
if ( m_useMapAxes )
{
cvf::Vec3d origin( m_mapAxes[2], m_mapAxes[3], 0.0 );
cvf::Vec3d xAxis = cvf::Vec3d( m_mapAxes[4] - origin[0], m_mapAxes[5] - origin[1], 0.0 ).getNormalized();
cvf::Vec3d yAxis = cvf::Vec3d( m_mapAxes[0] - origin[0], m_mapAxes[1] - origin[1], 0.0 ).getNormalized();
cvf::Vec3d zAxis( 0.0, 0.0, 1.0 );
mapAxisTrans = cvf::Mat4d::fromCoordSystemAxes( &xAxis, &yAxis, &zAxis );
mapAxisTrans.setTranslation( origin );
mapAxisTrans.invert();
}
else
{
mapAxisTrans.setIdentity();
}
return mapAxisTrans;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RigMainGrid::isDualPorosity() const
{
return m_dualPorosity;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RigMainGrid::setDualPorosity( bool enable )
{
m_dualPorosity = enable;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::array<double, 6> RigMainGrid::defaultMapAxes()
{
const double origin[2] = { 0.0, 0.0 };
const double xPoint[2] = { 1.0, 0.0 };
const double yPoint[2] = { 0.0, 1.0 };
// Order (see Elipse Reference Manual for keyword MAPAXES): Y_x, Y_y, O_x, O_y, X_x, X_y
return { yPoint[0], yPoint[1], origin[0], origin[1], xPoint[0], xPoint[1] };
}
} //namespace external

View File

@@ -1,146 +0,0 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2011- Statoil ASA
// Copyright (C) 2013- Ceetron Solutions AS
// Copyright (C) 2011-2012 Ceetron AS
//
// ResInsight 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.
//
// ResInsight 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 at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "RigCell.h"
#include "RigGridBase.h"
#include "RigLocalGrid.h"
#include "cvfBoundingBox.h"
#include "cvfCollection.h"
#include <vector>
namespace external {
class RigActiveCellInfo;
class RigNNCData;
namespace cvf
{
class BoundingBoxTree;
}
class RigMainGrid : public RigGridBase
{
public:
RigMainGrid();
~RigMainGrid() override;
public:
std::vector<cvf::Vec3d>& nodes();
const std::vector<cvf::Vec3d>& nodes() const;
std::vector<RigCell>& globalCellArray();
const std::vector<RigCell>& globalCellArray() const;
RigGridBase* gridAndGridLocalIdxFromGlobalCellIdx( size_t globalCellIdx, size_t* gridLocalCellIdx );
const RigGridBase* gridAndGridLocalIdxFromGlobalCellIdx( size_t globalCellIdx, size_t* gridLocalCellIdx ) const;
const RigCell& cellByGridAndGridLocalCellIdx( size_t gridIdx, size_t gridLocalCellIdx ) const;
size_t reservoirCellIndexByGridAndGridLocalCellIndex( size_t gridIdx, size_t gridLocalCellIdx ) const;
size_t findReservoirCellIndexFromPoint( const cvf::Vec3d& point ) const;
void addLocalGrid( RigLocalGrid* localGrid );
size_t gridCountOnFile() const;
size_t gridCount() const;
RigGridBase* gridByIndex( size_t localGridIndex );
const RigGridBase* gridByIndex( size_t localGridIndex ) const;
RigGridBase* gridById( int localGridId );
size_t totalTemporaryGridCellCount() const;
RigNNCData* nncData();
void setFaults( const cvf::Collection<RigFault>& faults );
const cvf::Collection<RigFault>& faults() const;
cvf::Collection<RigFault>& faults();
void calculateFaults( const RigActiveCellInfo* activeCellInfo );
void addUnNamedFaultFaces( int gcIdx,
const RigActiveCellInfo* activeCellInfo,
const std::vector<cvf::Vec3d>& vxs,
int unNamedFaultIdx,
int unNamedFaultWithInactiveIdx,
std::vector<RigFault::FaultFace>& unNamedFaultFaces,
std::vector<RigFault::FaultFace>& unNamedFaultFacesInactive,
RigFaultsPrCellAccumulator* faultsPrCellAcc ) const;
void distributeNNCsToFaults();
const RigFault* findFaultFromCellIndexAndCellFace( size_t reservoirCellIndex,
cvf::StructGridInterface::FaceType face ) const;
bool isFaceNormalsOutwards() const;
void computeCachedData();
void initAllSubGridsParentGridPointer();
cvf::Vec3d displayModelOffset() const override;
void setDisplayModelOffset( cvf::Vec3d offset );
void setFlipAxis( bool flipXAxis, bool flipYAxis );
void findIntersectingCells( const cvf::BoundingBox& inputBB, std::vector<size_t>* cellIndices ) const;
cvf::BoundingBox boundingBox() const;
bool isTempGrid() const override;
const std::string& associatedWellPathName() const override;
void setUseMapAxes( bool useMapAxes );
bool useMapAxes() const;
void setMapAxes( const std::array<double, 6>& mapAxes );
const std::array<double, 6>& mapAxes() const;
std::array<float, 6> mapAxesF() const;
cvf::Mat4d mapAxisTransform() const;
bool isDualPorosity() const;
void setDualPorosity( bool enable );
private:
void initAllSubCellsMainGridCellIndex();
void buildCellSearchTree();
bool hasFaultWithName( const QString& name ) const;
static std::array<double, 6> defaultMapAxes();
private:
std::vector<cvf::Vec3d> m_nodes; ///< Global vertex table
std::vector<RigCell> m_cells; ///< Global array of all cells in the reservoir (including the ones in LGR's)
cvf::Collection<RigLocalGrid> m_localGrids; ///< List of all the LGR's in this reservoir
std::vector<size_t> m_gridIdToIndexMapping; ///< Mapping from LGR Id to index.
cvf::Collection<RigFault> m_faults;
cvf::ref<RigNNCData> m_nncData;
cvf::ref<RigFaultsPrCellAccumulator> m_faultsPrCellAcc;
cvf::Vec3d m_displayModelOffset;
cvf::ref<cvf::BoundingBoxTree> m_cellSearchTree;
mutable cvf::BoundingBox m_boundingBox;
bool m_flipXAxis;
bool m_flipYAxis;
bool m_useMapAxes;
std::array<double, 6> m_mapAxes;
bool m_dualPorosity;
};
} //namespace external

View File

@@ -1,235 +0,0 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2017 Statoil ASA
//
// ResInsight 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.
//
// ResInsight 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 at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#include "RigWellPathIntersectionTools.h"
#include "RiaLogging.h"
#include "RigCellGeometryTools.h"
#include "RigEclipseCaseData.h"
#include "RigEclipseWellLogExtractor.h"
#include "RigMainGrid.h"
#include "RigSimulationWellCoordsAndMD.h"
#include "RigWellLogExtractionTools.h"
#include "RigWellPath.h"
#include "RimEclipseCase.h"
namespace external {
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<WellPathCellIntersectionInfo>
RigWellPathIntersectionTools::findCellIntersectionInfosAlongPath( const RigEclipseCaseData* caseData,
const QString& wellPathName,
const std::vector<cvf::Vec3d>& pathCoords,
const std::vector<double>& pathMds )
{
std::vector<WellPathCellIntersectionInfo> intersectionInfos;
if ( pathCoords.size() < 2 ) return intersectionInfos;
cvf::ref<RigWellPath> dummyWellPath = new RigWellPath( pathCoords, pathMds );
std::string errorIdName = ( wellPathName + " " + caseData->ownerCase()->caseUserDescription() ).toStdString();
cvf::ref<RigEclipseWellLogExtractor> extractor =
new RigEclipseWellLogExtractor( caseData, dummyWellPath.p(), errorIdName );
return extractor->cellIntersectionInfosAlongWellPath();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::set<size_t>
RigWellPathIntersectionTools::findIntersectedGlobalCellIndicesForWellPath( const RigEclipseCaseData* caseData,
const RigWellPath* wellPath )
{
std::set<size_t> globalCellIndices;
if ( caseData )
{
cvf::ref<RigEclipseWellLogExtractor> extractor =
new RigEclipseWellLogExtractor( caseData, wellPath, caseData->ownerCase()->caseUserDescription().toStdString() );
std::vector<WellPathCellIntersectionInfo> intersections = extractor->cellIntersectionInfosAlongWellPath();
for ( const auto& intersection : intersections )
{
globalCellIndices.insert( intersection.globCellIndex );
}
}
return globalCellIndices;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::set<size_t> RigWellPathIntersectionTools::findIntersectedGlobalCellIndices( const RigEclipseCaseData* caseData,
const std::vector<cvf::Vec3d>& coords,
const std::vector<double>& measuredDepths )
{
std::set<size_t> globalCellIndices;
if ( caseData )
{
cvf::ref<RigWellPath> dummyWellPath;
if ( measuredDepths.size() == coords.size() )
{
dummyWellPath = new RigWellPath( coords, measuredDepths );
}
else
{
RigSimulationWellCoordsAndMD helper( coords );
dummyWellPath = new RigWellPath( helper.wellPathPoints(), helper.measuredDepths() );
}
globalCellIndices = findIntersectedGlobalCellIndicesForWellPath( caseData, dummyWellPath.p() );
}
return globalCellIndices;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf::Vec3d RigWellPathIntersectionTools::calculateLengthInCell( const std::array<cvf::Vec3d, 8>& hexCorners,
const cvf::Vec3d& startPoint,
const cvf::Vec3d& endPoint )
{
cvf::Vec3d vec = endPoint - startPoint;
cvf::Vec3d iAxisDirection;
cvf::Vec3d jAxisDirection;
cvf::Vec3d kAxisDirection;
RigCellGeometryTools::findCellLocalXYZ( hexCorners, iAxisDirection, jAxisDirection, kAxisDirection );
cvf::Mat3d localCellCoordinateSystem( iAxisDirection.x(),
jAxisDirection.x(),
kAxisDirection.x(),
iAxisDirection.y(),
jAxisDirection.y(),
kAxisDirection.y(),
iAxisDirection.z(),
jAxisDirection.z(),
kAxisDirection.z() );
auto signedVector = vec.getTransformedVector( localCellCoordinateSystem.getInverted() );
return { std::fabs( signedVector.x() ), std::fabs( signedVector.y() ), std::fabs( signedVector.z() ) };
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf::Vec3d RigWellPathIntersectionTools::calculateLengthInCell( const RigMainGrid* grid,
size_t cellIndex,
const cvf::Vec3d& startPoint,
const cvf::Vec3d& endPoint )
{
std::array<cvf::Vec3d, 8> hexCorners;
grid->cellCornerVertices( cellIndex, hexCorners.data() );
return calculateLengthInCell( hexCorners, startPoint, endPoint );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<WellPathCellIntersectionInfo> RigWellPathIntersectionTools::buildContinuousIntersections(
const std::vector<WellPathCellIntersectionInfo>& originalIntersections,
const cvf::StructGridInterface* grid )
{
std::vector<WellPathCellIntersectionInfo> intersectionsNoGap;
if ( originalIntersections.empty() ) return intersectionsNoGap;
for ( size_t i = 0; i < originalIntersections.size() - 1; i++ )
{
const WellPathCellIntersectionInfo& current = originalIntersections[i];
const WellPathCellIntersectionInfo& next = originalIntersections[i + 1];
double distance = std::fabs( current.endMD - next.startMD );
double gapInGridThreshold = 0.1;
if ( distance > gapInGridThreshold )
{
WellPathCellIntersectionInfo extraIntersection;
bool showDebugInfo = false;
if ( showDebugInfo )
{
QString ijkTextCurrent;
{
size_t i = 0, j = 0, k = 0;
if ( grid )
{
grid->ijkFromCellIndex( current.globCellIndex, &i, &j, &k );
}
ijkTextCurrent = QString( "(%1 %2 %3)" ).arg( i + 1 ).arg( j + 1 ).arg( k + 1 );
}
QString ijkTextNext;
{
size_t i = 0, j = 0, k = 0;
if ( grid )
{
grid->ijkFromCellIndex( next.globCellIndex, &i, &j, &k );
}
ijkTextNext = QString( "(%1 %2 %3)" ).arg( i + 1 ).arg( j + 1 ).arg( k + 1 );
}
QString text = QString( "Gap detected : Distance diff : %1, epsilon = %2\n Global Cell Index 1 : %3, "
"IJK=%4, endMD : %5\n Global Cell Index 2 : %6, IJK=%7, startMD : %8" )
.arg( distance )
.arg( gapInGridThreshold )
.arg( current.globCellIndex )
.arg( ijkTextCurrent )
.arg( current.endMD )
.arg( next.globCellIndex )
.arg( ijkTextNext )
.arg( next.startMD );
RiaLogging::info( text );
}
extraIntersection.globCellIndex = std::numeric_limits<size_t>::max();
extraIntersection.startPoint = current.endPoint;
extraIntersection.endPoint = next.startPoint;
extraIntersection.startMD = current.endMD;
extraIntersection.endMD = next.startMD;
extraIntersection.intersectedCellFaceIn =
cvf::StructGridInterface::oppositeFace( current.intersectedCellFaceOut );
extraIntersection.intersectedCellFaceOut = cvf::StructGridInterface::oppositeFace( next.intersectedCellFaceIn );
extraIntersection.intersectionLengthsInCellCS = cvf::Vec3d::ZERO;
intersectionsNoGap.push_back( extraIntersection );
}
intersectionsNoGap.push_back( current );
}
if ( !originalIntersections.empty() )
{
intersectionsNoGap.push_back( originalIntersections.back() );
}
return intersectionsNoGap;
}
} //namespace external

View File

@@ -1,76 +0,0 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2017 Statoil ASA
//
// ResInsight 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.
//
// ResInsight 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 at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "cvfBoundingBox.h"
#include "cvfVector3.h"
#include <QString>
#include <array>
namespace external {
class RigWellPath;
class RigMainGrid;
class RigEclipseCaseData;
struct HexIntersectionInfo;
struct WellPathCellIntersectionInfo;
namespace cvf
{
class StructGridInterface;
};
//==================================================================================================
///
//==================================================================================================
class RigWellPathIntersectionTools
{
public:
static std::vector<WellPathCellIntersectionInfo>
findCellIntersectionInfosAlongPath( const RigEclipseCaseData* caseData,
const QString& wellPathName,
const std::vector<cvf::Vec3d>& pathCoords,
const std::vector<double>& pathMds );
static std::set<size_t> findIntersectedGlobalCellIndicesForWellPath( const RigEclipseCaseData* caseData,
const RigWellPath* wellPath );
static std::set<size_t> findIntersectedGlobalCellIndices( const RigEclipseCaseData* caseData,
const std::vector<cvf::Vec3d>& coords,
const std::vector<double>& measuredDepths = {} );
static cvf::Vec3d calculateLengthInCell( const std::array<cvf::Vec3d, 8>& hexCorners,
const cvf::Vec3d& startPoint,
const cvf::Vec3d& endPoint );
// Returns the length along each axis in local cell coordinate system
// The returned vector has unsigned component values
static cvf::Vec3d calculateLengthInCell( const RigMainGrid* grid,
size_t cellIndex,
const cvf::Vec3d& startPoint,
const cvf::Vec3d& endPoint );
// Insert dummy intersections used to represent gap in grid
static std::vector<WellPathCellIntersectionInfo>
buildContinuousIntersections( const std::vector<WellPathCellIntersectionInfo>& originalIntersections,
const cvf::StructGridInterface* grid );
};
} //namespace external