2015-05-19 03:48:29 +00:00
|
|
|
/*
|
|
|
|
Open Asset Import Library (assimp)
|
|
|
|
----------------------------------------------------------------------
|
|
|
|
|
2022-12-16 08:03:40 +00:00
|
|
|
Copyright (c) 2006-2022, assimp team
|
2018-01-28 18:42:05 +00:00
|
|
|
|
2015-05-19 03:48:29 +00:00
|
|
|
All rights reserved.
|
|
|
|
|
2015-05-19 03:52:10 +00:00
|
|
|
Redistribution and use of this software in source and binary forms,
|
|
|
|
with or without modification, are permitted provided that the
|
2015-05-19 03:48:29 +00:00
|
|
|
following conditions are met:
|
|
|
|
|
|
|
|
* Redistributions of source code must retain the above
|
|
|
|
copyright notice, this list of conditions and the
|
|
|
|
following disclaimer.
|
|
|
|
|
|
|
|
* Redistributions in binary form must reproduce the above
|
|
|
|
copyright notice, this list of conditions and the
|
|
|
|
following disclaimer in the documentation and/or other
|
|
|
|
materials provided with the distribution.
|
|
|
|
|
|
|
|
* Neither the name of the assimp team, nor the names of its
|
|
|
|
contributors may be used to endorse or promote products
|
|
|
|
derived from this software without specific prior
|
|
|
|
written permission of the assimp team.
|
|
|
|
|
2015-05-19 03:52:10 +00:00
|
|
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
|
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
2015-05-19 03:48:29 +00:00
|
|
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
2015-05-19 03:52:10 +00:00
|
|
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
2015-05-19 03:48:29 +00:00
|
|
|
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
2015-05-19 03:52:10 +00:00
|
|
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
2015-05-19 03:48:29 +00:00
|
|
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
2015-05-19 03:52:10 +00:00
|
|
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
|
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
|
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
2015-05-19 03:48:29 +00:00
|
|
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
|
|
|
|
----------------------------------------------------------------------
|
|
|
|
*/
|
|
|
|
|
2015-05-19 03:57:13 +00:00
|
|
|
/** @file ObjTools.h
|
|
|
|
* @brief Some helpful templates for text parsing
|
2015-05-19 03:48:29 +00:00
|
|
|
*/
|
|
|
|
#ifndef OBJ_TOOLS_H_INC
|
|
|
|
#define OBJ_TOOLS_H_INC
|
|
|
|
|
2018-01-06 00:18:33 +00:00
|
|
|
#include <assimp/ParsingUtils.h>
|
2020-03-15 09:21:08 +00:00
|
|
|
#include <assimp/fast_atof.h>
|
2015-05-19 03:48:29 +00:00
|
|
|
#include <vector>
|
|
|
|
|
2016-11-27 15:43:25 +00:00
|
|
|
namespace Assimp {
|
2015-05-19 03:48:29 +00:00
|
|
|
|
2021-09-21 09:34:58 +00:00
|
|
|
/**
|
|
|
|
* @brief Returns true, if the last entry of the buffer is reached.
|
|
|
|
* @param[in] it Iterator of current position.
|
|
|
|
* @param[in] end Iterator with end of buffer.
|
2015-05-19 03:57:13 +00:00
|
|
|
* @return true, if the end of the buffer is reached.
|
2015-05-19 03:48:29 +00:00
|
|
|
*/
|
2020-03-15 09:21:08 +00:00
|
|
|
template <class char_t>
|
|
|
|
inline bool isEndOfBuffer(char_t it, char_t end) {
|
|
|
|
if (it == end) {
|
2015-05-19 03:57:13 +00:00
|
|
|
return true;
|
|
|
|
}
|
2021-09-21 09:34:58 +00:00
|
|
|
--end;
|
|
|
|
|
2020-03-15 09:21:08 +00:00
|
|
|
return (it == end);
|
2015-05-19 03:48:29 +00:00
|
|
|
}
|
|
|
|
|
2021-09-21 09:34:58 +00:00
|
|
|
/**
|
|
|
|
* @brief Returns next word separated by a space
|
|
|
|
* @param[in] pBuffer Pointer to data buffer
|
|
|
|
* @param[in] pEnd Pointer to end of buffer
|
2015-05-19 03:57:13 +00:00
|
|
|
* @return Pointer to next space
|
2015-05-19 03:48:29 +00:00
|
|
|
*/
|
2020-03-15 09:21:08 +00:00
|
|
|
template <class Char_T>
|
|
|
|
inline Char_T getNextWord(Char_T pBuffer, Char_T pEnd) {
|
|
|
|
while (!isEndOfBuffer(pBuffer, pEnd)) {
|
|
|
|
if (!IsSpaceOrNewLine(*pBuffer) || IsLineEnd(*pBuffer)) {
|
|
|
|
break;
|
2017-05-25 20:40:36 +00:00
|
|
|
}
|
2021-09-21 09:34:58 +00:00
|
|
|
++pBuffer;
|
2015-05-19 03:57:13 +00:00
|
|
|
}
|
2021-09-21 09:34:58 +00:00
|
|
|
|
2015-05-19 03:57:13 +00:00
|
|
|
return pBuffer;
|
2015-05-19 03:48:29 +00:00
|
|
|
}
|
|
|
|
|
2021-09-21 09:34:58 +00:00
|
|
|
/**
|
|
|
|
* @brief Returns pointer a next token
|
|
|
|
* @param[in] pBuffer Pointer to data buffer
|
|
|
|
* @param[in] pEnd Pointer to end of buffer
|
2015-05-19 03:57:13 +00:00
|
|
|
* @return Pointer to next token
|
2015-05-19 03:48:29 +00:00
|
|
|
*/
|
2020-03-15 09:21:08 +00:00
|
|
|
template <class Char_T>
|
|
|
|
inline Char_T getNextToken(Char_T pBuffer, Char_T pEnd) {
|
|
|
|
while (!isEndOfBuffer(pBuffer, pEnd)) {
|
2021-09-21 09:34:58 +00:00
|
|
|
if (IsSpaceOrNewLine(*pBuffer)) {
|
2015-05-19 03:57:13 +00:00
|
|
|
break;
|
2021-09-21 09:34:58 +00:00
|
|
|
}
|
|
|
|
++pBuffer;
|
2015-05-19 03:57:13 +00:00
|
|
|
}
|
2020-03-15 09:21:08 +00:00
|
|
|
return getNextWord(pBuffer, pEnd);
|
2015-05-19 03:48:29 +00:00
|
|
|
}
|
|
|
|
|
2021-09-21 09:34:58 +00:00
|
|
|
/**
|
|
|
|
* @brief Skips a line
|
|
|
|
* @param[in] it Iterator set to current position
|
|
|
|
* @param[in] end Iterator set to end of scratch buffer for readout
|
|
|
|
* @param[out] uiLine Current line number in format
|
2015-05-19 03:57:13 +00:00
|
|
|
* @return Current-iterator with new position
|
2015-05-19 03:48:29 +00:00
|
|
|
*/
|
2020-03-15 09:21:08 +00:00
|
|
|
template <class char_t>
|
|
|
|
inline char_t skipLine(char_t it, char_t end, unsigned int &uiLine) {
|
2022-12-16 08:03:40 +00:00
|
|
|
if (it >= end) {
|
2022-12-11 00:54:57 +00:00
|
|
|
return it;
|
2022-12-16 08:03:40 +00:00
|
|
|
}
|
2022-12-11 00:54:57 +00:00
|
|
|
|
2020-03-15 09:21:08 +00:00
|
|
|
while (!isEndOfBuffer(it, end) && !IsLineEnd(*it)) {
|
2015-05-19 03:48:29 +00:00
|
|
|
++it;
|
|
|
|
}
|
2020-03-15 09:21:08 +00:00
|
|
|
|
|
|
|
if (it != end) {
|
2015-05-19 03:57:13 +00:00
|
|
|
++it;
|
|
|
|
++uiLine;
|
|
|
|
}
|
|
|
|
// fix .. from time to time there are spaces at the beginning of a material line
|
2020-03-15 09:21:08 +00:00
|
|
|
while (it != end && (*it == '\t' || *it == ' ')) {
|
2015-05-19 03:57:13 +00:00
|
|
|
++it;
|
2017-05-30 19:10:33 +00:00
|
|
|
}
|
|
|
|
|
2015-05-19 03:57:13 +00:00
|
|
|
return it;
|
2015-05-19 03:48:29 +00:00
|
|
|
}
|
|
|
|
|
2021-09-21 09:34:58 +00:00
|
|
|
/**
|
|
|
|
* @brief Get a name from the current line. Preserve space in the middle,
|
2022-12-16 08:03:40 +00:00
|
|
|
* but trim it at the end.
|
2021-09-21 09:34:58 +00:00
|
|
|
* @param[in] it set to current position
|
|
|
|
* @param[in] end set to end of scratch buffer for readout
|
|
|
|
* @param[out] name Separated name
|
2015-05-19 03:57:13 +00:00
|
|
|
* @return Current-iterator with new position
|
2015-05-19 03:48:29 +00:00
|
|
|
*/
|
2020-03-15 09:21:08 +00:00
|
|
|
template <class char_t>
|
|
|
|
inline char_t getName(char_t it, char_t end, std::string &name) {
|
2015-05-19 03:57:13 +00:00
|
|
|
name = "";
|
2020-03-15 09:21:08 +00:00
|
|
|
if (isEndOfBuffer(it, end)) {
|
2015-05-19 03:48:29 +00:00
|
|
|
return end;
|
|
|
|
}
|
2015-05-19 03:52:10 +00:00
|
|
|
|
2020-03-15 09:21:08 +00:00
|
|
|
char *pStart = &(*it);
|
|
|
|
while (!isEndOfBuffer(it, end) && !IsLineEnd(*it)) {
|
2015-05-19 03:57:13 +00:00
|
|
|
++it;
|
|
|
|
}
|
2015-05-19 03:48:29 +00:00
|
|
|
|
2020-03-15 09:21:08 +00:00
|
|
|
while (IsSpace(*it)) {
|
2015-05-19 03:57:13 +00:00
|
|
|
--it;
|
|
|
|
}
|
|
|
|
// Get name
|
|
|
|
// if there is no name, and the previous char is a separator, come back to start
|
2016-02-07 19:03:24 +00:00
|
|
|
while (&(*it) < pStart) {
|
2015-05-19 03:57:13 +00:00
|
|
|
++it;
|
|
|
|
}
|
2020-03-15 09:21:08 +00:00
|
|
|
std::string strName(pStart, &(*it));
|
2021-09-21 09:34:58 +00:00
|
|
|
if (!strName.empty()) {
|
2016-11-10 23:12:36 +00:00
|
|
|
name = strName;
|
2021-09-21 09:34:58 +00:00
|
|
|
}
|
|
|
|
|
2016-11-10 23:12:36 +00:00
|
|
|
|
|
|
|
return it;
|
|
|
|
}
|
|
|
|
|
2021-09-21 09:34:58 +00:00
|
|
|
/**
|
|
|
|
* @brief Get a name from the current line. Do not preserve space
|
2016-11-10 23:12:36 +00:00
|
|
|
* in the middle, but trim it at the end.
|
|
|
|
* @param it set to current position
|
|
|
|
* @param end set to end of scratch buffer for readout
|
|
|
|
* @param name Separated name
|
|
|
|
* @return Current-iterator with new position
|
|
|
|
*/
|
2020-03-15 09:21:08 +00:00
|
|
|
template <class char_t>
|
|
|
|
inline char_t getNameNoSpace(char_t it, char_t end, std::string &name) {
|
2016-11-10 23:12:36 +00:00
|
|
|
name = "";
|
2020-03-15 09:21:08 +00:00
|
|
|
if (isEndOfBuffer(it, end)) {
|
2016-11-10 23:12:36 +00:00
|
|
|
return end;
|
|
|
|
}
|
|
|
|
|
2020-03-15 09:21:08 +00:00
|
|
|
char *pStart = &(*it);
|
|
|
|
while (!isEndOfBuffer(it, end) && !IsLineEnd(*it) && !IsSpaceOrNewLine(*it)) {
|
2016-11-10 23:12:36 +00:00
|
|
|
++it;
|
|
|
|
}
|
|
|
|
|
2020-03-15 09:21:08 +00:00
|
|
|
while (isEndOfBuffer(it, end) || IsLineEnd(*it) || IsSpaceOrNewLine(*it)) {
|
2016-11-10 23:12:36 +00:00
|
|
|
--it;
|
|
|
|
}
|
|
|
|
++it;
|
|
|
|
|
|
|
|
// Get name
|
|
|
|
// if there is no name, and the previous char is a separator, come back to start
|
|
|
|
while (&(*it) < pStart) {
|
|
|
|
++it;
|
|
|
|
}
|
2020-03-15 09:21:08 +00:00
|
|
|
std::string strName(pStart, &(*it));
|
2021-09-21 09:34:58 +00:00
|
|
|
if (!strName.empty()) {
|
2015-05-19 03:57:13 +00:00
|
|
|
name = strName;
|
2021-09-21 09:34:58 +00:00
|
|
|
}
|
|
|
|
|
2015-05-19 03:57:13 +00:00
|
|
|
return it;
|
2015-05-19 03:48:29 +00:00
|
|
|
}
|
|
|
|
|
2021-09-21 09:34:58 +00:00
|
|
|
/**
|
|
|
|
* @brief Get next word from given line
|
|
|
|
* @param[in] it set to current position
|
|
|
|
* @param[in] end set to end of scratch buffer for readout
|
|
|
|
* @param[in] pBuffer Buffer for next word
|
|
|
|
* @param[in] length Buffer length
|
2015-05-19 03:57:13 +00:00
|
|
|
* @return Current-iterator with new position
|
2015-05-19 03:48:29 +00:00
|
|
|
*/
|
2020-03-15 09:21:08 +00:00
|
|
|
template <class char_t>
|
|
|
|
inline char_t CopyNextWord(char_t it, char_t end, char *pBuffer, size_t length) {
|
2015-05-19 03:57:13 +00:00
|
|
|
size_t index = 0;
|
2020-03-15 09:21:08 +00:00
|
|
|
it = getNextWord<char_t>(it, end);
|
|
|
|
while (!IsSpaceOrNewLine(*it) && !isEndOfBuffer(it, end)) {
|
|
|
|
pBuffer[index] = *it;
|
2021-09-21 09:34:58 +00:00
|
|
|
++index;
|
|
|
|
if (index == length - 1) {
|
2015-05-19 03:57:13 +00:00
|
|
|
break;
|
2021-09-21 09:34:58 +00:00
|
|
|
}
|
2015-05-19 03:57:13 +00:00
|
|
|
++it;
|
|
|
|
}
|
2020-03-15 09:21:08 +00:00
|
|
|
pBuffer[index] = '\0';
|
2015-05-19 03:57:13 +00:00
|
|
|
return it;
|
2015-05-19 03:48:29 +00:00
|
|
|
}
|
|
|
|
|
2021-09-21 09:34:58 +00:00
|
|
|
/**
|
|
|
|
* @brief Get next float from given line
|
|
|
|
* @param[in] it set to current position
|
|
|
|
* @param[in] end set to end of scratch buffer for readout
|
|
|
|
* @param[out] value Separated float value.
|
2015-05-19 03:57:13 +00:00
|
|
|
* @return Current-iterator with new position
|
2015-05-19 03:48:29 +00:00
|
|
|
*/
|
2020-03-15 09:21:08 +00:00
|
|
|
template <class char_t>
|
|
|
|
inline char_t getFloat(char_t it, char_t end, ai_real &value) {
|
2015-05-19 03:57:13 +00:00
|
|
|
static const size_t BUFFERSIZE = 1024;
|
2022-07-30 10:58:09 +00:00
|
|
|
char buffer[BUFFERSIZE] = {};
|
2020-03-15 09:21:08 +00:00
|
|
|
it = CopyNextWord<char_t>(it, end, buffer, BUFFERSIZE);
|
|
|
|
value = (ai_real)fast_atof(buffer);
|
2015-05-19 03:48:29 +00:00
|
|
|
|
2015-05-19 03:57:13 +00:00
|
|
|
return it;
|
2015-05-19 03:48:29 +00:00
|
|
|
}
|
|
|
|
|
2021-09-21 09:34:58 +00:00
|
|
|
/**
|
|
|
|
* @brief Will remove white-spaces for a string.
|
|
|
|
* @param[in] str The string to clean
|
|
|
|
* @return The trimmed string.
|
|
|
|
*/
|
2015-12-13 19:32:09 +00:00
|
|
|
template <class string_type>
|
2021-09-21 09:34:58 +00:00
|
|
|
inline string_type trim_whitespaces(string_type str) {
|
|
|
|
while (!str.empty() && IsSpace(str[0])) {
|
2020-03-15 09:21:08 +00:00
|
|
|
str.erase(0);
|
2021-09-21 09:34:58 +00:00
|
|
|
}
|
|
|
|
while (!str.empty() && IsSpace(str[str.length() - 1])) {
|
2020-03-15 09:21:08 +00:00
|
|
|
str.erase(str.length() - 1);
|
2021-09-21 09:34:58 +00:00
|
|
|
}
|
2015-12-13 19:32:09 +00:00
|
|
|
return str;
|
|
|
|
}
|
|
|
|
|
2021-09-21 09:34:58 +00:00
|
|
|
/**
|
|
|
|
* @brief Checks for a line-end.
|
|
|
|
* @param[in] it Current iterator in string.
|
|
|
|
* @param[in] end End of the string.
|
|
|
|
* @return The trimmed string.
|
|
|
|
*/
|
2020-03-15 09:21:08 +00:00
|
|
|
template <class T>
|
|
|
|
bool hasLineEnd(T it, T end) {
|
2021-09-21 09:34:58 +00:00
|
|
|
bool hasLineEnd = false;
|
2020-03-15 09:21:08 +00:00
|
|
|
while (!isEndOfBuffer(it, end)) {
|
2021-09-21 09:34:58 +00:00
|
|
|
++it;
|
2020-03-15 09:21:08 +00:00
|
|
|
if (IsLineEnd(it)) {
|
2016-10-11 10:29:40 +00:00
|
|
|
hasLineEnd = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return hasLineEnd;
|
|
|
|
}
|
|
|
|
|
2015-05-19 03:48:29 +00:00
|
|
|
} // Namespace Assimp
|
|
|
|
|
|
|
|
#endif // OBJ_TOOLS_H_INC
|