next steps.

pull/2966/head
Kim Kulling 2020-07-02 15:18:59 +02:00
commit b1369d0912
190 changed files with 13133 additions and 11515 deletions

View File

@ -0,0 +1,38 @@
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: ''
assignees: ''
---
**Describe the bug**
A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
**Expected behavior**
A clear and concise description of what you expected to happen.
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Desktop (please complete the following information):**
- OS: [e.g. iOS]
- Browser [e.g. chrome, safari]
- Version [e.g. 22]
**Smartphone (please complete the following information):**
- Device: [e.g. iPhone6]
- OS: [e.g. iOS8.1]
- Browser [e.g. stock browser, safari]
- Version [e.g. 22]
**Additional context**
Add any other context about the problem here.

View File

@ -0,0 +1,20 @@
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: ''
assignees: ''
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.

View File

@ -0,0 +1,707 @@
/*
---------------------------------------------------------------------------
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2020, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the 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.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
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
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------------
*/
/// \file AMFImporter.cpp
/// \brief AMF-format files importer for Assimp: main algorithm implementation.
/// \date 2016
/// \author smal.root@gmail.com
#ifndef ASSIMP_BUILD_NO_AMF_IMPORTER
// Header files, Assimp.
#include "AMFImporter.hpp"
#include "AMFImporter_Macro.hpp"
#include <assimp/fast_atof.h>
#include <assimp/DefaultIOSystem.h>
// Header files, stdlib.
#include <memory>
namespace Assimp
{
/// \var aiImporterDesc AMFImporter::Description
/// Conastant which hold importer description
const aiImporterDesc AMFImporter::Description = {
"Additive manufacturing file format(AMF) Importer",
"smalcom",
"",
"See documentation in source code. Chapter: Limitations.",
aiImporterFlags_SupportTextFlavour | aiImporterFlags_LimitedSupport | aiImporterFlags_Experimental,
0,
0,
0,
0,
"amf"
};
void AMFImporter::Clear()
{
mNodeElement_Cur = nullptr;
mUnit.clear();
mMaterial_Converted.clear();
mTexture_Converted.clear();
// Delete all elements
if(!mNodeElement_List.empty())
{
for(CAMFImporter_NodeElement* ne: mNodeElement_List) { delete ne; }
mNodeElement_List.clear();
}
}
AMFImporter::~AMFImporter()
{
if(mReader != nullptr) delete mReader;
// Clear() is accounting if data already is deleted. So, just check again if all data is deleted.
Clear();
}
/*********************************************************************************************************************************************/
/************************************************************ Functions: find set ************************************************************/
/*********************************************************************************************************************************************/
bool AMFImporter::Find_NodeElement(const std::string& pID, const CAMFImporter_NodeElement::EType pType, CAMFImporter_NodeElement** pNodeElement) const
{
for(CAMFImporter_NodeElement* ne: mNodeElement_List)
{
if((ne->ID == pID) && (ne->Type == pType))
{
if(pNodeElement != nullptr) *pNodeElement = ne;
return true;
}
}// for(CAMFImporter_NodeElement* ne: mNodeElement_List)
return false;
}
bool AMFImporter::Find_ConvertedNode(const std::string& pID, std::list<aiNode*>& pNodeList, aiNode** pNode) const
{
aiString node_name(pID.c_str());
for(aiNode* node: pNodeList)
{
if(node->mName == node_name)
{
if(pNode != nullptr) *pNode = node;
return true;
}
}// for(aiNode* node: pNodeList)
return false;
}
bool AMFImporter::Find_ConvertedMaterial(const std::string& pID, const SPP_Material** pConvertedMaterial) const
{
for(const SPP_Material& mat: mMaterial_Converted)
{
if(mat.ID == pID)
{
if(pConvertedMaterial != nullptr) *pConvertedMaterial = &mat;
return true;
}
}// for(const SPP_Material& mat: mMaterial_Converted)
return false;
}
/*********************************************************************************************************************************************/
/************************************************************ Functions: throw set ***********************************************************/
/*********************************************************************************************************************************************/
void AMFImporter::Throw_CloseNotFound(const std::string& pNode)
{
throw DeadlyImportError("Close tag for node <" + pNode + "> not found. Seems file is corrupt.");
}
void AMFImporter::Throw_IncorrectAttr(const std::string& pAttrName)
{
throw DeadlyImportError("Node <" + std::string(mReader->getNodeName()) + "> has incorrect attribute \"" + pAttrName + "\".");
}
void AMFImporter::Throw_IncorrectAttrValue(const std::string& pAttrName)
{
throw DeadlyImportError("Attribute \"" + pAttrName + "\" in node <" + std::string(mReader->getNodeName()) + "> has incorrect value.");
}
void AMFImporter::Throw_MoreThanOnceDefined(const std::string& pNodeType, const std::string& pDescription)
{
throw DeadlyImportError("\"" + pNodeType + "\" node can be used only once in " + mReader->getNodeName() + ". Description: " + pDescription);
}
void AMFImporter::Throw_ID_NotFound(const std::string& pID) const
{
throw DeadlyImportError("Not found node with name \"" + pID + "\".");
}
/*********************************************************************************************************************************************/
/************************************************************* Functions: XML set ************************************************************/
/*********************************************************************************************************************************************/
void AMFImporter::XML_CheckNode_MustHaveChildren()
{
if(mReader->isEmptyElement()) throw DeadlyImportError(std::string("Node <") + mReader->getNodeName() + "> must have children.");
}
void AMFImporter::XML_CheckNode_SkipUnsupported(const std::string& pParentNodeName)
{
static const size_t Uns_Skip_Len = 3;
const char* Uns_Skip[Uns_Skip_Len] = { "composite", "edge", "normal" };
static bool skipped_before[Uns_Skip_Len] = { false, false, false };
std::string nn(mReader->getNodeName());
bool found = false;
bool close_found = false;
size_t sk_idx;
for(sk_idx = 0; sk_idx < Uns_Skip_Len; sk_idx++)
{
if(nn != Uns_Skip[sk_idx]) continue;
found = true;
if(mReader->isEmptyElement())
{
close_found = true;
goto casu_cres;
}
while(mReader->read())
{
if((mReader->getNodeType() == irr::io::EXN_ELEMENT_END) && (nn == mReader->getNodeName()))
{
close_found = true;
goto casu_cres;
}
}
}// for(sk_idx = 0; sk_idx < Uns_Skip_Len; sk_idx++)
casu_cres:
if(!found) throw DeadlyImportError("Unknown node \"" + nn + "\" in " + pParentNodeName + ".");
if(!close_found) Throw_CloseNotFound(nn);
if(!skipped_before[sk_idx])
{
skipped_before[sk_idx] = true;
ASSIMP_LOG_WARN_F("Skipping node \"", nn, "\" in ", pParentNodeName, ".");
}
}
bool AMFImporter::XML_SearchNode(const std::string& pNodeName)
{
while(mReader->read())
{
if((mReader->getNodeType() == irr::io::EXN_ELEMENT) && XML_CheckNode_NameEqual(pNodeName)) return true;
}
return false;
}
bool AMFImporter::XML_ReadNode_GetAttrVal_AsBool(const int pAttrIdx)
{
std::string val(mReader->getAttributeValue(pAttrIdx));
if((val == "false") || (val == "0"))
return false;
else if((val == "true") || (val == "1"))
return true;
else
throw DeadlyImportError("Bool attribute value can contain \"false\"/\"0\" or \"true\"/\"1\" not the \"" + val + "\"");
}
float AMFImporter::XML_ReadNode_GetAttrVal_AsFloat(const int pAttrIdx)
{
std::string val;
float tvalf;
ParseHelper_FixTruncatedFloatString(mReader->getAttributeValue(pAttrIdx), val);
fast_atoreal_move(val.c_str(), tvalf, false);
return tvalf;
}
uint32_t AMFImporter::XML_ReadNode_GetAttrVal_AsU32(const int pAttrIdx)
{
return strtoul10(mReader->getAttributeValue(pAttrIdx));
}
float AMFImporter::XML_ReadNode_GetVal_AsFloat()
{
std::string val;
float tvalf;
if(!mReader->read()) throw DeadlyImportError("XML_ReadNode_GetVal_AsFloat. No data, seems file is corrupt.");
if(mReader->getNodeType() != irr::io::EXN_TEXT) throw DeadlyImportError("XML_ReadNode_GetVal_AsFloat. Invalid type of XML element, seems file is corrupt.");
ParseHelper_FixTruncatedFloatString(mReader->getNodeData(), val);
fast_atoreal_move(val.c_str(), tvalf, false);
return tvalf;
}
uint32_t AMFImporter::XML_ReadNode_GetVal_AsU32()
{
if(!mReader->read()) throw DeadlyImportError("XML_ReadNode_GetVal_AsU32. No data, seems file is corrupt.");
if(mReader->getNodeType() != irr::io::EXN_TEXT) throw DeadlyImportError("XML_ReadNode_GetVal_AsU32. Invalid type of XML element, seems file is corrupt.");
return strtoul10(mReader->getNodeData());
}
void AMFImporter::XML_ReadNode_GetVal_AsString(std::string& pValue)
{
if(!mReader->read()) throw DeadlyImportError("XML_ReadNode_GetVal_AsString. No data, seems file is corrupt.");
if(mReader->getNodeType() != irr::io::EXN_TEXT)
throw DeadlyImportError("XML_ReadNode_GetVal_AsString. Invalid type of XML element, seems file is corrupt.");
pValue = mReader->getNodeData();
}
/*********************************************************************************************************************************************/
/************************************************************ Functions: parse set ***********************************************************/
/*********************************************************************************************************************************************/
void AMFImporter::ParseHelper_Node_Enter(CAMFImporter_NodeElement* pNode)
{
mNodeElement_Cur->Child.push_back(pNode);// add new element to current element child list.
mNodeElement_Cur = pNode;// switch current element to new one.
}
void AMFImporter::ParseHelper_Node_Exit()
{
// check if we can walk up.
if(mNodeElement_Cur != nullptr) mNodeElement_Cur = mNodeElement_Cur->Parent;
}
void AMFImporter::ParseHelper_FixTruncatedFloatString(const char* pInStr, std::string& pOutString)
{
size_t instr_len;
pOutString.clear();
instr_len = strlen(pInStr);
if(!instr_len) return;
pOutString.reserve(instr_len * 3 / 2);
// check and correct floats in format ".x". Must be "x.y".
if(pInStr[0] == '.') pOutString.push_back('0');
pOutString.push_back(pInStr[0]);
for(size_t ci = 1; ci < instr_len; ci++)
{
if((pInStr[ci] == '.') && ((pInStr[ci - 1] == ' ') || (pInStr[ci - 1] == '-') || (pInStr[ci - 1] == '+') || (pInStr[ci - 1] == '\t')))
{
pOutString.push_back('0');
pOutString.push_back('.');
}
else
{
pOutString.push_back(pInStr[ci]);
}
}
}
static bool ParseHelper_Decode_Base64_IsBase64(const char pChar)
{
return (isalnum(pChar) || (pChar == '+') || (pChar == '/'));
}
void AMFImporter::ParseHelper_Decode_Base64(const std::string& pInputBase64, std::vector<uint8_t>& pOutputData) const
{
// With help from
// René Nyffenegger http://www.adp-gmbh.ch/cpp/common/base64.html
const std::string base64_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
uint8_t tidx = 0;
uint8_t arr4[4], arr3[3];
// check input data
if(pInputBase64.size() % 4) throw DeadlyImportError("Base64-encoded data must have size multiply of four.");
// prepare output place
pOutputData.clear();
pOutputData.reserve(pInputBase64.size() / 4 * 3);
for(size_t in_len = pInputBase64.size(), in_idx = 0; (in_len > 0) && (pInputBase64[in_idx] != '='); in_len--)
{
if(ParseHelper_Decode_Base64_IsBase64(pInputBase64[in_idx]))
{
arr4[tidx++] = pInputBase64[in_idx++];
if(tidx == 4)
{
for(tidx = 0; tidx < 4; tidx++) arr4[tidx] = (uint8_t)base64_chars.find(arr4[tidx]);
arr3[0] = (arr4[0] << 2) + ((arr4[1] & 0x30) >> 4);
arr3[1] = ((arr4[1] & 0x0F) << 4) + ((arr4[2] & 0x3C) >> 2);
arr3[2] = ((arr4[2] & 0x03) << 6) + arr4[3];
for(tidx = 0; tidx < 3; tidx++) pOutputData.push_back(arr3[tidx]);
tidx = 0;
}// if(tidx == 4)
}// if(ParseHelper_Decode_Base64_IsBase64(pInputBase64[in_idx]))
else
{
in_idx++;
}// if(ParseHelper_Decode_Base64_IsBase64(pInputBase64[in_idx])) else
}
if(tidx)
{
for(uint8_t i = tidx; i < 4; i++) arr4[i] = 0;
for(uint8_t i = 0; i < 4; i++) arr4[i] = (uint8_t)(base64_chars.find(arr4[i]));
arr3[0] = (arr4[0] << 2) + ((arr4[1] & 0x30) >> 4);
arr3[1] = ((arr4[1] & 0x0F) << 4) + ((arr4[2] & 0x3C) >> 2);
arr3[2] = ((arr4[2] & 0x03) << 6) + arr4[3];
for(uint8_t i = 0; i < (tidx - 1); i++) pOutputData.push_back(arr3[i]);
}
}
void AMFImporter::ParseFile(const std::string& pFile, IOSystem* pIOHandler)
{
irr::io::IrrXMLReader* OldReader = mReader;// store current XMLreader.
std::unique_ptr<IOStream> file(pIOHandler->Open(pFile, "rb"));
// Check whether we can read from the file
if (file.get() == nullptr) {
throw DeadlyImportError("Failed to open AMF file " + pFile + ".");
}
// generate a XML reader for it
std::unique_ptr<CIrrXML_IOStreamReader> mIOWrapper(new CIrrXML_IOStreamReader(file.get()));
mReader = irr::io::createIrrXMLReader(mIOWrapper.get());
if(!mReader) throw DeadlyImportError("Failed to create XML reader for file" + pFile + ".");
//
// start reading
// search for root tag <amf>
if(XML_SearchNode("amf"))
ParseNode_Root();
else
throw DeadlyImportError("Root node \"amf\" not found.");
delete mReader;
// restore old XMLreader
mReader = OldReader;
}
// <amf
// unit="" - The units to be used. May be "inch", "millimeter", "meter", "feet", or "micron".
// version="" - Version of file format.
// >
// </amf>
// Root XML element.
// Multi elements - No.
void AMFImporter::ParseNode_Root()
{
std::string unit, version;
CAMFImporter_NodeElement *ne( nullptr );
// Read attributes for node <amf>.
MACRO_ATTRREAD_LOOPBEG;
MACRO_ATTRREAD_CHECK_RET("unit", unit, mReader->getAttributeValue);
MACRO_ATTRREAD_CHECK_RET("version", version, mReader->getAttributeValue);
MACRO_ATTRREAD_LOOPEND_WSKIP;
// Check attributes
if(!mUnit.empty())
{
if((mUnit != "inch") && (mUnit != "millimeter") && (mUnit != "meter") && (mUnit != "feet") && (mUnit != "micron")) Throw_IncorrectAttrValue("unit");
}
// create root node element.
ne = new CAMFImporter_NodeElement_Root(nullptr);
mNodeElement_Cur = ne;// set first "current" element
// and assign attribute's values
((CAMFImporter_NodeElement_Root*)ne)->Unit = unit;
((CAMFImporter_NodeElement_Root*)ne)->Version = version;
// Check for child nodes
if(!mReader->isEmptyElement())
{
MACRO_NODECHECK_LOOPBEGIN("amf");
if(XML_CheckNode_NameEqual("object")) { ParseNode_Object(); continue; }
if(XML_CheckNode_NameEqual("material")) { ParseNode_Material(); continue; }
if(XML_CheckNode_NameEqual("texture")) { ParseNode_Texture(); continue; }
if(XML_CheckNode_NameEqual("constellation")) { ParseNode_Constellation(); continue; }
if(XML_CheckNode_NameEqual("metadata")) { ParseNode_Metadata(); continue; }
MACRO_NODECHECK_LOOPEND("amf");
mNodeElement_Cur = ne;// force restore "current" element
}// if(!mReader->isEmptyElement())
mNodeElement_List.push_back(ne);// add to node element list because its a new object in graph.
}
// <constellation
// id="" - The Object ID of the new constellation being defined.
// >
// </constellation>
// A collection of objects or constellations with specific relative locations.
// Multi elements - Yes.
// Parent element - <amf>.
void AMFImporter::ParseNode_Constellation()
{
std::string id;
CAMFImporter_NodeElement* ne( nullptr );
// Read attributes for node <constellation>.
MACRO_ATTRREAD_LOOPBEG;
MACRO_ATTRREAD_CHECK_RET("id", id, mReader->getAttributeValue);
MACRO_ATTRREAD_LOOPEND;
// create and if needed - define new grouping object.
ne = new CAMFImporter_NodeElement_Constellation(mNodeElement_Cur);
CAMFImporter_NodeElement_Constellation& als = *((CAMFImporter_NodeElement_Constellation*)ne);// alias for convenience
if(!id.empty()) als.ID = id;
// Check for child nodes
if(!mReader->isEmptyElement())
{
ParseHelper_Node_Enter(ne);
MACRO_NODECHECK_LOOPBEGIN("constellation");
if(XML_CheckNode_NameEqual("instance")) { ParseNode_Instance(); continue; }
if(XML_CheckNode_NameEqual("metadata")) { ParseNode_Metadata(); continue; }
MACRO_NODECHECK_LOOPEND("constellation");
ParseHelper_Node_Exit();
}// if(!mReader->isEmptyElement())
else
{
mNodeElement_Cur->Child.push_back(ne);// Add element to child list of current element
}// if(!mReader->isEmptyElement()) else
mNodeElement_List.push_back(ne);// and to node element list because its a new object in graph.
}
// <instance
// objectid="" - The Object ID of the new constellation being defined.
// >
// </instance>
// A collection of objects or constellations with specific relative locations.
// Multi elements - Yes.
// Parent element - <amf>.
void AMFImporter::ParseNode_Instance()
{
std::string objectid;
CAMFImporter_NodeElement* ne( nullptr );
// Read attributes for node <constellation>.
MACRO_ATTRREAD_LOOPBEG;
MACRO_ATTRREAD_CHECK_RET("objectid", objectid, mReader->getAttributeValue);
MACRO_ATTRREAD_LOOPEND;
// used object id must be defined, check that.
if(objectid.empty()) throw DeadlyImportError("\"objectid\" in <instance> must be defined.");
// create and define new grouping object.
ne = new CAMFImporter_NodeElement_Instance(mNodeElement_Cur);
CAMFImporter_NodeElement_Instance& als = *((CAMFImporter_NodeElement_Instance*)ne);// alias for convenience
als.ObjectID = objectid;
// Check for child nodes
if(!mReader->isEmptyElement())
{
bool read_flag[6] = { false, false, false, false, false, false };
als.Delta.Set(0, 0, 0);
als.Rotation.Set(0, 0, 0);
ParseHelper_Node_Enter(ne);
MACRO_NODECHECK_LOOPBEGIN("instance");
MACRO_NODECHECK_READCOMP_F("deltax", read_flag[0], als.Delta.x);
MACRO_NODECHECK_READCOMP_F("deltay", read_flag[1], als.Delta.y);
MACRO_NODECHECK_READCOMP_F("deltaz", read_flag[2], als.Delta.z);
MACRO_NODECHECK_READCOMP_F("rx", read_flag[3], als.Rotation.x);
MACRO_NODECHECK_READCOMP_F("ry", read_flag[4], als.Rotation.y);
MACRO_NODECHECK_READCOMP_F("rz", read_flag[5], als.Rotation.z);
MACRO_NODECHECK_LOOPEND("instance");
ParseHelper_Node_Exit();
// also convert degrees to radians.
als.Rotation.x = AI_MATH_PI_F * als.Rotation.x / 180.0f;
als.Rotation.y = AI_MATH_PI_F * als.Rotation.y / 180.0f;
als.Rotation.z = AI_MATH_PI_F * als.Rotation.z / 180.0f;
}// if(!mReader->isEmptyElement())
else
{
mNodeElement_Cur->Child.push_back(ne);// Add element to child list of current element
}// if(!mReader->isEmptyElement()) else
mNodeElement_List.push_back(ne);// and to node element list because its a new object in graph.
}
// <object
// id="" - A unique ObjectID for the new object being defined.
// >
// </object>
// An object definition.
// Multi elements - Yes.
// Parent element - <amf>.
void AMFImporter::ParseNode_Object()
{
std::string id;
CAMFImporter_NodeElement* ne( nullptr );
// Read attributes for node <object>.
MACRO_ATTRREAD_LOOPBEG;
MACRO_ATTRREAD_CHECK_RET("id", id, mReader->getAttributeValue);
MACRO_ATTRREAD_LOOPEND;
// create and if needed - define new geometry object.
ne = new CAMFImporter_NodeElement_Object(mNodeElement_Cur);
CAMFImporter_NodeElement_Object& als = *((CAMFImporter_NodeElement_Object*)ne);// alias for convenience
if(!id.empty()) als.ID = id;
// Check for child nodes
if(!mReader->isEmptyElement())
{
bool col_read = false;
ParseHelper_Node_Enter(ne);
MACRO_NODECHECK_LOOPBEGIN("object");
if(XML_CheckNode_NameEqual("color"))
{
// Check if color already defined for object.
if(col_read) Throw_MoreThanOnceDefined("color", "Only one color can be defined for <object>.");
// read data and set flag about it
ParseNode_Color();
col_read = true;
continue;
}
if(XML_CheckNode_NameEqual("mesh")) { ParseNode_Mesh(); continue; }
if(XML_CheckNode_NameEqual("metadata")) { ParseNode_Metadata(); continue; }
MACRO_NODECHECK_LOOPEND("object");
ParseHelper_Node_Exit();
}// if(!mReader->isEmptyElement())
else
{
mNodeElement_Cur->Child.push_back(ne);// Add element to child list of current element
}// if(!mReader->isEmptyElement()) else
mNodeElement_List.push_back(ne);// and to node element list because its a new object in graph.
}
// <metadata
// type="" - The type of the attribute.
// >
// </metadata>
// Specify additional information about an entity.
// Multi elements - Yes.
// Parent element - <amf>, <object>, <volume>, <material>, <vertex>.
//
// Reserved types are:
// "Name" - The alphanumeric label of the entity, to be used by the interpreter if interacting with the user.
// "Description" - A description of the content of the entity
// "URL" - A link to an external resource relating to the entity
// "Author" - Specifies the name(s) of the author(s) of the entity
// "Company" - Specifying the company generating the entity
// "CAD" - specifies the name of the originating CAD software and version
// "Revision" - specifies the revision of the entity
// "Tolerance" - specifies the desired manufacturing tolerance of the entity in entity's unit system
// "Volume" - specifies the total volume of the entity, in the entity's unit system, to be used for verification (object and volume only)
void AMFImporter::ParseNode_Metadata()
{
std::string type, value;
CAMFImporter_NodeElement* ne( nullptr );
// read attribute
MACRO_ATTRREAD_LOOPBEG;
MACRO_ATTRREAD_CHECK_RET("type", type, mReader->getAttributeValue);
MACRO_ATTRREAD_LOOPEND;
// and value of node.
value = mReader->getNodeData();
// Create node element and assign read data.
ne = new CAMFImporter_NodeElement_Metadata(mNodeElement_Cur);
((CAMFImporter_NodeElement_Metadata*)ne)->Type = type;
((CAMFImporter_NodeElement_Metadata*)ne)->Value = value;
mNodeElement_Cur->Child.push_back(ne);// Add element to child list of current element
mNodeElement_List.push_back(ne);// and to node element list because its a new object in graph.
}
/*********************************************************************************************************************************************/
/******************************************************** Functions: BaseImporter set ********************************************************/
/*********************************************************************************************************************************************/
bool AMFImporter::CanRead(const std::string& pFile, IOSystem* pIOHandler, bool pCheckSig) const
{
const std::string extension = GetExtension(pFile);
if ( extension == "amf" ) {
return true;
}
if(!extension.length() || pCheckSig)
{
const char* tokens[] = { "<amf" };
return SearchFileHeaderForToken( pIOHandler, pFile, tokens, 1 );
}
return false;
}
void AMFImporter::GetExtensionList(std::set<std::string>& pExtensionList)
{
pExtensionList.insert("amf");
}
const aiImporterDesc* AMFImporter::GetInfo () const
{
return &Description;
}
void AMFImporter::InternReadFile(const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler)
{
Clear();// delete old graph.
ParseFile(pFile, pIOHandler);
Postprocess_BuildScene(pScene);
// scene graph is ready, exit.
}
}// namespace Assimp
#endif // !ASSIMP_BUILD_NO_AMF_IMPORTER

View File

@ -367,7 +367,7 @@ void Discreet3DSExporter::WriteTexture(const aiMaterial &mat, aiTextureType type
aiTextureMapMode_Wrap, aiTextureMapMode_Wrap
};
ai_real blend = 1.0;
if (mat.GetTexture(type, 0, &path, NULL, NULL, &blend, NULL, map_mode) != AI_SUCCESS || !path.length) {
if (mat.GetTexture(type, 0, &path, nullptr, nullptr, &blend, nullptr, map_mode) != AI_SUCCESS || !path.length) {
return;
}

View File

@ -462,12 +462,10 @@ struct Material {
sTexAmbient(other.sTexAmbient),
mTwoSided(other.mTwoSided) {
// empty
}
//! Move constructor. This is explicitly written because MSVC doesn't support defaulting it
Material(Material &&other) AI_NO_EXCEPT :
mName(std::move(other.mName)),
Material(Material &&other) AI_NO_EXCEPT : mName(std::move(other.mName)),
mDiffuse(std::move(other.mDiffuse)),
mSpecularExponent(std::move(other.mSpecularExponent)),
mShininessStrength(std::move(other.mShininessStrength)),
@ -615,7 +613,12 @@ struct Node {
Node() = delete;
explicit Node(const std::string &name) :
mParent(NULL), mName(name), mInstanceNumber(0), mHierarchyPos(0), mHierarchyIndex(0), mInstanceCount(1) {
mParent(nullptr),
mName(name),
mInstanceNumber(0),
mHierarchyPos(0),
mHierarchyIndex(0),
mInstanceCount(1) {
aRotationKeys.reserve(20);
aPositionKeys.reserve(20);
aScalingKeys.reserve(20);

View File

@ -314,19 +314,19 @@ private:
++buf;
comp[1] = *buf;
++buf;
diffuse.r = static_cast<ai_real>(strtol(comp, NULL, 16)) / ai_real(255.0);
diffuse.r = static_cast<ai_real>(strtol(comp, nullptr, 16)) / ai_real(255.0);
comp[0] = *buf;
++buf;
comp[1] = *buf;
++buf;
diffuse.g = static_cast<ai_real>(strtol(comp, NULL, 16)) / ai_real(255.0);
diffuse.g = static_cast<ai_real>(strtol(comp, nullptr, 16)) / ai_real(255.0);
comp[0] = *buf;
++buf;
comp[1] = *buf;
++buf;
diffuse.b = static_cast<ai_real>(strtol(comp, NULL, 16)) / ai_real(255.0);
diffuse.b = static_cast<ai_real>(strtol(comp, nullptr, 16)) / ai_real(255.0);
if (7 == len)
return true;
@ -334,7 +334,7 @@ private:
++buf;
comp[1] = *buf;
++buf;
diffuse.a = static_cast<ai_real>(strtol(comp, NULL, 16)) / ai_real(255.0);
diffuse.a = static_cast<ai_real>(strtol(comp, nullptr, 16)) / ai_real(255.0);
return true;
}

View File

@ -45,19 +45,19 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "D3MFOpcPackage.h"
#include <assimp/Exceptional.h>
#include <assimp/ZipArchiveIOSystem.h>
#include <assimp/ai_assert.h>
#include <assimp/DefaultLogger.hpp>
#include <assimp/IOStream.hpp>
#include <assimp/IOSystem.hpp>
#include <assimp/DefaultLogger.hpp>
#include <assimp/ai_assert.h>
#include <assimp/ZipArchiveIOSystem.h>
#include <cstdlib>
#include <memory>
#include <vector>
#include <map>
#include "3MFXmlTags.h"
#include <algorithm>
#include <cassert>
#include "3MFXmlTags.h"
#include <cstdlib>
#include <map>
#include <memory>
#include <vector>
namespace Assimp {
@ -71,22 +71,18 @@ public:
OpcPackageRelationshipReader(XmlReader *xmlReader) {
while (xmlReader->read()) {
if (xmlReader->getNodeType() == irr::io::EXN_ELEMENT &&
xmlReader->getNodeName() == XmlTag::RELS_RELATIONSHIP_CONTAINER)
{
xmlReader->getNodeName() == XmlTag::RELS_RELATIONSHIP_CONTAINER) {
ParseRootNode(xmlReader);
}
}
}
void ParseRootNode(XmlReader* xmlReader)
{
void ParseRootNode(XmlReader *xmlReader) {
ParseAttributes(xmlReader);
while(xmlReader->read())
{
while (xmlReader->read()) {
if (xmlReader->getNodeType() == irr::io::EXN_ELEMENT &&
xmlReader->getNodeName() == XmlTag::RELS_RELATIONSHIP_NODE)
{
xmlReader->getNodeName() == XmlTag::RELS_RELATIONSHIP_NODE) {
ParseChildNode(xmlReader);
}
}
@ -118,9 +114,8 @@ public:
};
// ------------------------------------------------------------------------------------------------
D3MFOpcPackage::D3MFOpcPackage(IOSystem* pIOHandler, const std::string& rFile)
: mRootStream(nullptr)
, mZipArchive() {
D3MFOpcPackage::D3MFOpcPackage(IOSystem *pIOHandler, const std::string &rFile) :
mRootStream(nullptr), mZipArchive() {
mZipArchive.reset(new ZipArchiveIOSystem(pIOHandler, rFile));
if (!mZipArchive->isOpen()) {
throw DeadlyImportError("Failed to open file " + rFile + ".");
@ -131,12 +126,15 @@ D3MFOpcPackage::D3MFOpcPackage(IOSystem* pIOHandler, const std::string& rFile)
for (auto &file : fileList) {
if (file == D3MF::XmlTag::ROOT_RELATIONSHIPS_ARCHIVE) {
//PkgRelationshipReader pkgRelReader(file, archive);
ai_assert(mZipArchive->Exists(file.c_str()));
if (!mZipArchive->Exists(file.c_str())) {
continue;
}
IOStream *fileStream = mZipArchive->Open(file.c_str());
if (nullptr == fileStream) {
ai_assert(fileStream != nullptr);
continue;
}
std::string rootFile = ReadPackageRootRelationship(fileStream);
if (rootFile.size() > 0 && rootFile[0] == '/') {
@ -162,7 +160,6 @@ D3MFOpcPackage::D3MFOpcPackage(IOSystem* pIOHandler, const std::string& rFile)
} else {
ASSIMP_LOG_WARN_F("Ignored file of unknown type: ", file);
}
}
}

View File

@ -627,7 +627,7 @@ aiNode *AC3DImporter::ConvertObjectSection(Object &object,
std::unique_ptr<Subdivider> div(Subdivider::Create(Subdivider::CATMULL_CLARKE));
ASSIMP_LOG_INFO("AC3D: Evaluating subdivision surface: " + object.name);
std::vector<aiMesh *> cpy(meshes.size() - oldm, NULL);
std::vector<aiMesh *> cpy(meshes.size() - oldm, nullptr);
div->Subdivide(&meshes[oldm], cpy.size(), &cpy.front(), object.subDiv, true);
std::copy(cpy.begin(), cpy.end(), meshes.begin() + oldm);

View File

@ -88,7 +88,7 @@ void AMFImporter::Clear() {
}
}
AMFImporter::AMFImporter() :
AMFImporter::AMFImporter() AI_NO_EXCEPT :
mNodeElement_Cur(nullptr),
mXmlParser(nullptr) {
// empty
@ -182,7 +182,7 @@ void AMFImporter::XML_CheckNode_MustHaveChildren(pugi::xml_node &node) {
}
}
void AMFImporter::XML_CheckNode_SkipUnsupported(const std::string &pParentNodeName) {
/*void AMFImporter::XML_CheckNode_SkipUnsupported(const std::string &pParentNodeName) {
static const size_t Uns_Skip_Len = 3;
const char *Uns_Skip[Uns_Skip_Len] = { "composite", "edge", "normal" };
@ -221,7 +221,7 @@ casu_cres:
skipped_before[sk_idx] = true;
ASSIMP_LOG_WARN_F("Skipping node \"", nn, "\" in ", pParentNodeName, ".");
}
}
}*/
bool AMFImporter::XML_SearchNode(const std::string &nodeName) {
mXmlParser->h(nodeName);
@ -383,6 +383,7 @@ void AMFImporter::ParseFile(const std::string &pFile, IOSystem *pIOHandler) {
throw DeadlyImportError("Failed to open AMF file " + pFile + ".");
}
<<<<<<< HEAD
mXmlParser = new XmlParser();
if (!mXmlParser->parse( file.get() ) {
delete mXmlParser;
@ -391,6 +392,18 @@ void AMFImporter::ParseFile(const std::string &pFile, IOSystem *pIOHandler) {
// Start reading, search for root tag <amf>
if (!mXmlParser->hasNode("amf")) {
=======
// generate a XML reader for it
std::unique_ptr<CIrrXML_IOStreamReader> mIOWrapper(new CIrrXML_IOStreamReader(file.get()));
mReader = irr::io::createIrrXMLReader(mIOWrapper.get());
if (!mReader) throw DeadlyImportError("Failed to create XML reader for file" + pFile + ".");
//
// start reading
// search for root tag <amf>
if (XML_SearchNode("amf"))
ParseNode_Root();
else
>>>>>>> master
throw DeadlyImportError("Root node \"amf\" not found.");
}

View File

@ -925,7 +925,7 @@ void Parser::ParseLV2AnimationBlock(ASE::BaseNode &mesh) {
ASSIMP_LOG_ERROR("ASE: Found target animation channel "
"but the node is neither a camera nor a spot light");
anim = NULL;
anim = nullptr;
} else
anim = &mesh.mTargetAnim;
}
@ -1797,14 +1797,14 @@ void Parser::ParseLV4MeshFace(ASE::Face &out) {
}
// ------------------------------------------------------------------------------------------------
void Parser::ParseLV4MeshLongTriple(unsigned int *apOut) {
ai_assert(NULL != apOut);
ai_assert(nullptr != apOut);
for (unsigned int i = 0; i < 3; ++i)
ParseLV4MeshLong(apOut[i]);
}
// ------------------------------------------------------------------------------------------------
void Parser::ParseLV4MeshLongTriple(unsigned int *apOut, unsigned int &rIndexOut) {
ai_assert(NULL != apOut);
ai_assert(nullptr != apOut);
// parse the index
ParseLV4MeshLong(rIndexOut);
@ -1814,7 +1814,7 @@ void Parser::ParseLV4MeshLongTriple(unsigned int *apOut, unsigned int &rIndexOut
}
// ------------------------------------------------------------------------------------------------
void Parser::ParseLV4MeshFloatTriple(ai_real *apOut, unsigned int &rIndexOut) {
ai_assert(NULL != apOut);
ai_assert(nullptr != apOut);
// parse the index
ParseLV4MeshLong(rIndexOut);
@ -1824,7 +1824,7 @@ void Parser::ParseLV4MeshFloatTriple(ai_real *apOut, unsigned int &rIndexOut) {
}
// ------------------------------------------------------------------------------------------------
void Parser::ParseLV4MeshFloatTriple(ai_real *apOut) {
ai_assert(NULL != apOut);
ai_assert(nullptr != apOut);
for (unsigned int i = 0; i < 3; ++i)
ParseLV4MeshFloat(apOut[i]);

View File

@ -40,15 +40,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------
*/
/** @file Defines the helper data structures for importing ASE files */
#ifndef AI_ASEFILEHELPER_H_INC
#define AI_ASEFILEHELPER_H_INC
// public ASSIMP headers
#include <assimp/types.h>
#include <assimp/mesh.h>
#include <assimp/anim.h>
#include <assimp/mesh.h>
#include <assimp/types.h>
#ifndef ASSIMP_BUILD_NO_3DS_IMPORTER
@ -66,16 +65,15 @@ using namespace D3DS;
// ---------------------------------------------------------------------------
/** Helper structure representing an ASE material */
struct Material : public D3DS::Material
{
struct Material : public D3DS::Material {
//! Default constructor has been deleted
Material() = delete;
//! Constructor with explicit name
explicit Material(const std::string &name)
: D3DS::Material(name)
, pcInstance(NULL)
, bNeed (false) {
explicit Material(const std::string &name) :
D3DS::Material(name),
pcInstance(nullptr),
bNeed(false) {
// empty
}
@ -93,18 +91,15 @@ struct Material : public D3DS::Material
return *this;
}
//! Move constructor. This is explicitly written because MSVC doesn't support defaulting it
Material(Material &&other) AI_NO_EXCEPT
: D3DS::Material(std::move(other))
, avSubMaterials(std::move(other.avSubMaterials))
, pcInstance(std::move(other.pcInstance))
, bNeed(std::move(other.bNeed))
{
: D3DS::Material(std::move(other)),
avSubMaterials(std::move(other.avSubMaterials)),
pcInstance(std::move(other.pcInstance)),
bNeed(std::move(other.bNeed)) {
other.pcInstance = nullptr;
}
Material &operator=(Material &&other) AI_NO_EXCEPT {
if (this == &other) {
return *this;
@ -121,10 +116,8 @@ struct Material : public D3DS::Material
return *this;
}
~Material() {}
//! Contains all sub materials of this material
std::vector<Material> avSubMaterials;
@ -140,8 +133,8 @@ struct Material : public D3DS::Material
struct Face : public FaceWithSmoothingGroup {
//! Default constructor. Initializes everything with 0
Face() AI_NO_EXCEPT
: iMaterial(DEFAULT_MATINDEX)
, iFace(0) {
: iMaterial(DEFAULT_MATINDEX),
iFace(0) {
// empty
}
@ -172,8 +165,8 @@ struct Bone {
Bone() = delete;
//! Construction from an existing name
explicit Bone( const std::string& name)
: mName(name) {
explicit Bone(const std::string &name) :
mName(name) {
// empty
}
@ -196,12 +189,13 @@ struct Animation {
TRACK = 0x0,
BEZIER = 0x1,
TCB = 0x2
} mRotationType, mScalingType, mPositionType;
} mRotationType,
mScalingType, mPositionType;
Animation() AI_NO_EXCEPT
: mRotationType (TRACK)
, mScalingType (TRACK)
, mPositionType (TRACK) {
: mRotationType(TRACK),
mScalingType(TRACK),
mPositionType(TRACK) {
// empty
}
@ -246,10 +240,8 @@ struct BaseNode {
} mType;
//! Construction from an existing name
BaseNode(Type _mType, const std::string &name)
: mType (_mType)
, mName (name)
, mProcessed (false) {
BaseNode(Type _mType, const std::string &name) :
mType(_mType), mName(name), mProcessed(false) {
// Set mTargetPosition to qnan
const ai_real qnan = get_qnan();
mTargetPosition.x = qnan;
@ -289,13 +281,8 @@ struct Mesh : public MeshWithSmoothingGroups<ASE::Face>, public BaseNode {
Mesh() = delete;
//! Construction from an existing name
explicit Mesh(const std::string &name)
: BaseNode( BaseNode::Mesh, name )
, mVertexColors()
, mBoneVertices()
, mBones()
, iMaterialIndex(Face::DEFAULT_MATINDEX)
, bSkip (false) {
explicit Mesh(const std::string &name) :
BaseNode(BaseNode::Mesh, name), mVertexColors(), mBoneVertices(), mBones(), iMaterialIndex(Face::DEFAULT_MATINDEX), bSkip(false) {
for (unsigned int c = 0; c < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++c) {
this->mNumUVComponents[c] = 2;
}
@ -325,10 +312,8 @@ struct Mesh : public MeshWithSmoothingGroups<ASE::Face>, public BaseNode {
// ---------------------------------------------------------------------------
/** Helper structure to represent an ASE light source */
struct Light : public BaseNode
{
enum LightType
{
struct Light : public BaseNode {
enum LightType {
OMNI,
TARGET,
FREE,
@ -339,17 +324,13 @@ struct Light : public BaseNode
Light() = delete;
//! Construction from an existing name
explicit Light(const std::string &name)
: BaseNode (BaseNode::Light, name)
, mLightType (OMNI)
, mColor (1.f,1.f,1.f)
, mIntensity (1.f) // light is white by default
, mAngle (45.f)
, mFalloff (0.f)
{
explicit Light(const std::string &name) :
BaseNode(BaseNode::Light, name), mLightType(OMNI), mColor(1.f, 1.f, 1.f), mIntensity(1.f) // light is white by default
,
mAngle(45.f),
mFalloff(0.f) {
}
LightType mLightType;
aiColor3D mColor;
ai_real mIntensity;
@ -359,10 +340,8 @@ struct Light : public BaseNode
// ---------------------------------------------------------------------------
/** Helper structure to represent an ASE camera */
struct Camera : public BaseNode
{
enum CameraType
{
struct Camera : public BaseNode {
enum CameraType {
FREE,
TARGET
};
@ -370,18 +349,16 @@ struct Camera : public BaseNode
//! Default constructor has been deleted
Camera() = delete;
//! Construction from an existing name
explicit Camera(const std::string &name)
: BaseNode (BaseNode::Camera, name)
, mFOV (0.75f) // in radians
, mNear (0.1f)
, mFar (1000.f) // could be zero
, mCameraType (FREE)
{
explicit Camera(const std::string &name) :
BaseNode(BaseNode::Camera, name), mFOV(0.75f) // in radians
,
mNear(0.1f),
mFar(1000.f) // could be zero
,
mCameraType(FREE) {
}
ai_real mFOV, mNear, mFar;
CameraType mCameraType;
};
@ -414,7 +391,6 @@ private:
}
public:
// -------------------------------------------------------------------
//! Construct a parser from a given input file which is
//! guaranteed to be terminated with zero.
@ -428,9 +404,7 @@ public:
//! Parses the file into the parsers internal representation
void Parse();
private:
// -------------------------------------------------------------------
//! Parse the *SCENE block in a file
void ParseLV1SceneBlock();
@ -646,7 +620,6 @@ private:
bool ParseString(std::string &out, const char *szName);
public:
//! Pointer to current data
const char *filePtr;
@ -695,9 +668,8 @@ public:
unsigned int iFileFormat;
};
} // Namespace ASE
} // Namespace ASSIMP
} // namespace Assimp
#endif // ASSIMP_BUILD_NO_3DS_IMPORTER

View File

@ -336,7 +336,7 @@ protected:
void WriteBinaryNode(IOStream *container, const aiNode *node) {
AssbinChunkWriter chunk(container, ASSBIN_CHUNK_AINODE);
unsigned int nb_metadata = (node->mMetaData != NULL ? node->mMetaData->mNumProperties : 0);
unsigned int nb_metadata = (node->mMetaData != nullptr ? node->mMetaData->mNumProperties : 0);
Write<aiString>(&chunk, node->mName);
Write<aiMatrix4x4>(&chunk, node->mTransformation);
@ -744,7 +744,7 @@ public:
};
try {
time_t tt = time(NULL);
time_t tt = time(nullptr);
#if _WIN32
tm *p = gmtime(&tt);
#else
@ -790,7 +790,7 @@ public:
// Up to here the data is uncompressed. For compressed files, the rest
// is compressed using standard DEFLATE from zlib.
if (compressed) {
AssbinChunkWriter uncompressedStream(NULL, 0);
AssbinChunkWriter uncompressedStream(nullptr, 0);
WriteBinaryScene(&uncompressedStream, pScene);
uLongf uncompressedSize = static_cast<uLongf>(uncompressedStream.Tell());

View File

@ -604,7 +604,7 @@ void AssbinImporter::ReadBinaryScene(IOStream *stream, aiScene *scene) {
// Read node graph
//scene->mRootNode = new aiNode[1];
ReadBinaryNode(stream, &scene->mRootNode, (aiNode *)NULL);
ReadBinaryNode(stream, &scene->mRootNode, (aiNode *)nullptr);
// Read all meshes
if (scene->mNumMeshes) {

View File

@ -189,7 +189,7 @@ static std::string encodeXML(const std::string &data) {
// -----------------------------------------------------------------------------------
// Write a text model dump
static void WriteDump(const char *pFile, const char *cmd, const aiScene *scene, IOStream *io, bool shortened) {
time_t tt = ::time(NULL);
time_t tt = ::time(nullptr);
#if _WIN32
tm *p = gmtime(&tt);
#else

View File

@ -422,9 +422,9 @@ void BVHLoader::CreateAnimation(aiScene *pScene) {
anim->mNumChannels = static_cast<unsigned int>(mNodes.size());
anim->mChannels = new aiNodeAnim *[anim->mNumChannels];
// FIX: set the array elements to NULL to ensure proper deletion if an exception is thrown
// FIX: set the array elements to nullptr to ensure proper deletion if an exception is thrown
for (unsigned int i = 0; i < anim->mNumChannels; ++i)
anim->mChannels[i] = NULL;
anim->mChannels[i] = nullptr;
for (unsigned int a = 0; a < anim->mNumChannels; a++) {
const Node &node = mNodes[a];

View File

@ -230,7 +230,7 @@ public:
// --------------------------------------------------------
/** Access a field of the structure by its canonical name. The pointer version
* returns NULL on failure while the reference version raises an import error. */
* returns nullptr on failure while the reference version raises an import error. */
inline const Field &operator[](const std::string &ss) const;
inline const Field *Get(const std::string &ss) const;
@ -359,7 +359,7 @@ private:
template <typename T>
T *_allocate(vector<T> &out, size_t &s) const {
out.resize(s);
return s ? &out.front() : NULL;
return s ? &out.front() : nullptr;
}
// --------------------------------------------------------
@ -367,14 +367,14 @@ private:
struct _defaultInitializer {
template <typename T, unsigned int N>
void operator()(T (&out)[N], const char * = NULL) {
void operator()(T (&out)[N], const char * = nullptr) {
for (unsigned int i = 0; i < N; ++i) {
out[i] = T();
}
}
template <typename T, unsigned int N, unsigned int M>
void operator()(T (&out)[N][M], const char * = NULL) {
void operator()(T (&out)[N][M], const char * = nullptr) {
for (unsigned int i = 0; i < N; ++i) {
for (unsigned int j = 0; j < M; ++j) {
out[i][j] = T();
@ -383,7 +383,7 @@ private:
}
template <typename T>
void operator()(T &out, const char * = NULL) {
void operator()(T &out, const char * = nullptr) {
out = T();
}
};
@ -448,7 +448,7 @@ public:
public:
// --------------------------------------------------------
/** Access a structure by its canonical name, the pointer version returns NULL on failure
/** Access a structure by its canonical name, the pointer version returns nullptr on failure
* while the reference version raises an error. */
inline const Structure &operator[](const std::string &ss) const;
inline const Structure *Get(const std::string &ss) const;

View File

@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2020, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
@ -70,7 +69,7 @@ const Field& Structure :: operator [] (const std::string& ss) const
const Field* Structure :: Get (const std::string& ss) const
{
std::map<std::string, size_t>::const_iterator it = indices.find(ss);
return it == indices.end() ? NULL : &fields[(*it).second];
return it == indices.end() ? nullptr : &fields[(*it).second];
}
//--------------------------------------------------------------------------------
@ -239,11 +238,13 @@ bool Structure :: ReadFieldPtr(TOUT<T> (&out)[N], const char* name,
try {
f = &(*this)[name];
#ifdef _DEBUG
// sanity check, should never happen if the genblenddna script is right
if ((FieldFlag_Pointer|FieldFlag_Pointer) != (f->flags & (FieldFlag_Pointer|FieldFlag_Pointer))) {
throw Error((Formatter::format(),"Field `",name,"` of structure `",
this->name,"` ought to be a pointer AND an array"));
}
#endif // _DEBUG
db.reader->IncPtr(f->offset);

View File

@ -45,27 +45,25 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* @brief Implementation of the Blender3D importer class.
*/
//#define ASSIMP_BUILD_NO_COMPRESSED_BLEND
// Uncomment this to disable support for (gzip)compressed .BLEND files
#ifndef ASSIMP_BUILD_NO_BLEND_IMPORTER
#include "BlenderIntermediate.h"
#include "BlenderModifier.h"
#include "BlenderBMesh.h"
#include "BlenderCustomData.h"
#include "BlenderIntermediate.h"
#include "BlenderModifier.h"
#include <assimp/StringUtils.h>
#include <assimp/scene.h>
#include <assimp/importerdesc.h>
#include <assimp/scene.h>
#include <assimp/StringComparison.h>
#include <assimp/StreamReader.h>
#include <assimp/MemoryIOWrapper.h>
#include <assimp/StreamReader.h>
#include <assimp/StringComparison.h>
#include <cctype>
// zlib is needed for compressed blend files
#ifndef ASSIMP_BUILD_NO_COMPRESSED_BLEND
#ifdef ASSIMP_BUILD_NO_OWN_ZLIB
@ -76,12 +74,12 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endif
namespace Assimp {
template<> const char* LogFunctions<BlenderImporter>::Prefix()
{
template <>
const char *LogFunctions<BlenderImporter>::Prefix() {
static auto prefix = "BLEND: ";
return prefix;
}
}
} // namespace Assimp
using namespace Assimp;
using namespace Assimp::Blender;
@ -100,18 +98,16 @@ static const aiImporterDesc blenderDesc = {
"blend"
};
// ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer
BlenderImporter::BlenderImporter()
: modifier_cache(new BlenderModifierShowcase()) {
BlenderImporter::BlenderImporter() :
modifier_cache(new BlenderModifierShowcase()) {
// empty
}
// ------------------------------------------------------------------------------------------------
// Destructor, private as well
BlenderImporter::~BlenderImporter()
{
BlenderImporter::~BlenderImporter() {
delete modifier_cache;
}
@ -120,8 +116,7 @@ static const char* TokensForSearch[] = { "blender" };
// ------------------------------------------------------------------------------------------------
// Returns whether the class can handle the format of the given file.
bool BlenderImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
{
bool BlenderImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool checkSig) const {
const std::string &extension = GetExtension(pFile);
if (extension == "blend") {
return true;
@ -136,36 +131,30 @@ bool BlenderImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, b
// ------------------------------------------------------------------------------------------------
// List all extensions handled by this loader
void BlenderImporter::GetExtensionList(std::set<std::string>& app)
{
void BlenderImporter::GetExtensionList(std::set<std::string> &app) {
app.insert("blend");
}
// ------------------------------------------------------------------------------------------------
// Loader registry entry
const aiImporterDesc* BlenderImporter::GetInfo () const
{
const aiImporterDesc *BlenderImporter::GetInfo() const {
return &blenderDesc;
}
// ------------------------------------------------------------------------------------------------
// Setup configuration properties for the loader
void BlenderImporter::SetupProperties(const Importer* /*pImp*/)
{
void BlenderImporter::SetupProperties(const Importer * /*pImp*/) {
// nothing to be done for the moment
}
// ------------------------------------------------------------------------------------------------
// Imports the given file into the given scene structure.
void BlenderImporter::InternReadFile(const std::string &pFile,
aiScene* pScene, IOSystem* pIOHandler)
{
aiScene *pScene, IOSystem *pIOHandler) {
#ifndef ASSIMP_BUILD_NO_COMPRESSED_BLEND
std::vector<Bytef> uncompressed;
#endif
FileDatabase file;
std::shared_ptr<IOStream> stream(pIOHandler->Open(pFile, "rb"));
if (!stream) {
@ -227,8 +216,7 @@ void BlenderImporter::InternReadFile( const std::string& pFile,
total += have;
uncompressed.resize(total);
memcpy(uncompressed.data() + total - have, block, have);
}
while (ret != Z_STREAM_END);
} while (ret != Z_STREAM_END);
// terminate zlib
inflateEnd(&zstream);
@ -252,8 +240,7 @@ void BlenderImporter::InternReadFile( const std::string& pFile,
LogInfo((format(), "Blender version is ", magic[0], ".", magic + 1,
" (64bit: ", file.i64bit ? "true" : "false",
", little endian: ",file.little?"true":"false",")"
));
", little endian: ", file.little ? "true" : "false", ")"));
ParseBlendFile(file, stream);
@ -264,14 +251,14 @@ void BlenderImporter::InternReadFile( const std::string& pFile,
}
// ------------------------------------------------------------------------------------------------
void BlenderImporter::ParseBlendFile(FileDatabase& out, std::shared_ptr<IOStream> stream)
{
void BlenderImporter::ParseBlendFile(FileDatabase &out, std::shared_ptr<IOStream> stream) {
out.reader = std::shared_ptr<StreamReaderAny>(new StreamReaderAny(stream, out.little));
DNAParser dna_reader(out);
const DNA* dna = NULL;
const DNA *dna = nullptr;
out.entries.reserve(128); { // even small BLEND files tend to consist of many file blocks
out.entries.reserve(128);
{ // even small BLEND files tend to consist of many file blocks
SectionParser parser(*out.reader.get(), out.i64bit);
// first parse the file in search for the DNA and insert all other sections into the database
@ -280,8 +267,7 @@ void BlenderImporter::ParseBlendFile(FileDatabase& out, std::shared_ptr<IOStream
if (head.id == "ENDB") {
break; // only valid end of the file
}
else if (head.id == "DNA1") {
} else if (head.id == "DNA1") {
dna_reader.Parse();
dna = &dna_reader.GetDNA();
continue;
@ -298,9 +284,8 @@ void BlenderImporter::ParseBlendFile(FileDatabase& out, std::shared_ptr<IOStream
}
// ------------------------------------------------------------------------------------------------
void BlenderImporter::ExtractScene(Scene& out, const FileDatabase& file)
{
const FileBlockHead* block = NULL;
void BlenderImporter::ExtractScene(Scene &out, const FileDatabase &file) {
const FileBlockHead *block = nullptr;
std::map<std::string, size_t>::const_iterator it = file.dna.indices.find("Scene");
if (it == file.dna.indices.end()) {
ThrowException("There is no `Scene` structure record");
@ -332,14 +317,12 @@ void BlenderImporter::ExtractScene(Scene& out, const FileDatabase& file)
"(Stats) Fields read: ", file.stats().fields_read,
", pointers resolved: ", file.stats().pointers_resolved,
", cache hits: ", file.stats().cache_hits,
", cached objects: " ,file.stats().cached_objects
);
", cached objects: ", file.stats().cached_objects);
#endif
}
// ------------------------------------------------------------------------------------------------
void BlenderImporter::ConvertBlendFile(aiScene* out, const Scene& in,const FileDatabase& file)
{
void BlenderImporter::ConvertBlendFile(aiScene *out, const Scene &in, const FileDatabase &file) {
ConversionData conv(file);
// FIXME it must be possible to take the hierarchy directly from
@ -418,9 +401,10 @@ void BlenderImporter::ConvertBlendFile(aiScene* out, const Scene& in,const FileD
}
// ------------------------------------------------------------------------------------------------
void BlenderImporter::ResolveImage(aiMaterial* out, const Material* mat, const MTex* tex, const Image* img, ConversionData& conv_data)
{
(void)mat; (void)tex; (void)conv_data;
void BlenderImporter::ResolveImage(aiMaterial *out, const Material *mat, const MTex *tex, const Image *img, ConversionData &conv_data) {
(void)mat;
(void)tex;
(void)conv_data;
aiString name;
// check if the file contents are bundled with the BLEND file
@ -466,13 +450,11 @@ void BlenderImporter::ResolveImage(aiMaterial* out, const Material* mat, const M
else if (map_type & MTex::MapType_NORM) {
if (tex->tex->imaflag & Tex::ImageFlags_NORMALMAP) {
texture_type = aiTextureType_NORMALS;
}
else {
} else {
texture_type = aiTextureType_HEIGHT;
}
out->AddProperty(&tex->norfac, 1, AI_MATKEY_BUMPSCALING);
}
else if (map_type & MTex::MapType_COLSPEC)
} else if (map_type & MTex::MapType_COLSPEC)
texture_type = aiTextureType_SPECULAR;
else if (map_type & MTex::MapType_COLMIR)
texture_type = aiTextureType_REFLECTION;
@ -493,26 +475,23 @@ void BlenderImporter::ResolveImage(aiMaterial* out, const Material* mat, const M
out->AddProperty(&name, AI_MATKEY_TEXTURE(texture_type,
conv_data.next_texture[texture_type]++));
}
// ------------------------------------------------------------------------------------------------
void BlenderImporter::AddSentinelTexture(aiMaterial* out, const Material* mat, const MTex* tex, ConversionData& conv_data)
{
(void)mat; (void)tex; (void)conv_data;
void BlenderImporter::AddSentinelTexture(aiMaterial *out, const Material *mat, const MTex *tex, ConversionData &conv_data) {
(void)mat;
(void)tex;
(void)conv_data;
aiString name;
name.length = ai_snprintf(name.data, MAXLEN, "Procedural,num=%i,type=%s", conv_data.sentinel_cnt++,
GetTextureTypeDisplayString(tex->tex->type)
);
GetTextureTypeDisplayString(tex->tex->type));
out->AddProperty(&name, AI_MATKEY_TEXTURE_DIFFUSE(
conv_data.next_texture[aiTextureType_DIFFUSE]++)
);
conv_data.next_texture[aiTextureType_DIFFUSE]++));
}
// ------------------------------------------------------------------------------------------------
void BlenderImporter::ResolveTexture(aiMaterial* out, const Material* mat, const MTex* tex, ConversionData& conv_data)
{
void BlenderImporter::ResolveTexture(aiMaterial *out, const Material *mat, const MTex *tex, ConversionData &conv_data) {
const Tex *rtex = tex->tex.get();
if (!rtex || !rtex->type) {
return;
@ -521,8 +500,7 @@ void BlenderImporter::ResolveTexture(aiMaterial* out, const Material* mat, const
// We can't support most of the texture types because they're mostly procedural.
// These are substituted by a dummy texture.
const char *dispnam = "";
switch( rtex->type )
{
switch (rtex->type) {
// these are listed in blender's UI
case Tex::Type_CLOUDS:
case Tex::Type_WOOD:
@ -559,8 +537,7 @@ void BlenderImporter::ResolveTexture(aiMaterial* out, const Material* mat, const
}
// ------------------------------------------------------------------------------------------------
void BlenderImporter::BuildDefaultMaterial(Blender::ConversionData& conv_data)
{
void BlenderImporter::BuildDefaultMaterial(Blender::ConversionData &conv_data) {
// add a default material if necessary
unsigned int index = static_cast<unsigned int>(-1);
for (aiMesh *mesh : conv_data.meshes.get()) {
@ -593,8 +570,7 @@ void BlenderImporter::BuildDefaultMaterial(Blender::ConversionData& conv_data)
}
}
void BlenderImporter::AddBlendParams(aiMaterial* result, const Material* source)
{
void BlenderImporter::AddBlendParams(aiMaterial *result, const Material *source) {
aiColor3D diffuseColor(source->r, source->g, source->b);
result->AddProperty(&diffuseColor, 1, "$mat.blend.diffuse.color", 0, 0);
@ -607,7 +583,6 @@ void BlenderImporter::AddBlendParams(aiMaterial* result, const Material* source)
int diffuseRamp = 0;
result->AddProperty(&diffuseRamp, 1, "$mat.blend.diffuse.ramp", 0, 0);
aiColor3D specularColor(source->specr, source->specg, source->specb);
result->AddProperty(&specularColor, 1, "$mat.blend.specular.color", 0, 0);
@ -623,7 +598,6 @@ void BlenderImporter::AddBlendParams(aiMaterial* result, const Material* source)
int specularHardness = source->har;
result->AddProperty(&specularHardness, 1, "$mat.blend.specular.hardness", 0, 0);
int transparencyUse = source->mode & MA_TRANSPARENCY ? 1 : 0;
result->AddProperty(&transparencyUse, 1, "$mat.blend.transparency.use", 0, 0);
@ -666,7 +640,6 @@ void BlenderImporter::AddBlendParams(aiMaterial* result, const Material* source)
int transparencyGlossSamples = source->samp_gloss_tra;
result->AddProperty(&transparencyGlossSamples, 1, "$mat.blend.transparency.glossSamples", 0, 0);
int mirrorUse = source->mode & MA_RAYMIRROR ? 1 : 0;
result->AddProperty(&mirrorUse, 1, "$mat.blend.mirror.use", 0, 0);
@ -704,8 +677,7 @@ void BlenderImporter::AddBlendParams(aiMaterial* result, const Material* source)
result->AddProperty(&mirrorGlossAnisotropic, 1, "$mat.blend.mirror.glossAnisotropic", 0, 0);
}
void BlenderImporter::BuildMaterials(ConversionData& conv_data)
{
void BlenderImporter::BuildMaterials(ConversionData &conv_data) {
conv_data.materials->reserve(conv_data.materials_raw.size());
BuildDefaultMaterial(conv_data);
@ -773,34 +745,28 @@ void BlenderImporter::BuildMaterials(ConversionData& conv_data)
}
// ------------------------------------------------------------------------------------------------
void BlenderImporter::CheckActualType(const ElemBase* dt, const char* check)
{
void BlenderImporter::CheckActualType(const ElemBase *dt, const char *check) {
ai_assert(dt);
if (strcmp(dt->dna_type, check)) {
ThrowException((format(),
"Expected object at ", std::hex, dt, " to be of type `", check,
"`, but it claims to be a `",dt->dna_type,"`instead"
));
"`, but it claims to be a `", dt->dna_type, "`instead"));
}
}
// ------------------------------------------------------------------------------------------------
void BlenderImporter::NotSupportedObjectType(const Object* obj, const char* type)
{
void BlenderImporter::NotSupportedObjectType(const Object *obj, const char *type) {
LogWarn((format(), "Object `", obj->id.name, "` - type is unsupported: `", type, "`, skipping"));
}
// ------------------------------------------------------------------------------------------------
void BlenderImporter::ConvertMesh(const Scene & /*in*/, const Object * /*obj*/, const Mesh *mesh,
ConversionData& conv_data, TempArray<std::vector,aiMesh>& temp
)
{
ConversionData &conv_data, TempArray<std::vector, aiMesh> &temp) {
// TODO: Resolve various problems with BMesh triangulation before re-enabling.
// See issues #400, #373, #318 #315 and #132.
#if defined(TODO_FIX_BMESH_CONVERSION)
BlenderBMeshConverter BMeshConverter(mesh);
if ( BMeshConverter.ContainsBMesh( ) )
{
if (BMeshConverter.ContainsBMesh()) {
mesh = BMeshConverter.TriangulateBMesh();
}
#endif
@ -874,18 +840,16 @@ void BlenderImporter::ConvertMesh(const Scene& /*in*/, const Object* /*obj*/, co
std::shared_ptr<Material> mat = mesh->mat[it.first];
const std::deque<std::shared_ptr<Material>>::iterator has = std::find(
conv_data.materials_raw.begin(),
conv_data.materials_raw.end(),mat
);
conv_data.materials_raw.end(), mat);
if (has != conv_data.materials_raw.end()) {
out->mMaterialIndex = static_cast<unsigned int>(std::distance(conv_data.materials_raw.begin(), has));
}
else {
} else {
out->mMaterialIndex = static_cast<unsigned int>(conv_data.materials_raw.size());
conv_data.materials_raw.push_back(mat);
}
}
else out->mMaterialIndex = static_cast<unsigned int>( -1 );
} else
out->mMaterialIndex = static_cast<unsigned int>(-1);
}
for (int i = 0; i < mesh->totface; ++i) {
@ -966,8 +930,8 @@ void BlenderImporter::ConvertMesh(const Scene& /*in*/, const Object* /*obj*/, co
++vn;
out->mPrimitiveTypes |= aiPrimitiveType_POLYGON;
}
else out->mPrimitiveTypes |= aiPrimitiveType_TRIANGLE;
} else
out->mPrimitiveTypes |= aiPrimitiveType_TRIANGLE;
// }
// }
@ -990,8 +954,7 @@ void BlenderImporter::ConvertMesh(const Scene& /*in*/, const Object* /*obj*/, co
// which are assigned by the genblenddna.py script and
// cannot be changed without breaking the entire
// import process.
for (int j = 0;j < mf.totloop; ++j)
{
for (int j = 0; j < mf.totloop; ++j) {
const MLoop &loop = mesh->mloop[mf.loopstart + j];
if (loop.v >= mesh->totvert) {
@ -1010,14 +973,10 @@ void BlenderImporter::ConvertMesh(const Scene& /*in*/, const Object* /*obj*/, co
++vo;
++vn;
}
if (mf.totloop == 3)
{
if (mf.totloop == 3) {
out->mPrimitiveTypes |= aiPrimitiveType_TRIANGLE;
}
else
{
} else {
out->mPrimitiveTypes |= aiPrimitiveType_POLYGON;
}
}
@ -1056,13 +1015,13 @@ void BlenderImporter::ConvertMesh(const Scene& /*in*/, const Object* /*obj*/, co
ThrowException("Number of UV faces is larger than the corresponding UV face array (#1)");
}
for (std::vector<aiMesh *>::iterator it = temp->begin() + old; it != temp->end(); ++it) {
ai_assert((*it)->mNumVertices && (*it)->mNumFaces);
ai_assert(0 != (*it)->mNumVertices);
ai_assert(0 != (*it)->mNumFaces);
const auto itMatTexUvMapping = matTexUvMappings.find((*it)->mMaterialIndex);
if (itMatTexUvMapping == matTexUvMappings.end()) {
// default behaviour like before
(*it)->mTextureCoords[0] = new aiVector3D[(*it)->mNumVertices];
}
else {
} else {
// create texture coords for every mapped tex
for (uint32_t i = 0; i < itMatTexUvMapping->second.size(); ++i) {
(*it)->mTextureCoords[i] = new aiVector3D[(*it)->mNumVertices];
@ -1125,7 +1084,8 @@ void BlenderImporter::ConvertMesh(const Scene& /*in*/, const Object* /*obj*/, co
ThrowException("Number of faces is larger than the corresponding UV face array (#2)");
}
for (std::vector<aiMesh *>::iterator it = temp->begin() + old; it != temp->end(); ++it) {
ai_assert((*it)->mNumVertices && (*it)->mNumFaces);
ai_assert(0 != (*it)->mNumVertices);
ai_assert(0 != (*it)->mNumFaces);
(*it)->mTextureCoords[0] = new aiVector3D[(*it)->mNumVertices];
(*it)->mNumFaces = (*it)->mNumVertices = 0;
@ -1151,7 +1111,8 @@ void BlenderImporter::ConvertMesh(const Scene& /*in*/, const Object* /*obj*/, co
ThrowException("Number of faces is larger than the corresponding color face array");
}
for (std::vector<aiMesh *>::iterator it = temp->begin() + old; it != temp->end(); ++it) {
ai_assert((*it)->mNumVertices && (*it)->mNumFaces);
ai_assert(0 != (*it)->mNumVertices);
ai_assert(0 != (*it)->mNumFaces);
(*it)->mColors[0] = new aiColor4D[(*it)->mNumVertices];
(*it)->mNumFaces = (*it)->mNumVertices = 0;
@ -1171,7 +1132,8 @@ void BlenderImporter::ConvertMesh(const Scene& /*in*/, const Object* /*obj*/, co
vo->b = col->b;
vo->a = col->a;
}
for (unsigned int n = f.mNumIndices; n < 4; ++n);
for (unsigned int n = f.mNumIndices; n < 4; ++n)
;
}
for (int i = 0; i < mesh->totpoly; ++i) {
@ -1188,17 +1150,14 @@ void BlenderImporter::ConvertMesh(const Scene& /*in*/, const Object* /*obj*/, co
vo->b = ai_real(col.b) * scaleZeroToOne;
vo->a = ai_real(col.a) * scaleZeroToOne;
}
}
}
return;
}
// ------------------------------------------------------------------------------------------------
aiCamera* BlenderImporter::ConvertCamera(const Scene& /*in*/, const Object* obj, const Camera* cam, ConversionData& /*conv_data*/)
{
aiCamera *BlenderImporter::ConvertCamera(const Scene & /*in*/, const Object *obj, const Camera *cam, ConversionData & /*conv_data*/) {
std::unique_ptr<aiCamera> out(new aiCamera());
out->mName = obj->id.name + 2;
out->mPosition = aiVector3D(0.f, 0.f, 0.f);
@ -1214,13 +1173,11 @@ aiCamera* BlenderImporter::ConvertCamera(const Scene& /*in*/, const Object* obj,
}
// ------------------------------------------------------------------------------------------------
aiLight* BlenderImporter::ConvertLight(const Scene& /*in*/, const Object* obj, const Lamp* lamp, ConversionData& /*conv_data*/)
{
aiLight *BlenderImporter::ConvertLight(const Scene & /*in*/, const Object *obj, const Lamp *lamp, ConversionData & /*conv_data*/) {
std::unique_ptr<aiLight> out(new aiLight());
out->mName = obj->id.name + 2;
switch (lamp->type)
{
switch (lamp->type) {
case Lamp::Type_Local:
out->mType = aiLightSource_POINT;
break;
@ -1247,8 +1204,7 @@ aiLight* BlenderImporter::ConvertLight(const Scene& /*in*/, const Object* obj, c
if (lamp->area_shape == 0) {
out->mSize = aiVector2D(lamp->area_size, lamp->area_size);
}
else {
} else {
out->mSize = aiVector2D(lamp->area_size, lamp->area_sizey);
}
@ -1268,14 +1224,11 @@ aiLight* BlenderImporter::ConvertLight(const Scene& /*in*/, const Object* obj, c
// If default values are supplied, compute the coefficients from light's max distance
// Read this: https://imdoingitwrong.wordpress.com/2011/01/31/light-attenuation/
//
if (lamp->constant_coefficient == 1.0f && lamp->linear_coefficient == 0.0f && lamp->quadratic_coefficient == 0.0f && lamp->dist > 0.0f)
{
if (lamp->constant_coefficient == 1.0f && lamp->linear_coefficient == 0.0f && lamp->quadratic_coefficient == 0.0f && lamp->dist > 0.0f) {
out->mAttenuationConstant = 1.0f;
out->mAttenuationLinear = 2.0f / lamp->dist;
out->mAttenuationQuadratic = 1.0f / (lamp->dist * lamp->dist);
}
else
{
} else {
out->mAttenuationConstant = lamp->constant_coefficient;
out->mAttenuationLinear = lamp->linear_coefficient;
out->mAttenuationQuadratic = lamp->quadratic_coefficient;
@ -1285,8 +1238,7 @@ aiLight* BlenderImporter::ConvertLight(const Scene& /*in*/, const Object* obj, c
}
// ------------------------------------------------------------------------------------------------
aiNode* BlenderImporter::ConvertNode(const Scene& in, const Object* obj, ConversionData& conv_data, const aiMatrix4x4& parentTransform)
{
aiNode *BlenderImporter::ConvertNode(const Scene &in, const Object *obj, ConversionData &conv_data, const aiMatrix4x4 &parentTransform) {
std::deque<const Object *> children;
for (ObjectSet::iterator it = conv_data.objects.begin(); it != conv_data.objects.end();) {
const Object *object = *it;
@ -1301,12 +1253,10 @@ aiNode* BlenderImporter::ConvertNode(const Scene& in, const Object* obj, Convers
std::unique_ptr<aiNode> node(new aiNode(obj->id.name + 2)); // skip over the name prefix 'OB'
if (obj->data) {
switch (obj->type)
{
switch (obj->type) {
case Object ::Type_EMPTY:
break; // do nothing
// supported object types
case Object ::Type_MESH: {
const size_t old = conv_data.meshes->size();
@ -1319,27 +1269,24 @@ aiNode* BlenderImporter::ConvertNode(const Scene& in, const Object* obj, Convers
for (unsigned int i = 0; i < node->mNumMeshes; ++i) {
node->mMeshes[i] = static_cast<unsigned int>(i + old);
}
}}
break;
}
} break;
case Object ::Type_LAMP: {
CheckActualType(obj->data.get(), "Lamp");
aiLight* mesh = ConvertLight(in,obj,static_cast<const Lamp*>(
obj->data.get()),conv_data);
aiLight *mesh = ConvertLight(in, obj, static_cast<const Lamp *>(obj->data.get()), conv_data);
if (mesh) {
conv_data.lights->push_back(mesh);
}}
break;
}
} break;
case Object ::Type_CAMERA: {
CheckActualType(obj->data.get(), "Camera");
aiCamera* mesh = ConvertCamera(in,obj,static_cast<const Camera*>(
obj->data.get()),conv_data);
aiCamera *mesh = ConvertCamera(in, obj, static_cast<const Camera *>(obj->data.get()), conv_data);
if (mesh) {
conv_data.cameras->push_back(mesh);
}}
break;
}
} break;
// unsupported object types / log, but do not break
case Object ::Type_CURVE:

View File

@ -322,7 +322,9 @@ aiNode *COBImporter::BuildNodes(const Node &root, const Scene &scin, aiScene *fi
break;
default:
ASSIMP_LOG_ERROR("Unknown option.");
ai_assert(false); // shouldn't be here
break;
}
mat->AddProperty(&shader, 1, AI_MATKEY_SHADING_MODEL);
if (shader != aiShadingMode_Gouraud) {

View File

@ -127,7 +127,7 @@ void CSMImporter::InternReadFile( const std::string& pFile,
std::unique_ptr<IOStream> file( pIOHandler->Open( pFile, "rb"));
// Check whether we can read from the file
if( file.get() == NULL) {
if( file.get() == nullptr) {
throw DeadlyImportError( "Failed to open CSM file " + pFile + ".");
}

View File

@ -298,14 +298,14 @@ struct Accessor {
size_t mSubOffset[4]; // Suboffset inside the object for the common 4 elements. For a vector, that's XYZ, for a color RGBA and so on.
// For example, SubOffset[0] denotes which of the values inside the object is the vector X component.
std::string mSource; // URL of the source array
mutable const Data *mData; // Pointer to the source array, if resolved. NULL else
mutable const Data *mData; // Pointer to the source array, if resolved. nullptr else
Accessor() {
mCount = 0;
mSize = 0;
mOffset = 0;
mStride = 0;
mData = NULL;
mData = nullptr;
mSubOffset[0] = mSubOffset[1] = mSubOffset[2] = mSubOffset[3] = 0;
}
};
@ -321,13 +321,13 @@ struct InputChannel {
size_t mIndex; // Optional index, if multiple sets of the same data type are given
size_t mOffset; // Index offset in the indices array of per-face indices. Don't ask, can't explain that any better.
std::string mAccessor; // ID of the accessor where to read the actual values from.
mutable const Accessor *mResolved; // Pointer to the accessor, if resolved. NULL else
mutable const Accessor *mResolved; // Pointer to the accessor, if resolved. nullptr else
InputChannel() {
mType = IT_Invalid;
mIndex = 0;
mOffset = 0;
mResolved = NULL;
mResolved = nullptr;
}
};

View File

@ -145,7 +145,7 @@ bool ColladaLoader::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool
if (extension == "xml" || !extension.length() || checkSig) {
/* If CanRead() is called in order to check whether we
* support a specific file extension in general pIOHandler
* might be NULL and it's our duty to return true here.
* might be nullptr and it's our duty to return true here.
*/
if (!pIOHandler) {
return true;
@ -316,7 +316,7 @@ void ColladaLoader::ResolveNodeInstances(const ColladaParser &pParser, const Col
for (const auto &nodeInst : pNode->mNodeInstances) {
// find the corresponding node in the library
const ColladaParser::NodeLibrary::const_iterator itt = pParser.mNodeLibrary.find(nodeInst.mNode);
const Collada::Node *nd = itt == pParser.mNodeLibrary.end() ? NULL : (*itt).second;
const Collada::Node *nd = itt == pParser.mNodeLibrary.end() ? nullptr : (*itt).second;
// FIX for http://sourceforge.net/tracker/?func=detail&aid=3054873&group_id=226462&atid=1067632
// need to check for both name and ID to catch all. To avoid breaking valid files,
@ -716,7 +716,7 @@ aiMesh *ColladaLoader::CreateMesh(const ColladaParser &pParser, const Collada::M
if (targetMesh->mSubMeshes.size() > 1) {
throw DeadlyImportError("Morphing target mesh must be a single");
}
aimesh = CreateMesh(pParser, targetMesh, targetMesh->mSubMeshes.at(0), NULL, 0, 0);
aimesh = CreateMesh(pParser, targetMesh, targetMesh->mSubMeshes.at(0), nullptr, 0, 0);
mTargetMeshes.push_back(aimesh);
}
targetMeshes.push_back(aimesh);
@ -1000,7 +1000,7 @@ void ColladaLoader::StoreAnimations(aiScene *pScene, const ColladaParser &pParse
combinedAnim->mChannels = new aiNodeAnim *[combinedAnim->mNumChannels];
// add the template anim as first channel by moving its aiNodeAnim to the combined animation
combinedAnim->mChannels[0] = templateAnim->mChannels[0];
templateAnim->mChannels[0] = NULL;
templateAnim->mChannels[0] = nullptr;
delete templateAnim;
// combined animation replaces template animation in the anim array
mAnims[a] = combinedAnim;
@ -1009,7 +1009,7 @@ void ColladaLoader::StoreAnimations(aiScene *pScene, const ColladaParser &pParse
for (size_t b = 0; b < collectedAnimIndices.size(); ++b) {
aiAnimation *srcAnimation = mAnims[collectedAnimIndices[b]];
combinedAnim->mChannels[1 + b] = srcAnimation->mChannels[0];
srcAnimation->mChannels[0] = NULL;
srcAnimation->mChannels[0] = nullptr;
delete srcAnimation;
}
@ -1116,9 +1116,9 @@ void ColladaLoader::CreateAnimation(aiScene *pScene, const ColladaParser &pParse
// find the collada node corresponding to the aiNode
const Collada::Node *srcNode = FindNode(pParser.mRootNode, nodeName);
// ai_assert( srcNode != NULL);
if (!srcNode)
if (!srcNode) {
continue;
}
// now check all channels if they affect the current node
std::string targetID, subElement;
@ -1132,8 +1132,9 @@ void ColladaLoader::CreateAnimation(aiScene *pScene, const ColladaParser &pParse
std::string::size_type slashPos = srcChannel.mTarget.find('/');
if (slashPos == std::string::npos) {
std::string::size_type targetPos = srcChannel.mTarget.find(srcNode->mID);
if (targetPos == std::string::npos)
if (targetPos == std::string::npos) {
continue;
}
// not node transform, but something else. store as unknown animation channel for now
entry.mChannel = &(*cit);
@ -1777,11 +1778,12 @@ const Collada::Node *ColladaLoader::FindNode(const Collada::Node *pNode, const s
for (size_t a = 0; a < pNode->mChildren.size(); ++a) {
const Collada::Node *node = FindNode(pNode->mChildren[a], pName);
if (node)
if (node) {
return node;
}
}
return NULL;
return nullptr;
}
// ------------------------------------------------------------------------------------------------

View File

@ -86,7 +86,7 @@ ColladaParser::ColladaParser(IOSystem *pIOHandler, const std::string &pFile) :
mFormat(FV_1_5_n) {
// validate io-handler instance
if (nullptr == pIOHandler) {
throw DeadlyImportError("IOSystem is NULL.");
throw DeadlyImportError("IOSystem is nullptr.");
}
std::unique_ptr<IOStream> daefile;
@ -314,6 +314,7 @@ void ColladaParser::ReadContents(XmlNode &node) {
// ------------------------------------------------------------------------------------------------
// Reads the structure of the file
<<<<<<< HEAD
void ColladaParser::ReadStructure(XmlNode &node) {
for (pugi::xml_node curNode : node.children()) {
const std::string name = std::string(curNode.name());
@ -380,6 +381,44 @@ void ColladaParser::ReadStructure(XmlNode &node) {
} else if (mReader->getNodeType() == irr::io::EXN_ELEMENT_END) {
break;
}*/
=======
void ColladaParser::ReadStructure() {
while (mReader->read()) {
// beginning of elements
if (mReader->getNodeType() == irr::io::EXN_ELEMENT) {
if (IsElement("asset"))
ReadAssetInfo();
else if (IsElement("library_animations"))
ReadAnimationLibrary();
else if (IsElement("library_animation_clips"))
ReadAnimationClipLibrary();
else if (IsElement("library_controllers"))
ReadControllerLibrary();
else if (IsElement("library_images"))
ReadImageLibrary();
else if (IsElement("library_materials"))
ReadMaterialLibrary();
else if (IsElement("library_effects"))
ReadEffectLibrary();
else if (IsElement("library_geometries"))
ReadGeometryLibrary();
else if (IsElement("library_visual_scenes"))
ReadSceneLibrary();
else if (IsElement("library_lights"))
ReadLightLibrary();
else if (IsElement("library_cameras"))
ReadCameraLibrary();
else if (IsElement("library_nodes"))
ReadSceneNode(nullptr); /* some hacking to reuse this piece of code */
else if (IsElement("scene"))
ReadScene();
else
SkipElement();
} else if (mReader->getNodeType() == irr::io::EXN_ELEMENT_END) {
break;
}
}
>>>>>>> master
PostProcessRootAnimations();
PostProcessControllers();
@ -726,7 +765,7 @@ void ColladaParser::ReadAnimation(XmlNode &node, Collada::Animation *pParent) {
typedef std::map<std::string, AnimationChannel> ChannelMap;
ChannelMap channels;
// this is the anim container in case we're a container
Animation *anim = NULL;
Animation *anim = nullptr;
// optional name given as an attribute
std::string animName;
@ -1933,9 +1972,6 @@ void ColladaParser::ReadGeometryLibrary(XmlNode &node) {
int indexID = GetAttribute("id");
std::string id = mReader->getAttributeValue(indexID);
// TODO: (thom) support SIDs
// ai_assert( TestAttribute( "sid") == -1);
// create a mesh and store it in the library under its (resolved) ID
// Skip and warn if ID is not unique
if (mMeshLibrary.find(id) == mMeshLibrary.cend()) {
@ -2555,7 +2591,7 @@ size_t ColladaParser::ReadPrimitives(XmlNode &node, Mesh &pMesh, std::vector<Inp
return numPrimitives;
}
///@note This function willn't work correctly if both PerIndex and PerVertex channels have same channels.
///@note This function won't work correctly if both PerIndex and PerVertex channels have same channels.
///For example if TEXCOORD present in both <vertices> and <polylist> tags this function will create wrong uv coordinates.
///It's not clear from COLLADA documentation is this allowed or not. For now only exporter fixed to avoid such behavior
void ColladaParser::CopyVertex(size_t currentVertex, size_t numOffsets, size_t numPoints, size_t perVertexOffset, Mesh &pMesh,
@ -2760,8 +2796,6 @@ void ColladaParser::ReadSceneNode(XmlNode &node, Node *pNode) {
if (attrName > -1)
child->mName = mReader->getAttributeValue(attrName);
// TODO: (thom) support SIDs
// ai_assert( TestAttribute( "sid") == -1);
if (pNode) {
pNode->mChildren.push_back(child);
@ -2792,7 +2826,7 @@ void ColladaParser::ReadSceneNode(XmlNode &node, Node *pNode) {
ReadNodeTransformation(pNode, TF_SKEW);
else if (IsElement("translate"))
ReadNodeTransformation(pNode, TF_TRANSLATE);
else if (IsElement("render") && pNode->mParent == NULL && 0 == pNode->mPrimaryCamera.length()) {
else if (IsElement("render") && pNode->mParent == nullptr && 0 == pNode->mPrimaryCamera.length()) {
// ... scene evaluation or, in other words, postprocessing pipeline,
// or, again in other words, a turing-complete description how to
// render a Collada scene. The only thing that is interesting for
@ -3156,17 +3190,19 @@ const char *ColladaParser::GetTextContent() {
}
// ------------------------------------------------------------------------------------------------
// Reads the text contents of an element, returns NULL if not given. Skips leading whitespace.
// Reads the text contents of an element, returns nullptr if not given. Skips leading whitespace.
const char *ColladaParser::TestTextContent() {
// present node should be the beginning of an element
if (mReader->getNodeType() != irr::io::EXN_ELEMENT || mReader->isEmptyElement())
return NULL;
return nullptr;
// read contents of the element
if (!mReader->read())
return NULL;
if (mReader->getNodeType() != irr::io::EXN_TEXT && mReader->getNodeType() != irr::io::EXN_CDATA)
return NULL;
if (!mReader->read()) {
return nullptr;
}
if (mReader->getNodeType() != irr::io::EXN_TEXT && mReader->getNodeType() != irr::io::EXN_CDATA) {
return nullptr;
}
// skip leading whitespace
const char *text = mReader->getNodeData();

View File

@ -273,7 +273,7 @@ protected:
Skips leading whitespace. */
const char *GetTextContent();
/** Reads the text contents of an element, returns NULL if not given.
/** Reads the text contents of an element, returns nullptr if not given.
Skips leading whitespace. */
const char *TestTextContent();

View File

@ -47,10 +47,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef ASSIMP_BUILD_NO_FBX_IMPORTER
#include "FBXParser.h"
#include "FBXDocument.h"
#include "FBXImporter.h"
#include "FBXDocumentUtil.h"
#include "FBXImporter.h"
#include "FBXParser.h"
namespace Assimp {
namespace FBX {
@ -58,9 +58,8 @@ namespace FBX {
using namespace Util;
// ------------------------------------------------------------------------------------------------
AnimationCurve::AnimationCurve(uint64_t id, const Element& element, const std::string& name, const Document& /*doc*/)
: Object(id, element, name)
{
AnimationCurve::AnimationCurve(uint64_t id, const Element &element, const std::string &name, const Document & /*doc*/) :
Object(id, element, name) {
const Scope &sc = GetRequiredScope(element);
const Element &KeyTime = GetRequiredElement(sc, "KeyTime");
const Element &KeyValueFloat = GetRequiredElement(sc, "KeyValueFloat");
@ -89,19 +88,15 @@ AnimationCurve::AnimationCurve(uint64_t id, const Element& element, const std::s
}
// ------------------------------------------------------------------------------------------------
AnimationCurve::~AnimationCurve()
{
AnimationCurve::~AnimationCurve() {
// empty
}
// ------------------------------------------------------------------------------------------------
AnimationCurveNode::AnimationCurveNode(uint64_t id, const Element &element, const std::string &name,
const Document& doc, const char* const * target_prop_whitelist /*= NULL*/,
size_t whitelist_size /*= 0*/)
: Object(id, element, name)
, target()
, doc(doc)
{
const Document &doc, const char *const *target_prop_whitelist /*= nullptr*/,
size_t whitelist_size /*= 0*/) :
Object(id, element, name), target(), doc(doc) {
const Scope &sc = GetRequiredScope(element);
// find target node
@ -136,8 +131,6 @@ AnimationCurveNode::AnimationCurveNode(uint64_t id, const Element& element, cons
continue;
}
// XXX support constraints as DOM class
//ai_assert(dynamic_cast<const Model*>(ob) || dynamic_cast<const NodeAttribute*>(ob));
target = ob;
if (!target) {
continue;
@ -155,14 +148,12 @@ AnimationCurveNode::AnimationCurveNode(uint64_t id, const Element& element, cons
}
// ------------------------------------------------------------------------------------------------
AnimationCurveNode::~AnimationCurveNode()
{
AnimationCurveNode::~AnimationCurveNode() {
// empty
}
// ------------------------------------------------------------------------------------------------
const AnimationCurveMap& AnimationCurveNode::Curves() const
{
const AnimationCurveMap &AnimationCurveNode::Curves() const {
if (curves.empty()) {
// resolve attached animation curves
const std::vector<const Connection *> &conns = doc.GetConnectionsByDestinationSequenced(ID(), "AnimationCurve");
@ -175,13 +166,13 @@ const AnimationCurveMap& AnimationCurveNode::Curves() const
}
const Object *const ob = con->SourceObject();
if(!ob) {
if (nullptr == ob) {
DOMWarning("failed to read source object for AnimationCurve->AnimationCurveNode link, ignoring", &element);
continue;
}
const AnimationCurve *const anim = dynamic_cast<const AnimationCurve *>(ob);
if(!anim) {
if (nullptr == anim) {
DOMWarning("source object for ->AnimationCurveNode link is not an AnimationCurve", &element);
continue;
}
@ -194,10 +185,8 @@ const AnimationCurveMap& AnimationCurveNode::Curves() const
}
// ------------------------------------------------------------------------------------------------
AnimationLayer::AnimationLayer(uint64_t id, const Element& element, const std::string& name, const Document& doc)
: Object(id, element, name)
, doc(doc)
{
AnimationLayer::AnimationLayer(uint64_t id, const Element &element, const std::string &name, const Document &doc) :
Object(id, element, name), doc(doc) {
const Scope &sc = GetRequiredScope(element);
// note: the props table here bears little importance and is usually absent
@ -205,15 +194,13 @@ AnimationLayer::AnimationLayer(uint64_t id, const Element& element, const std::s
}
// ------------------------------------------------------------------------------------------------
AnimationLayer::~AnimationLayer()
{
AnimationLayer::~AnimationLayer() {
// empty
}
// ------------------------------------------------------------------------------------------------
AnimationCurveNodeList AnimationLayer::Nodes(const char* const * target_prop_whitelist /*= NULL*/,
size_t whitelist_size /*= 0*/) const
{
AnimationCurveNodeList AnimationLayer::Nodes(const char *const *target_prop_whitelist /*= nullptr*/,
size_t whitelist_size /*= 0*/) const {
AnimationCurveNodeList nodes;
// resolve attached animation nodes
@ -259,9 +246,8 @@ AnimationCurveNodeList AnimationLayer::Nodes(const char* const * target_prop_whi
}
// ------------------------------------------------------------------------------------------------
AnimationStack::AnimationStack(uint64_t id, const Element& element, const std::string& name, const Document& doc)
: Object(id, element, name)
{
AnimationStack::AnimationStack(uint64_t id, const Element &element, const std::string &name, const Document &doc) :
Object(id, element, name) {
const Scope &sc = GetRequiredScope(element);
// note: we don't currently use any of these properties so we shouldn't bother if it is missing
@ -294,12 +280,11 @@ AnimationStack::AnimationStack(uint64_t id, const Element& element, const std::s
}
// ------------------------------------------------------------------------------------------------
AnimationStack::~AnimationStack()
{
AnimationStack::~AnimationStack() {
// empty
}
} //!FBX
} //!Assimp
} // namespace FBX
} // namespace Assimp
#endif // ASSIMP_BUILD_NO_FBX_IMPORTER

View File

@ -804,11 +804,6 @@ bool FBXConverter::GenerateTransformationNodeChain(const Model &model, const std
aiMatrix4x4::Translation(-GeometricTranslation, chain[TransformationComp_GeometricTranslationInverse]);
}
// is_complex needs to be consistent with NeedsComplexTransformationChain()
// or the interplay between this code and the animation converter would
// not be guaranteed.
//ai_assert(NeedsComplexTransformationChain(model) == ((chainBits & chainMaskComplex) != 0));
// now, if we have more than just Translation, Scaling and Rotation,
// we need to generate a full node chain to accommodate for assimp's
// lack to express pivots and offsets.
@ -1163,7 +1158,8 @@ unsigned int FBXConverter::ConvertMeshSingleMaterial(const MeshGeometry &mesh, c
const std::vector<aiVector3D> &curVertices = shapeGeometry->GetVertices();
const std::vector<aiVector3D> &curNormals = shapeGeometry->GetNormals();
const std::vector<unsigned int> &curIndices = shapeGeometry->GetIndices();
animMesh->mName.Set(FixAnimMeshName(shapeGeometry->Name()));
//losing channel name if using shapeGeometry->Name()
animMesh->mName.Set(FixAnimMeshName(blendShapeChannel->Name()));
for (size_t j = 0; j < curIndices.size(); j++) {
const unsigned int curIndex = curIndices.at(j);
aiVector3D vertex = curVertices.at(j);
@ -1289,7 +1285,8 @@ unsigned int FBXConverter::ConvertMeshMultiMaterial(const MeshGeometry &mesh, co
}
if (binormals) {
ai_assert(tangents.size() == vertices.size() && binormals->size() == vertices.size());
ai_assert(tangents.size() == vertices.size());
ai_assert(binormals->size() == vertices.size());
out_mesh->mTangents = new aiVector3D[vertices.size()];
out_mesh->mBitangents = new aiVector3D[vertices.size()];
@ -3164,7 +3161,8 @@ FBXConverter::KeyFrameListList FBXConverter::GetKeyframeList(const std::vector<c
}
const AnimationCurve *const curve = kv.second;
ai_assert(curve->GetKeys().size() == curve->GetValues().size() && curve->GetKeys().size());
ai_assert(curve->GetKeys().size() == curve->GetValues().size());
ai_assert(curve->GetKeys().size());
//get values within the start/stop time window
std::shared_ptr<KeyTimeList> Keys(new KeyTimeList());

View File

@ -220,8 +220,8 @@ private:
* each output vertex the DOM index it maps to.
*/
void ConvertWeights(aiMesh *out, const MeshGeometry &geo, const aiMatrix4x4 &absolute_transform,
aiNode *parent = NULL, unsigned int materialIndex = NO_MATERIAL_SEPARATION,
std::vector<unsigned int> *outputVertStartIndices = NULL);
aiNode *parent = nullptr, unsigned int materialIndex = NO_MATERIAL_SEPARATION,
std::vector<unsigned int> *outputVertStartIndices = nullptr);
// ------------------------------------------------------------------------------------------------
void ConvertCluster(std::vector<aiBone *> &local_mesh_bones, const Cluster *cl,

View File

@ -221,7 +221,7 @@ const Object* LazyObject::Get(bool dieOnError)
if(!DefaultLogger::isNullLogger()) {
ASSIMP_LOG_ERROR(ex.what());
}
return NULL;
return nullptr;
}
if (!object.get()) {
@ -467,7 +467,7 @@ void Document::ReadPropertyTemplates()
const Element *Properties70 = (*innerSc)["Properties70"];
if(Properties70) {
std::shared_ptr<const PropertyTable> props = std::make_shared<const PropertyTable>(
*Properties70,std::shared_ptr<const PropertyTable>(static_cast<const PropertyTable*>(NULL))
*Properties70, std::shared_ptr<const PropertyTable>(static_cast<const PropertyTable *>(nullptr))
);
templates[oname+"."+pname] = props;

View File

@ -96,7 +96,7 @@ public:
template <typename T>
const T* Get(bool dieOnError = false) {
const Object* const ob = Get(dieOnError);
return ob ? dynamic_cast<const T*>(ob) : NULL;
return ob ? dynamic_cast<const T *>(ob) : nullptr;
}
uint64_t ID() const {
@ -213,7 +213,8 @@ private:
type name() const { \
const int ival = PropertyGet<int>(Props(), fbx_stringize(name), static_cast<int>(default_value)); \
if (ival < 0 || ival >= AI_CONCAT(type, _MAX)) { \
ai_assert(static_cast<int>(default_value) >= 0 && static_cast<int>(default_value) < AI_CONCAT(type, _MAX)); \
ai_assert(static_cast<int>(default_value) >= 0); \
ai_assert(static_cast<int>(default_value) < AI_CONCAT(type, _MAX)); \
return static_cast<type>(default_value); \
} \
return static_cast<type>(ival); \
@ -744,7 +745,7 @@ public:
wants animations for. If the curve node does not match one of these, std::range_error
will be thrown. */
AnimationCurveNode(uint64_t id, const Element& element, const std::string& name, const Document& doc,
const char* const * target_prop_whitelist = NULL, size_t whitelist_size = 0);
const char *const *target_prop_whitelist = nullptr, size_t whitelist_size = 0);
virtual ~AnimationCurveNode();
@ -756,7 +757,7 @@ public:
const AnimationCurveMap& Curves() const;
/** Object the curve is assigned to, this can be NULL if the
/** Object the curve is assigned to, this can be nullptr if the
* target object has no DOM representation or could not
* be read for other reasons.*/
const Object* Target() const {
@ -968,7 +969,7 @@ public:
// note: a connection ensures that the source and dest objects exist, but
// not that they have DOM representations, so the return value of one of
// these functions can still be NULL.
// these functions can still be nullptr.
const Object* SourceObject() const;
const Object* DestinationObject() const;

View File

@ -65,7 +65,7 @@ void DOMError(const std::string& message, const Token& token)
}
// ------------------------------------------------------------------------------------------------
void DOMError(const std::string& message, const Element* element /*= NULL*/)
void DOMError(const std::string& message, const Element* element /*= nullptr*/)
{
if(element) {
DOMError(message,element->KeyToken());
@ -84,7 +84,7 @@ void DOMWarning(const std::string& message, const Token& token)
}
// ------------------------------------------------------------------------------------------------
void DOMWarning(const std::string& message, const Element* element /*= NULL*/)
void DOMWarning(const std::string& message, const Element* element /*= nullptr*/)
{
if(element) {
DOMWarning(message,element->KeyToken());
@ -106,7 +106,7 @@ std::shared_ptr<const PropertyTable> GetPropertyTable(const Document& doc,
{
const Element* const Properties70 = sc["Properties70"];
std::shared_ptr<const PropertyTable> templateProps = std::shared_ptr<const PropertyTable>(
static_cast<const PropertyTable*>(NULL));
static_cast<const PropertyTable *>(nullptr));
if(templateName.length()) {
PropertyTemplateMap::const_iterator it = doc.Templates().find(templateName);

View File

@ -241,7 +241,7 @@ const MatIndexArray& MeshGeometry::GetMaterialIndices() const {
// ------------------------------------------------------------------------------------------------
const unsigned int* MeshGeometry::ToOutputVertexIndex( unsigned int in_index, unsigned int& count ) const {
if ( in_index >= m_mapping_counts.size() ) {
return NULL;
return nullptr;
}
ai_assert( m_mapping_counts.size() == m_mapping_offsets.size() );

View File

@ -61,10 +61,10 @@ public:
Geometry( uint64_t id, const Element& element, const std::string& name, const Document& doc );
virtual ~Geometry();
/** Get the Skin attached to this geometry or NULL */
/** Get the Skin attached to this geometry or nullptr */
const Skin* DeformerSkin() const;
/** Get the BlendShape attached to this geometry or NULL */
/** Get the BlendShape attached to this geometry or nullptr */
const std::vector<const BlendShape*>& GetBlendShapes() const;
private:
@ -123,7 +123,7 @@ public:
/** Get per-face-vertex material assignments */
const MatIndexArray& GetMaterialIndices() const;
/** Convert from a fbx file vertex index (for example from a #Cluster weight) or NULL
/** Convert from a fbx file vertex index (for example from a #Cluster weight) or nullptr
* if the vertex index is not valid. */
const unsigned int* ToOutputVertexIndex( unsigned int in_index, unsigned int& count ) const;

View File

@ -77,7 +77,7 @@ namespace {
}
// ------------------------------------------------------------------------------------------------
AI_WONT_RETURN void ParseError(const std::string& message, const Element* element = NULL) AI_WONT_RETURN_SUFFIX;
AI_WONT_RETURN void ParseError(const std::string &message, const Element *element = nullptr) AI_WONT_RETURN_SUFFIX;
AI_WONT_RETURN void ParseError(const std::string& message, const Element* element)
{
if(element) {
@ -181,7 +181,7 @@ Scope::Scope(Parser& parser,bool topLevel)
}
TokenPtr n = parser.AdvanceToNextToken();
if(n == NULL) {
if (n == nullptr) {
ParseError("unexpected end of file");
}
@ -196,7 +196,7 @@ Scope::Scope(Parser& parser,bool topLevel)
// Element() should stop at the next Key token (or right after a Close token)
n = parser.CurrentToken();
if(n == NULL) {
if (n == nullptr) {
if (topLevel) {
return;
}
@ -236,7 +236,7 @@ TokenPtr Parser::AdvanceToNextToken()
{
last = current;
if (cursor == tokens.end()) {
current = NULL;
current = nullptr;
} else {
current = *cursor++;
}
@ -258,7 +258,7 @@ TokenPtr Parser::LastToken() const
// ------------------------------------------------------------------------------------------------
uint64_t ParseTokenAsID(const Token& t, const char*& err_out)
{
err_out = NULL;
err_out = nullptr;
if (t.Type() != TokenType_DATA) {
err_out = "expected TOK_DATA token";
@ -296,7 +296,7 @@ uint64_t ParseTokenAsID(const Token& t, const char*& err_out)
size_t ParseTokenAsDim(const Token& t, const char*& err_out)
{
// same as ID parsing, except there is a trailing asterisk
err_out = NULL;
err_out = nullptr;
if (t.Type() != TokenType_DATA) {
err_out = "expected TOK_DATA token";
@ -342,7 +342,7 @@ size_t ParseTokenAsDim(const Token& t, const char*& err_out)
// ------------------------------------------------------------------------------------------------
float ParseTokenAsFloat(const Token& t, const char*& err_out)
{
err_out = NULL;
err_out = nullptr;
if (t.Type() != TokenType_DATA) {
err_out = "expected TOK_DATA token";
@ -385,7 +385,7 @@ float ParseTokenAsFloat(const Token& t, const char*& err_out)
// ------------------------------------------------------------------------------------------------
int ParseTokenAsInt(const Token& t, const char*& err_out)
{
err_out = NULL;
err_out = nullptr;
if (t.Type() != TokenType_DATA) {
err_out = "expected TOK_DATA token";
@ -421,7 +421,7 @@ int ParseTokenAsInt(const Token& t, const char*& err_out)
// ------------------------------------------------------------------------------------------------
int64_t ParseTokenAsInt64(const Token& t, const char*& err_out)
{
err_out = NULL;
err_out = nullptr;
if (t.Type() != TokenType_DATA) {
err_out = "expected TOK_DATA token";
@ -458,7 +458,7 @@ int64_t ParseTokenAsInt64(const Token& t, const char*& err_out)
// ------------------------------------------------------------------------------------------------
std::string ParseTokenAsString(const Token& t, const char*& err_out)
{
err_out = NULL;
err_out = nullptr;
if (t.Type() != TokenType_DATA) {
err_out = "expected TOK_DATA token";
@ -1211,7 +1211,7 @@ bool HasElement( const Scope& sc, const std::string& index ) {
// ------------------------------------------------------------------------------------------------
// extract a required element from a scope, abort if the element cannot be found
const Element& GetRequiredElement(const Scope& sc, const std::string& index, const Element* element /*= NULL*/)
const Element& GetRequiredElement(const Scope& sc, const std::string& index, const Element* element /*= nullptr*/)
{
const Element* el = sc[index];
if(!el) {

View File

@ -137,7 +137,7 @@ public:
return element->second;
}
}
return NULL;
return nullptr;
}
ElementCollection GetCollection(const std::string& index) const {
@ -219,7 +219,7 @@ void ParseVectorDataArray(std::vector<int64_t>& out, const Element& el);
bool HasElement( const Scope& sc, const std::string& index );
// extract a required element from a scope, abort if the element cannot be found
const Element& GetRequiredElement(const Scope& sc, const std::string& index, const Element* element = NULL);
const Element &GetRequiredElement(const Scope &sc, const std::string &index, const Element *element = nullptr);
// extract required compound scope
const Scope& GetRequiredScope(const Element& el);

View File

@ -70,7 +70,7 @@ Property::~Property()
namespace {
// ------------------------------------------------------------------------------------------------
// read a typed property out of a FBX element. The return value is NULL if the property cannot be read.
// read a typed property out of a FBX element. The return value is nullptr if the property cannot be read.
Property* ReadTypedProperty(const Element& element)
{
ai_assert(element.KeyToken().StringContents() == "P");
@ -112,7 +112,7 @@ Property* ReadTypedProperty(const Element& element)
else if (!strcmp(cs,"double") || !strcmp(cs,"Number") || !strcmp(cs,"Float") || !strcmp(cs,"FieldOfView") || !strcmp( cs, "UnitScaleFactor" ) ) {
return new TypedProperty<float>(ParseTokenAsFloat(*tok[4]));
}
return NULL;
return nullptr;
}
@ -197,7 +197,7 @@ const Property* PropertyTable::Get(const std::string& name) const
return templateProps->Get(name);
}
return NULL;
return nullptr;
}
}

View File

@ -110,7 +110,7 @@ public:
const Property* Get(const std::string& name) const;
// PropertyTable's need not be coupled with FBX elements so this can be NULL
// PropertyTable's need not be coupled with FBX elements so this can be nullptr
const Element* GetElement() const {
return element;
}

View File

@ -127,7 +127,7 @@ void ProcessDataToken( TokenList& output_tokens, const char*& start, const char*
TokenizeError("unexpected character, expected data token", line, column);
}
start = end = NULL;
start = end = nullptr;
}
}
@ -146,7 +146,7 @@ void Tokenize(TokenList& output_tokens, const char* input)
bool in_double_quotes = false;
bool pending_data_token = false;
const char* token_begin = NULL, *token_end = NULL;
const char *token_begin = nullptr, *token_end = nullptr;
for (const char* cur = input;*cur;column += (*cur == '\t' ? ASSIMP_FBX_TAB_WIDTH : 1), ++cur) {
const char c = *cur;

View File

@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2020, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
@ -43,17 +41,16 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/** @file Implementation of the MDL importer class */
#ifndef ASSIMP_BUILD_NO_HMP_IMPORTER
// internal headers
#include "AssetLib/HMP/HMPLoader.h"
#include "AssetLib/MD2/MD2FileData.h"
#include <assimp/IOSystem.hpp>
#include <assimp/DefaultLogger.hpp>
#include <assimp/scene.h>
#include <assimp/importerdesc.h>
#include <assimp/scene.h>
#include <assimp/DefaultLogger.hpp>
#include <assimp/IOSystem.hpp>
#include <memory>
@ -74,22 +71,19 @@ static const aiImporterDesc desc = {
// ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer
HMPImporter::HMPImporter()
{
HMPImporter::HMPImporter() {
// nothing to do here
}
// ------------------------------------------------------------------------------------------------
// Destructor, private as well
HMPImporter::~HMPImporter()
{
HMPImporter::~HMPImporter() {
// nothing to do here
}
// ------------------------------------------------------------------------------------------------
// Returns whether the class can handle the format of the given file.
bool HMPImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool cs) const
{
bool HMPImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool cs) const {
const std::string extension = GetExtension(pFile);
if (extension == "hmp")
return true;
@ -107,23 +101,22 @@ bool HMPImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool
// ------------------------------------------------------------------------------------------------
// Get list of all file extensions that are handled by this loader
const aiImporterDesc* HMPImporter::GetInfo () const
{
const aiImporterDesc *HMPImporter::GetInfo() const {
return &desc;
}
// ------------------------------------------------------------------------------------------------
// Imports the given file into the given scene structure.
void HMPImporter::InternReadFile(const std::string &pFile,
aiScene* _pScene, IOSystem* _pIOHandler)
{
aiScene *_pScene, IOSystem *_pIOHandler) {
pScene = _pScene;
mIOHandler = _pIOHandler;
std::unique_ptr<IOStream> file(mIOHandler->Open(pFile));
// Check whether we can read from the file
if( file.get() == nullptr)
if (file.get() == nullptr) {
throw DeadlyImportError("Failed to open HMP file " + pFile + ".");
}
// Check whether the HMP file is large enough to contain
// at least the file header
@ -141,27 +134,22 @@ void HMPImporter::InternReadFile( const std::string& pFile,
// HMP4 format
if (AI_HMP_MAGIC_NUMBER_LE_4 == iMagic ||
AI_HMP_MAGIC_NUMBER_BE_4 == iMagic)
{
AI_HMP_MAGIC_NUMBER_BE_4 == iMagic) {
ASSIMP_LOG_DEBUG("HMP subtype: 3D GameStudio A4, magic word is HMP4");
InternReadFile_HMP4();
}
// HMP5 format
else if (AI_HMP_MAGIC_NUMBER_LE_5 == iMagic ||
AI_HMP_MAGIC_NUMBER_BE_5 == iMagic)
{
AI_HMP_MAGIC_NUMBER_BE_5 == iMagic) {
ASSIMP_LOG_DEBUG("HMP subtype: 3D GameStudio A5, magic word is HMP5");
InternReadFile_HMP5();
}
// HMP7 format
else if (AI_HMP_MAGIC_NUMBER_LE_7 == iMagic ||
AI_HMP_MAGIC_NUMBER_BE_7 == iMagic)
{
AI_HMP_MAGIC_NUMBER_BE_7 == iMagic) {
ASSIMP_LOG_DEBUG("HMP subtype: 3D GameStudio A7, magic word is HMP7");
InternReadFile_HMP7();
}
else
{
} else {
// Print the magic word to the logger
char szBuffer[5];
szBuffer[0] = ((char *)&iMagic)[0];
@ -180,16 +168,13 @@ void HMPImporter::InternReadFile( const std::string& pFile,
delete[] mBuffer;
mBuffer = nullptr;
}
// ------------------------------------------------------------------------------------------------
void HMPImporter::ValidateHeader_HMP457( )
{
void HMPImporter::ValidateHeader_HMP457() {
const HMP::Header_HMP5 *const pcHeader = (const HMP::Header_HMP5 *)mBuffer;
if (120 > iFileSize)
{
if (120 > iFileSize) {
throw DeadlyImportError("HMP file is too small (header size is "
"120 bytes, this file is smaller)");
}
@ -202,18 +187,15 @@ void HMPImporter::ValidateHeader_HMP457( )
if (!pcHeader->numframes)
throw DeadlyImportError("There are no frames. At least one should be there");
}
// ------------------------------------------------------------------------------------------------
void HMPImporter::InternReadFile_HMP4( )
{
void HMPImporter::InternReadFile_HMP4() {
throw DeadlyImportError("HMP4 is currently not supported");
}
// ------------------------------------------------------------------------------------------------
void HMPImporter::InternReadFile_HMP5( )
{
void HMPImporter::InternReadFile_HMP5() {
// read the file header and skip everything to byte 84
const HMP::Header_HMP5 *pcHeader = (const HMP::Header_HMP5 *)mBuffer;
const unsigned char *szCurrent = (const unsigned char *)(mBuffer + 84);
@ -243,15 +225,15 @@ void HMPImporter::InternReadFile_HMP5( )
aiVector3D *pcVertOut = pcMesh->mVertices;
aiVector3D *pcNorOut = pcMesh->mNormals;
const HMP::Vertex_HMP5 *src = (const HMP::Vertex_HMP5 *)szCurrent;
for (unsigned int y = 0; y < height;++y)
{
for (unsigned int x = 0; x < width;++x)
{
for (unsigned int y = 0; y < height; ++y) {
for (unsigned int x = 0; x < width; ++x) {
pcVertOut->x = x * pcHeader->ftrisize_x;
pcVertOut->y = y * pcHeader->ftrisize_y;
pcVertOut->z = (((float)src->z / 0xffff) - 0.5f) * pcHeader->ftrisize_x * 8.0f;
MD2::LookupNormalIndex(src->normals162index, *pcNorOut);
++pcVertOut;++pcNorOut;++src;
++pcVertOut;
++pcNorOut;
++src;
}
}
@ -272,8 +254,7 @@ void HMPImporter::InternReadFile_HMP5( )
}
// ------------------------------------------------------------------------------------------------
void HMPImporter::InternReadFile_HMP7( )
{
void HMPImporter::InternReadFile_HMP7() {
// read the file header and skip everything to byte 84
const HMP::Header_HMP5 *const pcHeader = (const HMP::Header_HMP5 *)mBuffer;
const unsigned char *szCurrent = (const unsigned char *)(mBuffer + 84);
@ -304,10 +285,8 @@ void HMPImporter::InternReadFile_HMP7( )
aiVector3D *pcVertOut = pcMesh->mVertices;
aiVector3D *pcNorOut = pcMesh->mNormals;
const HMP::Vertex_HMP7 *src = (const HMP::Vertex_HMP7 *)szCurrent;
for (unsigned int y = 0; y < height;++y)
{
for (unsigned int x = 0; x < width;++x)
{
for (unsigned int y = 0; y < height; ++y) {
for (unsigned int x = 0; x < width; ++x) {
pcVertOut->x = x * pcHeader->ftrisize_x;
pcVertOut->y = y * pcHeader->ftrisize_y;
@ -321,7 +300,9 @@ void HMPImporter::InternReadFile_HMP7( )
pcNorOut->z = 1.0f;
pcNorOut->Normalize();
++pcVertOut;++pcNorOut;++src;
++pcVertOut;
++pcNorOut;
++src;
}
}
@ -342,23 +323,19 @@ void HMPImporter::InternReadFile_HMP7( )
// ------------------------------------------------------------------------------------------------
void HMPImporter::CreateMaterial(const unsigned char *szCurrent,
const unsigned char** szCurrentOut)
{
const unsigned char **szCurrentOut) {
aiMesh *const pcMesh = pScene->mMeshes[0];
const HMP::Header_HMP5 *const pcHeader = (const HMP::Header_HMP5 *)mBuffer;
// we don't need to generate texture coordinates if
// we have no textures in the file ...
if (pcHeader->numskins)
{
if (pcHeader->numskins) {
pcMesh->mTextureCoords[0] = new aiVector3D[pcHeader->numverts];
pcMesh->mNumUVComponents[0] = 2;
// now read the first skin and skip all others
ReadFirstSkin(pcHeader->numskins, szCurrent, &szCurrent);
}
else
{
} else {
// generate a default material
const int iMode = (int)aiShadingMode_Gouraud;
aiMaterial *pcHelper = new aiMaterial();
@ -385,8 +362,7 @@ void HMPImporter::CreateMaterial(const unsigned char* szCurrent,
}
// ------------------------------------------------------------------------------------------------
void HMPImporter::CreateOutputFaceList(unsigned int width,unsigned int height)
{
void HMPImporter::CreateOutputFaceList(unsigned int width, unsigned int height) {
aiMesh *const pcMesh = this->pScene->mMeshes[0];
// Allocate enough storage
@ -401,7 +377,7 @@ void HMPImporter::CreateOutputFaceList(unsigned int width,unsigned int height)
aiVector3D *pcVertOut = pcVertices;
aiVector3D *pcNorOut = pcNormals;
aiVector3D* pcUVs = pcMesh->mTextureCoords[0] ? new aiVector3D[pcMesh->mNumVertices] : NULL;
aiVector3D *pcUVs = pcMesh->mTextureCoords[0] ? new aiVector3D[pcMesh->mNumVertices] : nullptr;
aiVector3D *pcUVOut(pcUVs);
// Build the terrain square
@ -416,14 +392,12 @@ void HMPImporter::CreateOutputFaceList(unsigned int width,unsigned int height)
*pcVertOut++ = pcMesh->mVertices[(y + 1) * width + x + 1];
*pcVertOut++ = pcMesh->mVertices[y * width + x + 1];
*pcNorOut++ = pcMesh->mNormals[y * width + x];
*pcNorOut++ = pcMesh->mNormals[(y + 1) * width + x];
*pcNorOut++ = pcMesh->mNormals[(y + 1) * width + x + 1];
*pcNorOut++ = pcMesh->mNormals[y * width + x + 1];
if (pcMesh->mTextureCoords[0])
{
if (pcMesh->mTextureCoords[0]) {
*pcUVOut++ = pcMesh->mTextureCoords[0][y * width + x];
*pcUVOut++ = pcMesh->mTextureCoords[0][(y + 1) * width + x];
*pcUVOut++ = pcMesh->mTextureCoords[0][(y + 1) * width + x + 1];
@ -440,8 +414,7 @@ void HMPImporter::CreateOutputFaceList(unsigned int width,unsigned int height)
delete[] pcMesh->mNormals;
pcMesh->mNormals = pcNormals;
if (pcMesh->mTextureCoords[0])
{
if (pcMesh->mTextureCoords[0]) {
delete[] pcMesh->mTextureCoords[0];
pcMesh->mTextureCoords[0] = pcUVs;
}
@ -449,8 +422,7 @@ void HMPImporter::CreateOutputFaceList(unsigned int width,unsigned int height)
// ------------------------------------------------------------------------------------------------
void HMPImporter::ReadFirstSkin(unsigned int iNumSkins, const unsigned char *szCursor,
const unsigned char** szCursorOut)
{
const unsigned char **szCursorOut) {
ai_assert(0 != iNumSkins);
ai_assert(nullptr != szCursor);
@ -458,18 +430,18 @@ void HMPImporter::ReadFirstSkin(unsigned int iNumSkins, const unsigned char* szC
// sometimes we need to skip 12 bytes here, I don't know why ...
uint32_t iType = *((uint32_t *)szCursor);
szCursor += sizeof(uint32_t);
if (0 == iType)
{
if (0 == iType) {
szCursor += sizeof(uint32_t) * 2;
iType = *((uint32_t *)szCursor);
szCursor += sizeof(uint32_t);
if (!iType)
throw DeadlyImportError("Unable to read HMP7 skin chunk");
}
// read width and height
uint32_t iWidth = *((uint32_t*)szCursor); szCursor += sizeof(uint32_t);
uint32_t iHeight = *((uint32_t*)szCursor); szCursor += sizeof(uint32_t);
uint32_t iWidth = *((uint32_t *)szCursor);
szCursor += sizeof(uint32_t);
uint32_t iHeight = *((uint32_t *)szCursor);
szCursor += sizeof(uint32_t);
// allocate an output material
aiMaterial *pcMat = new aiMaterial();
@ -479,11 +451,13 @@ void HMPImporter::ReadFirstSkin(unsigned int iNumSkins, const unsigned char* szC
pcMat, iType, iWidth, iHeight);
// now we need to skip any other skins ...
for (unsigned int i = 1; i< iNumSkins;++i)
{
iType = *((uint32_t*)szCursor); szCursor += sizeof(uint32_t);
iWidth = *((uint32_t*)szCursor); szCursor += sizeof(uint32_t);
iHeight = *((uint32_t*)szCursor); szCursor += sizeof(uint32_t);
for (unsigned int i = 1; i < iNumSkins; ++i) {
iType = *((uint32_t *)szCursor);
szCursor += sizeof(uint32_t);
iWidth = *((uint32_t *)szCursor);
szCursor += sizeof(uint32_t);
iHeight = *((uint32_t *)szCursor);
szCursor += sizeof(uint32_t);
SkipSkinLump_3DGS_MDL7(szCursor, &szCursor, iType, iWidth, iHeight);
SizeCheck(szCursor);
@ -500,10 +474,10 @@ void HMPImporter::ReadFirstSkin(unsigned int iNumSkins, const unsigned char* szC
// ------------------------------------------------------------------------------------------------
// Generate proepr texture coords
void HMPImporter::GenerateTextureCoords(
const unsigned int width, const unsigned int height)
{
ai_assert(NULL != pScene->mMeshes && NULL != pScene->mMeshes[0] &&
NULL != pScene->mMeshes[0]->mTextureCoords[0]);
const unsigned int width, const unsigned int height) {
ai_assert(nullptr != pScene->mMeshes);
ai_assert(nullptr != pScene->mMeshes[0]);
ai_assert(nullptr != pScene->mMeshes[0]->mTextureCoords[0]);
aiVector3D *uv = pScene->mMeshes[0]->mTextureCoords[0];

View File

@ -131,7 +131,7 @@ void WritePolygon(std::vector<IfcVector3> &resultpoly, TempMesh &result) {
void ProcessBooleanHalfSpaceDifference(const Schema_2x3::IfcHalfSpaceSolid *hs, TempMesh &result,
const TempMesh &first_operand,
ConversionData & /*conv*/) {
ai_assert(hs != NULL);
ai_assert(hs != nullptr);
const Schema_2x3::IfcPlane *const plane = hs->BaseSurface->ToPtr<Schema_2x3::IfcPlane>();
if (!plane) {
@ -366,7 +366,7 @@ bool PointInPoly(const IfcVector3 &p, const std::vector<IfcVector3> &boundary) {
void ProcessPolygonalBoundedBooleanHalfSpaceDifference(const Schema_2x3::IfcPolygonalBoundedHalfSpace *hs, TempMesh &result,
const TempMesh &first_operand,
ConversionData &conv) {
ai_assert(hs != NULL);
ai_assert(hs != nullptr);
const Schema_2x3::IfcPlane *const plane = hs->BaseSurface->ToPtr<Schema_2x3::IfcPlane>();
if (!plane) {
@ -665,7 +665,7 @@ void ProcessPolygonalBoundedBooleanHalfSpaceDifference(const Schema_2x3::IfcPoly
void ProcessBooleanExtrudedAreaSolidDifference(const Schema_2x3::IfcExtrudedAreaSolid *as, TempMesh &result,
const TempMesh &first_operand,
ConversionData &conv) {
ai_assert(as != NULL);
ai_assert(as != nullptr);
// This case is handled by reduction to an instance of the quadrify() algorithm.
// Obviously, this won't work for arbitrarily complex cases. In fact, the first

View File

@ -389,7 +389,8 @@ public:
// --------------------------------------------------
void SampleDiscrete(TempMesh& out,IfcFloat a,IfcFloat b) const {
ai_assert(InRange(a) && InRange(b));
ai_assert(InRange(a));
ai_assert(InRange(b));
return base->SampleDiscrete(out,TrimParam(a),TrimParam(b));
}
@ -446,7 +447,8 @@ public:
// --------------------------------------------------
size_t EstimateSampleCount(IfcFloat a, IfcFloat b) const {
ai_assert(InRange(a) && InRange(b));
ai_assert(InRange(a));
ai_assert(InRange(b));
return static_cast<size_t>( std::ceil(b) - std::floor(a) );
}
@ -489,7 +491,7 @@ Curve* Curve::Convert(const IFC::Schema_2x3::IfcCurve& curve,ConversionData& con
}
// XXX OffsetCurve2D, OffsetCurve3D not currently supported
return NULL;
return nullptr;
}
#ifdef ASSIMP_BUILD_DEBUG

View File

@ -174,7 +174,7 @@ void ProcessPolygonBoundaries(TempMesh& result, const TempMesh& inmesh, size_t m
TempOpening& opening = fake_openings.back();
opening.extrusionDir = master_normal;
opening.solid = NULL;
opening.solid = nullptr;
opening.profileMesh = std::make_shared<TempMesh>();
opening.profileMesh->mVerts.reserve(*iit);

View File

@ -172,7 +172,7 @@ void IFCImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
if (GetExtension(pFile) == "ifczip") {
#ifndef ASSIMP_BUILD_NO_COMPRESSED_IFC
unzFile zip = unzOpen(pFile.c_str());
if (zip == NULL) {
if (zip == nullptr) {
ThrowException("Could not open ifczip file for reading, unzip failed");
}
@ -373,7 +373,7 @@ void SetUnits(ConversionData &conv) {
// ------------------------------------------------------------------------------------------------
void SetCoordinateSpace(ConversionData &conv) {
const Schema_2x3::IfcRepresentationContext *fav = NULL;
const Schema_2x3::IfcRepresentationContext *fav = nullptr;
for (const Schema_2x3::IfcRepresentationContext &v : conv.proj.RepresentationContexts) {
fav = &v;
// Model should be the most suitable type of context, hence ignore the others
@ -790,7 +790,7 @@ aiNode *ProcessSpatialStructure(aiNode *parent, const Schema_2x3::IfcProduct &el
for (const Schema_2x3::IfcObjectDefinition &def : aggr->RelatedObjects) {
if (const Schema_2x3::IfcProduct *const prod = def.ToPtr<Schema_2x3::IfcProduct>()) {
aiNode *const ndnew = ProcessSpatialStructure(nd_aggr.get(), *prod, conv, NULL);
aiNode *const ndnew = ProcessSpatialStructure(nd_aggr.get(), *prod, conv, nullptr);
if (ndnew) {
nd_aggr->mChildren[nd_aggr->mNumChildren++] = ndnew;
}
@ -870,7 +870,7 @@ void ProcessSpatialStructures(ConversionData &conv) {
if (def.GetID() == prod->GetID()) {
IFCImporter::LogVerboseDebug("selecting this spatial structure as root structure");
// got it, this is one primary site.
nodes.push_back(ProcessSpatialStructure(NULL, *prod, conv, NULL));
nodes.push_back(ProcessSpatialStructure(nullptr, *prod, conv, nullptr));
}
}
}
@ -887,7 +887,7 @@ void ProcessSpatialStructures(ConversionData &conv) {
continue;
}
nodes.push_back(ProcessSpatialStructure(NULL, *prod, conv, NULL));
nodes.push_back(ProcessSpatialStructure(nullptr, *prod, conv, nullptr));
}
nb_nodes = nodes.size();
@ -897,7 +897,7 @@ void ProcessSpatialStructures(ConversionData &conv) {
conv.out->mRootNode = nodes[0];
} else if (nb_nodes > 1) {
conv.out->mRootNode = new aiNode("Root");
conv.out->mRootNode->mParent = NULL;
conv.out->mRootNode->mParent = nullptr;
conv.out->mRootNode->mNumChildren = static_cast<unsigned int>(nb_nodes);
conv.out->mRootNode->mChildren = new aiNode *[conv.out->mRootNode->mNumChildren];

View File

@ -54,333 +54,333 @@ namespace {
typedef EXPRESS::ConversionSchema::SchemaEntry SchemaEntry;
static const SchemaEntry schema_raw_2x3[] = {
SchemaEntry("ifcstairtypeenum",NULL )
, SchemaEntry("ifcspacetypeenum",NULL )
, SchemaEntry("ifcwalltypeenum",NULL )
, SchemaEntry("ifcmonthinyearnumber",NULL )
, SchemaEntry("ifcheatfluxdensitymeasure",NULL )
, SchemaEntry("ifckinematicviscositymeasure",NULL )
, SchemaEntry("ifcsequenceenum",NULL )
, SchemaEntry("ifcairtoairheatrecoverytypeenum",NULL )
, SchemaEntry("ifcactorselect",NULL )
, SchemaEntry("ifctransformertypeenum",NULL )
, SchemaEntry("ifcunitaryequipmenttypeenum",NULL )
, SchemaEntry("ifcelectricflowstoragedevicetypeenum",NULL )
, SchemaEntry("ifcenergysequenceenum",NULL )
, SchemaEntry("ifcworkcontroltypeenum",NULL )
, SchemaEntry("ifccurvaturemeasure",NULL )
, SchemaEntry("ifcparametervalue",NULL )
, SchemaEntry("ifcappliedvalueselect",NULL )
, SchemaEntry("ifcwarpingconstantmeasure",NULL )
, SchemaEntry("ifcarithmeticoperatorenum",NULL )
, SchemaEntry("ifclinearforcemeasure",NULL )
, SchemaEntry("ifcwindowpanelpositionenum",NULL )
, SchemaEntry("ifcflowmetertypeenum",NULL )
, SchemaEntry("ifcrampflighttypeenum",NULL )
, SchemaEntry("ifcspecularhighlightselect",NULL )
, SchemaEntry("ifcactiontypeenum",NULL )
, SchemaEntry("ifcgeometricprojectionenum",NULL )
, SchemaEntry("ifctimeseriesdatatypeenum",NULL )
, SchemaEntry("ifcmagneticfluxmeasure",NULL )
, SchemaEntry("ifcobjecttypeenum",NULL )
, SchemaEntry("ifcdataoriginenum",NULL )
, SchemaEntry("ifcmassdensitymeasure",NULL )
, SchemaEntry("ifclightfixturetypeenum",NULL )
, SchemaEntry("ifcservicelifetypeenum",NULL )
, SchemaEntry("ifcelectricvoltagemeasure",NULL )
, SchemaEntry("ifcheatingvaluemeasure",NULL )
, SchemaEntry("ifcpresentabletext",NULL )
, SchemaEntry("ifcaheadorbehind",NULL )
, SchemaEntry("ifcsimplevalue",NULL )
, SchemaEntry("ifcsensortypeenum",NULL )
, SchemaEntry("ifcderivedunitenum",NULL )
, SchemaEntry("ifcsizeselect",NULL )
, SchemaEntry("ifctransportelementtypeenum",NULL )
, SchemaEntry("ifcinventorytypeenum",NULL )
, SchemaEntry("ifctextdecoration",NULL )
, SchemaEntry("ifcdirectionsenseenum",NULL )
, SchemaEntry("ifcductfittingtypeenum",NULL )
, SchemaEntry("ifcdocumentstatusenum",NULL )
, SchemaEntry("ifcslabtypeenum",NULL )
, SchemaEntry("ifcdoorstyleconstructionenum",NULL )
, SchemaEntry("ifcvolumemeasure",NULL )
, SchemaEntry("ifcinductancemeasure",NULL )
, SchemaEntry("ifccurtainwalltypeenum",NULL )
, SchemaEntry("ifcsiunitname",NULL )
, SchemaEntry("ifcspecularexponent",NULL )
, SchemaEntry("ifcsoundpressuremeasure",NULL )
, SchemaEntry("ifcanalysistheorytypeenum",NULL )
, SchemaEntry("ifcgasterminaltypeenum",NULL )
, SchemaEntry("ifcyearnumber",NULL )
, SchemaEntry("ifcmodulusofelasticitymeasure",NULL )
, SchemaEntry("ifcchangeactionenum",NULL )
, SchemaEntry("ifcdampertypeenum",NULL )
, SchemaEntry("ifcevaporatortypeenum",NULL )
, SchemaEntry("ifcionconcentrationmeasure",NULL )
, SchemaEntry("ifcductsegmenttypeenum",NULL )
, SchemaEntry("ifcprotectivedevicetypeenum",NULL )
, SchemaEntry("ifcabsorbeddosemeasure",NULL )
, SchemaEntry("ifcmassperlengthmeasure",NULL )
, SchemaEntry("ifctextfontname",NULL )
, SchemaEntry("ifcorientationselect",NULL )
, SchemaEntry("ifcilluminancemeasure",NULL )
, SchemaEntry("ifcfiresuppressionterminaltypeenum",NULL )
, SchemaEntry("ifcfontstyle",NULL )
, SchemaEntry("ifcmomentofinertiameasure",NULL )
, SchemaEntry("ifcmodulusofsubgradereactionmeasure",NULL )
, SchemaEntry("ifccomplexnumber",NULL )
, SchemaEntry("ifchumidifiertypeenum",NULL )
, SchemaEntry("ifcpresentationstyleselect",NULL )
, SchemaEntry("ifcthermaltransmittancemeasure",NULL )
, SchemaEntry("ifcribplatedirectionenum",NULL )
, SchemaEntry("ifcclassificationnotationselect",NULL )
, SchemaEntry("ifcminuteinhour",NULL )
, SchemaEntry("ifcinternalorexternalenum",NULL )
, SchemaEntry("ifcrotationalfrequencymeasure",NULL )
, SchemaEntry("ifcsanitaryterminaltypeenum",NULL )
, SchemaEntry("ifcsymbolstyleselect",NULL )
, SchemaEntry("ifcelementcompositionenum",NULL )
, SchemaEntry("ifctextpath",NULL )
, SchemaEntry("ifcpowermeasure",NULL )
, SchemaEntry("ifcsurfacestyleelementselect",NULL )
, SchemaEntry("ifcresourceconsumptionenum",NULL )
, SchemaEntry("ifcelectriccapacitancemeasure",NULL )
, SchemaEntry("ifclayersetdirectionenum",NULL )
, SchemaEntry("ifcrailingtypeenum",NULL )
, SchemaEntry("ifcobjectiveenum",NULL )
, SchemaEntry("ifcdocumentselect",NULL )
, SchemaEntry("ifcmodulusoflinearsubgradereactionmeasure",NULL )
, SchemaEntry("ifcthermaladmittancemeasure",NULL )
, SchemaEntry("ifctransitioncode",NULL )
, SchemaEntry("ifcconnectiontypeenum",NULL )
, SchemaEntry("ifcmonetarymeasure",NULL )
, SchemaEntry("ifcstackterminaltypeenum",NULL )
, SchemaEntry("ifccolour",NULL )
, SchemaEntry("ifctext",NULL )
, SchemaEntry("ifccontextdependentmeasure",NULL )
, SchemaEntry("ifcthermalconductivitymeasure",NULL )
, SchemaEntry("ifcprojectedortruelengthenum",NULL )
, SchemaEntry("ifcpressuremeasure",NULL )
, SchemaEntry("ifcmoisturediffusivitymeasure",NULL )
, SchemaEntry("ifcbooleanoperator",NULL )
, SchemaEntry("ifcpropertysourceenum",NULL )
, SchemaEntry("ifctimestamp",NULL )
, SchemaEntry("ifcmaterialselect",NULL )
, SchemaEntry("ifcgloballyuniqueid",NULL )
, SchemaEntry("ifcreflectancemethodenum",NULL )
, SchemaEntry("ifcvaporpermeabilitymeasure",NULL )
, SchemaEntry("ifctimeseriesscheduletypeenum",NULL )
, SchemaEntry("ifclinearmomentmeasure",NULL )
, SchemaEntry("ifcgeometricsetselect",NULL )
, SchemaEntry("ifcsectionmodulusmeasure",NULL )
, SchemaEntry("ifcbsplinecurveform",NULL )
, SchemaEntry("ifcdimensionextentusage",NULL )
, SchemaEntry("ifcthermalexpansioncoefficientmeasure",NULL )
, SchemaEntry("ifchourinday",NULL )
, SchemaEntry("ifclinearvelocitymeasure",NULL )
, SchemaEntry("ifctorquemeasure",NULL )
, SchemaEntry("ifctemperaturegradientmeasure",NULL )
, SchemaEntry("ifcfillstyleselect",NULL )
, SchemaEntry("ifcelectricchargemeasure",NULL )
, SchemaEntry("ifcheatexchangertypeenum",NULL )
, SchemaEntry("ifcelectriccurrentenum",NULL )
, SchemaEntry("ifcdaylightsavinghour",NULL )
, SchemaEntry("ifcshell",NULL )
, SchemaEntry("ifcdoseequivalentmeasure",NULL )
, SchemaEntry("ifcprojectordertypeenum",NULL )
, SchemaEntry("ifcderivedmeasurevalue",NULL )
, SchemaEntry("ifclightdistributioncurveenum",NULL )
, SchemaEntry("ifcwarpingmomentmeasure",NULL )
, SchemaEntry("ifcmembertypeenum",NULL )
, SchemaEntry("ifcsoundpowermeasure",NULL )
, SchemaEntry("ifctextalignment",NULL )
, SchemaEntry("ifccurveoredgecurve",NULL )
, SchemaEntry("ifcmassflowratemeasure",NULL )
, SchemaEntry("ifcisothermalmoisturecapacitymeasure",NULL )
, SchemaEntry("ifccsgselect",NULL )
, SchemaEntry("ifccoolingtowertypeenum",NULL )
, SchemaEntry("ifcmassmeasure",NULL )
, SchemaEntry("ifcpileconstructionenum",NULL )
, SchemaEntry("ifcdoorstyleoperationenum",NULL )
, SchemaEntry("ifcflowdirectionenum",NULL )
, SchemaEntry("ifcthermalloadsourceenum",NULL )
, SchemaEntry("ifclengthmeasure",NULL )
, SchemaEntry("ifcconstraintenum",NULL )
, SchemaEntry("ifcaxis2placement",NULL )
, SchemaEntry("ifcloadgrouptypeenum",NULL )
, SchemaEntry("ifcvalue",NULL )
, SchemaEntry("ifcreinforcingbarsurfaceenum",NULL )
, SchemaEntry("ifcprojectorderrecordtypeenum",NULL )
, SchemaEntry("ifcdatetimeselect",NULL )
, SchemaEntry("ifcstructuralsurfacetypeenum",NULL )
, SchemaEntry("ifcpermeablecoveringoperationenum",NULL )
, SchemaEntry("ifcfontweight",NULL )
, SchemaEntry("ifcphmeasure",NULL )
, SchemaEntry("ifcdescriptivemeasure",NULL )
, SchemaEntry("ifccurvestylefontselect",NULL )
, SchemaEntry("ifcunit",NULL )
, SchemaEntry("ifchatchlinedistanceselect",NULL )
, SchemaEntry("ifctextstyleselect",NULL )
, SchemaEntry("ifcmetricvalueselect",NULL )
, SchemaEntry("ifcvectorordirection",NULL )
, SchemaEntry("ifcassemblyplaceenum",NULL )
, SchemaEntry("ifcairterminaltypeenum",NULL )
, SchemaEntry("ifccoveringtypeenum",NULL )
, SchemaEntry("ifcplanarforcemeasure",NULL )
, SchemaEntry("ifcvalvetypeenum",NULL )
, SchemaEntry("ifcalarmtypeenum",NULL )
, SchemaEntry("ifcdynamicviscositymeasure",NULL )
, SchemaEntry("ifccurrencyenum",NULL )
, SchemaEntry("ifcmodulusofrotationalsubgradereactionmeasure",NULL )
, SchemaEntry("ifccablecarrierfittingtypeenum",NULL )
, SchemaEntry("ifcboolean",NULL )
, SchemaEntry("ifcactionsourcetypeenum",NULL )
, SchemaEntry("ifcstructuralactivityassignmentselect",NULL )
, SchemaEntry("ifcdistributionchamberelementtypeenum",NULL )
, SchemaEntry("ifcevaporativecoolertypeenum",NULL )
, SchemaEntry("ifcmagneticfluxdensitymeasure",NULL )
, SchemaEntry("ifclightdistributiondatasourceselect",NULL )
, SchemaEntry("ifctubebundletypeenum",NULL )
, SchemaEntry("ifcaccelerationmeasure",NULL )
, SchemaEntry("ifcboilertypeenum",NULL )
, SchemaEntry("ifcramptypeenum",NULL )
, SchemaEntry("ifcluminousintensitydistributionmeasure",NULL )
, SchemaEntry("ifctrimmingpreference",NULL )
, SchemaEntry("ifcspecificheatcapacitymeasure",NULL )
, SchemaEntry("ifcamountofsubstancemeasure",NULL )
, SchemaEntry("ifcroleenum",NULL )
, SchemaEntry("ifcdocumentconfidentialityenum",NULL )
, SchemaEntry("ifcfrequencymeasure",NULL )
, SchemaEntry("ifcsectiontypeenum",NULL )
, SchemaEntry("ifcelementassemblytypeenum",NULL )
, SchemaEntry("ifcfootingtypeenum",NULL )
, SchemaEntry("ifclayereditem",NULL )
, SchemaEntry("ifccablesegmenttypeenum",NULL )
, SchemaEntry("ifcdefinedsymbolselect",NULL )
, SchemaEntry("ifcbuildingelementproxytypeenum",NULL )
, SchemaEntry("ifcelectricgeneratortypeenum",NULL )
, SchemaEntry("ifcrotationalstiffnessmeasure",NULL )
, SchemaEntry("ifcspaceheatertypeenum",NULL )
, SchemaEntry("ifcareameasure",NULL )
, SchemaEntry("ifclabel",NULL )
, SchemaEntry("ifccostscheduletypeenum",NULL )
, SchemaEntry("ifcswitchingdevicetypeenum",NULL )
, SchemaEntry("ifcelectrictimecontroltypeenum",NULL )
, SchemaEntry("ifcfiltertypeenum",NULL )
, SchemaEntry("ifcpositivelengthmeasure",NULL )
, SchemaEntry("ifcnullstyle",NULL )
, SchemaEntry("ifcconditioncriterionselect",NULL )
, SchemaEntry("ifcshearmodulusmeasure",NULL )
, SchemaEntry("ifcnormalisedratiomeasure",NULL )
, SchemaEntry("ifcdoorpaneloperationenum",NULL )
, SchemaEntry("ifcpointorvertexpoint",NULL )
, SchemaEntry("ifcrooftypeenum",NULL )
, SchemaEntry("ifccountmeasure",NULL )
, SchemaEntry("ifcelectricconductancemeasure",NULL )
, SchemaEntry("ifcproceduretypeenum",NULL )
, SchemaEntry("ifcflowinstrumenttypeenum",NULL )
, SchemaEntry("ifcelectricmotortypeenum",NULL )
, SchemaEntry("ifcsurfaceside",NULL )
, SchemaEntry("ifcstructuralcurvetypeenum",NULL )
, SchemaEntry("ifccondensertypeenum",NULL )
, SchemaEntry("ifclinearstiffnessmeasure",NULL )
, SchemaEntry("ifcunitenum",NULL )
, SchemaEntry("ifcoccupanttypeenum",NULL )
, SchemaEntry("ifcthermalloadtypeenum",NULL )
, SchemaEntry("ifcreinforcingbarroleenum",NULL )
, SchemaEntry("ifcbenchmarkenum",NULL )
, SchemaEntry("ifcpositiveplaneanglemeasure",NULL )
, SchemaEntry("ifctexttransformation",NULL )
, SchemaEntry("ifcdraughtingcalloutelement",NULL )
, SchemaEntry("ifcratiomeasure",NULL )
, SchemaEntry("ifcsolidanglemeasure",NULL )
, SchemaEntry("ifcpipesegmenttypeenum",NULL )
, SchemaEntry("ifccablecarriersegmenttypeenum",NULL )
, SchemaEntry("ifccolourorfactor",NULL )
, SchemaEntry("ifcidentifier",NULL )
, SchemaEntry("ifctendontypeenum",NULL )
, SchemaEntry("ifccontrollertypeenum",NULL )
, SchemaEntry("ifcradioactivitymeasure",NULL )
, SchemaEntry("ifctimemeasure",NULL )
, SchemaEntry("ifcpumptypeenum",NULL )
, SchemaEntry("ifcelectricheatertypeenum",NULL )
, SchemaEntry("ifcbeamtypeenum",NULL )
, SchemaEntry("ifcstateenum",NULL )
, SchemaEntry("ifcsiprefix",NULL )
, SchemaEntry("ifcnumericmeasure",NULL )
, SchemaEntry("ifcoutlettypeenum",NULL )
, SchemaEntry("ifccompoundplaneanglemeasure",NULL )
, SchemaEntry("ifcservicelifefactortypeenum",NULL )
, SchemaEntry("ifclogicaloperatorenum",NULL )
, SchemaEntry("ifcbooleanoperand",NULL )
, SchemaEntry("ifcobjectreferenceselect",NULL )
, SchemaEntry("ifccooledbeamtypeenum",NULL )
, SchemaEntry("ifcductsilencertypeenum",NULL )
, SchemaEntry("ifcsectionalareaintegralmeasure",NULL )
, SchemaEntry("ifcfontvariant",NULL )
, SchemaEntry("ifcvolumetricflowratemeasure",NULL )
, SchemaEntry("ifcplatetypeenum",NULL )
, SchemaEntry("ifcenvironmentalimpactcategoryenum",NULL )
, SchemaEntry("ifcvibrationisolatortypeenum",NULL )
, SchemaEntry("ifcthermodynamictemperaturemeasure",NULL )
, SchemaEntry("ifcrotationalmassmeasure",NULL )
, SchemaEntry("ifcsecondinminute",NULL )
, SchemaEntry("ifcdayinmonthnumber",NULL )
, SchemaEntry("ifcdimensioncount",NULL )
, SchemaEntry("ifcwindowstyleoperationenum",NULL )
, SchemaEntry("ifcthermalresistancemeasure",NULL )
, SchemaEntry("ifcmeasurevalue",NULL )
, SchemaEntry("ifcwindowpaneloperationenum",NULL )
, SchemaEntry("ifcchillertypeenum",NULL )
, SchemaEntry("ifcpositiveratiomeasure",NULL )
, SchemaEntry("ifcinteger",NULL )
, SchemaEntry("ifclogical",NULL )
, SchemaEntry("ifcjunctionboxtypeenum",NULL )
, SchemaEntry("ifcaddresstypeenum",NULL )
, SchemaEntry("ifcwasteterminaltypeenum",NULL )
, SchemaEntry("ifctrimmingselect",NULL )
, SchemaEntry("ifclightemissionsourceenum",NULL )
, SchemaEntry("ifcsoundscaleenum",NULL )
, SchemaEntry("ifcluminousfluxmeasure",NULL )
, SchemaEntry("ifcelectricresistancemeasure",NULL )
, SchemaEntry("ifcintegercountratemeasure",NULL )
, SchemaEntry("ifcphysicalorvirtualenum",NULL )
, SchemaEntry("ifcmolecularweightmeasure",NULL )
, SchemaEntry("ifcprofiletypeenum",NULL )
, SchemaEntry("ifcboxalignment",NULL )
, SchemaEntry("ifcglobalorlocalenum",NULL )
, SchemaEntry("ifcspecularroughness",NULL )
, SchemaEntry("ifclamptypeenum",NULL )
, SchemaEntry("ifcpiletypeenum",NULL )
, SchemaEntry("ifcelectriccurrentmeasure",NULL )
, SchemaEntry("ifcfantypeenum",NULL )
, SchemaEntry("ifcsurfaceorfacesurface",NULL )
, SchemaEntry("ifcpipefittingtypeenum",NULL )
, SchemaEntry("ifctanktypeenum",NULL )
, SchemaEntry("ifccurvefontorscaledcurvefontselect",NULL )
, SchemaEntry("ifcwindowstyleconstructionenum",NULL )
, SchemaEntry("ifcairterminalboxtypeenum",NULL )
, SchemaEntry("ifcstairflighttypeenum",NULL )
, SchemaEntry("ifcluminousintensitymeasure",NULL )
, SchemaEntry("ifcmotorconnectiontypeenum",NULL )
, SchemaEntry("ifcplaneanglemeasure",NULL )
, SchemaEntry("ifcactuatortypeenum",NULL )
, SchemaEntry("ifccolumntypeenum",NULL )
, SchemaEntry("ifctextfontselect",NULL )
, SchemaEntry("ifcdoorpanelpositionenum",NULL )
, SchemaEntry("ifccoiltypeenum",NULL )
, SchemaEntry("ifcangularvelocitymeasure",NULL )
, SchemaEntry("ifcanalysismodeltypeenum",NULL )
, SchemaEntry("ifclibraryselect",NULL )
, SchemaEntry("ifcforcemeasure",NULL )
, SchemaEntry("ifcfillareastyletileshapeselect",NULL )
, SchemaEntry("ifcelectricappliancetypeenum",NULL )
, SchemaEntry("ifcsurfacetextureenum",NULL )
, SchemaEntry("ifccharacterstyleselect",NULL )
, SchemaEntry("ifcenergymeasure",NULL )
, SchemaEntry("ifcreal",NULL )
, SchemaEntry("ifccompressortypeenum",NULL )
, SchemaEntry("ifcelectricdistributionpointfunctionenum",NULL )
SchemaEntry("ifcstairtypeenum",nullptr )
, SchemaEntry("ifcspacetypeenum",nullptr )
, SchemaEntry("ifcwalltypeenum",nullptr )
, SchemaEntry("ifcmonthinyearnumber",nullptr )
, SchemaEntry("ifcheatfluxdensitymeasure",nullptr )
, SchemaEntry("ifckinematicviscositymeasure",nullptr )
, SchemaEntry("ifcsequenceenum",nullptr )
, SchemaEntry("ifcairtoairheatrecoverytypeenum",nullptr )
, SchemaEntry("ifcactorselect",nullptr )
, SchemaEntry("ifctransformertypeenum",nullptr )
, SchemaEntry("ifcunitaryequipmenttypeenum",nullptr )
, SchemaEntry("ifcelectricflowstoragedevicetypeenum",nullptr )
, SchemaEntry("ifcenergysequenceenum",nullptr )
, SchemaEntry("ifcworkcontroltypeenum",nullptr )
, SchemaEntry("ifccurvaturemeasure",nullptr )
, SchemaEntry("ifcparametervalue",nullptr )
, SchemaEntry("ifcappliedvalueselect",nullptr )
, SchemaEntry("ifcwarpingconstantmeasure",nullptr )
, SchemaEntry("ifcarithmeticoperatorenum",nullptr )
, SchemaEntry("ifclinearforcemeasure",nullptr )
, SchemaEntry("ifcwindowpanelpositionenum",nullptr )
, SchemaEntry("ifcflowmetertypeenum",nullptr )
, SchemaEntry("ifcrampflighttypeenum",nullptr )
, SchemaEntry("ifcspecularhighlightselect",nullptr )
, SchemaEntry("ifcactiontypeenum",nullptr )
, SchemaEntry("ifcgeometricprojectionenum",nullptr )
, SchemaEntry("ifctimeseriesdatatypeenum",nullptr )
, SchemaEntry("ifcmagneticfluxmeasure",nullptr )
, SchemaEntry("ifcobjecttypeenum",nullptr )
, SchemaEntry("ifcdataoriginenum",nullptr )
, SchemaEntry("ifcmassdensitymeasure",nullptr )
, SchemaEntry("ifclightfixturetypeenum",nullptr )
, SchemaEntry("ifcservicelifetypeenum",nullptr )
, SchemaEntry("ifcelectricvoltagemeasure",nullptr )
, SchemaEntry("ifcheatingvaluemeasure",nullptr )
, SchemaEntry("ifcpresentabletext",nullptr )
, SchemaEntry("ifcaheadorbehind",nullptr )
, SchemaEntry("ifcsimplevalue",nullptr )
, SchemaEntry("ifcsensortypeenum",nullptr )
, SchemaEntry("ifcderivedunitenum",nullptr )
, SchemaEntry("ifcsizeselect",nullptr )
, SchemaEntry("ifctransportelementtypeenum",nullptr )
, SchemaEntry("ifcinventorytypeenum",nullptr )
, SchemaEntry("ifctextdecoration",nullptr )
, SchemaEntry("ifcdirectionsenseenum",nullptr )
, SchemaEntry("ifcductfittingtypeenum",nullptr )
, SchemaEntry("ifcdocumentstatusenum",nullptr )
, SchemaEntry("ifcslabtypeenum",nullptr )
, SchemaEntry("ifcdoorstyleconstructionenum",nullptr )
, SchemaEntry("ifcvolumemeasure",nullptr )
, SchemaEntry("ifcinductancemeasure",nullptr )
, SchemaEntry("ifccurtainwalltypeenum",nullptr )
, SchemaEntry("ifcsiunitname",nullptr )
, SchemaEntry("ifcspecularexponent",nullptr )
, SchemaEntry("ifcsoundpressuremeasure",nullptr )
, SchemaEntry("ifcanalysistheorytypeenum",nullptr )
, SchemaEntry("ifcgasterminaltypeenum",nullptr )
, SchemaEntry("ifcyearnumber",nullptr )
, SchemaEntry("ifcmodulusofelasticitymeasure",nullptr )
, SchemaEntry("ifcchangeactionenum",nullptr )
, SchemaEntry("ifcdampertypeenum",nullptr )
, SchemaEntry("ifcevaporatortypeenum",nullptr )
, SchemaEntry("ifcionconcentrationmeasure",nullptr )
, SchemaEntry("ifcductsegmenttypeenum",nullptr )
, SchemaEntry("ifcprotectivedevicetypeenum",nullptr )
, SchemaEntry("ifcabsorbeddosemeasure",nullptr )
, SchemaEntry("ifcmassperlengthmeasure",nullptr )
, SchemaEntry("ifctextfontname",nullptr )
, SchemaEntry("ifcorientationselect",nullptr )
, SchemaEntry("ifcilluminancemeasure",nullptr )
, SchemaEntry("ifcfiresuppressionterminaltypeenum",nullptr )
, SchemaEntry("ifcfontstyle",nullptr )
, SchemaEntry("ifcmomentofinertiameasure",nullptr )
, SchemaEntry("ifcmodulusofsubgradereactionmeasure",nullptr )
, SchemaEntry("ifccomplexnumber",nullptr )
, SchemaEntry("ifchumidifiertypeenum",nullptr )
, SchemaEntry("ifcpresentationstyleselect",nullptr )
, SchemaEntry("ifcthermaltransmittancemeasure",nullptr )
, SchemaEntry("ifcribplatedirectionenum",nullptr )
, SchemaEntry("ifcclassificationnotationselect",nullptr )
, SchemaEntry("ifcminuteinhour",nullptr )
, SchemaEntry("ifcinternalorexternalenum",nullptr )
, SchemaEntry("ifcrotationalfrequencymeasure",nullptr )
, SchemaEntry("ifcsanitaryterminaltypeenum",nullptr )
, SchemaEntry("ifcsymbolstyleselect",nullptr )
, SchemaEntry("ifcelementcompositionenum",nullptr )
, SchemaEntry("ifctextpath",nullptr )
, SchemaEntry("ifcpowermeasure",nullptr )
, SchemaEntry("ifcsurfacestyleelementselect",nullptr )
, SchemaEntry("ifcresourceconsumptionenum",nullptr )
, SchemaEntry("ifcelectriccapacitancemeasure",nullptr )
, SchemaEntry("ifclayersetdirectionenum",nullptr )
, SchemaEntry("ifcrailingtypeenum",nullptr )
, SchemaEntry("ifcobjectiveenum",nullptr )
, SchemaEntry("ifcdocumentselect",nullptr )
, SchemaEntry("ifcmodulusoflinearsubgradereactionmeasure",nullptr )
, SchemaEntry("ifcthermaladmittancemeasure",nullptr )
, SchemaEntry("ifctransitioncode",nullptr )
, SchemaEntry("ifcconnectiontypeenum",nullptr )
, SchemaEntry("ifcmonetarymeasure",nullptr )
, SchemaEntry("ifcstackterminaltypeenum",nullptr )
, SchemaEntry("ifccolour",nullptr )
, SchemaEntry("ifctext",nullptr )
, SchemaEntry("ifccontextdependentmeasure",nullptr )
, SchemaEntry("ifcthermalconductivitymeasure",nullptr )
, SchemaEntry("ifcprojectedortruelengthenum",nullptr )
, SchemaEntry("ifcpressuremeasure",nullptr )
, SchemaEntry("ifcmoisturediffusivitymeasure",nullptr )
, SchemaEntry("ifcbooleanoperator",nullptr )
, SchemaEntry("ifcpropertysourceenum",nullptr )
, SchemaEntry("ifctimestamp",nullptr )
, SchemaEntry("ifcmaterialselect",nullptr )
, SchemaEntry("ifcgloballyuniqueid",nullptr )
, SchemaEntry("ifcreflectancemethodenum",nullptr )
, SchemaEntry("ifcvaporpermeabilitymeasure",nullptr )
, SchemaEntry("ifctimeseriesscheduletypeenum",nullptr )
, SchemaEntry("ifclinearmomentmeasure",nullptr )
, SchemaEntry("ifcgeometricsetselect",nullptr )
, SchemaEntry("ifcsectionmodulusmeasure",nullptr )
, SchemaEntry("ifcbsplinecurveform",nullptr )
, SchemaEntry("ifcdimensionextentusage",nullptr )
, SchemaEntry("ifcthermalexpansioncoefficientmeasure",nullptr )
, SchemaEntry("ifchourinday",nullptr )
, SchemaEntry("ifclinearvelocitymeasure",nullptr )
, SchemaEntry("ifctorquemeasure",nullptr )
, SchemaEntry("ifctemperaturegradientmeasure",nullptr )
, SchemaEntry("ifcfillstyleselect",nullptr )
, SchemaEntry("ifcelectricchargemeasure",nullptr )
, SchemaEntry("ifcheatexchangertypeenum",nullptr )
, SchemaEntry("ifcelectriccurrentenum",nullptr )
, SchemaEntry("ifcdaylightsavinghour",nullptr )
, SchemaEntry("ifcshell",nullptr )
, SchemaEntry("ifcdoseequivalentmeasure",nullptr )
, SchemaEntry("ifcprojectordertypeenum",nullptr )
, SchemaEntry("ifcderivedmeasurevalue",nullptr )
, SchemaEntry("ifclightdistributioncurveenum",nullptr )
, SchemaEntry("ifcwarpingmomentmeasure",nullptr )
, SchemaEntry("ifcmembertypeenum",nullptr )
, SchemaEntry("ifcsoundpowermeasure",nullptr )
, SchemaEntry("ifctextalignment",nullptr )
, SchemaEntry("ifccurveoredgecurve",nullptr )
, SchemaEntry("ifcmassflowratemeasure",nullptr )
, SchemaEntry("ifcisothermalmoisturecapacitymeasure",nullptr )
, SchemaEntry("ifccsgselect",nullptr )
, SchemaEntry("ifccoolingtowertypeenum",nullptr )
, SchemaEntry("ifcmassmeasure",nullptr )
, SchemaEntry("ifcpileconstructionenum",nullptr )
, SchemaEntry("ifcdoorstyleoperationenum",nullptr )
, SchemaEntry("ifcflowdirectionenum",nullptr )
, SchemaEntry("ifcthermalloadsourceenum",nullptr )
, SchemaEntry("ifclengthmeasure",nullptr )
, SchemaEntry("ifcconstraintenum",nullptr )
, SchemaEntry("ifcaxis2placement",nullptr )
, SchemaEntry("ifcloadgrouptypeenum",nullptr )
, SchemaEntry("ifcvalue",nullptr )
, SchemaEntry("ifcreinforcingbarsurfaceenum",nullptr )
, SchemaEntry("ifcprojectorderrecordtypeenum",nullptr )
, SchemaEntry("ifcdatetimeselect",nullptr )
, SchemaEntry("ifcstructuralsurfacetypeenum",nullptr )
, SchemaEntry("ifcpermeablecoveringoperationenum",nullptr )
, SchemaEntry("ifcfontweight",nullptr )
, SchemaEntry("ifcphmeasure",nullptr )
, SchemaEntry("ifcdescriptivemeasure",nullptr )
, SchemaEntry("ifccurvestylefontselect",nullptr )
, SchemaEntry("ifcunit",nullptr )
, SchemaEntry("ifchatchlinedistanceselect",nullptr )
, SchemaEntry("ifctextstyleselect",nullptr )
, SchemaEntry("ifcmetricvalueselect",nullptr )
, SchemaEntry("ifcvectorordirection",nullptr )
, SchemaEntry("ifcassemblyplaceenum",nullptr )
, SchemaEntry("ifcairterminaltypeenum",nullptr )
, SchemaEntry("ifccoveringtypeenum",nullptr )
, SchemaEntry("ifcplanarforcemeasure",nullptr )
, SchemaEntry("ifcvalvetypeenum",nullptr )
, SchemaEntry("ifcalarmtypeenum",nullptr )
, SchemaEntry("ifcdynamicviscositymeasure",nullptr )
, SchemaEntry("ifccurrencyenum",nullptr )
, SchemaEntry("ifcmodulusofrotationalsubgradereactionmeasure",nullptr )
, SchemaEntry("ifccablecarrierfittingtypeenum",nullptr )
, SchemaEntry("ifcboolean",nullptr )
, SchemaEntry("ifcactionsourcetypeenum",nullptr )
, SchemaEntry("ifcstructuralactivityassignmentselect",nullptr )
, SchemaEntry("ifcdistributionchamberelementtypeenum",nullptr )
, SchemaEntry("ifcevaporativecoolertypeenum",nullptr )
, SchemaEntry("ifcmagneticfluxdensitymeasure",nullptr )
, SchemaEntry("ifclightdistributiondatasourceselect",nullptr )
, SchemaEntry("ifctubebundletypeenum",nullptr )
, SchemaEntry("ifcaccelerationmeasure",nullptr )
, SchemaEntry("ifcboilertypeenum",nullptr )
, SchemaEntry("ifcramptypeenum",nullptr )
, SchemaEntry("ifcluminousintensitydistributionmeasure",nullptr )
, SchemaEntry("ifctrimmingpreference",nullptr )
, SchemaEntry("ifcspecificheatcapacitymeasure",nullptr )
, SchemaEntry("ifcamountofsubstancemeasure",nullptr )
, SchemaEntry("ifcroleenum",nullptr )
, SchemaEntry("ifcdocumentconfidentialityenum",nullptr )
, SchemaEntry("ifcfrequencymeasure",nullptr )
, SchemaEntry("ifcsectiontypeenum",nullptr )
, SchemaEntry("ifcelementassemblytypeenum",nullptr )
, SchemaEntry("ifcfootingtypeenum",nullptr )
, SchemaEntry("ifclayereditem",nullptr )
, SchemaEntry("ifccablesegmenttypeenum",nullptr )
, SchemaEntry("ifcdefinedsymbolselect",nullptr )
, SchemaEntry("ifcbuildingelementproxytypeenum",nullptr )
, SchemaEntry("ifcelectricgeneratortypeenum",nullptr )
, SchemaEntry("ifcrotationalstiffnessmeasure",nullptr )
, SchemaEntry("ifcspaceheatertypeenum",nullptr )
, SchemaEntry("ifcareameasure",nullptr )
, SchemaEntry("ifclabel",nullptr )
, SchemaEntry("ifccostscheduletypeenum",nullptr )
, SchemaEntry("ifcswitchingdevicetypeenum",nullptr )
, SchemaEntry("ifcelectrictimecontroltypeenum",nullptr )
, SchemaEntry("ifcfiltertypeenum",nullptr )
, SchemaEntry("ifcpositivelengthmeasure",nullptr )
, SchemaEntry("ifcnullstyle",nullptr )
, SchemaEntry("ifcconditioncriterionselect",nullptr )
, SchemaEntry("ifcshearmodulusmeasure",nullptr )
, SchemaEntry("ifcnormalisedratiomeasure",nullptr )
, SchemaEntry("ifcdoorpaneloperationenum",nullptr )
, SchemaEntry("ifcpointorvertexpoint",nullptr )
, SchemaEntry("ifcrooftypeenum",nullptr )
, SchemaEntry("ifccountmeasure",nullptr )
, SchemaEntry("ifcelectricconductancemeasure",nullptr )
, SchemaEntry("ifcproceduretypeenum",nullptr )
, SchemaEntry("ifcflowinstrumenttypeenum",nullptr )
, SchemaEntry("ifcelectricmotortypeenum",nullptr )
, SchemaEntry("ifcsurfaceside",nullptr )
, SchemaEntry("ifcstructuralcurvetypeenum",nullptr )
, SchemaEntry("ifccondensertypeenum",nullptr )
, SchemaEntry("ifclinearstiffnessmeasure",nullptr )
, SchemaEntry("ifcunitenum",nullptr )
, SchemaEntry("ifcoccupanttypeenum",nullptr )
, SchemaEntry("ifcthermalloadtypeenum",nullptr )
, SchemaEntry("ifcreinforcingbarroleenum",nullptr )
, SchemaEntry("ifcbenchmarkenum",nullptr )
, SchemaEntry("ifcpositiveplaneanglemeasure",nullptr )
, SchemaEntry("ifctexttransformation",nullptr )
, SchemaEntry("ifcdraughtingcalloutelement",nullptr )
, SchemaEntry("ifcratiomeasure",nullptr )
, SchemaEntry("ifcsolidanglemeasure",nullptr )
, SchemaEntry("ifcpipesegmenttypeenum",nullptr )
, SchemaEntry("ifccablecarriersegmenttypeenum",nullptr )
, SchemaEntry("ifccolourorfactor",nullptr )
, SchemaEntry("ifcidentifier",nullptr )
, SchemaEntry("ifctendontypeenum",nullptr )
, SchemaEntry("ifccontrollertypeenum",nullptr )
, SchemaEntry("ifcradioactivitymeasure",nullptr )
, SchemaEntry("ifctimemeasure",nullptr )
, SchemaEntry("ifcpumptypeenum",nullptr )
, SchemaEntry("ifcelectricheatertypeenum",nullptr )
, SchemaEntry("ifcbeamtypeenum",nullptr )
, SchemaEntry("ifcstateenum",nullptr )
, SchemaEntry("ifcsiprefix",nullptr )
, SchemaEntry("ifcnumericmeasure",nullptr )
, SchemaEntry("ifcoutlettypeenum",nullptr )
, SchemaEntry("ifccompoundplaneanglemeasure",nullptr )
, SchemaEntry("ifcservicelifefactortypeenum",nullptr )
, SchemaEntry("ifclogicaloperatorenum",nullptr )
, SchemaEntry("ifcbooleanoperand",nullptr )
, SchemaEntry("ifcobjectreferenceselect",nullptr )
, SchemaEntry("ifccooledbeamtypeenum",nullptr )
, SchemaEntry("ifcductsilencertypeenum",nullptr )
, SchemaEntry("ifcsectionalareaintegralmeasure",nullptr )
, SchemaEntry("ifcfontvariant",nullptr )
, SchemaEntry("ifcvolumetricflowratemeasure",nullptr )
, SchemaEntry("ifcplatetypeenum",nullptr )
, SchemaEntry("ifcenvironmentalimpactcategoryenum",nullptr )
, SchemaEntry("ifcvibrationisolatortypeenum",nullptr )
, SchemaEntry("ifcthermodynamictemperaturemeasure",nullptr )
, SchemaEntry("ifcrotationalmassmeasure",nullptr )
, SchemaEntry("ifcsecondinminute",nullptr )
, SchemaEntry("ifcdayinmonthnumber",nullptr )
, SchemaEntry("ifcdimensioncount",nullptr )
, SchemaEntry("ifcwindowstyleoperationenum",nullptr )
, SchemaEntry("ifcthermalresistancemeasure",nullptr )
, SchemaEntry("ifcmeasurevalue",nullptr )
, SchemaEntry("ifcwindowpaneloperationenum",nullptr )
, SchemaEntry("ifcchillertypeenum",nullptr )
, SchemaEntry("ifcpositiveratiomeasure",nullptr )
, SchemaEntry("ifcinteger",nullptr )
, SchemaEntry("ifclogical",nullptr )
, SchemaEntry("ifcjunctionboxtypeenum",nullptr )
, SchemaEntry("ifcaddresstypeenum",nullptr )
, SchemaEntry("ifcwasteterminaltypeenum",nullptr )
, SchemaEntry("ifctrimmingselect",nullptr )
, SchemaEntry("ifclightemissionsourceenum",nullptr )
, SchemaEntry("ifcsoundscaleenum",nullptr )
, SchemaEntry("ifcluminousfluxmeasure",nullptr )
, SchemaEntry("ifcelectricresistancemeasure",nullptr )
, SchemaEntry("ifcintegercountratemeasure",nullptr )
, SchemaEntry("ifcphysicalorvirtualenum",nullptr )
, SchemaEntry("ifcmolecularweightmeasure",nullptr )
, SchemaEntry("ifcprofiletypeenum",nullptr )
, SchemaEntry("ifcboxalignment",nullptr )
, SchemaEntry("ifcglobalorlocalenum",nullptr )
, SchemaEntry("ifcspecularroughness",nullptr )
, SchemaEntry("ifclamptypeenum",nullptr )
, SchemaEntry("ifcpiletypeenum",nullptr )
, SchemaEntry("ifcelectriccurrentmeasure",nullptr )
, SchemaEntry("ifcfantypeenum",nullptr )
, SchemaEntry("ifcsurfaceorfacesurface",nullptr )
, SchemaEntry("ifcpipefittingtypeenum",nullptr )
, SchemaEntry("ifctanktypeenum",nullptr )
, SchemaEntry("ifccurvefontorscaledcurvefontselect",nullptr )
, SchemaEntry("ifcwindowstyleconstructionenum",nullptr )
, SchemaEntry("ifcairterminalboxtypeenum",nullptr )
, SchemaEntry("ifcstairflighttypeenum",nullptr )
, SchemaEntry("ifcluminousintensitymeasure",nullptr )
, SchemaEntry("ifcmotorconnectiontypeenum",nullptr )
, SchemaEntry("ifcplaneanglemeasure",nullptr )
, SchemaEntry("ifcactuatortypeenum",nullptr )
, SchemaEntry("ifccolumntypeenum",nullptr )
, SchemaEntry("ifctextfontselect",nullptr )
, SchemaEntry("ifcdoorpanelpositionenum",nullptr )
, SchemaEntry("ifccoiltypeenum",nullptr )
, SchemaEntry("ifcangularvelocitymeasure",nullptr )
, SchemaEntry("ifcanalysismodeltypeenum",nullptr )
, SchemaEntry("ifclibraryselect",nullptr )
, SchemaEntry("ifcforcemeasure",nullptr )
, SchemaEntry("ifcfillareastyletileshapeselect",nullptr )
, SchemaEntry("ifcelectricappliancetypeenum",nullptr )
, SchemaEntry("ifcsurfacetextureenum",nullptr )
, SchemaEntry("ifccharacterstyleselect",nullptr )
, SchemaEntry("ifcenergymeasure",nullptr )
, SchemaEntry("ifcreal",nullptr )
, SchemaEntry("ifccompressortypeenum",nullptr )
, SchemaEntry("ifcelectricdistributionpointfunctionenum",nullptr )
, SchemaEntry("ifcroot",&STEP::ObjectHelper<IfcRoot,4>::Construct )
, SchemaEntry("ifcobjectdefinition",&STEP::ObjectHelper<IfcObjectDefinition,0>::Construct )
, SchemaEntry("ifctypeobject",&STEP::ObjectHelper<IfcTypeObject,2>::Construct )

View File

@ -71,7 +71,7 @@ aiMesh* TempMesh::ToMesh()
ai_assert(mVerts.size() == std::accumulate(mVertcnt.begin(),mVertcnt.end(),size_t(0)));
if (mVerts.empty()) {
return NULL;
return nullptr;
}
std::unique_ptr<aiMesh> mesh(new aiMesh());

View File

@ -201,7 +201,7 @@ struct ConversionData
struct MeshCacheIndex {
const IFC::Schema_2x3::IfcRepresentationItem* item; unsigned int matindex;
MeshCacheIndex() : item(NULL), matindex(0) { }
MeshCacheIndex() : item(nullptr), matindex(0) { }
MeshCacheIndex(const IFC::Schema_2x3::IfcRepresentationItem* i, unsigned int mi) : item(i), matindex(mi) { }
bool operator == (const MeshCacheIndex& o) const { return item == o.item && matindex == o.matindex; }
bool operator < (const MeshCacheIndex& o) const { return item < o.item || (item == o.item && matindex < o.matindex); }

File diff suppressed because it is too large Load Diff

View File

@ -129,6 +129,7 @@ static void releaseMesh(aiMesh **mesh) {
// ------------------------------------------------------------------------------------------------
// Imports the given file into the given scene structure.
<<<<<<< HEAD
void IRRMeshImporter::InternReadFile(const std::string &pFile,
aiScene *pScene, IOSystem *pIOHandler) {
std::unique_ptr<IOStream> file(pIOHandler->Open(pFile));
@ -511,6 +512,406 @@ void IRRMeshImporter::InternReadFile(const std::string &pFile,
pScene->mRootNode->mMeshes[i] = i;
}
=======
void IRRMeshImporter::InternReadFile( const std::string& pFile,
aiScene* pScene, IOSystem* pIOHandler)
{
std::unique_ptr<IOStream> file( pIOHandler->Open( pFile));
// Check whether we can read from the file
if (file.get() == nullptr) {
throw DeadlyImportError("Failed to open IRRMESH file " + pFile + ".");
}
// Construct the irrXML parser
CIrrXML_IOStreamReader st(file.get());
reader = createIrrXMLReader((IFileReadCallBack*) &st);
// final data
std::vector<aiMaterial*> materials;
std::vector<aiMesh*> meshes;
materials.reserve (5);
meshes.reserve(5);
// temporary data - current mesh buffer
aiMaterial* curMat = nullptr;
aiMesh* curMesh = nullptr;
unsigned int curMatFlags = 0;
std::vector<aiVector3D> curVertices,curNormals,curTangents,curBitangents;
std::vector<aiColor4D> curColors;
std::vector<aiVector3D> curUVs,curUV2s;
// some temporary variables
int textMeaning = 0;
int vertexFormat = 0; // 0 = normal; 1 = 2 tcoords, 2 = tangents
bool useColors = false;
// Parse the XML file
while (reader->read()) {
switch (reader->getNodeType()) {
case EXN_ELEMENT:
if (!ASSIMP_stricmp(reader->getNodeName(),"buffer") && (curMat || curMesh)) {
// end of previous buffer. A material and a mesh should be there
if ( !curMat || !curMesh) {
ASSIMP_LOG_ERROR("IRRMESH: A buffer must contain a mesh and a material");
releaseMaterial( &curMat );
releaseMesh( &curMesh );
} else {
materials.push_back(curMat);
meshes.push_back(curMesh);
}
curMat = nullptr;
curMesh = nullptr;
curVertices.clear();
curColors.clear();
curNormals.clear();
curUV2s.clear();
curUVs.clear();
curTangents.clear();
curBitangents.clear();
}
if (!ASSIMP_stricmp(reader->getNodeName(),"material")) {
if (curMat) {
ASSIMP_LOG_WARN("IRRMESH: Only one material description per buffer, please");
releaseMaterial( &curMat );
}
curMat = ParseMaterial(curMatFlags);
}
/* no else here! */ if (!ASSIMP_stricmp(reader->getNodeName(),"vertices"))
{
int num = reader->getAttributeValueAsInt("vertexCount");
if (!num) {
// This is possible ... remove the mesh from the list and skip further reading
ASSIMP_LOG_WARN("IRRMESH: Found mesh with zero vertices");
releaseMaterial( &curMat );
releaseMesh( &curMesh );
textMeaning = 0;
continue;
}
curVertices.reserve(num);
curNormals.reserve(num);
curColors.reserve(num);
curUVs.reserve(num);
// Determine the file format
const char* t = reader->getAttributeValueSafe("type");
if (!ASSIMP_stricmp("2tcoords", t)) {
curUV2s.reserve (num);
vertexFormat = 1;
if (curMatFlags & AI_IRRMESH_EXTRA_2ND_TEXTURE) {
// *********************************************************
// We have a second texture! So use this UV channel
// for it. The 2nd texture can be either a normal
// texture (solid_2layer or lightmap_xxx) or a normal
// map (normal_..., parallax_...)
// *********************************************************
int idx = 1;
aiMaterial* mat = ( aiMaterial* ) curMat;
if (curMatFlags & AI_IRRMESH_MAT_lightmap){
mat->AddProperty(&idx,1,AI_MATKEY_UVWSRC_LIGHTMAP(0));
}
else if (curMatFlags & AI_IRRMESH_MAT_normalmap_solid){
mat->AddProperty(&idx,1,AI_MATKEY_UVWSRC_NORMALS(0));
}
else if (curMatFlags & AI_IRRMESH_MAT_solid_2layer) {
mat->AddProperty(&idx,1,AI_MATKEY_UVWSRC_DIFFUSE(1));
}
}
}
else if (!ASSIMP_stricmp("tangents", t)) {
curTangents.reserve (num);
curBitangents.reserve (num);
vertexFormat = 2;
}
else if (ASSIMP_stricmp("standard", t)) {
releaseMaterial( &curMat );
ASSIMP_LOG_WARN("IRRMESH: Unknown vertex format");
}
else vertexFormat = 0;
textMeaning = 1;
}
else if (!ASSIMP_stricmp(reader->getNodeName(),"indices")) {
if (curVertices.empty() && curMat) {
releaseMaterial( &curMat );
throw DeadlyImportError("IRRMESH: indices must come after vertices");
}
textMeaning = 2;
// start a new mesh
curMesh = new aiMesh();
// allocate storage for all faces
curMesh->mNumVertices = reader->getAttributeValueAsInt("indexCount");
if (!curMesh->mNumVertices) {
// This is possible ... remove the mesh from the list and skip further reading
ASSIMP_LOG_WARN("IRRMESH: Found mesh with zero indices");
// mesh - away
releaseMesh( &curMesh );
// material - away
releaseMaterial( &curMat );
textMeaning = 0;
continue;
}
if (curMesh->mNumVertices % 3) {
ASSIMP_LOG_WARN("IRRMESH: Number if indices isn't divisible by 3");
}
curMesh->mNumFaces = curMesh->mNumVertices / 3;
curMesh->mFaces = new aiFace[curMesh->mNumFaces];
// setup some members
curMesh->mMaterialIndex = (unsigned int)materials.size();
curMesh->mPrimitiveTypes = aiPrimitiveType_TRIANGLE;
// allocate storage for all vertices
curMesh->mVertices = new aiVector3D[curMesh->mNumVertices];
if (curNormals.size() == curVertices.size()) {
curMesh->mNormals = new aiVector3D[curMesh->mNumVertices];
}
if (curTangents.size() == curVertices.size()) {
curMesh->mTangents = new aiVector3D[curMesh->mNumVertices];
}
if (curBitangents.size() == curVertices.size()) {
curMesh->mBitangents = new aiVector3D[curMesh->mNumVertices];
}
if (curColors.size() == curVertices.size() && useColors) {
curMesh->mColors[0] = new aiColor4D[curMesh->mNumVertices];
}
if (curUVs.size() == curVertices.size()) {
curMesh->mTextureCoords[0] = new aiVector3D[curMesh->mNumVertices];
}
if (curUV2s.size() == curVertices.size()) {
curMesh->mTextureCoords[1] = new aiVector3D[curMesh->mNumVertices];
}
}
break;
case EXN_TEXT:
{
const char* sz = reader->getNodeData();
if (textMeaning == 1) {
textMeaning = 0;
// read vertices
do {
SkipSpacesAndLineEnd(&sz);
aiVector3D temp;aiColor4D c;
// Read the vertex position
sz = fast_atoreal_move<float>(sz,(float&)temp.x);
SkipSpaces(&sz);
sz = fast_atoreal_move<float>(sz,(float&)temp.y);
SkipSpaces(&sz);
sz = fast_atoreal_move<float>(sz,(float&)temp.z);
SkipSpaces(&sz);
curVertices.push_back(temp);
// Read the vertex normals
sz = fast_atoreal_move<float>(sz,(float&)temp.x);
SkipSpaces(&sz);
sz = fast_atoreal_move<float>(sz,(float&)temp.y);
SkipSpaces(&sz);
sz = fast_atoreal_move<float>(sz,(float&)temp.z);
SkipSpaces(&sz);
curNormals.push_back(temp);
// read the vertex colors
uint32_t clr = strtoul16(sz,&sz);
ColorFromARGBPacked(clr,c);
if (!curColors.empty() && c != *(curColors.end()-1))
useColors = true;
curColors.push_back(c);
SkipSpaces(&sz);
// read the first UV coordinate set
sz = fast_atoreal_move<float>(sz,(float&)temp.x);
SkipSpaces(&sz);
sz = fast_atoreal_move<float>(sz,(float&)temp.y);
SkipSpaces(&sz);
temp.z = 0.f;
temp.y = 1.f - temp.y; // DX to OGL
curUVs.push_back(temp);
// read the (optional) second UV coordinate set
if (vertexFormat == 1) {
sz = fast_atoreal_move<float>(sz,(float&)temp.x);
SkipSpaces(&sz);
sz = fast_atoreal_move<float>(sz,(float&)temp.y);
temp.y = 1.f - temp.y; // DX to OGL
curUV2s.push_back(temp);
}
// read optional tangent and bitangent vectors
else if (vertexFormat == 2) {
// tangents
sz = fast_atoreal_move<float>(sz,(float&)temp.x);
SkipSpaces(&sz);
sz = fast_atoreal_move<float>(sz,(float&)temp.z);
SkipSpaces(&sz);
sz = fast_atoreal_move<float>(sz,(float&)temp.y);
SkipSpaces(&sz);
temp.y *= -1.0f;
curTangents.push_back(temp);
// bitangents
sz = fast_atoreal_move<float>(sz,(float&)temp.x);
SkipSpaces(&sz);
sz = fast_atoreal_move<float>(sz,(float&)temp.z);
SkipSpaces(&sz);
sz = fast_atoreal_move<float>(sz,(float&)temp.y);
SkipSpaces(&sz);
temp.y *= -1.0f;
curBitangents.push_back(temp);
}
}
/* IMPORTANT: We assume that each vertex is specified in one
line. So we can skip the rest of the line - unknown vertex
elements are ignored.
*/
while (SkipLine(&sz));
}
else if (textMeaning == 2) {
textMeaning = 0;
// read indices
aiFace* curFace = curMesh->mFaces;
aiFace* const faceEnd = curMesh->mFaces + curMesh->mNumFaces;
aiVector3D* pcV = curMesh->mVertices;
aiVector3D* pcN = curMesh->mNormals;
aiVector3D* pcT = curMesh->mTangents;
aiVector3D* pcB = curMesh->mBitangents;
aiColor4D* pcC0 = curMesh->mColors[0];
aiVector3D* pcT0 = curMesh->mTextureCoords[0];
aiVector3D* pcT1 = curMesh->mTextureCoords[1];
unsigned int curIdx = 0;
unsigned int total = 0;
while(SkipSpacesAndLineEnd(&sz)) {
if (curFace >= faceEnd) {
ASSIMP_LOG_ERROR("IRRMESH: Too many indices");
break;
}
if (!curIdx) {
curFace->mNumIndices = 3;
curFace->mIndices = new unsigned int[3];
}
unsigned int idx = strtoul10(sz,&sz);
if (idx >= curVertices.size()) {
ASSIMP_LOG_ERROR("IRRMESH: Index out of range");
idx = 0;
}
curFace->mIndices[curIdx] = total++;
*pcV++ = curVertices[idx];
if (pcN)*pcN++ = curNormals[idx];
if (pcT)*pcT++ = curTangents[idx];
if (pcB)*pcB++ = curBitangents[idx];
if (pcC0)*pcC0++ = curColors[idx];
if (pcT0)*pcT0++ = curUVs[idx];
if (pcT1)*pcT1++ = curUV2s[idx];
if (++curIdx == 3) {
++curFace;
curIdx = 0;
}
}
if (curFace != faceEnd)
ASSIMP_LOG_ERROR("IRRMESH: Not enough indices");
// Finish processing the mesh - do some small material workarounds
if (curMatFlags & AI_IRRMESH_MAT_trans_vertex_alpha && !useColors) {
// Take the opacity value of the current material
// from the common vertex color alpha
aiMaterial* mat = (aiMaterial*)curMat;
mat->AddProperty(&curColors[0].a,1,AI_MATKEY_OPACITY);
}
}}
break;
default:
// GCC complains here ...
break;
};
}
// End of the last buffer. A material and a mesh should be there
if (curMat || curMesh) {
if ( !curMat || !curMesh) {
ASSIMP_LOG_ERROR("IRRMESH: A buffer must contain a mesh and a material");
releaseMaterial( &curMat );
releaseMesh( &curMesh );
}
else {
materials.push_back(curMat);
meshes.push_back(curMesh);
}
}
if (materials.empty())
throw DeadlyImportError("IRRMESH: Unable to read a mesh from this file");
// now generate the output scene
pScene->mNumMeshes = (unsigned int)meshes.size();
pScene->mMeshes = new aiMesh*[pScene->mNumMeshes];
for (unsigned int i = 0; i < pScene->mNumMeshes;++i) {
pScene->mMeshes[i] = meshes[i];
// clean this value ...
pScene->mMeshes[i]->mNumUVComponents[3] = 0;
}
pScene->mNumMaterials = (unsigned int)materials.size();
pScene->mMaterials = new aiMaterial*[pScene->mNumMaterials];
::memcpy(pScene->mMaterials,&materials[0],sizeof(void*)*pScene->mNumMaterials);
pScene->mRootNode = new aiNode();
pScene->mRootNode->mName.Set("<IRRMesh>");
pScene->mRootNode->mNumMeshes = pScene->mNumMeshes;
pScene->mRootNode->mMeshes = new unsigned int[pScene->mNumMeshes];
for (unsigned int i = 0; i < pScene->mNumMeshes;++i)
pScene->mRootNode->mMeshes[i] = i;
// clean up and return
delete reader;
AI_DEBUG_INVALIDATE_PTR(reader);
>>>>>>> master
}
#endif // !! ASSIMP_BUILD_NO_IRRMESH_IMPORTER

View File

@ -538,11 +538,11 @@ void AnimResolver::GetKeys(std::vector<aiVectorKey> &out,
// ------------------------------------------------------------------------------------------------
// Extract animation channel
void AnimResolver::ExtractAnimChannel(aiNodeAnim **out, unsigned int /*= 0*/) {
*out = NULL;
*out = nullptr;
//FIXME: crashes if more than one component is animated at different timings, to be resolved.
// If we have no envelopes, return NULL
// If we have no envelopes, return nullptr
if (envelopes.empty()) {
return;
}

View File

@ -211,7 +211,7 @@ public:
// ------------------------------------------------------------------
/** @brief Extract a node animation channel
* @param out Receives a pointer to a newly allocated node anim.
* If there's just one keyframe defined, *out is set to NULL and
* If there's just one keyframe defined, *out is set to nullptr and
* no animation channel is computed.
* @param flags Any combination of the AI_LWO_ANIM_FLAG_XXX flags.
*/
@ -261,7 +261,7 @@ protected:
* @param envl_y Y-component envelope
* @param envl_z Z-component envelope
* @param flags Any combination of the AI_LWO_ANIM_FLAG_XXX flags.
* @note Up to two input envelopes may be NULL
* @note Up to two input envelopes may be nullptr
*/
void GetKeys(std::vector<aiVectorKey>& out,
LWO::Envelope* envl_x,

View File

@ -255,7 +255,7 @@ void LWOImporter::LoadLWOBSurface(unsigned int size)
mSurfaces->push_back( LWO::Surface () );
LWO::Surface& surf = mSurfaces->back();
LWO::Texture* pTex = NULL;
LWO::Texture *pTex = nullptr;
GetS0(surf.mName,size);
bool running = true;

View File

@ -917,7 +917,7 @@ inline void CreateNewEntry(std::vector<T> &list, unsigned int srcIdx) {
// ------------------------------------------------------------------------------------------------
inline void LWOImporter::DoRecursiveVMAPAssignment(VMapEntry *base, unsigned int numRead,
unsigned int idx, float *data) {
ai_assert(NULL != data);
ai_assert(nullptr != data);
LWO::ReferrerList &refList = mCurLayer->mPointReferrers;
unsigned int i;

View File

@ -305,7 +305,7 @@ private:
/** Add children to a node
* @param node Node to become a father
* @param parent Index of the node
* @param apcNodes Flat list of nodes - used nodes are set to NULL.
* @param apcNodes Flat list of nodes - used nodes are set to nullptr.
*/
void AddChildren(aiNode* node, uint16_t parent,
std::vector<aiNode*>& apcNodes);

View File

@ -79,7 +79,7 @@ inline aiTextureMapMode GetMapMode(LWO::Texture::Wrap in) {
// ------------------------------------------------------------------------------------------------
bool LWOImporter::HandleTextures(aiMaterial *pcMat, const TextureList &in, aiTextureType type) {
ai_assert(NULL != pcMat);
ai_assert(nullptr != pcMat);
unsigned int cur = 0, temp = 0;
aiString s;
@ -603,7 +603,7 @@ void LWOImporter::LoadLWO2TextureBlock(LE_NCONST IFF::SubChunkHeader *head, unsi
}
// get the destination channel
TextureList *listRef = NULL;
TextureList *listRef = nullptr;
switch (tex.type) {
case AI_LWO_COLR:
listRef = &surf.mColorTextures;

View File

@ -342,7 +342,7 @@ void LWSImporter::BuildGraph(aiNode *nd, LWS::NodeDesc &src, std::vector<Attachm
if (src.type == LWS::NodeDesc::OBJECT) {
// If the object is from an external file, get it
aiScene *obj = NULL;
aiScene *obj = nullptr;
if (src.path.length()) {
obj = batch.GetImport(src.id);
if (!obj) {
@ -359,7 +359,7 @@ void LWSImporter::BuildGraph(aiNode *nd, LWS::NodeDesc &src, std::vector<Attachm
//Remove first node from obj (the old pivot), reset transform of second node (the mesh node)
aiNode *newRootNode = obj->mRootNode->mChildren[0];
obj->mRootNode->mChildren[0] = NULL;
obj->mRootNode->mChildren[0] = nullptr;
delete obj->mRootNode;
obj->mRootNode = newRootNode;
@ -600,7 +600,7 @@ void LWSImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
d.number = cur_object++;
}
std::string path = FindLWOFile(c);
d.id = batch.AddLoadRequest(path, 0, NULL);
d.id = batch.AddLoadRequest(path, 0, nullptr);
d.path = path;
nodes.push_back(d);

View File

@ -84,7 +84,19 @@ public:
*/
struct NodeDesc {
NodeDesc() :
type(), id(), number(0), parent(0), name(""), isPivotSet(false), lightColor(1.f, 1.f, 1.f), lightIntensity(1.f), lightType(0), lightFalloffType(0), lightConeAngle(45.f), lightEdgeAngle(), parent_resolved(NULL) {}
type(),
id(),
number(0),
parent(0),
name(""),
isPivotSet(false),
lightColor(1.f, 1.f, 1.f),
lightIntensity(1.f),
lightType(0),
lightFalloffType(0),
lightConeAngle(45.f),
lightEdgeAngle(),
parent_resolved(nullptr) {}
enum {

View File

@ -181,7 +181,7 @@ M3D_INDEX addMaterial(const Assimp::M3DWrapper &m3d, const aiMaterial *mat) {
}
m3d->material[mi].name = SafeStr(name, true);
m3d->material[mi].numprop = 0;
m3d->material[mi].prop = NULL;
m3d->material[mi].prop = nullptr;
// iterate through the material property table and see what we got
for (k = 0; k < 15; k++) {
unsigned int j;
@ -229,8 +229,8 @@ M3D_INDEX addMaterial(const Assimp::M3DWrapper &m3d, const aiMaterial *mat) {
}
if (aiTxProps[k].pKey &&
mat->GetTexture((aiTextureType)aiTxProps[k].type,
aiTxProps[k].index, &name, NULL, NULL, NULL,
NULL, NULL) == AI_SUCCESS) {
aiTxProps[k].index, &name, nullptr, nullptr, nullptr,
nullptr, nullptr) == AI_SUCCESS) {
unsigned int i;
for (j = name.length - 1; j > 0 && name.data[j] != '.'; j++)
;
@ -259,7 +259,7 @@ M3D_INDEX addMaterial(const Assimp::M3DWrapper &m3d, const aiMaterial *mat) {
m3d->texture[i].name = fn;
m3d->texture[i].w = 0;
m3d->texture[i].h = 0;
m3d->texture[i].d = NULL;
m3d->texture[i].d = nullptr;
}
addProp(&m3d->material[mi],
m3d_propertytypes[k].id + 128, i);

View File

@ -618,8 +618,10 @@ aiColor4D M3DImporter::mkColor(uint32_t c) {
void M3DImporter::convertPose(const M3DWrapper &m3d, aiMatrix4x4 *m, unsigned int posid, unsigned int orientid) {
ai_assert(m != nullptr);
ai_assert(m3d);
ai_assert(posid != M3D_UNDEF && posid < m3d->numvertex);
ai_assert(orientid != M3D_UNDEF && orientid < m3d->numvertex);
ai_assert(posid != M3D_UNDEF);
ai_assert(posid < m3d->numvertex);
ai_assert(orientid != M3D_UNDEF);
ai_assert(orientid < m3d->numvertex);
if (!m3d->numvertex || !m3d->vertex)
return;
m3dv_t *p = &m3d->vertex[posid];

View File

@ -71,14 +71,14 @@ static const aiMatProp aiProps[] = {
{ AI_MATKEY_OPACITY }, /* m3dp_d */
{ AI_MATKEY_SHADING_MODEL }, /* m3dp_il */
{ NULL, 0, 0 }, /* m3dp_Pr */
{ nullptr, 0, 0 }, /* m3dp_Pr */
{ AI_MATKEY_REFLECTIVITY }, /* m3dp_Pm */
{ NULL, 0, 0 }, /* m3dp_Ps */
{ nullptr, 0, 0 }, /* m3dp_Ps */
{ AI_MATKEY_REFRACTI }, /* m3dp_Ni */
{ NULL, 0, 0 }, /* m3dp_Nt */
{ NULL, 0, 0 },
{ NULL, 0, 0 },
{ NULL, 0, 0 }
{ nullptr, 0, 0 }, /* m3dp_Nt */
{ nullptr, 0, 0 },
{ nullptr, 0, 0 },
{ nullptr, 0, 0 }
};
/* --- Texture Map Properties --- !!!!! must match m3d_propertytypes !!!!! */
@ -88,19 +88,19 @@ static const aiMatProp aiTxProps[] = {
{ AI_MATKEY_TEXTURE_SPECULAR(0) }, /* m3dp_map_Ks */
{ AI_MATKEY_TEXTURE_SHININESS(0) }, /* m3dp_map_Ns */
{ AI_MATKEY_TEXTURE_EMISSIVE(0) }, /* m3dp_map_Ke */
{ NULL, 0, 0 }, /* m3dp_map_Tf */
{ nullptr, 0, 0 }, /* m3dp_map_Tf */
{ AI_MATKEY_TEXTURE_HEIGHT(0) }, /* m3dp_bump */
{ AI_MATKEY_TEXTURE_OPACITY(0) }, /* m3dp_map_d */
{ AI_MATKEY_TEXTURE_NORMALS(0) }, /* m3dp_map_N */
{ AI_MATKEY_TEXTURE(aiTextureType_DIFFUSE_ROUGHNESS,0) },/* m3dp_map_Pr */
{ AI_MATKEY_TEXTURE(aiTextureType_METALNESS,0) }, /* m3dp_map_Pm */
{ NULL, 0, 0 }, /* m3dp_map_Ps */
{ nullptr, 0, 0 }, /* m3dp_map_Ps */
{ AI_MATKEY_TEXTURE(aiTextureType_REFLECTION,0) }, /* m3dp_map_Ni */
{ NULL, 0, 0 }, /* m3dp_map_Nt */
{ NULL, 0, 0 },
{ NULL, 0, 0 },
{ NULL, 0, 0 }
{ nullptr, 0, 0 }, /* m3dp_map_Nt */
{ nullptr, 0, 0 },
{ nullptr, 0, 0 },
{ nullptr, 0, 0 }
};
#endif // AI_M3DMATERIALS_H_INC

View File

@ -72,7 +72,7 @@ unsigned char *m3dimporter_readfile(char *fn, unsigned int *size) {
std::unique_ptr<Assimp::IOStream> pStream(
(reinterpret_cast<Assimp::IOSystem *>(m3dimporter_pIOHandler))->Open(file, "rb"));
size_t fileSize = 0;
unsigned char *data = NULL;
unsigned char *data = nullptr;
// sometimes pStream is nullptr in a single-threaded scenario too for some reason
// (should be an empty object returning nothing I guess)
if (pStream) {

View File

@ -5071,7 +5071,7 @@ unsigned char *m3d_save(m3d_t *model, int quality, int flags, unsigned int *size
ptr += sprintf(ptr, "\r\n");
}
/* mathematical shapes face */
if (model->numshape && model->numshape && !(flags & M3D_EXP_NOFACE)) {
if (model->numshape !(flags & M3D_EXP_NOFACE)) {
for (j = 0; j < model->numshape; j++) {
sn = _m3d_safestr(model->shape[j].name, 0);
if (!sn) {

View File

@ -221,20 +221,21 @@ void MD2Importer::InternReadFile( const std::string& pFile,
std::unique_ptr<IOStream> file( pIOHandler->Open( pFile));
// Check whether we can read from the file
if( file.get() == NULL)
if (file.get() == nullptr) {
throw DeadlyImportError("Failed to open MD2 file " + pFile + "");
}
// check whether the md3 file is large enough to contain
// at least the file header
fileSize = (unsigned int)file->FileSize();
if( fileSize < sizeof(MD2::Header))
if (fileSize < sizeof(MD2::Header)) {
throw DeadlyImportError("MD2 File is too small");
}
std::vector<uint8_t> mBuffer2(fileSize);
file->Read(&mBuffer2[0], 1, fileSize);
mBuffer = &mBuffer2[0];
m_pcHeader = (BE_NCONST MD2::Header*)mBuffer;
#ifdef AI_BUILD_BIG_ENDIAN

View File

@ -50,21 +50,20 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* http://www.heppler.com/shader/shader/
*/
#ifndef ASSIMP_BUILD_NO_MD3_IMPORTER
#include "AssetLib/MD3/MD3Loader.h"
#include "Common/Importer.h"
#include <assimp/SceneCombiner.h>
#include <assimp/GenericProperty.h>
#include <assimp/RemoveComments.h>
#include <assimp/ParsingUtils.h>
#include <assimp/DefaultLogger.hpp>
#include <assimp/IOSystem.hpp>
#include <assimp/RemoveComments.h>
#include <assimp/SceneCombiner.h>
#include <assimp/importerdesc.h>
#include <assimp/material.h>
#include <assimp/scene.h>
#include <assimp/importerdesc.h>
#include <assimp/DefaultLogger.hpp>
#include <assimp/IOSystem.hpp>
#include <cctype>
#include <memory>
@ -86,8 +85,7 @@ static const aiImporterDesc desc = {
// ------------------------------------------------------------------------------------------------
// Convert a Q3 shader blend function to the appropriate enum value
Q3Shader::BlendFunc StringToBlendFunc(const std::string& m)
{
Q3Shader::BlendFunc StringToBlendFunc(const std::string &m) {
if (m == "GL_ONE") {
return Q3Shader::BLEND_GL_ONE;
}
@ -109,8 +107,7 @@ Q3Shader::BlendFunc StringToBlendFunc(const std::string& m)
// ------------------------------------------------------------------------------------------------
// Load a Quake 3 shader
bool Q3Shader::LoadShader(ShaderData& fill, const std::string& pFile,IOSystem* io)
{
bool Q3Shader::LoadShader(ShaderData &fill, const std::string &pFile, IOSystem *io) {
std::unique_ptr<IOStream> file(io->Open(pFile, "rt"));
if (!file.get())
return false; // if we can't access the file, don't worry and return
@ -127,8 +124,8 @@ bool Q3Shader::LoadShader(ShaderData& fill, const std::string& pFile,IOSystem* i
CommentRemover::RemoveLineComments("//", &_buff[0]);
const char *buff = &_buff[0];
Q3Shader::ShaderDataBlock* curData = NULL;
Q3Shader::ShaderMapBlock* curMap = NULL;
Q3Shader::ShaderDataBlock *curData = nullptr;
Q3Shader::ShaderMapBlock *curMap = nullptr;
// read line per line
for (; SkipSpacesAndLineEnd(&buff); SkipLine(&buff)) {
@ -161,16 +158,13 @@ bool Q3Shader::LoadShader(ShaderData& fill, const std::string& pFile,IOSystem* i
if (blend_src == "add") {
curMap->blend_src = Q3Shader::BLEND_GL_ONE;
curMap->blend_dest = Q3Shader::BLEND_GL_ONE;
}
else if (blend_src == "filter") {
} else if (blend_src == "filter") {
curMap->blend_src = Q3Shader::BLEND_GL_DST_COLOR;
curMap->blend_dest = Q3Shader::BLEND_GL_ZERO;
}
else if (blend_src == "blend") {
} else if (blend_src == "blend") {
curMap->blend_src = Q3Shader::BLEND_GL_SRC_ALPHA;
curMap->blend_dest = Q3Shader::BLEND_GL_ONE_MINUS_SRC_ALPHA;
}
else {
} else {
curMap->blend_src = StringToBlendFunc(blend_src);
curMap->blend_dest = StringToBlendFunc(GetNextToken(buff));
}
@ -180,26 +174,22 @@ bool Q3Shader::LoadShader(ShaderData& fill, const std::string& pFile,IOSystem* i
const std::string at = GetNextToken(buff);
if (at == "GT0") {
curMap->alpha_test = Q3Shader::AT_GT0;
}
else if (at == "LT128") {
} else if (at == "LT128") {
curMap->alpha_test = Q3Shader::AT_LT128;
}
else if (at == "GE128") {
} else if (at == "GE128") {
curMap->alpha_test = Q3Shader::AT_GE128;
}
}
else if (*buff == '}') {
} else if (*buff == '}') {
++buff;
// close this map section
curMap = NULL;
curMap = nullptr;
break;
}
}
}
else if (*buff == '}') {
} else if (*buff == '}') {
++buff;
curData = NULL;
curData = nullptr;
break;
}
@ -231,8 +221,7 @@ bool Q3Shader::LoadShader(ShaderData& fill, const std::string& pFile,IOSystem* i
// ------------------------------------------------------------------------------------------------
// Load a Quake 3 skin
bool Q3Shader::LoadSkin(SkinData& fill, const std::string& pFile,IOSystem* io)
{
bool Q3Shader::LoadSkin(SkinData &fill, const std::string &pFile, IOSystem *io) {
std::unique_ptr<IOStream> file(io->Open(pFile, "rt"));
if (!file.get())
return false; // if we can't access the file, don't worry and return
@ -241,7 +230,8 @@ bool Q3Shader::LoadSkin(SkinData& fill, const std::string& pFile,IOSystem* io)
// read file in memory
const size_t s = file->FileSize();
std::vector<char> _buff(s+1);const char* buff = &_buff[0];
std::vector<char> _buff(s + 1);
const char *buff = &_buff[0];
file->Read(&_buff[0], s, 1);
_buff[s] = 0;
@ -270,9 +260,8 @@ bool Q3Shader::LoadSkin(SkinData& fill, const std::string& pFile,IOSystem* io)
// ------------------------------------------------------------------------------------------------
// Convert Q3Shader to material
void Q3Shader::ConvertShaderToMaterial(aiMaterial* out, const ShaderDataBlock& shader)
{
ai_assert(NULL != out);
void Q3Shader::ConvertShaderToMaterial(aiMaterial *out, const ShaderDataBlock &shader) {
ai_assert(nullptr != out);
/* IMPORTANT: This is not a real conversion. Actually we're just guessing and
* hacking around to build an aiMaterial that looks nearly equal to the
@ -309,7 +298,8 @@ void Q3Shader::ConvertShaderToMaterial(aiMaterial* out, const ShaderDataBlock& s
// Textures with alpha funcs
// - aiTextureFlags_UseAlpha is set (otherwise aiTextureFlags_NoAlpha is explicitly set)
aiString s((*it).name);
aiTextureType type; unsigned int index;
aiTextureType type;
unsigned int index;
if ((*it).blend_src == Q3Shader::BLEND_GL_ONE && (*it).blend_dest == Q3Shader::BLEND_GL_ONE) {
if (it == shader.maps.begin()) {
@ -318,17 +308,14 @@ void Q3Shader::ConvertShaderToMaterial(aiMaterial* out, const ShaderDataBlock& s
index = cur_diffuse++;
type = aiTextureType_DIFFUSE;
}
else {
} else {
index = cur_emissive++;
type = aiTextureType_EMISSIVE;
}
}
else if ((*it).blend_src == Q3Shader::BLEND_GL_DST_COLOR && (*it).blend_dest == Q3Shader::BLEND_GL_ZERO) {
} else if ((*it).blend_src == Q3Shader::BLEND_GL_DST_COLOR && (*it).blend_dest == Q3Shader::BLEND_GL_ZERO) {
index = cur_lm++;
type = aiTextureType_LIGHTMAP;
}
else {
} else {
const int blend = aiBlendMode_Default;
out->AddProperty(&blend, 1, AI_MATKEY_BLEND_FUNC);
@ -353,26 +340,16 @@ void Q3Shader::ConvertShaderToMaterial(aiMaterial* out, const ShaderDataBlock& s
// ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer
MD3Importer::MD3Importer()
: configFrameID (0)
, configHandleMP (true)
, configSpeedFlag()
, pcHeader()
, mBuffer()
, fileSize()
, mScene()
, mIOHandler()
{}
MD3Importer::MD3Importer() :
configFrameID(0), configHandleMP(true), configSpeedFlag(), pcHeader(), mBuffer(), fileSize(), mScene(), mIOHandler() {}
// ------------------------------------------------------------------------------------------------
// Destructor, private as well
MD3Importer::~MD3Importer()
{}
MD3Importer::~MD3Importer() {}
// ------------------------------------------------------------------------------------------------
// Returns whether the class can handle the format of the given file.
bool MD3Importer::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
{
bool MD3Importer::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool checkSig) const {
const std::string extension = GetExtension(pFile);
if (extension == "md3")
return true;
@ -387,8 +364,7 @@ bool MD3Importer::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool
}
// ------------------------------------------------------------------------------------------------
void MD3Importer::ValidateHeaderOffsets()
{
void MD3Importer::ValidateHeaderOffsets() {
// Check magic number
if (pcHeader->IDENT != AI_MD3_MAGIC_NUMBER_BE &&
pcHeader->IDENT != AI_MD3_MAGIC_NUMBER_LE)
@ -420,8 +396,7 @@ void MD3Importer::ValidateHeaderOffsets()
}
// ------------------------------------------------------------------------------------------------
void MD3Importer::ValidateSurfaceHeaderOffsets(const MD3::Surface* pcSurf)
{
void MD3Importer::ValidateSurfaceHeaderOffsets(const MD3::Surface *pcSurf) {
// Calculate the relative offset of the surface
const int32_t ofs = int32_t((const unsigned char *)pcSurf - this->mBuffer);
@ -460,8 +435,7 @@ const aiImporterDesc* MD3Importer::GetInfo () const {
// ------------------------------------------------------------------------------------------------
// Setup configuration properties
void MD3Importer::SetupProperties(const Importer* pImp)
{
void MD3Importer::SetupProperties(const Importer *pImp) {
// The
// AI_CONFIG_IMPORT_MD3_KEYFRAME option overrides the
// AI_CONFIG_IMPORT_GLOBAL_KEYFRAME option.
@ -485,8 +459,7 @@ void MD3Importer::SetupProperties(const Importer* pImp)
// ------------------------------------------------------------------------------------------------
// Try to read the skin for a MD3 file
void MD3Importer::ReadSkin(Q3Shader::SkinData& fill) const
{
void MD3Importer::ReadSkin(Q3Shader::SkinData &fill) const {
// skip any postfixes (e.g. lower_1.md3)
std::string::size_type s = filename.find_last_of('_');
if (s == std::string::npos) {
@ -503,8 +476,7 @@ void MD3Importer::ReadSkin(Q3Shader::SkinData& fill) const
// ------------------------------------------------------------------------------------------------
// Try to read the shader for a MD3 file
void MD3Importer::ReadShader(Q3Shader::ShaderData& fill) const
{
void MD3Importer::ReadShader(Q3Shader::ShaderData &fill) const {
// Determine Q3 model name from given path
const std::string::size_type s = path.find_last_of("\\/", path.length() - 2);
const std::string model_file = path.substr(s + 1, path.length() - (s + 2));
@ -514,8 +486,7 @@ void MD3Importer::ReadShader(Q3Shader::ShaderData& fill) const
if (!Q3Shader::LoadShader(fill, path + "..\\..\\..\\scripts\\" + model_file + ".shader", mIOHandler)) {
Q3Shader::LoadShader(fill, path + "..\\..\\..\\scripts\\" + filename + ".shader", mIOHandler);
}
}
else {
} else {
// If the given string specifies a file, load this file.
// Otherwise it's a directory.
const std::string::size_type st = configShaderFile.find_last_of('.');
@ -524,8 +495,7 @@ void MD3Importer::ReadShader(Q3Shader::ShaderData& fill) const
if (!Q3Shader::LoadShader(fill, configShaderFile + model_file + ".shader", mIOHandler)) {
Q3Shader::LoadShader(fill, configShaderFile + filename + ".shader", mIOHandler);
}
}
else {
} else {
Q3Shader::LoadShader(fill, configShaderFile, mIOHandler);
}
}
@ -533,8 +503,7 @@ void MD3Importer::ReadShader(Q3Shader::ShaderData& fill) const
// ------------------------------------------------------------------------------------------------
// Tiny helper to remove a single node from its parent' list
void RemoveSingleNodeFromList(aiNode* nd)
{
void RemoveSingleNodeFromList(aiNode *nd) {
if (!nd || nd->mNumChildren || !nd->mParent) return;
aiNode *par = nd->mParent;
for (unsigned int i = 0; i < par->mNumChildren; ++i) {
@ -551,8 +520,7 @@ void RemoveSingleNodeFromList(aiNode* nd)
// ------------------------------------------------------------------------------------------------
// Read a multi-part Q3 player model
bool MD3Importer::ReadMultipartFile()
{
bool MD3Importer::ReadMultipartFile() {
// check whether the file name contains a common postfix, e.g lower_2.md3
std::string::size_type s = filename.find_last_of('_'), t = filename.find_last_of('.');
@ -569,9 +537,9 @@ bool MD3Importer::ReadMultipartFile()
const std::string upper = path + "upper" + suffix + ".md3";
const std::string head = path + "head" + suffix + ".md3";
aiScene* scene_upper = NULL;
aiScene* scene_lower = NULL;
aiScene* scene_head = NULL;
aiScene *scene_upper = nullptr;
aiScene *scene_lower = nullptr;
aiScene *scene_head = nullptr;
std::string failure;
aiNode *tag_torso, *tag_head;
@ -681,8 +649,7 @@ error_cleanup:
// ------------------------------------------------------------------------------------------------
// Convert a MD3 path to a proper value
void MD3Importer::ConvertPath(const char* texture_name, const char* header_name, std::string& out) const
{
void MD3Importer::ConvertPath(const char *texture_name, const char *header_name, std::string &out) const {
// If the MD3's internal path itself and the given path are using
// the same directory, remove it completely to get right output paths.
const char *end1 = ::strrchr(header_name, '\\');
@ -706,8 +673,8 @@ void MD3Importer::ConvertPath(const char* texture_name, const char* header_name,
out = end2 + 1;
return;
}
}
else len2 = std::min (len1, (size_t)(end2 - texture_name ));
} else
len2 = std::min(len1, (size_t)(end2 - texture_name));
if (!ASSIMP_strincmp(texture_name, header_name, static_cast<unsigned int>(len2))) {
// Use the file name only
out = end2 + 1;
@ -747,8 +714,9 @@ void MD3Importer::InternReadFile( const std::string& pFile, aiScene* pScene, IOS
std::unique_ptr<IOStream> file(pIOHandler->Open(pFile));
// Check whether we can read from the file
if( file.get() == NULL)
if (file.get() == nullptr) {
throw DeadlyImportError("Failed to open MD3 file " + pFile + ".");
}
// Check whether the md3 file is large enough to contain the header
fileSize = (unsigned int)file->FileSize();
@ -852,24 +820,19 @@ void MD3Importer::InternReadFile( const std::string& pFile, aiScene* pScene, IOS
ValidateSurfaceHeaderOffsets(pcSurfaces);
// Navigate to the vertex list of the surface
BE_NCONST MD3::Vertex* pcVertices = (BE_NCONST MD3::Vertex*)
(((uint8_t*)pcSurfaces) + pcSurfaces->OFS_XYZNORMAL);
BE_NCONST MD3::Vertex *pcVertices = (BE_NCONST MD3::Vertex *)(((uint8_t *)pcSurfaces) + pcSurfaces->OFS_XYZNORMAL);
// Navigate to the triangle list of the surface
BE_NCONST MD3::Triangle* pcTriangles = (BE_NCONST MD3::Triangle*)
(((uint8_t*)pcSurfaces) + pcSurfaces->OFS_TRIANGLES);
BE_NCONST MD3::Triangle *pcTriangles = (BE_NCONST MD3::Triangle *)(((uint8_t *)pcSurfaces) + pcSurfaces->OFS_TRIANGLES);
// Navigate to the texture coordinate list of the surface
BE_NCONST MD3::TexCoord* pcUVs = (BE_NCONST MD3::TexCoord*)
(((uint8_t*)pcSurfaces) + pcSurfaces->OFS_ST);
BE_NCONST MD3::TexCoord *pcUVs = (BE_NCONST MD3::TexCoord *)(((uint8_t *)pcSurfaces) + pcSurfaces->OFS_ST);
// Navigate to the shader list of the surface
BE_NCONST MD3::Shader* pcShaders = (BE_NCONST MD3::Shader*)
(((uint8_t*)pcSurfaces) + pcSurfaces->OFS_SHADERS);
BE_NCONST MD3::Shader *pcShaders = (BE_NCONST MD3::Shader *)(((uint8_t *)pcSurfaces) + pcSurfaces->OFS_SHADERS);
// If the submesh is empty ignore it
if (0 == pcSurfaces->NUM_VERTICES || 0 == pcSurfaces->NUM_TRIANGLES)
{
if (0 == pcSurfaces->NUM_VERTICES || 0 == pcSurfaces->NUM_TRIANGLES) {
pcSurfaces = (BE_NCONST MD3::Surface *)(((uint8_t *)pcSurfaces) + pcSurfaces->OFS_END);
pScene->mNumMeshes--;
continue;
@ -880,7 +843,7 @@ void MD3Importer::InternReadFile( const std::string& pFile, aiScene* pScene, IOS
aiMesh *pcMesh = pScene->mMeshes[iNum];
std::string _texture_name;
const char* texture_name = NULL;
const char *texture_name = nullptr;
// Check whether we have a texture record for this surface in the .skin file
std::list<Q3Shader::SkinData::TextureEntry>::iterator it = std::find(
@ -902,7 +865,7 @@ void MD3Importer::InternReadFile( const std::string& pFile, aiScene* pScene, IOS
ConvertPath(texture_name, header_name, convertedPath);
}
const Q3Shader::ShaderDataBlock* shader = NULL;
const Q3Shader::ShaderDataBlock *shader = nullptr;
// Now search the current shader for a record with this name (
// excluding texture file extension)
@ -1089,8 +1052,7 @@ void MD3Importer::InternReadFile( const std::string& pFile, aiScene* pScene, IOS
1.f, 0.f, 0.f, 0.f,
0.f, 0.f, 1.f, 0.f,
0.f, -1.f, 0.f, 0.f,
0.f,0.f,0.f,1.f
);
0.f, 0.f, 0.f, 1.f);
}
#endif // !! ASSIMP_BUILD_NO_MD3_IMPORTER

View File

@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2020, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
@ -82,7 +80,15 @@ static const aiImporterDesc desc = {
// ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer
MD5Importer::MD5Importer() :
mIOHandler(nullptr), mBuffer(), fileSize(), iLineNumber(), pScene(), bHadMD5Mesh(), bHadMD5Anim(), bHadMD5Camera(), configNoAutoLoad(false) {
mIOHandler(nullptr),
mBuffer(),
mFileSize(),
mLineNumber(),
mScene(),
mHadMD5Mesh(),
mHadMD5Anim(),
mHadMD5Camera(),
mCconfigNoAutoLoad(false) {
// empty
}
@ -106,6 +112,7 @@ bool MD5Importer::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool c
const char *tokens[] = { "MD5Version" };
return SearchFileHeaderForToken(pIOHandler, pFile, tokens, 1);
}
return false;
}
@ -119,16 +126,15 @@ const aiImporterDesc *MD5Importer::GetInfo() const {
// Setup import properties
void MD5Importer::SetupProperties(const Importer *pImp) {
// AI_CONFIG_IMPORT_MD5_NO_ANIM_AUTOLOAD
configNoAutoLoad = (0 != pImp->GetPropertyInteger(AI_CONFIG_IMPORT_MD5_NO_ANIM_AUTOLOAD, 0));
mCconfigNoAutoLoad = (0 != pImp->GetPropertyInteger(AI_CONFIG_IMPORT_MD5_NO_ANIM_AUTOLOAD, 0));
}
// ------------------------------------------------------------------------------------------------
// Imports the given file into the given scene structure.
void MD5Importer::InternReadFile(const std::string &pFile,
aiScene *_pScene, IOSystem *pIOHandler) {
void MD5Importer::InternReadFile(const std::string &pFile, aiScene *_pScene, IOSystem *pIOHandler) {
mIOHandler = pIOHandler;
pScene = _pScene;
bHadMD5Mesh = bHadMD5Anim = bHadMD5Camera = false;
mScene = _pScene;
mHadMD5Mesh = mHadMD5Anim = mHadMD5Camera = false;
// remove the file extension
const std::string::size_type pos = pFile.find_last_of('.');
@ -138,7 +144,7 @@ void MD5Importer::InternReadFile(const std::string &pFile,
try {
if (extension == "md5camera") {
LoadMD5CameraFile();
} else if (configNoAutoLoad || extension == "md5anim") {
} else if (mCconfigNoAutoLoad || extension == "md5anim") {
// determine file extension and process just *one* file
if (extension.length() == 0) {
throw DeadlyImportError("Failure, need file extension to determine MD5 part type");
@ -158,17 +164,17 @@ void MD5Importer::InternReadFile(const std::string &pFile,
}
// make sure we have at least one file
if (!bHadMD5Mesh && !bHadMD5Anim && !bHadMD5Camera) {
if (!mHadMD5Mesh && !mHadMD5Anim && !mHadMD5Camera) {
throw DeadlyImportError("Failed to read valid contents out of this MD5* file");
}
// Now rotate the whole scene 90 degrees around the x axis to match our internal coordinate system
pScene->mRootNode->mTransformation = aiMatrix4x4(1.f, 0.f, 0.f, 0.f,
mScene->mRootNode->mTransformation = aiMatrix4x4(1.f, 0.f, 0.f, 0.f,
0.f, 0.f, 1.f, 0.f, 0.f, -1.f, 0.f, 0.f, 0.f, 0.f, 0.f, 1.f);
// the output scene wouldn't pass the validation without this flag
if (!bHadMD5Mesh) {
pScene->mFlags |= AI_SCENE_FLAGS_INCOMPLETE;
if (!mHadMD5Mesh) {
mScene->mFlags |= AI_SCENE_FLAGS_INCOMPLETE;
}
// clean the instance -- the BaseImporter instance may be reused later.
@ -181,17 +187,17 @@ void MD5Importer::LoadFileIntoMemory(IOStream *file) {
// unload the previous buffer, if any
UnloadFileFromMemory();
ai_assert(NULL != file);
fileSize = (unsigned int)file->FileSize();
ai_assert(fileSize);
ai_assert(nullptr != file);
mFileSize = (unsigned int)file->FileSize();
ai_assert(mFileSize);
// allocate storage and copy the contents of the file to a memory buffer
mBuffer = new char[fileSize + 1];
file->Read((void *)mBuffer, 1, fileSize);
iLineNumber = 1;
mBuffer = new char[mFileSize + 1];
file->Read((void *)mBuffer, 1, mFileSize);
mLineNumber = 1;
// append a terminal 0
mBuffer[fileSize] = '\0';
mBuffer[mFileSize] = '\0';
// now remove all line comments from the file
CommentRemover::RemoveLineComments("//", mBuffer, ' ');
@ -202,8 +208,8 @@ void MD5Importer::LoadFileIntoMemory(IOStream *file) {
void MD5Importer::UnloadFileFromMemory() {
// delete the file buffer
delete[] mBuffer;
mBuffer = NULL;
fileSize = 0;
mBuffer = nullptr;
mFileSize = 0;
}
// ------------------------------------------------------------------------------------------------
@ -243,7 +249,8 @@ void MD5Importer::MakeDataUnique(MD5::MeshDesc &meshSrc) {
// ------------------------------------------------------------------------------------------------
// Recursive node graph construction from a MD5MESH
void MD5Importer::AttachChilds_Mesh(int iParentID, aiNode *piParent, BoneList &bones) {
ai_assert(NULL != piParent && !piParent->mNumChildren);
ai_assert(nullptr != piParent);
ai_assert(!piParent->mNumChildren);
// First find out how many children we'll have
for (int i = 0; i < (int)bones.size(); ++i) {
@ -293,7 +300,8 @@ void MD5Importer::AttachChilds_Mesh(int iParentID, aiNode *piParent, BoneList &b
// ------------------------------------------------------------------------------------------------
// Recursive node graph construction from a MD5ANIM
void MD5Importer::AttachChilds_Anim(int iParentID, aiNode *piParent, AnimBoneList &bones, const aiNodeAnim **node_anims) {
ai_assert(NULL != piParent && !piParent->mNumChildren);
ai_assert(nullptr != piParent);
ai_assert(!piParent->mNumChildren);
// First find out how many children we'll have
for (int i = 0; i < (int)bones.size(); ++i) {
@ -332,37 +340,37 @@ void MD5Importer::AttachChilds_Anim(int iParentID, aiNode *piParent, AnimBoneLis
// ------------------------------------------------------------------------------------------------
// Load a MD5MESH file
void MD5Importer::LoadMD5MeshFile() {
std::string pFile = mFile + "md5mesh";
std::unique_ptr<IOStream> file(mIOHandler->Open(pFile, "rb"));
std::string filename = mFile + "md5mesh";
std::unique_ptr<IOStream> file(mIOHandler->Open(filename, "rb"));
// Check whether we can read from the file
if (file.get() == nullptr || !file->FileSize()) {
ASSIMP_LOG_WARN("Failed to access MD5MESH file: " + pFile);
ASSIMP_LOG_WARN("Failed to access MD5MESH file: " + filename);
return;
}
bHadMD5Mesh = true;
mHadMD5Mesh = true;
LoadFileIntoMemory(file.get());
// now construct a parser and parse the file
MD5::MD5Parser parser(mBuffer, fileSize);
MD5::MD5Parser parser(mBuffer, mFileSize);
// load the mesh information from it
MD5::MD5MeshParser meshParser(parser.mSections);
// create the bone hierarchy - first the root node and dummy nodes for all meshes
pScene->mRootNode = new aiNode("<MD5_Root>");
pScene->mRootNode->mNumChildren = 2;
pScene->mRootNode->mChildren = new aiNode *[2];
mScene->mRootNode = new aiNode("<MD5_Root>");
mScene->mRootNode->mNumChildren = 2;
mScene->mRootNode->mChildren = new aiNode *[2];
// build the hierarchy from the MD5MESH file
aiNode *pcNode = pScene->mRootNode->mChildren[1] = new aiNode();
aiNode *pcNode = mScene->mRootNode->mChildren[1] = new aiNode();
pcNode->mName.Set("<MD5_Hierarchy>");
pcNode->mParent = pScene->mRootNode;
pcNode->mParent = mScene->mRootNode;
AttachChilds_Mesh(-1, pcNode, meshParser.mJoints);
pcNode = pScene->mRootNode->mChildren[0] = new aiNode();
pcNode = mScene->mRootNode->mChildren[0] = new aiNode();
pcNode->mName.Set("<MD5_Mesh>");
pcNode->mParent = pScene->mRootNode;
pcNode->mParent = mScene->mRootNode;
#if 0
if (pScene->mRootNode->mChildren[1]->mNumChildren) /* start at the right hierarchy level */
@ -371,28 +379,31 @@ void MD5Importer::LoadMD5MeshFile() {
// FIX: MD5 files exported from Blender can have empty meshes
for (std::vector<MD5::MeshDesc>::const_iterator it = meshParser.mMeshes.begin(), end = meshParser.mMeshes.end(); it != end; ++it) {
if (!(*it).mFaces.empty() && !(*it).mVertices.empty())
++pScene->mNumMaterials;
if (!(*it).mFaces.empty() && !(*it).mVertices.empty()) {
++mScene->mNumMaterials;
}
}
// generate all meshes
pScene->mNumMeshes = pScene->mNumMaterials;
pScene->mMeshes = new aiMesh *[pScene->mNumMeshes];
pScene->mMaterials = new aiMaterial *[pScene->mNumMeshes];
mScene->mNumMeshes = mScene->mNumMaterials;
mScene->mMeshes = new aiMesh *[mScene->mNumMeshes];
mScene->mMaterials = new aiMaterial *[mScene->mNumMeshes];
// storage for node mesh indices
pcNode->mNumMeshes = pScene->mNumMeshes;
pcNode->mNumMeshes = mScene->mNumMeshes;
pcNode->mMeshes = new unsigned int[pcNode->mNumMeshes];
for (unsigned int m = 0; m < pcNode->mNumMeshes; ++m)
for (unsigned int m = 0; m < pcNode->mNumMeshes; ++m) {
pcNode->mMeshes[m] = m;
}
unsigned int n = 0;
for (std::vector<MD5::MeshDesc>::iterator it = meshParser.mMeshes.begin(), end = meshParser.mMeshes.end(); it != end; ++it) {
MD5::MeshDesc &meshSrc = *it;
if (meshSrc.mFaces.empty() || meshSrc.mVertices.empty())
if (meshSrc.mFaces.empty() || meshSrc.mVertices.empty()) {
continue;
}
aiMesh *mesh = pScene->mMeshes[n] = new aiMesh();
aiMesh *mesh = mScene->mMeshes[n] = new aiMesh();
mesh->mPrimitiveTypes = aiPrimitiveType_TRIANGLE;
// generate unique vertices in our internal verbose format
@ -422,17 +433,19 @@ void MD5Importer::LoadMD5MeshFile() {
for (unsigned int jub = (*iter).mFirstWeight, w = jub; w < jub + (*iter).mNumWeights; ++w) {
MD5::WeightDesc &weightDesc = meshSrc.mWeights[w];
/* FIX for some invalid exporters */
if (!(weightDesc.mWeight < AI_MD5_WEIGHT_EPSILON && weightDesc.mWeight >= -AI_MD5_WEIGHT_EPSILON))
if (!(weightDesc.mWeight < AI_MD5_WEIGHT_EPSILON && weightDesc.mWeight >= -AI_MD5_WEIGHT_EPSILON)) {
++piCount[weightDesc.mBone];
}
}
}
// check how many we will need
for (unsigned int p = 0; p < meshParser.mJoints.size(); ++p)
for (unsigned int p = 0; p < meshParser.mJoints.size(); ++p) {
if (piCount[p]) mesh->mNumBones++;
}
if (mesh->mNumBones) // just for safety
{
// just for safety
if (mesh->mNumBones) {
mesh->mBones = new aiBone *[mesh->mNumBones];
for (unsigned int q = 0, h = 0; q < meshParser.mJoints.size(); ++q) {
if (!piCount[q]) continue;
@ -457,8 +470,9 @@ void MD5Importer::LoadMD5MeshFile() {
// there are models which have weights which don't sum to 1 ...
ai_real fSum = 0.0;
for (unsigned int jub = (*iter).mFirstWeight, w = jub; w < jub + (*iter).mNumWeights; ++w)
for (unsigned int jub = (*iter).mFirstWeight, w = jub; w < jub + (*iter).mNumWeights; ++w) {
fSum += meshSrc.mWeights[w].mWeight;
}
if (!fSum) {
ASSIMP_LOG_ERROR("MD5MESH: The sum of all vertex bone weights is 0");
continue;
@ -466,8 +480,9 @@ void MD5Importer::LoadMD5MeshFile() {
// process bone weights
for (unsigned int jub = (*iter).mFirstWeight, w = jub; w < jub + (*iter).mNumWeights; ++w) {
if (w >= meshSrc.mWeights.size())
if (w >= meshSrc.mWeights.size()) {
throw DeadlyImportError("MD5MESH: Invalid weight index");
}
MD5::WeightDesc &weightDesc = meshSrc.mWeights[w];
if (weightDesc.mWeight < AI_MD5_WEIGHT_EPSILON && weightDesc.mWeight >= -AI_MD5_WEIGHT_EPSILON) {
@ -504,12 +519,12 @@ void MD5Importer::LoadMD5MeshFile() {
for (unsigned int c = 0; c < mesh->mNumFaces; ++c) {
mesh->mFaces[c].mNumIndices = 3;
mesh->mFaces[c].mIndices = meshSrc.mFaces[c].mIndices;
meshSrc.mFaces[c].mIndices = NULL;
meshSrc.mFaces[c].mIndices = nullptr;
}
// generate a material for the mesh
aiMaterial *mat = new aiMaterial();
pScene->mMaterials[n] = mat;
mScene->mMaterials[n] = mat;
// insert the typical doom3 textures:
// nnn_local.tga - normal map
@ -555,10 +570,11 @@ void MD5Importer::LoadMD5AnimFile() {
ASSIMP_LOG_WARN("Failed to read MD5ANIM file: " + pFile);
return;
}
LoadFileIntoMemory(file.get());
// parse the basic file structure
MD5::MD5Parser parser(mBuffer, fileSize);
MD5::MD5Parser parser(mBuffer, mFileSize);
// load the animation information from the parse tree
MD5::MD5AnimParser animParser(parser.mSections);
@ -568,10 +584,10 @@ void MD5Importer::LoadMD5AnimFile() {
animParser.mBaseFrames.size() != animParser.mAnimatedBones.size()) {
ASSIMP_LOG_ERROR("MD5ANIM: No frames or animated bones loaded");
} else {
bHadMD5Anim = true;
mHadMD5Anim = true;
pScene->mAnimations = new aiAnimation *[pScene->mNumAnimations = 1];
aiAnimation *anim = pScene->mAnimations[0] = new aiAnimation();
mScene->mAnimations = new aiAnimation *[mScene->mNumAnimations = 1];
aiAnimation *anim = mScene->mAnimations[0] = new aiAnimation();
anim->mNumChannels = (unsigned int)animParser.mAnimatedBones.size();
anim->mChannels = new aiNodeAnim *[anim->mNumChannels];
for (unsigned int i = 0; i < anim->mNumChannels; ++i) {
@ -637,15 +653,15 @@ void MD5Importer::LoadMD5AnimFile() {
// If we didn't build the hierarchy yet (== we didn't load a MD5MESH),
// construct it now from the data given in the MD5ANIM.
if (!pScene->mRootNode) {
pScene->mRootNode = new aiNode();
pScene->mRootNode->mName.Set("<MD5_Hierarchy>");
if (!mScene->mRootNode) {
mScene->mRootNode = new aiNode();
mScene->mRootNode->mName.Set("<MD5_Hierarchy>");
AttachChilds_Anim(-1, pScene->mRootNode, animParser.mAnimatedBones, (const aiNodeAnim **)anim->mChannels);
AttachChilds_Anim(-1, mScene->mRootNode, animParser.mAnimatedBones, (const aiNodeAnim **)anim->mChannels);
// Call SkeletonMeshBuilder to construct a mesh to represent the shape
if (pScene->mRootNode->mNumChildren) {
SkeletonMeshBuilder skeleton_maker(pScene, pScene->mRootNode->mChildren[0]);
if (mScene->mRootNode->mNumChildren) {
SkeletonMeshBuilder skeleton_maker(mScene, mScene->mRootNode->mChildren[0]);
}
}
}
@ -661,11 +677,11 @@ void MD5Importer::LoadMD5CameraFile() {
if (!file.get() || !file->FileSize()) {
throw DeadlyImportError("Failed to read MD5CAMERA file: " + pFile);
}
bHadMD5Camera = true;
mHadMD5Camera = true;
LoadFileIntoMemory(file.get());
// parse the basic file structure
MD5::MD5Parser parser(mBuffer, fileSize);
MD5::MD5Parser parser(mBuffer, mFileSize);
// load the camera animation data from the parse tree
MD5::MD5CameraParser cameraParser(parser.mSections);
@ -679,14 +695,14 @@ void MD5Importer::LoadMD5CameraFile() {
// Construct output graph - a simple root with a dummy child.
// The root node performs the coordinate system conversion
aiNode *root = pScene->mRootNode = new aiNode("<MD5CameraRoot>");
aiNode *root = mScene->mRootNode = new aiNode("<MD5CameraRoot>");
root->mChildren = new aiNode *[root->mNumChildren = 1];
root->mChildren[0] = new aiNode("<MD5Camera>");
root->mChildren[0]->mParent = root;
// ... but with one camera assigned to it
pScene->mCameras = new aiCamera *[pScene->mNumCameras = 1];
aiCamera *cam = pScene->mCameras[0] = new aiCamera();
mScene->mCameras = new aiCamera *[mScene->mNumCameras = 1];
aiCamera *cam = mScene->mCameras[0] = new aiCamera();
cam->mName = "<MD5Camera>";
// FIXME: Fov is currently set to the first frame's value
@ -703,8 +719,8 @@ void MD5Importer::LoadMD5CameraFile() {
cuts.push_back(static_cast<unsigned int>(frames.size() - 1));
}
pScene->mNumAnimations = static_cast<unsigned int>(cuts.size() - 1);
aiAnimation **tmp = pScene->mAnimations = new aiAnimation *[pScene->mNumAnimations];
mScene->mNumAnimations = static_cast<unsigned int>(cuts.size() - 1);
aiAnimation **tmp = mScene->mAnimations = new aiAnimation *[mScene->mNumAnimations];
for (std::vector<unsigned int>::const_iterator it = cuts.begin(); it != cuts.end() - 1; ++it) {
aiAnimation *anim = *tmp++ = new aiAnimation();

View File

@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2020, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
@ -156,25 +155,25 @@ protected:
char *mBuffer;
/** Size of the file */
unsigned int fileSize;
unsigned int mFileSize;
/** Current line number. For debugging purposes */
unsigned int iLineNumber;
unsigned int mLineNumber;
/** Scene to be filled */
aiScene *pScene;
aiScene *mScene;
/** true if a MD5MESH file has already been parsed */
bool bHadMD5Mesh;
bool mHadMD5Mesh;
/** true if a MD5ANIM file has already been parsed */
bool bHadMD5Anim;
bool mHadMD5Anim;
/** true if a MD5CAMERA file has already been parsed */
bool bHadMD5Camera;
bool mHadMD5Camera;
/** configuration option: prevent anim autoload */
bool configNoAutoLoad;
bool mCconfigNoAutoLoad;
};
} // end of namespace Assimp

View File

@ -45,25 +45,24 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* @brief Implementation of the MD5 parser class
*/
// internal headers
#include "AssetLib/MD5/MD5Loader.h"
#include "Material/MaterialSystem.h"
#include <assimp/fast_atof.h>
#include <assimp/ParsingUtils.h>
#include <assimp/StringComparison.h>
#include <assimp/DefaultLogger.hpp>
#include <assimp/fast_atof.h>
#include <assimp/mesh.h>
#include <assimp/DefaultLogger.hpp>
using namespace Assimp;
using namespace Assimp::MD5;
// ------------------------------------------------------------------------------------------------
// Parse the segment structure fo a MD5 file
MD5Parser::MD5Parser(char* _buffer, unsigned int _fileSize )
{
ai_assert(NULL != _buffer && 0 != _fileSize);
MD5Parser::MD5Parser(char *_buffer, unsigned int _fileSize) {
ai_assert(nullptr != _buffer);
ai_assert(0 != _fileSize);
buffer = _buffer;
fileSize = _fileSize;
@ -93,8 +92,7 @@ MD5Parser::MD5Parser(char* _buffer, unsigned int _fileSize )
// ------------------------------------------------------------------------------------------------
// Report error to the log stream
/*static*/ AI_WONT_RETURN void MD5Parser::ReportError (const char* error, unsigned int line)
{
/*static*/ AI_WONT_RETURN void MD5Parser::ReportError(const char *error, unsigned int line) {
char szBuffer[1024];
::ai_snprintf(szBuffer, 1024, "[MD5] Line %u: %s", line, error);
throw DeadlyImportError(szBuffer);
@ -102,8 +100,7 @@ MD5Parser::MD5Parser(char* _buffer, unsigned int _fileSize )
// ------------------------------------------------------------------------------------------------
// Report warning to the log stream
/*static*/ void MD5Parser::ReportWarning (const char* warn, unsigned int line)
{
/*static*/ void MD5Parser::ReportWarning(const char *warn, unsigned int line) {
char szBuffer[1024];
::sprintf(szBuffer, "[MD5] Line %u: %s", line, warn);
ASSIMP_LOG_WARN(szBuffer);
@ -111,8 +108,7 @@ MD5Parser::MD5Parser(char* _buffer, unsigned int _fileSize )
// ------------------------------------------------------------------------------------------------
// Parse and validate the MD5 header
void MD5Parser::ParseHeader()
{
void MD5Parser::ParseHeader() {
// parse and validate the file version
SkipSpaces();
if (!TokenMatch(buffer, "MD5Version", 10)) {
@ -128,21 +124,22 @@ void MD5Parser::ParseHeader()
// print the command line options to the console
// FIX: can break the log length limit, so we need to be careful
char *sz = buffer;
while (!IsLineEnd( *buffer++));
while (!IsLineEnd(*buffer++))
;
ASSIMP_LOG_INFO(std::string(sz, std::min((uintptr_t)MAX_LOG_MESSAGE_LENGTH, (uintptr_t)(buffer - sz))));
SkipSpacesAndLineEnd();
}
// ------------------------------------------------------------------------------------------------
// Recursive MD5 parsing function
bool MD5Parser::ParseSection(Section& out)
{
bool MD5Parser::ParseSection(Section &out) {
// store the current line number for use in error messages
out.iLineNumber = lineNumber;
// first parse the name of the section
char *sz = buffer;
while (!IsSpaceOrNewLine( *buffer))buffer++;
while (!IsSpaceOrNewLine(*buffer))
buffer++;
out.mName = std::string(sz, (uintptr_t)(buffer - sz));
SkipSpaces();
@ -152,8 +149,7 @@ bool MD5Parser::ParseSection(Section& out)
// it is a normal section so read all lines
buffer++;
bool run = true;
while (run)
{
while (run) {
if (!SkipSpacesAndLineEnd()) {
return false; // seems this was the last section
}
@ -169,18 +165,19 @@ bool MD5Parser::ParseSection(Section& out)
elem.szStart = buffer;
// terminate the line with zero
while (!IsLineEnd( *buffer))buffer++;
while (!IsLineEnd(*buffer))
buffer++;
if (*buffer) {
++lineNumber;
*buffer++ = '\0';
}
}
break;
}
else if (!IsSpaceOrNewLine(*buffer)) {
} else if (!IsSpaceOrNewLine(*buffer)) {
// it is an element at global scope. Parse its value and go on
sz = buffer;
while (!IsSpaceOrNewLine( *buffer++));
while (!IsSpaceOrNewLine(*buffer++))
;
out.mGlobalValue = std::string(sz, (uintptr_t)(buffer - sz));
continue;
}
@ -193,7 +190,8 @@ bool MD5Parser::ParseSection(Section& out)
// Some dirty macros just because they're so funny and easy to debug
// skip all spaces ... handle EOL correctly
#define AI_MD5_SKIP_SPACES() if(!SkipSpaces(&sz)) \
#define AI_MD5_SKIP_SPACES() \
if (!SkipSpaces(&sz)) \
MD5Parser::ReportWarning("Unexpected end of line", elem.iLineNumber);
// read a triple float in brackets: (1.0 1.0 1.0)
@ -215,7 +213,8 @@ bool MD5Parser::ParseSection(Section& out)
#define AI_MD5_PARSE_STRING(out) \
bool bQuota = (*sz == '\"'); \
const char *szStart = sz; \
while (!IsSpaceOrNewLine(*sz))++sz; \
while (!IsSpaceOrNewLine(*sz)) \
++sz; \
const char *szEnd = sz; \
if (bQuota) { \
szStart++; \
@ -231,28 +230,27 @@ bool MD5Parser::ParseSection(Section& out)
// parse a string, enclosed in quotation marks
#define AI_MD5_PARSE_STRING_IN_QUOTATION(out) \
while('\"'!=*sz)++sz; \
while ('\"' != *sz) \
++sz; \
const char *szStart = ++sz; \
while('\"'!=*sz)++sz; \
while ('\"' != *sz) \
++sz; \
const char *szEnd = (sz++); \
out.length = (ai_uint32)(szEnd - szStart); \
::memcpy(out.data, szStart, out.length); \
out.data[out.length] = '\0';
// ------------------------------------------------------------------------------------------------
// .MD5MESH parsing function
MD5MeshParser::MD5MeshParser(SectionList& mSections)
{
MD5MeshParser::MD5MeshParser(SectionList &mSections) {
ASSIMP_LOG_DEBUG("MD5MeshParser begin");
// now parse all sections
for (SectionList::const_iterator iter = mSections.begin(), iterEnd = mSections.end(); iter != iterEnd; ++iter) {
if ((*iter).mName == "numMeshes") {
mMeshes.reserve(::strtoul10((*iter).mGlobalValue.c_str()));
}
else if ( (*iter).mName == "numJoints") {
} else if ((*iter).mName == "numJoints") {
mJoints.reserve(::strtoul10((*iter).mGlobalValue.c_str()));
}
else if ((*iter).mName == "joints") {
} else if ((*iter).mName == "joints") {
// "origin" -1 ( -0.000000 0.016430 -0.006044 ) ( 0.707107 0.000000 0.707107 )
for (const auto &elem : (*iter).mElements) {
mJoints.push_back(BoneDesc());
@ -268,8 +266,7 @@ MD5MeshParser::MD5MeshParser(SectionList& mSections)
AI_MD5_READ_TRIPLE(desc.mPositionXYZ);
AI_MD5_READ_TRIPLE(desc.mRotationQuat); // normalized quaternion, so w is not there
}
}
else if ((*iter).mName == "mesh") {
} else if ((*iter).mName == "mesh") {
mMeshes.push_back(MeshDesc());
MeshDesc &desc = mMeshes.back();
@ -358,8 +355,7 @@ MD5MeshParser::MD5MeshParser(SectionList& mSections)
// ------------------------------------------------------------------------------------------------
// .MD5ANIM parsing function
MD5AnimParser::MD5AnimParser(SectionList& mSections)
{
MD5AnimParser::MD5AnimParser(SectionList &mSections) {
ASSIMP_LOG_DEBUG("MD5AnimParser begin");
fFrameRate = 24.0f;
@ -388,8 +384,7 @@ MD5AnimParser::MD5AnimParser(SectionList& mSections)
// index of the first animation keyframe component for this joint
desc.iFirstKeyIndex = ::strtoul10(sz, &sz);
}
}
else if((*iter).mName == "baseframe") {
} else if ((*iter).mName == "baseframe") {
// ( -0.000000 0.016430 -0.006044 ) ( 0.707107 0.000242 0.707107 )
for (const auto &elem : (*iter).mElements) {
const char *sz = elem.szStart;
@ -400,8 +395,7 @@ MD5AnimParser::MD5AnimParser(SectionList& mSections)
AI_MD5_READ_TRIPLE(desc.vPositionXYZ);
AI_MD5_READ_TRIPLE(desc.vRotationQuat);
}
}
else if((*iter).mName == "frame") {
} else if ((*iter).mName == "frame") {
if (!(*iter).mGlobalValue.length()) {
MD5Parser::ReportWarning("A frame section must have a frame index", (*iter).iLineNumber);
continue;
@ -420,15 +414,14 @@ MD5AnimParser::MD5AnimParser(SectionList& mSections)
for (const auto &elem : (*iter).mElements) {
const char *sz = elem.szStart;
while (SkipSpacesAndLineEnd(&sz)) {
float f;sz = fast_atoreal_move<float>(sz,f);
float f;
sz = fast_atoreal_move<float>(sz, f);
desc.mValues.push_back(f);
}
}
}
else if((*iter).mName == "numFrames") {
} else if ((*iter).mName == "numFrames") {
mFrames.reserve(strtoul10((*iter).mGlobalValue.c_str()));
}
else if((*iter).mName == "numJoints") {
} else if ((*iter).mName == "numJoints") {
const unsigned int num = strtoul10((*iter).mGlobalValue.c_str());
mAnimatedBones.reserve(num);
@ -436,11 +429,9 @@ MD5AnimParser::MD5AnimParser(SectionList& mSections)
if (UINT_MAX == mNumAnimatedComponents) {
mNumAnimatedComponents = num * 6;
}
}
else if((*iter).mName == "numAnimatedComponents") {
} else if ((*iter).mName == "numAnimatedComponents") {
mAnimatedBones.reserve(strtoul10((*iter).mGlobalValue.c_str()));
}
else if((*iter).mName == "frameRate") {
} else if ((*iter).mName == "frameRate") {
fast_atoreal_move<float>((*iter).mGlobalValue.c_str(), fFrameRate);
}
}
@ -449,27 +440,22 @@ MD5AnimParser::MD5AnimParser(SectionList& mSections)
// ------------------------------------------------------------------------------------------------
// .MD5CAMERA parsing function
MD5CameraParser::MD5CameraParser(SectionList& mSections)
{
MD5CameraParser::MD5CameraParser(SectionList &mSections) {
ASSIMP_LOG_DEBUG("MD5CameraParser begin");
fFrameRate = 24.0f;
for (SectionList::const_iterator iter = mSections.begin(), iterEnd = mSections.end(); iter != iterEnd; ++iter) {
if ((*iter).mName == "numFrames") {
frames.reserve(strtoul10((*iter).mGlobalValue.c_str()));
}
else if ((*iter).mName == "frameRate") {
} else if ((*iter).mName == "frameRate") {
fFrameRate = fast_atof((*iter).mGlobalValue.c_str());
}
else if ((*iter).mName == "numCuts") {
} else if ((*iter).mName == "numCuts") {
cuts.reserve(strtoul10((*iter).mGlobalValue.c_str()));
}
else if ((*iter).mName == "cuts") {
} else if ((*iter).mName == "cuts") {
for (const auto &elem : (*iter).mElements) {
cuts.push_back(strtoul10(elem.szStart) + 1);
}
}
else if ((*iter).mName == "camera") {
} else if ((*iter).mName == "camera") {
for (const auto &elem : (*iter).mElements) {
const char *sz = elem.szStart;
@ -484,4 +470,3 @@ MD5CameraParser::MD5CameraParser(SectionList& mSections)
}
ASSIMP_LOG_DEBUG("MD5CameraParser end");
}

View File

@ -267,7 +267,7 @@ void MDCImporter::InternReadFile(
// necessary that we don't crash if an exception occurs
for (unsigned int i = 0; i < pScene->mNumMeshes; ++i) {
pScene->mMeshes[i] = NULL;
pScene->mMeshes[i] = nullptr;
}
// now read all surfaces
@ -347,8 +347,8 @@ void MDCImporter::InternReadFile(
#endif
const MDC::CompressedVertex *pcCVerts = NULL;
int16_t *mdcCompVert = NULL;
const MDC::CompressedVertex *pcCVerts = nullptr;
int16_t *mdcCompVert = nullptr;
// access compressed frames for large frame numbers, but never for the first
if (this->configFrameID && pcSurface->ulNumCompFrames > 0) {
@ -359,7 +359,7 @@ void MDCImporter::InternReadFile(
pcSurface->ulOffsetCompVerts) +
*mdcCompVert * pcSurface->ulNumVertices;
} else
mdcCompVert = NULL;
mdcCompVert = nullptr;
}
// copy all faces

View File

@ -222,12 +222,14 @@ void HL1MDLLoader::load_file_into_buffer(const std::string &file_path, unsigned
std::unique_ptr<IOStream> file(io_->Open(file_path));
if (file.get() == NULL)
if (file.get() == nullptr) {
throw DeadlyImportError("Failed to open MDL file " + DefaultIOSystem::fileName(file_path) + ".");
}
const size_t file_size = file->FileSize();
if (file_size < sizeof(MDLFileHeader))
if (file_size < sizeof(MDLFileHeader)) {
throw DeadlyImportError("MDL file is too small.");
}
buffer = new unsigned char[1 + file_size];
file->Read((void *)buffer, 1, file_size);

View File

@ -278,7 +278,7 @@ void MDLImporter::SizeCheck(const void *szPos) {
// ------------------------------------------------------------------------------------------------
// Just for debugging purposes
void MDLImporter::SizeCheck(const void *szPos, const char *szFile, unsigned int iLine) {
ai_assert(NULL != szFile);
ai_assert(nullptr != szFile);
if (!szPos || (const unsigned char *)szPos > mBuffer + iFileSize) {
// remove a directory if there is one
const char *szFilePtr = ::strrchr(szFile, '\\');
@ -304,7 +304,7 @@ void MDLImporter::SizeCheck(const void *szPos, const char *szFile, unsigned int
// ------------------------------------------------------------------------------------------------
// Validate a quake file header
void MDLImporter::ValidateHeader_Quake1(const MDL::Header *pcHeader) {
// some values may not be NULL
// some values may not be nullptr
if (!pcHeader->num_frames)
throw DeadlyImportError("[Quake 1 MDL] There are no frames in the file");
@ -359,7 +359,7 @@ void FlipQuakeHeader(BE_NCONST MDL::Header *pcHeader) {
// ------------------------------------------------------------------------------------------------
// Read a Quake 1 file
void MDLImporter::InternReadFile_Quake1() {
ai_assert(NULL != pScene);
ai_assert(nullptr != pScene);
BE_NCONST MDL::Header *pcHeader = (BE_NCONST MDL::Header *)this->mBuffer;
@ -548,7 +548,7 @@ void MDLImporter::SetupMaterialProperties_3DGS_MDL5_Quake1() {
delete pScene->mTextures[0];
delete[] pScene->mTextures;
pScene->mTextures = NULL;
pScene->mTextures = nullptr;
pScene->mNumTextures = 0;
} else {
clr.b = clr.a = clr.g = clr.r = 1.0f;
@ -572,7 +572,7 @@ void MDLImporter::SetupMaterialProperties_3DGS_MDL5_Quake1() {
// ------------------------------------------------------------------------------------------------
// Read a MDL 3,4,5 file
void MDLImporter::InternReadFile_3DGS_MDL345() {
ai_assert(NULL != pScene);
ai_assert(nullptr != pScene);
// the header of MDL 3/4/5 is nearly identical to the original Quake1 header
BE_NCONST MDL::Header *pcHeader = (BE_NCONST MDL::Header *)this->mBuffer;
@ -791,7 +791,7 @@ void MDLImporter::ImportUVCoordinate_3DGS_MDL345(
aiVector3D &vOut,
const MDL::TexCoord_MDL3 *pcSrc,
unsigned int iIndex) {
ai_assert(NULL != pcSrc);
ai_assert(nullptr != pcSrc);
const MDL::Header *const pcHeader = (const MDL::Header *)this->mBuffer;
// validate UV indices
@ -860,7 +860,7 @@ void MDLImporter::CalculateUVCoordinates_MDL5() {
// ------------------------------------------------------------------------------------------------
// Validate the header of a MDL7 file
void MDLImporter::ValidateHeader_3DGS_MDL7(const MDL::Header_MDL7 *pcHeader) {
ai_assert(NULL != pcHeader);
ai_assert(nullptr != pcHeader);
// There are some fixed sizes ...
if (sizeof(MDL::ColorValue_MDL7) != pcHeader->colorvalue_stc_size) {
@ -887,7 +887,7 @@ void MDLImporter::ValidateHeader_3DGS_MDL7(const MDL::Header_MDL7 *pcHeader) {
void MDLImporter::CalcAbsBoneMatrices_3DGS_MDL7(MDL::IntBone_MDL7 **apcOutBones) {
const MDL::Header_MDL7 *pcHeader = (const MDL::Header_MDL7 *)this->mBuffer;
const MDL::Bone_MDL7 *pcBones = (const MDL::Bone_MDL7 *)(pcHeader + 1);
ai_assert(NULL != apcOutBones);
ai_assert(nullptr != apcOutBones);
// first find the bone that has NO parent, calculate the
// animation matrix for it, then go on and search for the next parent
@ -979,7 +979,7 @@ MDL::IntBone_MDL7 **MDLImporter::LoadBones_3DGS_MDL7() {
AI_MDL7_BONE_STRUCT_SIZE__NAME_IS_32_CHARS != pcHeader->bone_stc_size &&
AI_MDL7_BONE_STRUCT_SIZE__NAME_IS_NOT_THERE != pcHeader->bone_stc_size) {
ASSIMP_LOG_WARN("Unknown size of bone data structure");
return NULL;
return nullptr;
}
MDL::IntBone_MDL7 **apcBonesOut = new MDL::IntBone_MDL7 *[pcHeader->bones_num];
@ -990,7 +990,7 @@ MDL::IntBone_MDL7 **MDLImporter::LoadBones_3DGS_MDL7() {
CalcAbsBoneMatrices_3DGS_MDL7(apcBonesOut);
return apcBonesOut;
}
return NULL;
return nullptr;
}
// ------------------------------------------------------------------------------------------------
@ -1337,7 +1337,7 @@ void MDLImporter::SortByMaterials_3DGS_MDL7(
// ------------------------------------------------------------------------------------------------
// Read a MDL7 file
void MDLImporter::InternReadFile_3DGS_MDL7() {
ai_assert(NULL != pScene);
ai_assert(nullptr != pScene);
MDL::IntSharedData_MDL7 sharedData;
@ -1368,7 +1368,7 @@ void MDLImporter::InternReadFile_3DGS_MDL7() {
// load all bones (they are shared by all groups, so
// we'll need to add them to all groups/meshes later)
// apcBonesOut is a list of all bones or NULL if they could not been loaded
// apcBonesOut is a list of all bones or nullptr if they could not been loaded
szCurrent += pcHeader->bones_num * pcHeader->bone_stc_size;
sharedData.apcOutBones = this->LoadBones_3DGS_MDL7();
@ -1558,9 +1558,9 @@ void MDLImporter::InternReadFile_3DGS_MDL7() {
if (1 == pScene->mRootNode->mNumChildren && !sharedData.apcOutBones) {
aiNode *pcOldRoot = this->pScene->mRootNode;
pScene->mRootNode = pcOldRoot->mChildren[0];
pcOldRoot->mChildren[0] = NULL;
pcOldRoot->mChildren[0] = nullptr;
delete pcOldRoot;
pScene->mRootNode->mParent = NULL;
pScene->mRootNode->mParent = nullptr;
} else
pScene->mRootNode->mName.Set("<mesh_root>");
@ -1665,7 +1665,8 @@ void MDLImporter::ParseBoneTrafoKeys_3DGS_MDL7(
// Attach bones to the output nodegraph
void MDLImporter::AddBonesToNodeGraph_3DGS_MDL7(const MDL::IntBone_MDL7 **apcBones,
aiNode *pcParent, uint16_t iParentIndex) {
ai_assert(NULL != apcBones && NULL != pcParent);
ai_assert(nullptr != apcBones);
ai_assert(nullptr != pcParent);
// get a pointer to the header ...
const MDL::Header_MDL7 *const pcHeader = (const MDL::Header_MDL7 *)this->mBuffer;
@ -1696,7 +1697,7 @@ void MDLImporter::AddBonesToNodeGraph_3DGS_MDL7(const MDL::IntBone_MDL7 **apcBon
// Build output animations
void MDLImporter::BuildOutputAnims_3DGS_MDL7(
const MDL::IntBone_MDL7 **apcBonesOut) {
ai_assert(NULL != apcBonesOut);
ai_assert(nullptr != apcBonesOut);
const MDL::Header_MDL7 *const pcHeader = (const MDL::Header_MDL7 *)mBuffer;
// one animation ...
@ -1755,8 +1756,8 @@ void MDLImporter::BuildOutputAnims_3DGS_MDL7(
void MDLImporter::AddAnimationBoneTrafoKey_3DGS_MDL7(unsigned int iTrafo,
const MDL::BoneTransform_MDL7 *pcBoneTransforms,
MDL::IntBone_MDL7 **apcBonesOut) {
ai_assert(NULL != pcBoneTransforms);
ai_assert(NULL != apcBonesOut);
ai_assert(nullptr != pcBoneTransforms);
ai_assert(nullptr != apcBonesOut);
// first .. get the transformation matrix
aiMatrix4x4 mTransform;
@ -1920,7 +1921,9 @@ void MDLImporter::JoinSkins_3DGS_MDL7(
aiMaterial *pcMat1,
aiMaterial *pcMat2,
aiMaterial *pcMatOut) {
ai_assert(NULL != pcMat1 && NULL != pcMat2 && NULL != pcMatOut);
ai_assert(nullptr != pcMat1);
ai_assert(nullptr != pcMat2);
ai_assert(nullptr != pcMatOut);
// first create a full copy of the first skin property set
// and assign it to the output material

View File

@ -320,7 +320,7 @@ protected:
/** Load the bone list of a MDL7 file
* \return If the bones could be loaded successfully, a valid
* array containing pointers to a temporary bone
* representation. NULL if the bones could not be loaded.
* representation. nullptr if the bones could not be loaded.
*/
MDL::IntBone_MDL7** LoadBones_3DGS_MDL7();

View File

@ -364,7 +364,7 @@ void MDLImporter::ParseTextureColorData(const unsigned char *szData,
void MDLImporter::CreateTexture_3DGS_MDL5(const unsigned char *szData,
unsigned int iType,
unsigned int *piSkip) {
ai_assert(NULL != piSkip);
ai_assert(nullptr != piSkip);
bool bNoRead = *piSkip == UINT_MAX;
// allocate a new texture object
@ -428,7 +428,7 @@ void MDLImporter::CreateTexture_3DGS_MDL5(const unsigned char *szData,
delete[] pc;
}
} else {
pcNew->pcData = NULL;
pcNew->pcData = nullptr;
delete pcNew;
}
return;

View File

@ -134,7 +134,7 @@ void MMDImporter::InternReadFile(const std::string &file, aiScene *pScene,
// ------------------------------------------------------------------------------------------------
void MMDImporter::CreateDataFromImport(const pmx::PmxModel *pModel,
aiScene *pScene) {
if (pModel == NULL) {
if (pModel == nullptr) {
return;
}

View File

@ -131,7 +131,7 @@ namespace pmd
stream->read((char*) &index_count, sizeof(uint32_t));
stream->read((char*) &buffer, sizeof(char) * 20);
char* pstar = strchr(buffer, '*');
if (NULL == pstar)
if (nullptr == pstar)
{
texture_filename = std::string(buffer);
sphere_filename.clear();

View File

@ -657,7 +657,7 @@ void MS3DImporter::InternReadFile( const std::string& pFile,
}
// fixup to pass the validation if not a single animation channel is non-trivial
if (!anim->mNumChannels) {
anim->mChannels = NULL;
anim->mChannels = nullptr;
}
}
}

View File

@ -154,7 +154,7 @@ void NFFImporter::LoadNFF2MaterialTable(std::vector<ShadingInfo> &output,
return;
}
ShadingInfo *curShader = NULL;
ShadingInfo *curShader = nullptr;
// No read the file line per line
char line[4096];
@ -238,9 +238,9 @@ void NFFImporter::InternReadFile(const std::string &pFile,
bool hasCam = false;
MeshInfo *currentMeshWithNormals = NULL;
MeshInfo *currentMesh = NULL;
MeshInfo *currentMeshWithUVCoords = NULL;
MeshInfo *currentMeshWithNormals = nullptr;
MeshInfo *currentMesh = nullptr;
MeshInfo *currentMeshWithUVCoords = nullptr;
ShadingInfo s; // current material info
@ -542,7 +542,7 @@ void NFFImporter::InternReadFile(const std::string &pFile,
// search the list of all shaders we have for this object whether
// there is an identical one. In this case, we append our mesh
// data to it.
MeshInfo *mesh = NULL;
MeshInfo *mesh = nullptr;
for (std::vector<MeshInfo>::iterator it = meshes.begin() + objStart, end = meshes.end();
it != end; ++it) {
if ((*it).shader == shader && (*it).matIndex == matIdx) {
@ -603,11 +603,11 @@ void NFFImporter::InternReadFile(const std::string &pFile,
while (GetNextLine(buffer, line)) {
sz = line;
if ('p' == line[0] || TokenMatch(sz, "tpp", 3)) {
MeshInfo *out = NULL;
MeshInfo *out = nullptr;
// 'tpp' - texture polygon patch primitive
if ('t' == line[0]) {
currentMeshWithUVCoords = NULL;
currentMeshWithUVCoords = nullptr;
for (auto &mesh : meshesWithUVCoords) {
if (mesh.shader == s) {
currentMeshWithUVCoords = &mesh;
@ -624,7 +624,7 @@ void NFFImporter::InternReadFile(const std::string &pFile,
}
// 'pp' - polygon patch primitive
else if ('p' == line[1]) {
currentMeshWithNormals = NULL;
currentMeshWithNormals = nullptr;
for (auto &mesh : meshesWithNormals) {
if (mesh.shader == s) {
currentMeshWithNormals = &mesh;
@ -642,7 +642,7 @@ void NFFImporter::InternReadFile(const std::string &pFile,
}
// 'p' - polygon primitive
else {
currentMesh = NULL;
currentMesh = nullptr;
for (auto &mesh : meshes) {
if (mesh.shader == s) {
currentMesh = &mesh;
@ -969,8 +969,8 @@ void NFFImporter::InternReadFile(const std::string &pFile,
root->mNumChildren = numNamed + (hasCam ? 1 : 0) + (unsigned int)lights.size();
root->mNumMeshes = pScene->mNumMeshes - numNamed;
aiNode **ppcChildren = NULL;
unsigned int *pMeshes = NULL;
aiNode **ppcChildren = nullptr;
unsigned int *pMeshes = nullptr;
if (root->mNumMeshes)
pMeshes = root->mMeshes = new unsigned int[root->mNumMeshes];
if (root->mNumChildren)
@ -1037,7 +1037,7 @@ void NFFImporter::InternReadFile(const std::string &pFile,
mesh->mNumFaces = (unsigned int)src.faces.size();
// Generate sub nodes for named meshes
if (src.name[0] && NULL != ppcChildren) {
if (src.name[0] && nullptr != ppcChildren) {
aiNode *const node = *ppcChildren = new aiNode();
node->mParent = root;
node->mNumMeshes = 1;

View File

@ -70,14 +70,14 @@ void ExportSceneObj(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene
// we're still here - export successfully completed. Write both the main OBJ file and the material script
{
std::unique_ptr<IOStream> outfile (pIOSystem->Open(pFile,"wt"));
if(outfile == NULL) {
if (outfile == nullptr) {
throw DeadlyExportError("could not open output .obj file: " + std::string(pFile));
}
outfile->Write( exporter.mOutput.str().c_str(), static_cast<size_t>(exporter.mOutput.tellp()),1);
}
{
std::unique_ptr<IOStream> outfile (pIOSystem->Open(exporter.GetMaterialLibFileName(),"wt"));
if(outfile == NULL) {
if (outfile == nullptr) {
throw DeadlyExportError("could not open output .mtl file: " + std::string(exporter.GetMaterialLibFileName()));
}
outfile->Write( exporter.mOutputMat.str().c_str(), static_cast<size_t>(exporter.mOutputMat.tellp()),1);
@ -97,7 +97,7 @@ void ExportSceneObjNoMtl(const char* pFile,IOSystem* pIOSystem, const aiScene* p
// we're still here - export successfully completed. Write both the main OBJ file and the material script
{
std::unique_ptr<IOStream> outfile (pIOSystem->Open(pFile,"wt"));
if(outfile == NULL) {
if (outfile == nullptr) {
throw DeadlyExportError("could not open output .obj file: " + std::string(pFile));
}
outfile->Write( exporter.mOutput.str().c_str(), static_cast<size_t>(exporter.mOutput.tellp()),1);

View File

@ -215,7 +215,11 @@ struct Mesh {
/// Constructor
explicit Mesh(const std::string &name) :
m_name(name), m_pMaterial(NULL), m_uiNumIndices(0), m_uiMaterialIndex(NoMaterial), m_hasNormals(false) {
m_name(name),
m_pMaterial(nullptr),
m_uiNumIndices(0),
m_uiMaterialIndex(NoMaterial),
m_hasNormals(false) {
memset(m_uiUVCoordinates, 0, sizeof(unsigned int) * AI_MAX_NUMBER_OF_TEXTURECOORDS);
}
@ -275,13 +279,13 @@ struct Model {
//! \brief The default class constructor
Model() :
m_ModelName(""),
m_pCurrent(NULL),
m_pCurrentMaterial(NULL),
m_pDefaultMaterial(NULL),
m_pGroupFaceIDs(NULL),
m_pCurrent(nullptr),
m_pCurrentMaterial(nullptr),
m_pDefaultMaterial(nullptr),
m_pGroupFaceIDs(nullptr),
m_strActiveGroup(""),
m_TextureCoordDim(0),
m_pCurrentMesh(NULL) {
m_pCurrentMesh(nullptr) {
// empty
}

View File

@ -252,9 +252,9 @@ void ObjFileImporter::CreateDataFromImport(const ObjFile::Model *pModel, aiScene
aiNode *ObjFileImporter::createNodes(const ObjFile::Model *pModel, const ObjFile::Object *pObject,
aiNode *pParent, aiScene *pScene,
std::vector<aiMesh *> &MeshArray) {
ai_assert(NULL != pModel);
if (NULL == pObject) {
return NULL;
ai_assert(nullptr != pModel);
if (nullptr == pObject) {
return nullptr;
}
// Store older mesh size to be able to computes mesh offsets for new mesh instances
@ -264,7 +264,7 @@ aiNode *ObjFileImporter::createNodes(const ObjFile::Model *pModel, const ObjFile
pNode->mName = pObject->m_strObjName;
// If we have a parent node, store it
ai_assert(NULL != pParent);
ai_assert(nullptr != pParent);
appendChildToParentNode(pParent, pNode);
for (size_t i = 0; i < pObject->m_Meshes.size(); ++i) {
@ -308,20 +308,20 @@ aiNode *ObjFileImporter::createNodes(const ObjFile::Model *pModel, const ObjFile
// Create topology data
aiMesh *ObjFileImporter::createTopology(const ObjFile::Model *pModel, const ObjFile::Object *pData, unsigned int meshIndex) {
// Checking preconditions
ai_assert(NULL != pModel);
ai_assert(nullptr != pModel);
if (NULL == pData) {
return NULL;
if (nullptr == pData) {
return nullptr;
}
// Create faces
ObjFile::Mesh *pObjMesh = pModel->m_Meshes[meshIndex];
if (!pObjMesh) {
return NULL;
return nullptr;
}
if (pObjMesh->m_Faces.empty()) {
return NULL;
return nullptr;
}
std::unique_ptr<aiMesh> pMesh(new aiMesh);
@ -331,7 +331,7 @@ aiMesh *ObjFileImporter::createTopology(const ObjFile::Model *pModel, const ObjF
for (size_t index = 0; index < pObjMesh->m_Faces.size(); index++) {
ObjFile::Face *const inp = pObjMesh->m_Faces[index];
ai_assert(NULL != inp);
ai_assert(nullptr != inp);
if (inp->m_PrimitiveType == aiPrimitiveType_LINE) {
pMesh->mNumFaces += static_cast<unsigned int>(inp->m_vertices.size() - 1);
@ -400,7 +400,7 @@ void ObjFileImporter::createVertexArray(const ObjFile::Model *pModel,
aiMesh *pMesh,
unsigned int numIndices) {
// Checking preconditions
ai_assert(NULL != pCurrentObject);
ai_assert(nullptr != pCurrentObject);
// Break, if no faces are stored in object
if (pCurrentObject->m_Meshes.empty())
@ -408,7 +408,7 @@ void ObjFileImporter::createVertexArray(const ObjFile::Model *pModel,
// Get current mesh
ObjFile::Mesh *pObjMesh = pModel->m_Meshes[uiMeshIndex];
if (NULL == pObjMesh || pObjMesh->m_uiNumIndices < 1) {
if (nullptr == pObjMesh || pObjMesh->m_uiNumIndices < 1) {
return;
}
@ -561,7 +561,7 @@ void ObjFileImporter::addTextureMappingModeProperty(aiMaterial *mat, aiTextureTy
// ------------------------------------------------------------------------------------------------
// Creates the material
void ObjFileImporter::createMaterials(const ObjFile::Model *pModel, aiScene *pScene) {
if (NULL == pScene) {
if (nullptr == pScene) {
return;
}
@ -717,8 +717,8 @@ void ObjFileImporter::createMaterials(const ObjFile::Model *pModel, aiScene *pSc
// Appends this node to the parent node
void ObjFileImporter::appendChildToParentNode(aiNode *pParent, aiNode *pChild) {
// Checking preconditions
ai_assert(NULL != pParent);
ai_assert(NULL != pChild);
ai_assert(nullptr != pParent);
ai_assert(nullptr != pChild);
// Assign parent to child
pChild->mParent = pParent;

View File

@ -200,7 +200,7 @@ void ObjFileMtlImporter::load() {
// -------------------------------------------------------------------
// Loads a color definition
void ObjFileMtlImporter::getColorRGBA(aiColor3D *pColor) {
ai_assert(NULL != pColor);
ai_assert(nullptr != pColor);
ai_real r(0.0), g(0.0), b(0.0);
m_DataIt = getFloat<DataArrayIt>(m_DataIt, m_DataItEnd, r);
@ -274,7 +274,7 @@ void ObjFileMtlImporter::createMaterial() {
// -------------------------------------------------------------------
// Gets a texture name from data.
void ObjFileMtlImporter::getTexture() {
aiString *out(NULL);
aiString *out(nullptr);
int clampIndex = -1;
const char *pPtr(&(*m_DataIt));
@ -332,7 +332,7 @@ void ObjFileMtlImporter::getTexture() {
std::string texture;
m_DataIt = getName<DataArrayIt>(m_DataIt, m_DataItEnd, texture);
if (NULL != out) {
if (nullptr != out) {
out->Set(texture);
}
}

View File

@ -253,7 +253,6 @@ static bool isDataDefinitionEnd(const char *tmp) {
if (*tmp == '\\') {
tmp++;
if (IsLineEnd(*tmp)) {
tmp++;
return true;
}
}
@ -495,19 +494,19 @@ void ObjFileParser::getFace(aiPrimitiveType type) {
}
// Set active material, if one set
if (NULL != m_pModel->m_pCurrentMaterial) {
if (nullptr != m_pModel->m_pCurrentMaterial) {
face->m_pMaterial = m_pModel->m_pCurrentMaterial;
} else {
face->m_pMaterial = m_pModel->m_pDefaultMaterial;
}
// Create a default object, if nothing is there
if (NULL == m_pModel->m_pCurrent) {
if (nullptr == m_pModel->m_pCurrent) {
createObject(DefaultObjName);
}
// Assign face to mesh
if (NULL == m_pModel->m_pCurrentMesh) {
if (nullptr == m_pModel->m_pCurrentMesh) {
createMesh(DefaultObjName);
}
@ -754,7 +753,7 @@ void ObjFileParser::getObjectName() {
std::string strObjectName(pStart, &(*m_DataIt));
if (!strObjectName.empty()) {
// Reset current object
m_pModel->m_pCurrent = NULL;
m_pModel->m_pCurrent = nullptr;
// Search for actual object
for (std::vector<ObjFile::Object *>::const_iterator it = m_pModel->m_Objects.begin();
@ -767,7 +766,7 @@ void ObjFileParser::getObjectName() {
}
// Allocate a new object, if current one was not found before
if (NULL == m_pModel->m_pCurrent) {
if (nullptr == m_pModel->m_pCurrent) {
createObject(strObjectName);
}
}
@ -776,7 +775,7 @@ void ObjFileParser::getObjectName() {
// -------------------------------------------------------------------
// Creates a new object instance
void ObjFileParser::createObject(const std::string &objName) {
ai_assert(NULL != m_pModel);
ai_assert(nullptr != m_pModel);
m_pModel->m_pCurrent = new ObjFile::Object;
m_pModel->m_pCurrent->m_strObjName = objName;
@ -793,11 +792,12 @@ void ObjFileParser::createObject(const std::string &objName) {
// -------------------------------------------------------------------
// Creates a new mesh
void ObjFileParser::createMesh(const std::string &meshName) {
ai_assert(NULL != m_pModel);
ai_assert(nullptr != m_pModel);
m_pModel->m_pCurrentMesh = new ObjFile::Mesh(meshName);
m_pModel->m_Meshes.push_back(m_pModel->m_pCurrentMesh);
unsigned int meshId = static_cast<unsigned int>(m_pModel->m_Meshes.size() - 1);
if (NULL != m_pModel->m_pCurrent) {
if (nullptr != m_pModel->m_pCurrent) {
m_pModel->m_pCurrent->m_Meshes.push_back(meshId);
} else {
ASSIMP_LOG_ERROR("OBJ: No object detected to attach a new mesh instance.");

View File

@ -43,16 +43,13 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef ASSIMP_BUILD_NO_OGRE_IMPORTER
#include "OgreStructs.h"
#include <assimp/Exceptional.h>
#include <assimp/TinyFormatter.h>
#include <assimp/scene.h>
#include <assimp/DefaultLogger.hpp>
#include <assimp/Exceptional.h>
namespace Assimp
{
namespace Ogre
{
namespace Assimp {
namespace Ogre {
// VertexElement
@ -61,24 +58,19 @@ VertexElement::VertexElement() :
source(0),
offset(0),
type(VET_FLOAT1),
semantic(VES_POSITION)
{
semantic(VES_POSITION) {
}
size_t VertexElement::Size() const
{
size_t VertexElement::Size() const {
return TypeSize(type);
}
size_t VertexElement::ComponentCount() const
{
size_t VertexElement::ComponentCount() const {
return ComponentCount(type);
}
size_t VertexElement::ComponentCount(Type type)
{
switch(type)
{
size_t VertexElement::ComponentCount(Type type) {
switch (type) {
case VET_COLOUR:
case VET_COLOUR_ABGR:
case VET_COLOUR_ARGB:
@ -115,10 +107,8 @@ size_t VertexElement::ComponentCount(Type type)
return 0;
}
size_t VertexElement::TypeSize(Type type)
{
switch(type)
{
size_t VertexElement::TypeSize(Type type) {
switch (type) {
case VET_COLOUR:
case VET_COLOUR_ABGR:
case VET_COLOUR_ARGB:
@ -177,15 +167,12 @@ size_t VertexElement::TypeSize(Type type)
return 0;
}
std::string VertexElement::TypeToString()
{
std::string VertexElement::TypeToString() {
return TypeToString(type);
}
std::string VertexElement::TypeToString(Type type)
{
switch(type)
{
std::string VertexElement::TypeToString(Type type) {
switch (type) {
case VET_COLOUR: return "COLOUR";
case VET_COLOUR_ABGR: return "COLOUR_ABGR";
case VET_COLOUR_ARGB: return "COLOUR_ARGB";
@ -218,15 +205,12 @@ std::string VertexElement::TypeToString(Type type)
return "Uknown_VertexElement::Type";
}
std::string VertexElement::SemanticToString()
{
std::string VertexElement::SemanticToString() {
return SemanticToString(semantic);
}
std::string VertexElement::SemanticToString(Semantic semantic)
{
switch(semantic)
{
std::string VertexElement::SemanticToString(Semantic semantic) {
switch (semantic) {
case VES_POSITION: return "POSITION";
case VES_BLEND_WEIGHTS: return "BLEND_WEIGHTS";
case VES_BLEND_INDICES: return "BLEND_INDICES";
@ -243,27 +227,21 @@ std::string VertexElement::SemanticToString(Semantic semantic)
// IVertexData
IVertexData::IVertexData() :
count(0)
{
count(0) {
}
bool IVertexData::HasBoneAssignments() const
{
bool IVertexData::HasBoneAssignments() const {
return !boneAssignments.empty();
}
void IVertexData::AddVertexMapping(uint32_t oldIndex, uint32_t newIndex)
{
void IVertexData::AddVertexMapping(uint32_t oldIndex, uint32_t newIndex) {
BoneAssignmentsForVertex(oldIndex, newIndex, boneAssignmentsMap[newIndex]);
vertexIndexMapping[oldIndex].push_back(newIndex);
}
void IVertexData::BoneAssignmentsForVertex(uint32_t currentIndex, uint32_t newIndex, VertexBoneAssignmentList &dest) const
{
for (const auto &boneAssign : boneAssignments)
{
if (boneAssign.vertexIndex == currentIndex)
{
void IVertexData::BoneAssignmentsForVertex(uint32_t currentIndex, uint32_t newIndex, VertexBoneAssignmentList &dest) const {
for (const auto &boneAssign : boneAssignments) {
if (boneAssign.vertexIndex == currentIndex) {
VertexBoneAssignment a = boneAssign;
a.vertexIndex = newIndex;
dest.push_back(a);
@ -271,15 +249,12 @@ void IVertexData::BoneAssignmentsForVertex(uint32_t currentIndex, uint32_t newIn
}
}
AssimpVertexBoneWeightList IVertexData::AssimpBoneWeights(size_t vertices)
{
AssimpVertexBoneWeightList IVertexData::AssimpBoneWeights(size_t vertices) {
AssimpVertexBoneWeightList weights;
for(size_t vi=0; vi<vertices; ++vi)
{
for (size_t vi = 0; vi < vertices; ++vi) {
VertexBoneAssignmentList &vertexWeights = boneAssignmentsMap[static_cast<unsigned int>(vi)];
for (VertexBoneAssignmentList::const_iterator iter = vertexWeights.begin(), end = vertexWeights.end();
iter!=end; ++iter)
{
iter != end; ++iter) {
std::vector<aiVertexWeight> &boneWeights = weights[iter->boneIndex];
boneWeights.push_back(aiVertexWeight(static_cast<unsigned int>(vi), iter->weight));
}
@ -287,11 +262,9 @@ AssimpVertexBoneWeightList IVertexData::AssimpBoneWeights(size_t vertices)
return weights;
}
std::set<uint16_t> IVertexData::ReferencedBonesByWeights() const
{
std::set<uint16_t> IVertexData::ReferencedBonesByWeights() const {
std::set<uint16_t> referenced;
for (const auto &boneAssign : boneAssignments)
{
for (const auto &boneAssign : boneAssignments) {
referenced.insert(boneAssign.boneIndex);
}
return referenced;
@ -299,44 +272,36 @@ std::set<uint16_t> IVertexData::ReferencedBonesByWeights() const
// VertexData
VertexData::VertexData()
{
VertexData::VertexData() {
}
VertexData::~VertexData()
{
VertexData::~VertexData() {
Reset();
}
void VertexData::Reset()
{
void VertexData::Reset() {
// Releases shared ptr memory streams.
vertexBindings.clear();
vertexElements.clear();
}
uint32_t VertexData::VertexSize(uint16_t source) const
{
uint32_t VertexData::VertexSize(uint16_t source) const {
uint32_t size = 0;
for(const auto &element : vertexElements)
{
for (const auto &element : vertexElements) {
if (element.source == source)
size += static_cast<uint32_t>(element.Size());
}
return size;
}
MemoryStream *VertexData::VertexBuffer(uint16_t source)
{
MemoryStream *VertexData::VertexBuffer(uint16_t source) {
if (vertexBindings.find(source) != vertexBindings.end())
return vertexBindings[source].get();
return 0;
}
VertexElement *VertexData::GetVertexElement(VertexElement::Semantic semantic, uint16_t index)
{
for(auto & element : vertexElements)
{
VertexElement *VertexData::GetVertexElement(VertexElement::Semantic semantic, uint16_t index) {
for (auto &element : vertexElements) {
if (element.semantic == semantic && element.index == index)
return &element;
}
@ -345,32 +310,26 @@ VertexElement *VertexData::GetVertexElement(VertexElement::Semantic semantic, ui
// VertexDataXml
VertexDataXml::VertexDataXml()
{
VertexDataXml::VertexDataXml() {
}
bool VertexDataXml::HasPositions() const
{
bool VertexDataXml::HasPositions() const {
return !positions.empty();
}
bool VertexDataXml::HasNormals() const
{
bool VertexDataXml::HasNormals() const {
return !normals.empty();
}
bool VertexDataXml::HasTangents() const
{
bool VertexDataXml::HasTangents() const {
return !tangents.empty();
}
bool VertexDataXml::HasUvs() const
{
bool VertexDataXml::HasUvs() const {
return !uvs.empty();
}
size_t VertexDataXml::NumUvs() const
{
size_t VertexDataXml::NumUvs() const {
return uvs.size();
}
@ -379,50 +338,42 @@ size_t VertexDataXml::NumUvs() const
IndexData::IndexData() :
count(0),
faceCount(0),
is32bit(false)
{
is32bit(false) {
}
IndexData::~IndexData()
{
IndexData::~IndexData() {
Reset();
}
void IndexData::Reset()
{
void IndexData::Reset() {
// Release shared ptr memory stream.
buffer.reset();
}
size_t IndexData::IndexSize() const
{
size_t IndexData::IndexSize() const {
return (is32bit ? sizeof(uint32_t) : sizeof(uint16_t));
}
size_t IndexData::FaceSize() const
{
size_t IndexData::FaceSize() const {
return IndexSize() * 3;
}
// Mesh
Mesh::Mesh()
: hasSkeletalAnimations(false)
, skeleton(NULL)
, sharedVertexData(NULL)
, subMeshes()
, animations()
, poses()
{
Mesh::Mesh() :
hasSkeletalAnimations(false),
skeleton(nullptr),
sharedVertexData(nullptr),
subMeshes(),
animations(),
poses() {
}
Mesh::~Mesh()
{
Mesh::~Mesh() {
Reset();
}
void Mesh::Reset()
{
void Mesh::Reset() {
OGRE_SAFE_DELETE(skeleton)
OGRE_SAFE_DELETE(sharedVertexData)
@ -440,13 +391,11 @@ void Mesh::Reset()
poses.clear();
}
size_t Mesh::NumSubMeshes() const
{
size_t Mesh::NumSubMeshes() const {
return subMeshes.size();
}
SubMesh *Mesh::GetSubMesh( size_t index ) const
{
SubMesh *Mesh::GetSubMesh(size_t index) const {
for (size_t i = 0; i < subMeshes.size(); ++i) {
if (subMeshes[i]->index == index) {
return subMeshes[i];
@ -455,8 +404,7 @@ SubMesh *Mesh::GetSubMesh( size_t index ) const
return 0;
}
void Mesh::ConvertToAssimpScene(aiScene* dest)
{
void Mesh::ConvertToAssimpScene(aiScene *dest) {
if (nullptr == dest) {
return;
}
@ -477,29 +425,24 @@ void Mesh::ConvertToAssimpScene(aiScene* dest)
}
// Export skeleton
if (skeleton)
{
if (skeleton) {
// Bones
if (!skeleton->bones.empty())
{
if (!skeleton->bones.empty()) {
BoneList rootBones = skeleton->RootBones();
dest->mRootNode->mNumChildren = static_cast<unsigned int>(rootBones.size());
dest->mRootNode->mChildren = new aiNode *[dest->mRootNode->mNumChildren];
for(size_t i=0, len=rootBones.size(); i<len; ++i)
{
for (size_t i = 0, len = rootBones.size(); i < len; ++i) {
dest->mRootNode->mChildren[i] = rootBones[i]->ConvertToAssimpNode(skeleton, dest->mRootNode);
}
}
// Animations
if (!skeleton->animations.empty())
{
if (!skeleton->animations.empty()) {
dest->mNumAnimations = static_cast<unsigned int>(skeleton->animations.size());
dest->mAnimations = new aiAnimation *[dest->mNumAnimations];
for(size_t i=0, len=skeleton->animations.size(); i<len; ++i)
{
for (size_t i = 0, len = skeleton->animations.size(); i < len; ++i) {
dest->mAnimations[i] = skeleton->animations[i]->ConvertToAssimpAnimation();
}
}
@ -512,31 +455,26 @@ ISubMesh::ISubMesh() :
index(0),
materialIndex(-1),
usesSharedVertexData(false),
operationType(OT_POINT_LIST)
{
operationType(OT_POINT_LIST) {
}
// SubMesh
SubMesh::SubMesh() :
vertexData(0),
indexData(new IndexData())
{
indexData(new IndexData()) {
}
SubMesh::~SubMesh()
{
SubMesh::~SubMesh() {
Reset();
}
void SubMesh::Reset()
{
void SubMesh::Reset(){
OGRE_SAFE_DELETE(vertexData)
OGRE_SAFE_DELETE(indexData)
}
aiMesh *SubMesh::ConvertToAssimpMesh(Mesh *parent)
{
aiMesh *SubMesh::ConvertToAssimpMesh(Mesh *parent) {
if (operationType != OT_TRIANGLE_LIST) {
throw DeadlyImportError(Formatter::format() << "Only mesh operation type OT_TRIANGLE_LIST is supported. Found " << operationType);
}
@ -602,28 +540,20 @@ aiMesh *SubMesh::ConvertToAssimpMesh(Mesh *parent)
dest->mNormals = new aiVector3D[dest->mNumVertices];
// Prepare UVs, ignoring incompatible UVs.
if (uv1)
{
if (uv1Element->type == VertexElement::VET_FLOAT2 || uv1Element->type == VertexElement::VET_FLOAT3)
{
if (uv1) {
if (uv1Element->type == VertexElement::VET_FLOAT2 || uv1Element->type == VertexElement::VET_FLOAT3) {
dest->mNumUVComponents[0] = static_cast<unsigned int>(uv1Element->ComponentCount());
dest->mTextureCoords[0] = new aiVector3D[dest->mNumVertices];
}
else
{
} else {
ASSIMP_LOG_WARN(Formatter::format() << "Ogre imported UV0 type " << uv1Element->TypeToString() << " is not compatible with Assimp. Ignoring UV.");
uv1 = 0;
}
}
if (uv2)
{
if (uv2Element->type == VertexElement::VET_FLOAT2 || uv2Element->type == VertexElement::VET_FLOAT3)
{
if (uv2) {
if (uv2Element->type == VertexElement::VET_FLOAT2 || uv2Element->type == VertexElement::VET_FLOAT3) {
dest->mNumUVComponents[1] = static_cast<unsigned int>(uv2Element->ComponentCount());
dest->mTextureCoords[1] = new aiVector3D[dest->mNumVertices];
}
else
{
} else {
ASSIMP_LOG_WARN(Formatter::format() << "Ogre imported UV0 type " << uv2Element->TypeToString() << " is not compatible with Assimp. Ignoring UV.");
uv2 = 0;
}
@ -634,23 +564,18 @@ aiMesh *SubMesh::ConvertToAssimpMesh(Mesh *parent)
MemoryStream *faces = indexData->buffer.get();
for (size_t fi = 0, isize = indexData->IndexSize(), fsize = indexData->FaceSize();
fi<dest->mNumFaces; ++fi)
{
fi < dest->mNumFaces; ++fi) {
// Source Ogre face
aiFace ogreFace;
ogreFace.mNumIndices = 3;
ogreFace.mIndices = new unsigned int[3];
faces->Seek(fi * fsize, aiOrigin_SET);
if (indexData->is32bit)
{
if (indexData->is32bit) {
faces->Read(&ogreFace.mIndices[0], isize, 3);
}
else
{
} else {
uint16_t iout = 0;
for (size_t ii=0; ii<3; ++ii)
{
for (size_t ii = 0; ii < 3; ++ii) {
faces->Read(&iout, isize, 1);
ogreFace.mIndices[ii] = static_cast<unsigned int>(iout);
}
@ -662,8 +587,7 @@ aiMesh *SubMesh::ConvertToAssimpMesh(Mesh *parent)
face.mIndices = new unsigned int[3];
const size_t pos = fi * 3;
for (size_t v=0; v<3; ++v)
{
for (size_t v = 0; v < 3; ++v) {
const size_t newIndex = pos + v;
// Write face index
@ -678,21 +602,18 @@ aiMesh *SubMesh::ConvertToAssimpMesh(Mesh *parent)
positions->Read(&dest->mVertices[newIndex], sizePosition, 1);
// Normal
if (normals)
{
if (normals) {
normals->Seek((vWidthNormal * ogreVertexIndex) + normalsElement->offset, aiOrigin_SET);
normals->Read(&dest->mNormals[newIndex], sizeNormal, 1);
}
// UV0
if (uv1 && uv1Dest)
{
if (uv1 && uv1Dest) {
uv1->Seek((vWidthUv1 * ogreVertexIndex) + uv1Element->offset, aiOrigin_SET);
uv1->Read(&uv1Dest[newIndex], sizeUv1, 1);
uv1Dest[newIndex].y = (uv1Dest[newIndex].y * -1) + 1; // Flip UV from Ogre to Assimp form
}
// UV1
if (uv2 && uv2Dest)
{
if (uv2 && uv2Dest) {
uv2->Seek((vWidthUv2 * ogreVertexIndex) + uv2Element->offset, aiOrigin_SET);
uv2->Read(&uv2Dest[newIndex], sizeUv2, 1);
uv2Dest[newIndex].y = (uv2Dest[newIndex].y * -1) + 1; // Flip UV from Ogre to Assimp form
@ -701,8 +622,7 @@ aiMesh *SubMesh::ConvertToAssimpMesh(Mesh *parent)
}
// Bones and bone weights
if (parent->skeleton && boneAssignments)
{
if (parent->skeleton && boneAssignments) {
AssimpVertexBoneWeightList weights = src->AssimpBoneWeights(dest->mNumVertices);
std::set<uint16_t> referencedBones = src->ReferencedBonesByWeights();
@ -710,8 +630,7 @@ aiMesh *SubMesh::ConvertToAssimpMesh(Mesh *parent)
dest->mBones = new aiBone *[dest->mNumBones];
size_t assimpBoneIndex = 0;
for(std::set<uint16_t>::const_iterator rbIter=referencedBones.begin(), rbEnd=referencedBones.end(); rbIter != rbEnd; ++rbIter, ++assimpBoneIndex)
{
for (std::set<uint16_t>::const_iterator rbIter = referencedBones.begin(), rbEnd = referencedBones.end(); rbIter != rbEnd; ++rbIter, ++assimpBoneIndex) {
Bone *bone = parent->skeleton->BoneById((*rbIter));
dest->mBones[assimpBoneIndex] = bone->ConvertToAssimpBone(parent->skeleton, weights[bone->id]);
}
@ -724,17 +643,14 @@ aiMesh *SubMesh::ConvertToAssimpMesh(Mesh *parent)
MeshXml::MeshXml() :
skeleton(0),
sharedVertexData(0)
{
sharedVertexData(0) {
}
MeshXml::~MeshXml()
{
MeshXml::~MeshXml() {
Reset();
}
void MeshXml::Reset()
{
void MeshXml::Reset() {
OGRE_SAFE_DELETE(skeleton)
OGRE_SAFE_DELETE(sharedVertexData)
@ -744,21 +660,18 @@ void MeshXml::Reset()
subMeshes.clear();
}
size_t MeshXml::NumSubMeshes() const
{
size_t MeshXml::NumSubMeshes() const {
return subMeshes.size();
}
SubMeshXml *MeshXml::GetSubMesh(uint16_t index) const
{
SubMeshXml *MeshXml::GetSubMesh(uint16_t index) const {
for (size_t i = 0; i < subMeshes.size(); ++i)
if (subMeshes[i]->index == index)
return subMeshes[i];
return 0;
}
void MeshXml::ConvertToAssimpScene(aiScene* dest)
{
void MeshXml::ConvertToAssimpScene(aiScene *dest) {
// Setup
dest->mNumMeshes = static_cast<unsigned int>(NumSubMeshes());
dest->mMeshes = new aiMesh *[dest->mNumMeshes];
@ -769,36 +682,30 @@ void MeshXml::ConvertToAssimpScene(aiScene* dest)
dest->mRootNode->mMeshes = new unsigned int[dest->mRootNode->mNumMeshes];
// Export meshes
for(size_t i=0; i<dest->mNumMeshes; ++i)
{
for (size_t i = 0; i < dest->mNumMeshes; ++i) {
dest->mMeshes[i] = subMeshes[i]->ConvertToAssimpMesh(this);
dest->mRootNode->mMeshes[i] = static_cast<unsigned int>(i);
}
// Export skeleton
if (skeleton)
{
if (skeleton) {
// Bones
if (!skeleton->bones.empty())
{
if (!skeleton->bones.empty()) {
BoneList rootBones = skeleton->RootBones();
dest->mRootNode->mNumChildren = static_cast<unsigned int>(rootBones.size());
dest->mRootNode->mChildren = new aiNode *[dest->mRootNode->mNumChildren];
for(size_t i=0, len=rootBones.size(); i<len; ++i)
{
for (size_t i = 0, len = rootBones.size(); i < len; ++i) {
dest->mRootNode->mChildren[i] = rootBones[i]->ConvertToAssimpNode(skeleton, dest->mRootNode);
}
}
// Animations
if (!skeleton->animations.empty())
{
if (!skeleton->animations.empty()) {
dest->mNumAnimations = static_cast<unsigned int>(skeleton->animations.size());
dest->mAnimations = new aiAnimation *[dest->mNumAnimations];
for(size_t i=0, len=skeleton->animations.size(); i<len; ++i)
{
for (size_t i = 0, len = skeleton->animations.size(); i < len; ++i) {
dest->mAnimations[i] = skeleton->animations[i]->ConvertToAssimpAnimation();
}
}
@ -809,23 +716,19 @@ void MeshXml::ConvertToAssimpScene(aiScene* dest)
SubMeshXml::SubMeshXml() :
indexData(new IndexDataXml()),
vertexData(0)
{
vertexData(0) {
}
SubMeshXml::~SubMeshXml()
{
SubMeshXml::~SubMeshXml() {
Reset();
}
void SubMeshXml::Reset()
{
void SubMeshXml::Reset(){
OGRE_SAFE_DELETE(indexData)
OGRE_SAFE_DELETE(vertexData)
}
aiMesh *SubMeshXml::ConvertToAssimpMesh(MeshXml *parent)
{
aiMesh *SubMeshXml::ConvertToAssimpMesh(MeshXml *parent) {
aiMesh *dest = new aiMesh();
dest->mPrimitiveTypes = aiPrimitiveType_TRIANGLE;
@ -855,14 +758,12 @@ aiMesh *SubMeshXml::ConvertToAssimpMesh(MeshXml *parent)
dest->mNormals = new aiVector3D[dest->mNumVertices];
// Prepare UVs
for(size_t uvi=0; uvi<uvs; ++uvi)
{
for (size_t uvi = 0; uvi < uvs; ++uvi) {
dest->mNumUVComponents[uvi] = 2;
dest->mTextureCoords[uvi] = new aiVector3D[dest->mNumVertices];
}
for (size_t fi=0; fi<dest->mNumFaces; ++fi)
{
for (size_t fi = 0; fi < dest->mNumFaces; ++fi) {
// Source Ogre face
aiFace &ogreFace = indexData->faces[fi];
@ -872,8 +773,7 @@ aiMesh *SubMeshXml::ConvertToAssimpMesh(MeshXml *parent)
face.mIndices = new unsigned int[3];
const size_t pos = fi * 3;
for (size_t v=0; v<3; ++v)
{
for (size_t v = 0; v < 3; ++v) {
const size_t newIndex = pos + v;
// Write face index
@ -891,8 +791,7 @@ aiMesh *SubMeshXml::ConvertToAssimpMesh(MeshXml *parent)
dest->mNormals[newIndex] = src->normals[ogreVertexIndex];
// UVs
for(size_t uvi=0; uvi<uvs; ++uvi)
{
for (size_t uvi = 0; uvi < uvs; ++uvi) {
aiVector3D *uvDest = dest->mTextureCoords[uvi];
std::vector<aiVector3D> &uvSrc = src->uvs[uvi];
uvDest[newIndex] = uvSrc[ogreVertexIndex];
@ -901,8 +800,7 @@ aiMesh *SubMeshXml::ConvertToAssimpMesh(MeshXml *parent)
}
// Bones and bone weights
if (parent->skeleton && boneAssignments)
{
if (parent->skeleton && boneAssignments) {
AssimpVertexBoneWeightList weights = src->AssimpBoneWeights(dest->mNumVertices);
std::set<uint16_t> referencedBones = src->ReferencedBonesByWeights();
@ -910,8 +808,7 @@ aiMesh *SubMeshXml::ConvertToAssimpMesh(MeshXml *parent)
dest->mBones = new aiBone *[dest->mNumBones];
size_t assimpBoneIndex = 0;
for(std::set<uint16_t>::const_iterator rbIter=referencedBones.begin(), rbEnd=referencedBones.end(); rbIter != rbEnd; ++rbIter, ++assimpBoneIndex)
{
for (std::set<uint16_t>::const_iterator rbIter = referencedBones.begin(), rbEnd = referencedBones.end(); rbIter != rbEnd; ++rbIter, ++assimpBoneIndex) {
Bone *bone = parent->skeleton->BoneById((*rbIter));
dest->mBones[assimpBoneIndex] = bone->ConvertToAssimpBone(parent->skeleton, weights[bone->id]);
}
@ -923,48 +820,46 @@ aiMesh *SubMeshXml::ConvertToAssimpMesh(MeshXml *parent)
// Animation
Animation::Animation(Skeleton *parent) :
parentMesh(NULL),
parentMesh(nullptr),
parentSkeleton(parent),
length(0.0f),
baseTime(-1.0f)
{
baseTime(-1.0f) {
// empty
}
Animation::Animation(Mesh *parent) :
parentMesh(parent),
parentSkeleton(0),
length(0.0f),
baseTime(-1.0f)
{
baseTime(-1.0f) {
// empty
}
VertexData *Animation::AssociatedVertexData(VertexAnimationTrack *track) const
{
if (!parentMesh)
return 0;
VertexData *Animation::AssociatedVertexData(VertexAnimationTrack *track) const {
if (nullptr == parentMesh) {
return nullptr;
}
bool sharedGeom = (track->target == 0);
if (sharedGeom)
if (sharedGeom) {
return parentMesh->sharedVertexData;
else
}
return parentMesh->GetSubMesh(track->target - 1)->vertexData;
}
aiAnimation *Animation::ConvertToAssimpAnimation()
{
aiAnimation *Animation::ConvertToAssimpAnimation() {
aiAnimation *anim = new aiAnimation();
anim->mName = name;
anim->mDuration = static_cast<double>(length);
anim->mTicksPerSecond = 1.0;
// Tracks
if (!tracks.empty())
{
if (!tracks.empty()) {
anim->mNumChannels = static_cast<unsigned int>(tracks.size());
anim->mChannels = new aiNodeAnim *[anim->mNumChannels];
for(size_t i=0, len=tracks.size(); i<len; ++i)
{
for (size_t i = 0, len = tracks.size(); i < len; ++i) {
anim->mChannels[i] = tracks[i].ConvertToAssimpAnimationNode(parentSkeleton);
}
}
@ -976,17 +871,14 @@ aiAnimation *Animation::ConvertToAssimpAnimation()
Skeleton::Skeleton() :
bones(),
animations(),
blendMode(ANIMBLEND_AVERAGE)
{
blendMode(ANIMBLEND_AVERAGE) {
}
Skeleton::~Skeleton()
{
Skeleton::~Skeleton() {
Reset();
}
void Skeleton::Reset()
{
void Skeleton::Reset() {
for (auto &bone : bones) {
OGRE_SAFE_DELETE(bone)
}
@ -997,42 +889,34 @@ void Skeleton::Reset()
animations.clear();
}
BoneList Skeleton::RootBones() const
{
BoneList Skeleton::RootBones() const {
BoneList rootBones;
for(BoneList::const_iterator iter = bones.begin(); iter != bones.end(); ++iter)
{
for (BoneList::const_iterator iter = bones.begin(); iter != bones.end(); ++iter) {
if (!(*iter)->IsParented())
rootBones.push_back((*iter));
}
return rootBones;
}
size_t Skeleton::NumRootBones() const
{
size_t Skeleton::NumRootBones() const {
size_t num = 0;
for(BoneList::const_iterator iter = bones.begin(); iter != bones.end(); ++iter)
{
for (BoneList::const_iterator iter = bones.begin(); iter != bones.end(); ++iter) {
if (!(*iter)->IsParented())
num++;
}
return num;
}
Bone *Skeleton::BoneByName(const std::string &name) const
{
for(BoneList::const_iterator iter = bones.begin(); iter != bones.end(); ++iter)
{
Bone *Skeleton::BoneByName(const std::string &name) const {
for (BoneList::const_iterator iter = bones.begin(); iter != bones.end(); ++iter) {
if ((*iter)->name == name)
return (*iter);
}
return 0;
}
Bone *Skeleton::BoneById(uint16_t id) const
{
for(BoneList::const_iterator iter = bones.begin(); iter != bones.end(); ++iter)
{
Bone *Skeleton::BoneById(uint16_t id) const {
for (BoneList::const_iterator iter = bones.begin(); iter != bones.end(); ++iter) {
if ((*iter)->id == id)
return (*iter);
}
@ -1045,22 +929,18 @@ Bone::Bone() :
id(0),
parent(0),
parentId(-1),
scale(1.0f, 1.0f, 1.0f)
{
scale(1.0f, 1.0f, 1.0f) {
}
bool Bone::IsParented() const
{
bool Bone::IsParented() const {
return (parentId != -1 && parent != 0);
}
uint16_t Bone::ParentId() const
{
uint16_t Bone::ParentId() const {
return static_cast<uint16_t>(parentId);
}
void Bone::AddChild(Bone *bone)
{
void Bone::AddChild(Bone *bone) {
if (!bone)
return;
if (bone->IsParented())
@ -1071,8 +951,7 @@ void Bone::AddChild(Bone *bone)
children.push_back(bone->id);
}
void Bone::CalculateWorldMatrixAndDefaultPose(Skeleton *skeleton)
{
void Bone::CalculateWorldMatrixAndDefaultPose(Skeleton *skeleton) {
if (!IsParented())
worldMatrix = aiMatrix4x4(scale, rotation, position).Inverse();
else
@ -1081,8 +960,7 @@ void Bone::CalculateWorldMatrixAndDefaultPose(Skeleton *skeleton)
defaultPose = aiMatrix4x4(scale, rotation, position);
// Recursively for all children now that the parent matrix has been calculated.
for (auto boneId : children)
{
for (auto boneId : children) {
Bone *child = skeleton->BoneById(boneId);
if (!child) {
throw DeadlyImportError(Formatter::format() << "CalculateWorldMatrixAndDefaultPose: Failed to find child bone " << boneId << " for parent " << id << " " << name);
@ -1091,21 +969,18 @@ void Bone::CalculateWorldMatrixAndDefaultPose(Skeleton *skeleton)
}
}
aiNode *Bone::ConvertToAssimpNode(Skeleton *skeleton, aiNode *parentNode)
{
aiNode *Bone::ConvertToAssimpNode(Skeleton *skeleton, aiNode *parentNode) {
// Bone node
aiNode *node = new aiNode(name);
node->mParent = parentNode;
node->mTransformation = defaultPose;
// Children
if (!children.empty())
{
if (!children.empty()) {
node->mNumChildren = static_cast<unsigned int>(children.size());
node->mChildren = new aiNode *[node->mNumChildren];
for(size_t i=0, len=children.size(); i<len; ++i)
{
for (size_t i = 0, len = children.size(); i < len; ++i) {
Bone *child = skeleton->BoneById(children[i]);
if (!child) {
throw DeadlyImportError(Formatter::format() << "ConvertToAssimpNode: Failed to find child bone " << children[i] << " for parent " << id << " " << name);
@ -1116,14 +991,12 @@ aiNode *Bone::ConvertToAssimpNode(Skeleton *skeleton, aiNode *parentNode)
return node;
}
aiBone *Bone::ConvertToAssimpBone(Skeleton * /*parent*/, const std::vector<aiVertexWeight> &boneWeights)
{
aiBone *Bone::ConvertToAssimpBone(Skeleton * /*parent*/, const std::vector<aiVertexWeight> &boneWeights) {
aiBone *bone = new aiBone();
bone->mName = name;
bone->mOffsetMatrix = worldMatrix;
if (!boneWeights.empty())
{
if (!boneWeights.empty()) {
bone->mNumWeights = static_cast<unsigned int>(boneWeights.size());
bone->mWeights = new aiVertexWeight[boneWeights.size()];
memcpy(bone->mWeights, &boneWeights[0], boneWeights.size() * sizeof(aiVertexWeight));
@ -1136,12 +1009,10 @@ aiBone *Bone::ConvertToAssimpBone(Skeleton * /*parent*/, const std::vector<aiVer
VertexAnimationTrack::VertexAnimationTrack() :
type(VAT_NONE),
target(0)
{
target(0) {
}
aiNodeAnim *VertexAnimationTrack::ConvertToAssimpAnimationNode(Skeleton *skeleton)
{
aiNodeAnim *VertexAnimationTrack::ConvertToAssimpAnimationNode(Skeleton *skeleton) {
if (boneName.empty() || type != VAT_TRANSFORM) {
throw DeadlyImportError("VertexAnimationTrack::ConvertToAssimpAnimationNode: Cannot convert track that has no target bone name or is not type of VAT_TRANSFORM");
}
@ -1164,12 +1035,13 @@ aiNodeAnim *VertexAnimationTrack::ConvertToAssimpAnimationNode(Skeleton *skeleto
nodeAnim->mNumRotationKeys = static_cast<unsigned int>(numKeyframes);
nodeAnim->mNumScalingKeys = static_cast<unsigned int>(numKeyframes);
for(size_t kfi=0; kfi<numKeyframes; ++kfi)
{
for (size_t kfi = 0; kfi < numKeyframes; ++kfi) {
TransformKeyFrame &kfSource = transformKeyFrames[kfi];
// Calculate the complete transformation from world space to bone space
aiVector3D pos; aiQuaternion rot; aiVector3D scale;
aiVector3D pos;
aiQuaternion rot;
aiVector3D scale;
aiMatrix4x4 finalTransform = bone->defaultPose * kfSource.Transform();
finalTransform.Decompose(scale, rot, pos);
@ -1191,16 +1063,14 @@ aiNodeAnim *VertexAnimationTrack::ConvertToAssimpAnimationNode(Skeleton *skeleto
TransformKeyFrame::TransformKeyFrame() :
timePos(0.0f),
scale(1.0f, 1.0f, 1.0f)
{
scale(1.0f, 1.0f, 1.0f) {
}
aiMatrix4x4 TransformKeyFrame::Transform()
{
aiMatrix4x4 TransformKeyFrame::Transform() {
return aiMatrix4x4(scale, rotation, position);
}
} // Ogre
} // Assimp
} // namespace Ogre
} // namespace Assimp
#endif // ASSIMP_BUILD_NO_OGRE_IMPORTER

View File

@ -77,7 +77,7 @@ void ExportScenePly(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene
// we're still here - export successfully completed. Write the file.
std::unique_ptr<IOStream> outfile (pIOSystem->Open(pFile,"wt"));
if(outfile == NULL) {
if (outfile == nullptr) {
throw DeadlyExportError("could not open output .ply file: " + std::string(pFile));
}
@ -91,7 +91,7 @@ void ExportScenePlyBinary(const char* pFile, IOSystem* pIOSystem, const aiScene*
// we're still here - export successfully completed. Write the file.
std::unique_ptr<IOStream> outfile(pIOSystem->Open(pFile, "wb"));
if (outfile == NULL) {
if (outfile == nullptr) {
throw DeadlyExportError("could not open output .ply file: " + std::string(pFile));
}

View File

@ -693,7 +693,7 @@ void PLYImporter::GetMaterialColor(const std::vector<PLY::PropertyInstance> &avL
unsigned int aiPositions[4],
PLY::EDataType aiTypes[4],
aiColor4D *clrOut) {
ai_assert(NULL != clrOut);
ai_assert(nullptr != clrOut);
if (0xFFFFFFFF == aiPositions[0])
clrOut->r = 0.0f;
@ -736,7 +736,7 @@ void PLYImporter::GetMaterialColor(const std::vector<PLY::PropertyInstance> &avL
// ------------------------------------------------------------------------------------------------
// Extract a material from the PLY DOM
void PLYImporter::LoadMaterial(std::vector<aiMaterial *> *pvOut, std::string &defaultTexture, const bool pointsOnly) {
ai_assert(NULL != pvOut);
ai_assert(nullptr != pvOut);
// diffuse[4], specular[4], ambient[4]
// rgba order
@ -752,7 +752,7 @@ void PLYImporter::LoadMaterial(std::vector<aiMaterial *> *pvOut, std::string &de
{ EDT_Char, EDT_Char, EDT_Char, EDT_Char },
{ EDT_Char, EDT_Char, EDT_Char, EDT_Char }
};
PLY::ElementInstanceList *pcList = NULL;
PLY::ElementInstanceList *pcList = nullptr;
unsigned int iPhong = 0xFFFFFFFF;
PLY::EDataType ePhong = EDT_Char;
@ -835,7 +835,7 @@ void PLYImporter::LoadMaterial(std::vector<aiMaterial *> *pvOut, std::string &de
}
}
// check whether we have a valid source for the material data
if (NULL != pcList) {
if (nullptr != pcList) {
for (std::vector<ElementInstance>::const_iterator i = pcList->alInstances.begin(); i != pcList->alInstances.end(); ++i) {
aiColor4D clrOut;
aiMaterial *pcHelper = new aiMaterial();

File diff suppressed because it is too large Load Diff

View File

@ -43,8 +43,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef ASSIMP_BUILD_NO_Q3BSP_IMPORTER
#include "Q3BSPFileImporter.h"
#include "Q3BSPFileParser.h"
#include "Q3BSPFileData.h"
#include "Q3BSPFileParser.h"
#include <assimp/DefaultLogger.hpp>
@ -54,16 +54,16 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "../contrib/zlib/zlib.h"
#endif
#include <assimp/types.h>
#include <assimp/DefaultIOSystem.h>
#include <assimp/StringComparison.h>
#include <assimp/ZipArchiveIOSystem.h>
#include <assimp/ai_assert.h>
#include <assimp/importerdesc.h>
#include <assimp/mesh.h>
#include <assimp/scene.h>
#include <assimp/ai_assert.h>
#include <assimp/DefaultIOSystem.h>
#include <assimp/ZipArchiveIOSystem.h>
#include <assimp/importerdesc.h>
#include <vector>
#include <assimp/types.h>
#include <sstream>
#include <assimp/StringComparison.h>
#include <vector>
static const aiImporterDesc desc = {
"Quake III BSP Importer",
@ -138,11 +138,8 @@ static void normalizePathName( const std::string &rPath, std::string &normalized
// ------------------------------------------------------------------------------------------------
// Constructor.
Q3BSPFileImporter::Q3BSPFileImporter()
: m_pCurrentMesh( nullptr )
, m_pCurrentFace(nullptr)
, m_MaterialLookupMap()
, mTextures() {
Q3BSPFileImporter::Q3BSPFileImporter() :
m_pCurrentMesh(nullptr), m_pCurrentFace(nullptr), m_MaterialLookupMap(), mTextures() {
// empty
}
@ -349,7 +346,7 @@ aiNode *Q3BSPFileImporter::CreateTopology( const Q3BSP::Q3BSPModel *pModel, unsi
mesh->mNumUVComponents[1] = 2;
for (std::vector<sQ3BSPFace *>::const_iterator it = rArray.begin(); it != rArray.end(); ++it) {
Q3BSP::sQ3BSPFace *pQ3BSPFace = *it;
ai_assert( NULL != pQ3BSPFace );
ai_assert(nullptr != pQ3BSPFace);
if (nullptr == pQ3BSPFace) {
continue;
}
@ -452,10 +449,8 @@ void Q3BSPFileImporter::createMaterials( const Q3BSP::Q3BSPModel *pModel, aiScen
ASSIMP_LOG_ERROR("Cannot import texture from archive " + texName);
}
}
}
if ( -1 != lightmapId )
{
if (-1 != lightmapId) {
importLightmap(pModel, pScene, pMatHelper, lightmapId);
}
pScene->mMaterials[pScene->mNumMaterials] = pMatHelper;
@ -471,11 +466,9 @@ void Q3BSPFileImporter::createMaterials( const Q3BSP::Q3BSPModel *pModel, aiScen
size_t Q3BSPFileImporter::countData(const std::vector<sQ3BSPFace *> &faceArray) const {
size_t numVerts(0);
for (std::vector<sQ3BSPFace *>::const_iterator it = faceArray.begin(); it != faceArray.end();
++it )
{
++it) {
sQ3BSPFace *pQ3BSPFace = *it;
if ( pQ3BSPFace->iType == Polygon || pQ3BSPFace->iType == TriangleMesh )
{
if (pQ3BSPFace->iType == Polygon || pQ3BSPFace->iType == TriangleMesh) {
Q3BSP::sQ3BSPFace *face = *it;
if (nullptr != face) {
numVerts += face->iNumOfFaceVerts;
@ -488,15 +481,12 @@ size_t Q3BSPFileImporter::countData( const std::vector<sQ3BSPFace*> &faceArray )
// ------------------------------------------------------------------------------------------------
// Counts the faces with vertices.
size_t Q3BSPFileImporter::countFaces( const std::vector<Q3BSP::sQ3BSPFace*> &rArray ) const
{
size_t Q3BSPFileImporter::countFaces(const std::vector<Q3BSP::sQ3BSPFace *> &rArray) const {
size_t numFaces = 0;
for (std::vector<sQ3BSPFace *>::const_iterator it = rArray.begin(); it != rArray.end();
++it )
{
++it) {
Q3BSP::sQ3BSPFace *pQ3BSPFace = *it;
if ( pQ3BSPFace->iNumOfFaceVerts > 0 )
{
if (pQ3BSPFace->iNumOfFaceVerts > 0) {
numFaces++;
}
}
@ -506,15 +496,12 @@ size_t Q3BSPFileImporter::countFaces( const std::vector<Q3BSP::sQ3BSPFace*> &rAr
// ------------------------------------------------------------------------------------------------
// Counts the number of triangles in a Q3-face-array.
size_t Q3BSPFileImporter::countTriangles( const std::vector<Q3BSP::sQ3BSPFace*> &rArray ) const
{
size_t Q3BSPFileImporter::countTriangles(const std::vector<Q3BSP::sQ3BSPFace *> &rArray) const {
size_t numTriangles = 0;
for (std::vector<Q3BSP::sQ3BSPFace *>::const_iterator it = rArray.begin(); it != rArray.end();
++it )
{
++it) {
const Q3BSP::sQ3BSPFace *pQ3BSPFace = *it;
if ( NULL != pQ3BSPFace )
{
if (nullptr != pQ3BSPFace) {
numTriangles += pQ3BSPFace->iNumOfFaceVerts / 3;
}
}
@ -526,9 +513,8 @@ size_t Q3BSPFileImporter::countTriangles( const std::vector<Q3BSP::sQ3BSPFace*>
// Creates the faces-to-material map.
void Q3BSPFileImporter::createMaterialMap(const Q3BSP::Q3BSPModel *pModel) {
std::string key("");
std::vector<sQ3BSPFace*> *pCurFaceArray = NULL;
for ( size_t idx = 0; idx < pModel->m_Faces.size(); idx++ )
{
std::vector<sQ3BSPFace *> *pCurFaceArray = nullptr;
for (size_t idx = 0; idx < pModel->m_Faces.size(); idx++) {
Q3BSP::sQ3BSPFace *pQ3BSPFace = pModel->m_Faces[idx];
const int texId = pQ3BSPFace->iTextureID;
const int lightMapId = pQ3BSPFace->iLightmapID;
@ -537,14 +523,11 @@ void Q3BSPFileImporter::createMaterialMap( const Q3BSP::Q3BSPModel *pModel ) {
if (m_MaterialLookupMap.end() == it) {
pCurFaceArray = new std::vector<Q3BSP::sQ3BSPFace *>;
m_MaterialLookupMap[key] = pCurFaceArray;
}
else
{
} else {
pCurFaceArray = (*it).second;
}
ai_assert(nullptr != pCurFaceArray);
if (nullptr != pCurFaceArray )
{
if (nullptr != pCurFaceArray) {
pCurFaceArray->push_back(pQ3BSPFace);
}
}
@ -628,8 +611,7 @@ bool Q3BSPFileImporter::importTextureFromArchive( const Q3BSP::Q3BSPModel *model
// ------------------------------------------------------------------------------------------------
// Imports a light map file.
bool Q3BSPFileImporter::importLightmap(const Q3BSP::Q3BSPModel *pModel, aiScene *pScene,
aiMaterial *pMatHelper, int lightmapId )
{
aiMaterial *pMatHelper, int lightmapId) {
if (nullptr == pModel || nullptr == pScene || nullptr == pMatHelper) {
return false;
}
@ -672,24 +654,20 @@ bool Q3BSPFileImporter::importLightmap( const Q3BSP::Q3BSPModel *pModel, aiScene
// Will search for a supported extension.
bool Q3BSPFileImporter::expandFile(ZipArchiveIOSystem *pArchive, const std::string &rFilename,
const std::vector<std::string> &rExtList, std::string &rFile,
std::string &rExt )
{
ai_assert( NULL != pArchive );
std::string &rExt) {
ai_assert(nullptr != pArchive);
ai_assert(!rFilename.empty());
if ( rExtList.empty() )
{
if (rExtList.empty()) {
rFile = rFilename;
rExt = "";
return true;
}
bool found = false;
for ( std::vector<std::string>::const_iterator it = rExtList.begin(); it != rExtList.end(); ++it )
{
for (std::vector<std::string>::const_iterator it = rExtList.begin(); it != rExtList.end(); ++it) {
const std::string textureName = rFilename + *it;
if ( pArchive->Exists( textureName.c_str() ) )
{
if (pArchive->Exists(textureName.c_str())) {
rExt = *it;
rFile = textureName;
found = true;

View File

@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2020, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
@ -45,17 +43,16 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* @brief Implementation of the Q3D importer class
*/
#ifndef ASSIMP_BUILD_NO_Q3D_IMPORTER
// internal headers
#include "Q3DLoader.h"
#include <assimp/StreamReader.h>
#include <assimp/fast_atof.h>
#include <assimp/IOSystem.hpp>
#include <assimp/DefaultLogger.hpp>
#include <assimp/scene.h>
#include <assimp/importerdesc.h>
#include <assimp/scene.h>
#include <assimp/DefaultLogger.hpp>
#include <assimp/IOSystem.hpp>
using namespace Assimp;
@ -74,18 +71,19 @@ static const aiImporterDesc desc = {
// ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer
Q3DImporter::Q3DImporter()
{}
Q3DImporter::Q3DImporter() {
// empty
}
// ------------------------------------------------------------------------------------------------
// Destructor, private as well
Q3DImporter::~Q3DImporter()
{}
Q3DImporter::~Q3DImporter() {
// empty
}
// ------------------------------------------------------------------------------------------------
// Returns whether the class can handle the format of the given file.
bool Q3DImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
{
bool Q3DImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool checkSig) const {
const std::string extension = GetExtension(pFile);
if (extension == "q3s" || extension == "q3o")
@ -100,16 +98,14 @@ bool Q3DImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool
}
// ------------------------------------------------------------------------------------------------
const aiImporterDesc* Q3DImporter::GetInfo () const
{
const aiImporterDesc *Q3DImporter::GetInfo() const {
return &desc;
}
// ------------------------------------------------------------------------------------------------
// Imports the given file into the given scene structure.
void Q3DImporter::InternReadFile(const std::string &pFile,
aiScene* pScene, IOSystem* pIOHandler)
{
aiScene *pScene, IOSystem *pIOHandler) {
StreamReaderLE stream(pIOHandler->Open(pFile, "rb"));
// The header is 22 bytes large
@ -118,8 +114,7 @@ void Q3DImporter::InternReadFile( const std::string& pFile,
// Check the file's signature
if (ASSIMP_strincmp((const char *)stream.GetPtr(), "quick3Do", 8) &&
ASSIMP_strincmp( (const char*)stream.GetPtr(), "quick3Ds", 8 ))
{
ASSIMP_strincmp((const char *)stream.GetPtr(), "quick3Ds", 8)) {
throw DeadlyImportError("Not a Quick3D file. Signature string is: " +
std::string((const char *)stream.GetPtr(), 8));
}
@ -149,17 +144,13 @@ void Q3DImporter::InternReadFile( const std::string& pFile,
aiColor3D fgColor(0.6f, 0.6f, 0.6f);
// Now read all file chunks
while (true)
{
while (true) {
if (stream.GetRemainingSize() < 1) break;
char c = stream.GetI1();
switch (c)
{
switch (c) {
// Meshes chunk
case 'm':
{
for (unsigned int quak = 0; quak < numMeshes; ++quak)
{
case 'm': {
for (unsigned int quak = 0; quak < numMeshes; ++quak) {
meshes.push_back(Mesh());
Mesh &mesh = meshes.back();
@ -171,8 +162,7 @@ void Q3DImporter::InternReadFile( const std::string& pFile,
std::vector<aiVector3D> &verts = mesh.verts;
verts.resize(numVerts);
for (unsigned int i = 0; i < numVerts;++i)
{
for (unsigned int i = 0; i < numVerts; ++i) {
verts[i].x = stream.GetF4();
verts[i].y = stream.GetF4();
verts[i].z = stream.GetF4();
@ -187,24 +177,21 @@ void Q3DImporter::InternReadFile( const std::string& pFile,
faces.reserve(numVerts);
// number of indices
for (unsigned int i = 0; i < numVerts;++i)
{
for (unsigned int i = 0; i < numVerts; ++i) {
faces.push_back(Face(stream.GetI2()));
if (faces.back().indices.empty())
throw DeadlyImportError("Quick3D: Found face with zero indices");
}
// indices
for (unsigned int i = 0; i < numVerts;++i)
{
for (unsigned int i = 0; i < numVerts; ++i) {
Face &vec = faces[i];
for (unsigned int a = 0; a < (unsigned int)vec.indices.size(); ++a)
vec.indices[a] = stream.GetI4();
}
// material indices
for (unsigned int i = 0; i < numVerts;++i)
{
for (unsigned int i = 0; i < numVerts; ++i) {
faces[i].mat = (unsigned int)stream.GetI4();
}
@ -213,32 +200,27 @@ void Q3DImporter::InternReadFile( const std::string& pFile,
std::vector<aiVector3D> &normals = mesh.normals;
normals.resize(numVerts);
for (unsigned int i = 0; i < numVerts;++i)
{
for (unsigned int i = 0; i < numVerts; ++i) {
normals[i].x = stream.GetF4();
normals[i].y = stream.GetF4();
normals[i].z = stream.GetF4();
}
numVerts = (unsigned int)stream.GetI4();
if (numTextures && numVerts)
{
if (numTextures && numVerts) {
// read all texture coordinates
std::vector<aiVector3D> &uv = mesh.uv;
uv.resize(numVerts);
for (unsigned int i = 0; i < numVerts;++i)
{
for (unsigned int i = 0; i < numVerts; ++i) {
uv[i].x = stream.GetF4();
uv[i].y = stream.GetF4();
}
// UV indices
for (unsigned int i = 0; i < (unsigned int)faces.size();++i)
{
for (unsigned int i = 0; i < (unsigned int)faces.size(); ++i) {
Face &vec = faces[i];
for (unsigned int a = 0; a < (unsigned int)vec.indices.size();++a)
{
for (unsigned int a = 0; a < (unsigned int)vec.indices.size(); ++a) {
vec.uvindices[a] = stream.GetI4();
if (!i && !a)
mesh.prevUVIdx = vec.uvindices[a];
@ -254,14 +236,12 @@ void Q3DImporter::InternReadFile( const std::string& pFile,
stream.IncPtr(mesh.faces.size());
}
// stream.IncPtr(4); // unknown value here
}
break;
} break;
// materials chunk
case 'c':
for (unsigned int i = 0; i < numMats; ++i)
{
for (unsigned int i = 0; i < numMats; ++i) {
materials.push_back(Material());
Material &mat = materials.back();
@ -315,7 +295,8 @@ void Q3DImporter::InternReadFile( const std::string& pFile,
aiTexture *tex = pScene->mTextures[i] = new aiTexture;
// skip the texture name
while (stream.GetI1());
while (stream.GetI1())
;
// read texture width and height
tex->mWidth = (unsigned int)stream.GetI4();
@ -329,7 +310,6 @@ void Q3DImporter::InternReadFile( const std::string& pFile,
aiTexel *begin = tex->pcData = new aiTexel[mul];
aiTexel *const end = &begin[mul - 1] + 1;
for (; begin != end; ++begin) {
begin->r = stream.GetI1();
begin->g = stream.GetI1();
@ -341,8 +321,7 @@ void Q3DImporter::InternReadFile( const std::string& pFile,
break;
// scene chunk
case 's':
{
case 's': {
// skip position and rotation
stream.IncPtr(12);
@ -389,20 +368,19 @@ void Q3DImporter::InternReadFile( const std::string& pFile,
light->mColorSpecular = light->mColorDiffuse;
// We don't need the rest, but we need to know where this chunk ends.
unsigned int temp = (unsigned int)(stream.GetI4() * stream.GetI4());
// skip the background file name
while (stream.GetI1());
while (stream.GetI1())
;
// skip background texture data + the remaining fields
stream.IncPtr(temp * 3 + 20); // 4 bytes of unknown data here
// TODO
goto outer;
}
break;
} break;
default:
throw DeadlyImportError("Quick3D: Unknown chunk");
@ -416,8 +394,7 @@ outer:
throw DeadlyImportError("Quick3D: No meshes loaded");
// If we have no materials loaded - generate a default mat
if (materials.empty())
{
if (materials.empty()) {
ASSIMP_LOG_INFO("Quick3D: No material found, generating one");
materials.push_back(Material());
materials.back().diffuse = fgColor;
@ -430,14 +407,11 @@ outer:
unsigned int p = 0;
for (std::vector<Mesh>::iterator it = meshes.begin(), end = meshes.end();
it != end; ++it,++p)
{
it != end; ++it, ++p) {
unsigned int q = 0;
for (std::vector<Face>::iterator fit = (*it).faces.begin(), fend = (*it).faces.end();
fit != fend; ++fit,++q)
{
if ((*fit).mat >= materials.size())
{
fit != fend; ++fit, ++q) {
if ((*fit).mat >= materials.size()) {
ASSIMP_LOG_WARN("Quick3D: Material index overflow");
(*fit).mat = 0;
}
@ -449,8 +423,7 @@ outer:
pScene->mMaterials = new aiMaterial *[pScene->mNumMaterials];
pScene->mMeshes = new aiMesh *[pScene->mNumMaterials];
for (unsigned int i = 0, real = 0; i < (unsigned int)materials.size(); ++i)
{
for (unsigned int i = 0, real = 0; i < (unsigned int)materials.size(); ++i) {
if (fidx[i].empty()) continue;
// Allocate a mesh and a material
@ -485,8 +458,7 @@ outer:
mat->AddProperty(&srcMat.name, AI_MATKEY_NAME);
// Add a texture
if (srcMat.texIdx < pScene->mNumTextures || real < pScene->mNumTextures)
{
if (srcMat.texIdx < pScene->mNumTextures || real < pScene->mNumTextures) {
srcMat.name.data[0] = '*';
srcMat.name.length = ASSIMP_itoa10(&srcMat.name.data[1], 1000,
(srcMat.texIdx < pScene->mNumTextures ? srcMat.texIdx : real));
@ -499,40 +471,32 @@ outer:
// Now build the output mesh. First find out how many
// vertices we'll need
for (FaceIdxArray::const_iterator it = fidx[i].begin(), end = fidx[i].end();
it != end; ++it)
{
mesh->mNumVertices += (unsigned int)meshes[(*it).first].faces[
(*it).second].indices.size();
it != end; ++it) {
mesh->mNumVertices += (unsigned int)meshes[(*it).first].faces[(*it).second].indices.size();
}
aiVector3D *verts = mesh->mVertices = new aiVector3D[mesh->mNumVertices];
aiVector3D *norms = mesh->mNormals = new aiVector3D[mesh->mNumVertices];
aiVector3D* uv;
if (real < pScene->mNumTextures)
{
aiVector3D *uv = nullptr;
if (real < pScene->mNumTextures) {
uv = mesh->mTextureCoords[0] = new aiVector3D[mesh->mNumVertices];
mesh->mNumUVComponents[0] = 2;
}
else uv = NULL;
// Build the final array
unsigned int cnt = 0;
for (FaceIdxArray::const_iterator it = fidx[i].begin(), end = fidx[i].end();
it != end; ++it, ++faces)
{
it != end; ++it, ++faces) {
Mesh &curMesh = meshes[(*it).first];
Face &face = curMesh.faces[(*it).second];
faces->mNumIndices = (unsigned int)face.indices.size();
faces->mIndices = new unsigned int[faces->mNumIndices];
aiVector3D faceNormal;
bool fnOK = false;
for (unsigned int n = 0; n < faces->mNumIndices;++n, ++cnt, ++norms, ++verts)
{
if (face.indices[n] >= curMesh.verts.size())
{
for (unsigned int n = 0; n < faces->mNumIndices; ++n, ++cnt, ++norms, ++verts) {
if (face.indices[n] >= curMesh.verts.size()) {
ASSIMP_LOG_WARN("Quick3D: Vertex index overflow");
face.indices[n] = 0;
}
@ -540,11 +504,9 @@ outer:
// copy vertices
*verts = curMesh.verts[face.indices[n]];
if (face.indices[n] >= curMesh.normals.size() && faces->mNumIndices >= 3)
{
if (face.indices[n] >= curMesh.normals.size() && faces->mNumIndices >= 3) {
// we have no normal here - assign the face normal
if (!fnOK)
{
if (!fnOK) {
const aiVector3D &pV1 = curMesh.verts[face.indices[0]];
const aiVector3D &pV2 = curMesh.verts[face.indices[1]];
const aiVector3D &pV3 = curMesh.verts[face.indices.size() - 1];
@ -557,16 +519,12 @@ outer:
}
// copy texture coordinates
if (uv && curMesh.uv.size())
{
if (uv && curMesh.uv.size()) {
if (curMesh.prevUVIdx != 0xffffffff && curMesh.uv.size() >= curMesh.verts.size()) // workaround
{
*uv = curMesh.uv[face.indices[n]];
}
else
{
if (face.uvindices[n] >= curMesh.uv.size())
{
} else {
if (face.uvindices[n] >= curMesh.uv.size()) {
ASSIMP_LOG_WARN("Quick3D: Texture coordinate index overflow");
face.uvindices[n] = 0;
}
@ -579,7 +537,6 @@ outer:
// setup the new vertex index
faces->mIndices[n] = cnt;
}
}
++real;
}
@ -601,8 +558,7 @@ outer:
// Add cameras and light sources to the scene root node
pScene->mRootNode->mNumChildren = pScene->mNumLights + pScene->mNumCameras;
if (pScene->mRootNode->mNumChildren)
{
if (pScene->mRootNode->mNumChildren) {
pScene->mRootNode->mChildren = new aiNode *[pScene->mRootNode->mNumChildren];
// the light source

View File

@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2020, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
@ -45,18 +43,17 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* @brief Implementation of the RAW importer class
*/
#ifndef ASSIMP_BUILD_NO_RAW_IMPORTER
// internal headers
#include "RawLoader.h"
#include <assimp/ParsingUtils.h>
#include <assimp/fast_atof.h>
#include <memory>
#include <assimp/IOSystem.hpp>
#include <assimp/DefaultLogger.hpp>
#include <assimp/scene.h>
#include <assimp/importerdesc.h>
#include <assimp/scene.h>
#include <assimp/DefaultLogger.hpp>
#include <assimp/IOSystem.hpp>
#include <memory>
using namespace Assimp;
@ -75,36 +72,35 @@ static const aiImporterDesc desc = {
// ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer
RAWImporter::RAWImporter()
{}
RAWImporter::RAWImporter() {
// empty
}
// ------------------------------------------------------------------------------------------------
// Destructor, private as well
RAWImporter::~RAWImporter()
{}
RAWImporter::~RAWImporter() {
// empty
}
// ------------------------------------------------------------------------------------------------
// Returns whether the class can handle the format of the given file.
bool RAWImporter::CanRead( const std::string& pFile, IOSystem* /*pIOHandler*/, bool /*checkSig*/) const
{
bool RAWImporter::CanRead(const std::string &pFile, IOSystem * /*pIOHandler*/, bool /*checkSig*/) const {
return SimpleExtensionCheck(pFile, "raw");
}
// ------------------------------------------------------------------------------------------------
const aiImporterDesc* RAWImporter::GetInfo () const
{
const aiImporterDesc *RAWImporter::GetInfo() const {
return &desc;
}
// ------------------------------------------------------------------------------------------------
// Imports the given file into the given scene structure.
void RAWImporter::InternReadFile(const std::string &pFile,
aiScene* pScene, IOSystem* pIOHandler)
{
aiScene *pScene, IOSystem *pIOHandler) {
std::unique_ptr<IOStream> file(pIOHandler->Open(pFile, "rb"));
// Check whether we can read from the file
if( file.get() == NULL) {
if (file.get() == nullptr) {
throw DeadlyImportError("Failed to open RAW file " + pFile + ".");
}
@ -120,87 +116,73 @@ void RAWImporter::InternReadFile( const std::string& pFile,
// now read all lines
char line[4096];
while (GetNextLine(buffer,line))
{
while (GetNextLine(buffer, line)) {
// if the line starts with a non-numeric identifier, it marks
// the beginning of a new group
const char* sz = line;SkipSpaces(&sz);
const char *sz = line;
SkipSpaces(&sz);
if (IsLineEnd(*sz)) continue;
if (!IsNumeric(*sz))
{
if (!IsNumeric(*sz)) {
const char *sz2 = sz;
while (!IsSpaceOrNewLine(*sz2))++sz2;
while (!IsSpaceOrNewLine(*sz2))
++sz2;
const unsigned int length = (unsigned int)(sz2 - sz);
// find an existing group with this name
for (std::vector<GroupInformation>::iterator it = outGroups.begin(), end = outGroups.end();
it != end;++it)
{
if (length == (*it).name.length() && !::strcmp(sz,(*it).name.c_str()))
{
curGroup = it;sz2 = NULL;
it != end; ++it) {
if (length == (*it).name.length() && !::strcmp(sz, (*it).name.c_str())) {
curGroup = it;
sz2 = nullptr;
break;
}
}
if (sz2)
{
if (sz2) {
outGroups.push_back(GroupInformation(std::string(sz, length)));
curGroup = outGroups.end() - 1;
}
}
else
{
} else {
// there can be maximally 12 floats plus an extra texture file name
float data[12];
unsigned int num;
for (num = 0; num < 12;++num)
{
for (num = 0; num < 12; ++num) {
if (!SkipSpaces(&sz) || !IsNumeric(*sz)) break;
sz = fast_atoreal_move<float>(sz, data[num]);
}
if (num != 12 && num != 9)
{
if (num != 12 && num != 9) {
ASSIMP_LOG_ERROR("A line may have either 9 or 12 floats and an optional texture");
continue;
}
MeshInformation* output = NULL;
MeshInformation *output = nullptr;
const char *sz2 = sz;
unsigned int length;
if (!IsLineEnd(*sz))
{
while (!IsSpaceOrNewLine(*sz2))++sz2;
if (!IsLineEnd(*sz)) {
while (!IsSpaceOrNewLine(*sz2))
++sz2;
length = (unsigned int)(sz2 - sz);
}
else if (9 == num)
{
} else if (9 == num) {
sz = "%default%";
length = 9;
}
else
{
} else {
sz = "";
length = 0;
}
// search in the list of meshes whether we have one with this texture
for (auto &mesh : (*curGroup).meshes)
{
if (length == mesh.name.length() && (length ? !::strcmp(sz, mesh.name.c_str()) : true))
{
for (auto &mesh : (*curGroup).meshes) {
if (length == mesh.name.length() && (length ? !::strcmp(sz, mesh.name.c_str()) : true)) {
output = &mesh;
break;
}
}
// if we don't have the mesh, create it
if (!output)
{
if (!output) {
(*curGroup).meshes.push_back(MeshInformation(std::string(sz, length)));
output = &((*curGroup).meshes.back());
}
if (12 == num)
{
if (12 == num) {
aiColor4D v(data[0], data[1], data[2], 1.0f);
output->colors.push_back(v);
output->colors.push_back(v);
@ -209,9 +191,7 @@ void RAWImporter::InternReadFile( const std::string& pFile,
output->vertices.push_back(aiVector3D(data[3], data[4], data[5]));
output->vertices.push_back(aiVector3D(data[6], data[7], data[8]));
output->vertices.push_back(aiVector3D(data[9], data[10], data[11]));
}
else
{
} else {
output->vertices.push_back(aiVector3D(data[0], data[1], data[2]));
output->vertices.push_back(aiVector3D(data[3], data[4], data[5]));
output->vertices.push_back(aiVector3D(data[6], data[7], data[8]));
@ -224,24 +204,20 @@ void RAWImporter::InternReadFile( const std::string& pFile,
// count the number of valid groups
// (meshes can't be empty)
for (auto & outGroup : outGroups)
{
if (!outGroup.meshes.empty())
{
for (auto &outGroup : outGroups) {
if (!outGroup.meshes.empty()) {
++pScene->mRootNode->mNumChildren;
pScene->mNumMeshes += (unsigned int)outGroup.meshes.size();
}
}
if (!pScene->mNumMeshes)
{
if (!pScene->mNumMeshes) {
throw DeadlyImportError("RAW: No meshes loaded. The file seems to be corrupt or empty.");
}
pScene->mMeshes = new aiMesh *[pScene->mNumMeshes];
aiNode **cc;
if (1 == pScene->mRootNode->mNumChildren)
{
if (1 == pScene->mRootNode->mNumChildren) {
cc = &pScene->mRootNode;
pScene->mRootNode->mNumChildren = 0;
} else {
@ -254,25 +230,23 @@ void RAWImporter::InternReadFile( const std::string& pFile,
aiMaterial **mats = pScene->mMaterials = new aiMaterial *[pScene->mNumMaterials];
unsigned int meshIdx = 0;
for (auto & outGroup : outGroups)
{
for (auto &outGroup : outGroups) {
if (outGroup.meshes.empty()) continue;
aiNode *node;
if (pScene->mRootNode->mNumChildren)
{
if (pScene->mRootNode->mNumChildren) {
node = *cc = new aiNode();
node->mParent = pScene->mRootNode;
}
else node = *cc;
} else
node = *cc;
node->mName.Set(outGroup.name);
// add all meshes
node->mNumMeshes = (unsigned int)outGroup.meshes.size();
unsigned int *pi = node->mMeshes = new unsigned int[node->mNumMeshes];
for (std::vector<MeshInformation>::iterator it2 = outGroup.meshes.begin(),
end2 = outGroup.meshes.end(); it2 != end2; ++it2)
{
end2 = outGroup.meshes.end();
it2 != end2; ++it2) {
ai_assert(!(*it2).vertices.empty());
// allocate the mesh
@ -287,8 +261,7 @@ void RAWImporter::InternReadFile( const std::string& pFile,
mesh->mVertices = new aiVector3D[mesh->mNumVertices];
::memcpy(mesh->mVertices, &(*it2).vertices[0], sizeof(aiVector3D) * mesh->mNumVertices);
if ((*it2).colors.size())
{
if ((*it2).colors.size()) {
ai_assert((*it2).colors.size() == mesh->mNumVertices);
mesh->mColors[0] = new aiColor4D[mesh->mNumVertices];
@ -300,8 +273,7 @@ void RAWImporter::InternReadFile( const std::string& pFile,
aiFace *fc = mesh->mFaces = new aiFace[mesh->mNumFaces = mesh->mNumVertices / 3];
aiFace *const fcEnd = fc + mesh->mNumFaces;
unsigned int n = 0;
while (fc != fcEnd)
{
while (fc != fcEnd) {
aiFace &f = *fc++;
f.mIndices = new unsigned int[f.mNumIndices = 3];
for (unsigned int m = 0; m < 3; ++m)
@ -315,8 +287,7 @@ void RAWImporter::InternReadFile( const std::string& pFile,
if ("%default%" == (*it2).name) // a gray default material
{
clr.r = clr.g = clr.b = 0.6f;
}
else if ((*it2).name.length() > 0) // a texture
} else if ((*it2).name.length() > 0) // a texture
{
aiString s;
s.Set((*it2).name);

View File

@ -51,7 +51,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* Nevertheless, this implementation is reasonably complete.
*/
#ifndef ASSIMP_BUILD_NO_SIB_IMPORTER
// internal headers
@ -65,10 +64,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//# include "../contrib/ConvertUTF/ConvertUTF.h"
#include "../contrib/utf8cpp/source/utf8.h"
#endif
#include <assimp/IOSystem.hpp>
#include <assimp/DefaultLogger.hpp>
#include <assimp/scene.h>
#include <assimp/importerdesc.h>
#include <assimp/scene.h>
#include <assimp/DefaultLogger.hpp>
#include <assimp/IOSystem.hpp>
#include <map>
@ -148,8 +147,7 @@ static SIBEdge& GetEdge(SIBMesh* mesh, uint32_t posA, uint32_t posB) {
#define TAG(A, B, C, D) ((A << 24) | (B << 16) | (C << 8) | D)
static SIBChunk ReadChunk(StreamReaderLE* stream)
{
static SIBChunk ReadChunk(StreamReaderLE *stream) {
SIBChunk chunk;
chunk.Tag = stream->GetU4();
chunk.Size = stream->GetU4();
@ -159,8 +157,7 @@ static SIBChunk ReadChunk(StreamReaderLE* stream)
return chunk;
}
static aiColor3D ReadColor(StreamReaderLE* stream)
{
static aiColor3D ReadColor(StreamReaderLE *stream) {
float r = stream->GetF4();
float g = stream->GetF4();
float b = stream->GetF4();
@ -168,8 +165,7 @@ static aiColor3D ReadColor(StreamReaderLE* stream)
return aiColor3D(r, g, b);
}
static void UnknownChunk(StreamReaderLE* /*stream*/, const SIBChunk& chunk)
{
static void UnknownChunk(StreamReaderLE * /*stream*/, const SIBChunk &chunk) {
char temp[5] = {
static_cast<char>((chunk.Tag >> 24) & 0xff),
static_cast<char>((chunk.Tag >> 16) & 0xff),
@ -245,11 +241,9 @@ static void ReadVerts(SIBMesh* mesh, StreamReaderLE* stream, uint32_t count) {
}
// ------------------------------------------------------------------------------------------------
static void ReadFaces(SIBMesh* mesh, StreamReaderLE* stream)
{
static void ReadFaces(SIBMesh *mesh, StreamReaderLE *stream) {
uint32_t ptIdx = 0;
while (stream->GetRemainingSizeToLimit() > 0)
{
while (stream->GetRemainingSizeToLimit() > 0) {
uint32_t numPoints = stream->GetU4();
// Store room for the N index channels, plus the point count.
@ -265,8 +259,7 @@ static void ReadFaces(SIBMesh* mesh, StreamReaderLE* stream)
// UV/normals will be supplied later.
// Positions are supplied indexed already, so we preserve that
// mapping. UVs are supplied uniquely, so we allocate unique indices.
for (uint32_t n=0;n<numPoints;n++,idx+=N,ptIdx++)
{
for (uint32_t n = 0; n < numPoints; n++, idx += N, ptIdx++) {
uint32_t p = stream->GetU4();
if (p >= mesh->pos.size())
throw DeadlyImportError("Vertex index is out of range.");
@ -284,10 +277,8 @@ static void ReadFaces(SIBMesh* mesh, StreamReaderLE* stream)
}
// ------------------------------------------------------------------------------------------------
static void ReadUVs(SIBMesh* mesh, StreamReaderLE* stream)
{
while (stream->GetRemainingSizeToLimit() > 0)
{
static void ReadUVs(SIBMesh *mesh, StreamReaderLE *stream) {
while (stream->GetRemainingSizeToLimit() > 0) {
uint32_t faceIdx = stream->GetU4();
uint32_t numPoints = stream->GetU4();
@ -297,8 +288,7 @@ static void ReadUVs(SIBMesh* mesh, StreamReaderLE* stream)
uint32_t pos = mesh->faceStart[faceIdx];
uint32_t *idx = &mesh->idx[pos + 1];
for (uint32_t n=0;n<numPoints;n++,idx+=N)
{
for (uint32_t n = 0; n < numPoints; n++, idx += N) {
uint32_t id = idx[UV];
mesh->uv[id].x = stream->GetF4();
mesh->uv[id].y = stream->GetF4();
@ -307,19 +297,16 @@ static void ReadUVs(SIBMesh* mesh, StreamReaderLE* stream)
}
// ------------------------------------------------------------------------------------------------
static void ReadMtls(SIBMesh* mesh, StreamReaderLE* stream)
{
static void ReadMtls(SIBMesh *mesh, StreamReaderLE *stream) {
// Material assignments are stored run-length encoded.
// Also, we add 1 to each material so that we can use mtl #0
// as the default material.
uint32_t prevFace = stream->GetU4();
uint32_t prevMtl = stream->GetU4() + 1;
while (stream->GetRemainingSizeToLimit() > 0)
{
while (stream->GetRemainingSizeToLimit() > 0) {
uint32_t face = stream->GetU4();
uint32_t mtl = stream->GetU4() + 1;
while (prevFace < face)
{
while (prevFace < face) {
if (prevFace >= mesh->mtls.size())
throw DeadlyImportError("Invalid face index.");
mesh->mtls[prevFace++] = prevMtl;
@ -334,8 +321,7 @@ static void ReadMtls(SIBMesh* mesh, StreamReaderLE* stream)
}
// ------------------------------------------------------------------------------------------------
static void ReadAxis(aiMatrix4x4& axis, StreamReaderLE* stream)
{
static void ReadAxis(aiMatrix4x4 &axis, StreamReaderLE *stream) {
axis.a4 = stream->GetF4();
axis.b4 = stream->GetF4();
axis.c4 = stream->GetF4();
@ -355,10 +341,8 @@ static void ReadAxis(aiMatrix4x4& axis, StreamReaderLE* stream)
}
// ------------------------------------------------------------------------------------------------
static void ReadEdges(SIBMesh* mesh, StreamReaderLE* stream)
{
while (stream->GetRemainingSizeToLimit() > 0)
{
static void ReadEdges(SIBMesh *mesh, StreamReaderLE *stream) {
while (stream->GetRemainingSizeToLimit() > 0) {
uint32_t posA = stream->GetU4();
uint32_t posB = stream->GetU4();
GetEdge(mesh, posA, posB);
@ -366,10 +350,8 @@ static void ReadEdges(SIBMesh* mesh, StreamReaderLE* stream)
}
// ------------------------------------------------------------------------------------------------
static void ReadCreases(SIBMesh* mesh, StreamReaderLE* stream)
{
while (stream->GetRemainingSizeToLimit() > 0)
{
static void ReadCreases(SIBMesh *mesh, StreamReaderLE *stream) {
while (stream->GetRemainingSizeToLimit() > 0) {
uint32_t edge = stream->GetU4();
if (edge >= mesh->edges.size())
throw DeadlyImportError("SIB: Invalid edge index.");
@ -378,18 +360,15 @@ static void ReadCreases(SIBMesh* mesh, StreamReaderLE* stream)
}
// ------------------------------------------------------------------------------------------------
static void ConnectFaces(SIBMesh* mesh)
{
static void ConnectFaces(SIBMesh *mesh) {
// Find faces connected to each edge.
size_t numFaces = mesh->faceStart.size();
for (size_t faceIdx=0;faceIdx<numFaces;faceIdx++)
{
for (size_t faceIdx = 0; faceIdx < numFaces; faceIdx++) {
uint32_t *idx = &mesh->idx[mesh->faceStart[faceIdx]];
uint32_t numPoints = *idx++;
uint32_t prev = idx[(numPoints - 1) * N + POS];
for (uint32_t i=0;i<numPoints;i++,idx+=N)
{
for (uint32_t i = 0; i < numPoints; i++, idx += N) {
uint32_t next = idx[POS];
// Find this edge.
@ -410,22 +389,19 @@ static void ConnectFaces(SIBMesh* mesh)
// ------------------------------------------------------------------------------------------------
static aiVector3D CalculateVertexNormal(SIBMesh *mesh, uint32_t faceIdx, uint32_t pos,
const std::vector<aiVector3D>& faceNormals)
{
const std::vector<aiVector3D> &faceNormals) {
// Creased edges complicate this. We need to find the start/end range of the
// ring of faces that touch this position.
// We do this in two passes. The first pass is to find the end of the range,
// the second is to work backwards to the start and calculate the final normal.
aiVector3D vtxNormal;
for (int pass=0;pass<2;pass++)
{
for (int pass = 0; pass < 2; pass++) {
vtxNormal = aiVector3D(0, 0, 0);
uint32_t startFaceIdx = faceIdx;
uint32_t prevFaceIdx = faceIdx;
// Process each connected face.
while (true)
{
while (true) {
// Accumulate the face normal.
vtxNormal += faceNormals[faceIdx];
@ -435,19 +411,16 @@ static aiVector3D CalculateVertexNormal(SIBMesh* mesh, uint32_t faceIdx, uint32_
uint32_t *idx = &mesh->idx[mesh->faceStart[faceIdx]];
uint32_t numPoints = *idx++;
uint32_t posA = idx[(numPoints - 1) * N + POS];
for (uint32_t n=0;n<numPoints;n++,idx+=N)
{
for (uint32_t n = 0; n < numPoints; n++, idx += N) {
uint32_t posB = idx[POS];
// Test if this edge shares our target position.
if (posA == pos || posB == pos)
{
if (posA == pos || posB == pos) {
SIBEdge &edge = GetEdge(mesh, posA, posB);
// Non-manifold meshes can produce faces which share
// positions but have no edge entry, so check it.
if (edge.faceA == faceIdx || edge.faceB == faceIdx)
{
if (edge.faceA == faceIdx || edge.faceB == faceIdx) {
// Move to whichever side we didn't just come from.
if (!edge.creased) {
if (edge.faceA != prevFaceIdx && edge.faceA != faceIdx && edge.faceA != 0xffffffff)
@ -479,14 +452,12 @@ static aiVector3D CalculateVertexNormal(SIBMesh* mesh, uint32_t faceIdx, uint32_
}
// ------------------------------------------------------------------------------------------------
static void CalculateNormals(SIBMesh* mesh)
{
static void CalculateNormals(SIBMesh *mesh) {
size_t numFaces = mesh->faceStart.size();
// Calculate face normals.
std::vector<aiVector3D> faceNormals(numFaces);
for (size_t faceIdx=0;faceIdx<numFaces;faceIdx++)
{
for (size_t faceIdx = 0; faceIdx < numFaces; faceIdx++) {
uint32_t *idx = &mesh->idx[mesh->faceStart[faceIdx]];
uint32_t numPoints = *idx++;
@ -494,8 +465,7 @@ static void CalculateNormals(SIBMesh* mesh)
uint32_t *prev = &idx[(numPoints - 1) * N];
for (uint32_t i=0;i<numPoints;i++)
{
for (uint32_t i = 0; i < numPoints; i++) {
uint32_t *next = &idx[i * N];
faceNormal += mesh->pos[prev[POS]] ^ mesh->pos[next[POS]];
@ -506,13 +476,11 @@ static void CalculateNormals(SIBMesh* mesh)
}
// Calculate vertex normals.
for (size_t faceIdx=0;faceIdx<numFaces;faceIdx++)
{
for (size_t faceIdx = 0; faceIdx < numFaces; faceIdx++) {
uint32_t *idx = &mesh->idx[mesh->faceStart[faceIdx]];
uint32_t numPoints = *idx++;
for (uint32_t i=0;i<numPoints;i++)
{
for (uint32_t i = 0; i < numPoints; i++) {
uint32_t pos = idx[i * N + POS];
uint32_t nrm = idx[i * N + NRM];
aiVector3D vtxNorm = CalculateVertexNormal(mesh, static_cast<uint32_t>(faceIdx), pos, faceNormals);
@ -522,26 +490,22 @@ static void CalculateNormals(SIBMesh* mesh)
}
// ------------------------------------------------------------------------------------------------
struct TempMesh
{
struct TempMesh {
std::vector<aiVector3D> vtx;
std::vector<aiVector3D> nrm;
std::vector<aiVector3D> uv;
std::vector<aiFace> faces;
};
static void ReadShape(SIB* sib, StreamReaderLE* stream)
{
static void ReadShape(SIB *sib, StreamReaderLE *stream) {
SIBMesh smesh;
aiString name;
while (stream->GetRemainingSizeToLimit() >= sizeof(SIBChunk))
{
while (stream->GetRemainingSizeToLimit() >= sizeof(SIBChunk)) {
SIBChunk chunk = ReadChunk(stream);
unsigned oldLimit = stream->SetReadLimit(stream->GetCurrentPos() + chunk.Size);
switch (chunk.Tag)
{
switch (chunk.Tag) {
case TAG('M', 'I', 'R', 'P'): break; // mirror plane maybe?
case TAG('I', 'M', 'R', 'P'): break; // instance mirror? (not supported here yet)
case TAG('D', 'I', 'N', 'F'): break; // display info, not needed
@ -585,14 +549,12 @@ static void ReadShape(SIB* sib, StreamReaderLE* stream)
std::vector<TempMesh> meshes(sib->mtls.size());
// Un-index the source data and apply to each vertex.
for (unsigned fi=0;fi<smesh.faceStart.size();fi++)
{
for (unsigned fi = 0; fi < smesh.faceStart.size(); fi++) {
uint32_t start = smesh.faceStart[fi];
uint32_t mtl = smesh.mtls[fi];
uint32_t *idx = &smesh.idx[start];
if (mtl >= meshes.size())
{
if (mtl >= meshes.size()) {
ASSIMP_LOG_ERROR("SIB: Face material index is invalid.");
mtl = 0;
}
@ -602,8 +564,7 @@ static void ReadShape(SIB* sib, StreamReaderLE* stream)
aiFace face;
face.mNumIndices = *idx++;
face.mIndices = new unsigned[face.mNumIndices];
for (unsigned pt=0;pt<face.mNumIndices;pt++,idx+=N)
{
for (unsigned pt = 0; pt < face.mNumIndices; pt++, idx += N) {
size_t vtxIdx = dest.vtx.size();
face.mIndices[pt] = static_cast<unsigned int>(vtxIdx);
@ -632,8 +593,7 @@ static void ReadShape(SIB* sib, StreamReaderLE* stream)
// Now that we know the size of everything,
// we can build the final one-material-per-mesh data.
for (size_t n=0;n<meshes.size();n++)
{
for (size_t n = 0; n < meshes.size(); n++) {
TempMesh &src = meshes[n];
if (src.faces.empty())
continue;
@ -649,14 +609,12 @@ static void ReadShape(SIB* sib, StreamReaderLE* stream)
mesh->mNumUVComponents[0] = 2;
mesh->mMaterialIndex = static_cast<unsigned int>(n);
for (unsigned i=0;i<mesh->mNumVertices;i++)
{
for (unsigned i = 0; i < mesh->mNumVertices; i++) {
mesh->mVertices[i] = src.vtx[i];
mesh->mNormals[i] = src.nrm[i];
mesh->mTextureCoords[0][i] = src.uv[i];
}
for (unsigned i=0;i<mesh->mNumFaces;i++)
{
for (unsigned i = 0; i < mesh->mNumFaces; i++) {
mesh->mFaces[i] = src.faces[i];
}
@ -668,8 +626,7 @@ static void ReadShape(SIB* sib, StreamReaderLE* stream)
}
// ------------------------------------------------------------------------------------------------
static void ReadMaterial(SIB* sib, StreamReaderLE* stream)
{
static void ReadMaterial(SIB *sib, StreamReaderLE *stream) {
aiColor3D diff = ReadColor(stream);
aiColor3D ambi = ReadColor(stream);
aiColor3D spec = ReadColor(stream);
@ -697,8 +654,7 @@ static void ReadMaterial(SIB* sib, StreamReaderLE* stream)
}
// ------------------------------------------------------------------------------------------------
static void ReadLightInfo(aiLight* light, StreamReaderLE* stream)
{
static void ReadLightInfo(aiLight *light, StreamReaderLE *stream) {
uint32_t type = stream->GetU4();
switch (type) {
case 0: light->mType = aiLightSource_POINT; break;
@ -739,17 +695,14 @@ static void ReadLightInfo(aiLight* light, StreamReaderLE* stream)
light->mAngleOuterCone = outer;
}
static void ReadLight(SIB* sib, StreamReaderLE* stream)
{
static void ReadLight(SIB *sib, StreamReaderLE *stream) {
aiLight *light = new aiLight();
while (stream->GetRemainingSizeToLimit() >= sizeof(SIBChunk))
{
while (stream->GetRemainingSizeToLimit() >= sizeof(SIBChunk)) {
SIBChunk chunk = ReadChunk(stream);
unsigned oldLimit = stream->SetReadLimit(stream->GetCurrentPos() + chunk.Size);
switch (chunk.Tag)
{
switch (chunk.Tag) {
case TAG('L', 'N', 'F', 'O'): ReadLightInfo(light, stream); break;
case TAG('S', 'N', 'A', 'M'): light->mName = ReadString(stream, chunk.Size / 2); break;
default: UnknownChunk(stream, chunk); break;
@ -763,8 +716,7 @@ static void ReadLight(SIB* sib, StreamReaderLE* stream)
}
// ------------------------------------------------------------------------------------------------
static void ReadScale(aiMatrix4x4& axis, StreamReaderLE* stream)
{
static void ReadScale(aiMatrix4x4 &axis, StreamReaderLE *stream) {
aiMatrix4x4 scale;
scale.a1 = stream->GetF4();
scale.b1 = stream->GetF4();
@ -786,18 +738,15 @@ static void ReadScale(aiMatrix4x4& axis, StreamReaderLE* stream)
axis = axis * scale;
}
static void ReadInstance(SIB* sib, StreamReaderLE* stream)
{
static void ReadInstance(SIB *sib, StreamReaderLE *stream) {
SIBObject inst;
uint32_t shapeIndex = 0;
while (stream->GetRemainingSizeToLimit() >= sizeof(SIBChunk))
{
while (stream->GetRemainingSizeToLimit() >= sizeof(SIBChunk)) {
SIBChunk chunk = ReadChunk(stream);
unsigned oldLimit = stream->SetReadLimit(stream->GetCurrentPos() + chunk.Size);
switch (chunk.Tag)
{
switch (chunk.Tag) {
case TAG('D', 'I', 'N', 'F'): break; // display info, not needed
case TAG('P', 'I', 'N', 'F'): break; // ?
case TAG('A', 'X', 'I', 'S'): ReadAxis(inst.axis, stream); break;
@ -822,24 +771,20 @@ static void ReadInstance(SIB* sib, StreamReaderLE* stream)
}
// ------------------------------------------------------------------------------------------------
static void CheckVersion(StreamReaderLE* stream)
{
static void CheckVersion(StreamReaderLE *stream) {
uint32_t version = stream->GetU4();
if (version < 1 || version > 2) {
throw DeadlyImportError("SIB: Unsupported file version.");
}
}
static void ReadScene(SIB* sib, StreamReaderLE* stream)
{
static void ReadScene(SIB *sib, StreamReaderLE *stream) {
// Parse each chunk in turn.
while (stream->GetRemainingSizeToLimit() >= sizeof(SIBChunk))
{
while (stream->GetRemainingSizeToLimit() >= sizeof(SIBChunk)) {
SIBChunk chunk = ReadChunk(stream);
unsigned oldLimit = stream->SetReadLimit(stream->GetCurrentPos() + chunk.Size);
switch (chunk.Tag)
{
switch (chunk.Tag) {
case TAG('H', 'E', 'A', 'D'): CheckVersion(stream); break;
case TAG('S', 'H', 'A', 'P'): ReadShape(sib, stream); break;
case TAG('G', 'R', 'P', 'S'): break; // group assignment, we don't import this
@ -858,8 +803,7 @@ static void ReadScene(SIB* sib, StreamReaderLE* stream)
// ------------------------------------------------------------------------------------------------
// Imports the given file into the given scene structure.
void SIBImporter::InternReadFile(const std::string &pFile,
aiScene* pScene, IOSystem* pIOHandler)
{
aiScene *pScene, IOSystem *pIOHandler) {
StreamReaderLE stream(pIOHandler->Open(pFile, "rb"));
// We should have at least one chunk
@ -886,9 +830,9 @@ void SIBImporter::InternReadFile(const std::string& pFile,
pScene->mNumMaterials = static_cast<unsigned int>(sib.mtls.size());
pScene->mNumMeshes = static_cast<unsigned int>(sib.meshes.size());
pScene->mNumLights = static_cast<unsigned int>(sib.lights.size());
pScene->mMaterials = pScene->mNumMaterials ? new aiMaterial*[pScene->mNumMaterials] : NULL;
pScene->mMeshes = pScene->mNumMeshes ? new aiMesh*[pScene->mNumMeshes] : NULL;
pScene->mLights = pScene->mNumLights ? new aiLight*[pScene->mNumLights] : NULL;
pScene->mMaterials = pScene->mNumMaterials ? new aiMaterial *[pScene->mNumMaterials] : nullptr;
pScene->mMeshes = pScene->mNumMeshes ? new aiMesh *[pScene->mNumMeshes] : nullptr;
pScene->mLights = pScene->mNumLights ? new aiLight *[pScene->mNumLights] : nullptr;
if (pScene->mNumMaterials)
memcpy(pScene->mMaterials, &sib.mtls[0], sizeof(aiMaterial *) * pScene->mNumMaterials);
if (pScene->mNumMeshes)
@ -901,12 +845,11 @@ void SIBImporter::InternReadFile(const std::string& pFile,
aiNode *root = new aiNode();
root->mName.Set("<SIBRoot>");
root->mNumChildren = static_cast<unsigned int>(sib.objs.size() + sib.lights.size());
root->mChildren = root->mNumChildren ? new aiNode*[root->mNumChildren] : NULL;
root->mChildren = root->mNumChildren ? new aiNode *[root->mNumChildren] : nullptr;
pScene->mRootNode = root;
// Add nodes for each object.
for (size_t n=0;n<sib.objs.size();n++)
{
for (size_t n = 0; n < sib.objs.size(); n++) {
ai_assert(root->mChildren);
SIBObject &obj = sib.objs[n];
aiNode *node = new aiNode;
@ -916,13 +859,12 @@ void SIBImporter::InternReadFile(const std::string& pFile,
node->mTransformation = obj.axis;
node->mNumMeshes = static_cast<unsigned int>(obj.meshCount);
node->mMeshes = node->mNumMeshes ? new unsigned[node->mNumMeshes] : NULL;
node->mMeshes = node->mNumMeshes ? new unsigned[node->mNumMeshes] : nullptr;
for (unsigned i = 0; i < node->mNumMeshes; i++)
node->mMeshes[i] = static_cast<unsigned int>(obj.meshIdx + i);
// Mark instanced objects as being so.
if (n >= firstInst)
{
if (n >= firstInst) {
node->mMetaData = aiMetadata::Alloc(1);
node->mMetaData->Set(0, "IsInstance", true);
}
@ -930,8 +872,7 @@ void SIBImporter::InternReadFile(const std::string& pFile,
// Add nodes for each light.
// (no transformation as the light is already in world space)
for (size_t n=0;n<sib.lights.size();n++)
{
for (size_t n = 0; n < sib.lights.size(); n++) {
ai_assert(root->mChildren);
aiLight *light = sib.lights[n];
if (nullptr != light) {

View File

@ -577,7 +577,7 @@ void SMDImporter::GetAnimationFileList(const std::string &pFile, IOSystem* pIOHa
char *context1, *context2;
tok1 = strtok_s(&buf[0], "\r\n", &context1);
while (tok1 != NULL) {
while (tok1 != nullptr) {
tok2 = strtok_s(tok1, " \t", &context2);
if (tok2) {
char *p = tok2;

View File

@ -299,7 +299,7 @@ void STEP::ReadFile(DB& db,const EXPRESS::ConversionSchema& scheme,
}
// ------------------------------------------------------------------------------------------------
std::shared_ptr<const EXPRESS::DataType> EXPRESS::DataType::Parse(const char*& inout,uint64_t line, const EXPRESS::ConversionSchema* schema /*= NULL*/)
std::shared_ptr<const EXPRESS::DataType> EXPRESS::DataType::Parse(const char*& inout,uint64_t line, const EXPRESS::ConversionSchema* schema /*= nullptr*/)
{
const char* cur = inout;
SkipSpaces(&cur);
@ -422,7 +422,7 @@ std::shared_ptr<const EXPRESS::DataType> EXPRESS::DataType::Parse(const char*& i
}
// ------------------------------------------------------------------------------------------------
std::shared_ptr<const EXPRESS::LIST> EXPRESS::LIST::Parse(const char*& inout,uint64_t line, const EXPRESS::ConversionSchema* schema /*= NULL*/) {
std::shared_ptr<const EXPRESS::LIST> EXPRESS::LIST::Parse(const char*& inout,uint64_t line, const EXPRESS::ConversionSchema* schema /*= nullptr*/) {
const std::shared_ptr<EXPRESS::LIST> list = std::make_shared<EXPRESS::LIST>();
EXPRESS::LIST::MemberList& members = list->members;
@ -540,9 +540,9 @@ void STEP::LazyObject::LazyInit() const {
const char* acopy = args;
std::shared_ptr<const EXPRESS::LIST> conv_args = EXPRESS::LIST::Parse(acopy,(uint64_t)STEP::SyntaxError::LINE_NOT_SPECIFIED,&db.GetSchema());
delete[] args;
args = NULL;
args = nullptr;
// if the converter fails, it should throw an exception, but it should never return NULL
// if the converter fails, it should throw an exception, but it should never return nullptr
try {
obj = proc(db,*conv_args);
}

View File

@ -72,7 +72,7 @@ void ExportSceneSTL(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene
// we're still here - export successfully completed. Write the file.
std::unique_ptr<IOStream> outfile (pIOSystem->Open(pFile,"wt"));
if(outfile == NULL) {
if (outfile == nullptr) {
throw DeadlyExportError("could not open output .stl file: " + std::string(pFile));
}
@ -91,7 +91,7 @@ void ExportSceneSTLBinary(const char* pFile,IOSystem* pIOSystem, const aiScene*
// we're still here - export successfully completed. Write the file.
std::unique_ptr<IOStream> outfile (pIOSystem->Open(pFile,"wb"));
if(outfile == NULL) {
if (outfile == nullptr) {
throw DeadlyExportError("could not open output .stl file: " + std::string(pFile));
}

View File

@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2020, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
@ -101,11 +99,13 @@ static bool IsAsciiSTL(const char *buffer, unsigned int fileSize) {
const char *bufferEnd = buffer + fileSize;
if (!SkipSpaces(&buffer))
if (!SkipSpaces(&buffer)) {
return false;
}
if (buffer + 5 >= bufferEnd)
if (buffer + 5 >= bufferEnd) {
return false;
}
bool isASCII(strncmp(buffer, "solid", 5) == 0);
if (isASCII) {
@ -370,13 +370,21 @@ void STLImporter::LoadASCIIFile(aiNode *root) {
pMesh->mNumFaces = static_cast<unsigned int>(positionBuffer.size() / 3);
pMesh->mNumVertices = static_cast<unsigned int>(positionBuffer.size());
pMesh->mVertices = new aiVector3D[pMesh->mNumVertices];
memcpy(pMesh->mVertices, &positionBuffer[0].x, pMesh->mNumVertices * sizeof(aiVector3D));
for (size_t i=0; i<pMesh->mNumVertices; ++i ) {
pMesh->mVertices[i].x = positionBuffer[i].x;
pMesh->mVertices[i].y = positionBuffer[i].y;
pMesh->mVertices[i].z = positionBuffer[i].z;
}
positionBuffer.clear();
}
// also only process normalBuffer when filled, else exception when accessing with index operator
if (!normalBuffer.empty()) {
pMesh->mNormals = new aiVector3D[pMesh->mNumVertices];
memcpy(pMesh->mNormals, &normalBuffer[0].x, pMesh->mNumVertices * sizeof(aiVector3D));
for (size_t i=0; i<pMesh->mNumVertices; ++i ) {
pMesh->mNormals[i].x = normalBuffer[i].x;
pMesh->mNormals[i].y = normalBuffer[i].y;
pMesh->mNormals[i].z = normalBuffer[i].z;
}
normalBuffer.clear();
}

View File

@ -108,7 +108,7 @@ void ExportSceneStep(const char* pFile,IOSystem* pIOSystem, const aiScene* pScen
// we're still here - export successfully completed. Write result to the given IOSYstem
std::unique_ptr<IOStream> outfile (pIOSystem->Open(pFile,"wt"));
if(outfile == NULL) {
if (outfile == nullptr) {
throw DeadlyExportError("could not open output .stp file: " + std::string(pFile));
}
@ -204,7 +204,7 @@ void StepExporter::WriteFile()
static const unsigned int date_nb_chars = 20;
char date_str[date_nb_chars];
std::time_t date = std::time(NULL);
std::time_t date = std::time(nullptr);
std::strftime(date_str, date_nb_chars, "%Y-%m-%dT%H:%M:%S", std::localtime(&date));
// write the header

View File

@ -87,12 +87,16 @@ bool TerragenImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, b
if (!extension.length() || checkSig) {
/* If CanRead() is called in order to check whether we
* support a specific file extension in general pIOHandler
* might be NULL and it's our duty to return true here.
* might be nullptr and it's our duty to return true here.
*/
if (!pIOHandler) return true;
if (!pIOHandler) {
return true;
}
const char *tokens[] = { "terragen" };
return SearchFileHeaderForToken(pIOHandler, pFile, tokens, 1);
}
return false;
}
@ -116,7 +120,7 @@ void TerragenImporter::InternReadFile(const std::string &pFile,
IOStream *file = pIOHandler->Open(pFile, "rb");
// Check whether we can read from the file
if (file == NULL)
if (file == nullptr)
throw DeadlyImportError("Failed to open TERRAGEN TERRAIN file " + pFile + ".");
// Construct a stream reader to read all data in the correct endianness
@ -199,7 +203,7 @@ void TerragenImporter::InternReadFile(const std::string &pFile,
aiFace *f = m->mFaces = new aiFace[m->mNumFaces = (x - 1) * (y - 1)];
aiVector3D *pv = m->mVertices = new aiVector3D[m->mNumVertices = m->mNumFaces * 4];
aiVector3D *uv(NULL);
aiVector3D *uv(nullptr);
float step_y(0.0f), step_x(0.0f);
if (configComputeUVs) {
uv = m->mTextureCoords[0] = new aiVector3D[m->mNumVertices];

View File

@ -89,7 +89,7 @@ void ExportSceneXFile(const char* pFile,IOSystem* pIOSystem, const aiScene* pSce
// we're still here - export successfully completed. Write result to the given IOSYstem
std::unique_ptr<IOStream> outfile (pIOSystem->Open(pFile,"wt"));
if(outfile == NULL) {
if (outfile == nullptr) {
throw DeadlyExportError("could not open output .x file: " + std::string(pFile));
}

View File

@ -113,7 +113,7 @@ const aiImporterDesc* XFileImporter::GetInfo () const {
void XFileImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler) {
// read file into memory
std::unique_ptr<IOStream> file( pIOHandler->Open( pFile));
if ( file.get() == NULL ) {
if ( file.get() == nullptr ) {
throw DeadlyImportError( "Failed to open file " + pFile + "." );
}

File diff suppressed because it is too large Load Diff

View File

@ -104,7 +104,7 @@ protected:
//! reads header of data object including the opening brace.
//! returns false if error happened, and writes name of object
//! if there is one
void readHeadOfDataObject( std::string* poName = NULL);
void readHeadOfDataObject(std::string *poName = nullptr);
//! checks for closing curly brace, throws exception if not there
void CheckForClosingBrace();

View File

@ -64,8 +64,8 @@ namespace Assimp
// A ProtoInstance node (with the proper node type) can be substituted for any node in this content model."
// </Shape>
// A Shape node is unlit if either of the following is true:
// The shape's appearance field is NULL (default).
// The material field in the Appearance node is NULL (default).
// The shape's appearance field is nullptr (default).
// The material field in the Appearance node is nullptr (default).
// NOTE Geometry nodes that represent lines or points do not support lighting.
void X3DImporter::ParseNode_Shape_Shape()
{

View File

@ -71,8 +71,13 @@ using namespace Assimp;
namespace Assimp { // this has to be in here because LogFunctions is in ::Assimp
template <>
const char *LogFunctions<XGLImporter>::Prefix() {
<<<<<<< HEAD
static auto prefix = "XGL: ";
return prefix;
=======
static auto prefix = "XGL: ";
return prefix;
>>>>>>> master
}
} // namespace Assimp
@ -92,8 +97,13 @@ static const aiImporterDesc desc = {
// ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer
XGLImporter::XGLImporter() :
<<<<<<< HEAD
m_xmlParser(nullptr), m_scene(nullptr) {
// empty
=======
m_reader(nullptr), m_scene(nullptr) {
// empty
>>>>>>> master
}
// ------------------------------------------------------------------------------------------------
@ -105,13 +115,18 @@ XGLImporter::~XGLImporter() {
// ------------------------------------------------------------------------------------------------
// Returns whether the class can handle the format of the given file.
bool XGLImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool checkSig) const {
<<<<<<< HEAD
/* NOTE: A simple check for the file extension is not enough
=======
/* NOTE: A simple check for the file extension is not enough
>>>>>>> master
* here. XGL and ZGL are ok, but xml is too generic
* and might be collada as well. So open the file and
* look for typical signal tokens.
*/
const std::string extension = GetExtension(pFile);
<<<<<<< HEAD
if (extension == "xgl" || extension == "zgl") {
return true;
} else if (extension == "xml" || checkSig) {
@ -121,22 +136,42 @@ bool XGLImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool c
return SearchFileHeaderForToken(pIOHandler, pFile, tokens, 3);
}
return false;
=======
if (extension == "xgl" || extension == "zgl") {
return true;
} else if (extension == "xml" || checkSig) {
ai_assert(pIOHandler != nullptr);
const char *tokens[] = { "<world>", "<World>", "<WORLD>" };
return SearchFileHeaderForToken(pIOHandler, pFile, tokens, 3);
}
return false;
>>>>>>> master
}
// ------------------------------------------------------------------------------------------------
// Get a list of all file extensions which are handled by this class
const aiImporterDesc *XGLImporter::GetInfo() const {
<<<<<<< HEAD
return &desc;
=======
return &desc;
>>>>>>> master
}
// ------------------------------------------------------------------------------------------------
// Imports the given file into the given scene structure.
void XGLImporter::InternReadFile(const std::string &pFile,
<<<<<<< HEAD
aiScene *pScene, IOSystem *pIOHandler) {
=======
aiScene *pScene, IOSystem *pIOHandler) {
>>>>>>> master
#ifndef ASSIMP_BUILD_NO_COMPRESSED_XGL
std::vector<Bytef> uncompressed;
#endif
<<<<<<< HEAD
m_scene = pScene;
std::shared_ptr<IOStream> stream(pIOHandler->Open(pFile, "rb"));
@ -144,12 +179,22 @@ void XGLImporter::InternReadFile(const std::string &pFile,
if (stream.get() == NULL) {
throw DeadlyImportError("Failed to open XGL/ZGL file " + pFile + "");
}
=======
m_scene = pScene;
std::shared_ptr<IOStream> stream(pIOHandler->Open(pFile, "rb"));
// check whether we can read from the file
if (stream.get() == nullptr) {
throw DeadlyImportError("Failed to open XGL/ZGL file " + pFile + "");
}
>>>>>>> master
// see if its compressed, if so uncompress it
if (GetExtension(pFile) == "zgl") {
#ifdef ASSIMP_BUILD_NO_COMPRESSED_XGL
ThrowException("Cannot read ZGL file since Assimp was built without compression support");
#else
<<<<<<< HEAD
std::unique_ptr<StreamReaderLE> raw_reader(new StreamReaderLE(stream));
// build a zlib stream
@ -214,10 +259,69 @@ void XGLImporter::InternReadFile(const std::string &pFile,
/* while (ReadElement()) {
if (!ASSIMP_stricmp(m_reader->getNodeName(),"world")) {
=======
std::unique_ptr<StreamReaderLE> raw_reader(new StreamReaderLE(stream));
// build a zlib stream
z_stream zstream;
zstream.opaque = Z_NULL;
zstream.zalloc = Z_NULL;
zstream.zfree = Z_NULL;
zstream.data_type = Z_BINARY;
// raw decompression without a zlib or gzip header
inflateInit2(&zstream, -MAX_WBITS);
// skip two extra bytes, zgl files do carry a crc16 upfront (I think)
raw_reader->IncPtr(2);
zstream.next_in = reinterpret_cast<Bytef *>(raw_reader->GetPtr());
zstream.avail_in = (uInt)raw_reader->GetRemainingSize();
size_t total = 0l;
// TODO: be smarter about this, decompress directly into heap buffer
// and decompress the data .... do 1k chunks in the hope that we won't kill the stack
#define MYBLOCK 1024
Bytef block[MYBLOCK];
int ret;
do {
zstream.avail_out = MYBLOCK;
zstream.next_out = block;
ret = inflate(&zstream, Z_NO_FLUSH);
if (ret != Z_STREAM_END && ret != Z_OK) {
ThrowException("Failure decompressing this file using gzip, seemingly it is NOT a compressed .XGL file");
}
const size_t have = MYBLOCK - zstream.avail_out;
total += have;
uncompressed.resize(total);
memcpy(uncompressed.data() + total - have, block, have);
} while (ret != Z_STREAM_END);
// terminate zlib
inflateEnd(&zstream);
// replace the input stream with a memory stream
stream.reset(new MemoryIOStream(reinterpret_cast<uint8_t *>(uncompressed.data()), total));
#endif
}
// construct the irrXML parser
CIrrXML_IOStreamReader st(stream.get());
m_reader.reset(createIrrXMLReader((IFileReadCallBack *)&st));
// parse the XML file
TempScope scope;
while (ReadElement()) {
if (!ASSIMP_stricmp(m_reader->getNodeName(), "world")) {
>>>>>>> master
ReadWorld(scope);
}
}*/
<<<<<<< HEAD
std::vector<aiMesh *> &meshes = scope.meshes_linear;
std::vector<aiMaterial *> &materials = scope.materials_linear;
if (!meshes.size() || !materials.size()) {
@ -238,6 +342,28 @@ void XGLImporter::InternReadFile(const std::string &pFile,
m_scene->mNumLights = 1;
m_scene->mLights = new aiLight *[1];
m_scene->mLights[0] = scope.light;
=======
std::vector<aiMesh *> &meshes = scope.meshes_linear;
std::vector<aiMaterial *> &materials = scope.materials_linear;
if (!meshes.size() || !materials.size()) {
ThrowException("failed to extract data from XGL file, no meshes loaded");
}
// copy meshes
m_scene->mNumMeshes = static_cast<unsigned int>(meshes.size());
m_scene->mMeshes = new aiMesh *[m_scene->mNumMeshes]();
std::copy(meshes.begin(), meshes.end(), m_scene->mMeshes);
// copy materials
m_scene->mNumMaterials = static_cast<unsigned int>(materials.size());
m_scene->mMaterials = new aiMaterial *[m_scene->mNumMaterials]();
std::copy(materials.begin(), materials.end(), m_scene->mMaterials);
if (scope.light) {
m_scene->mNumLights = 1;
m_scene->mLights = new aiLight *[1];
m_scene->mLights[0] = scope.light;
>>>>>>> master
scope.light->mName = m_scene->mRootNode->mName;
}
@ -246,6 +372,7 @@ void XGLImporter::InternReadFile(const std::string &pFile,
}
// ------------------------------------------------------------------------------------------------
<<<<<<< HEAD
void XGLImporter::ReadWorld(TempScope &scope) {
XmlNode *root = m_xmlParser->getRootNode();
for (XmlNode &node : root->children()) {
@ -422,6 +549,223 @@ aiMatrix4x4 XGLImporter::ReadTrafo(XmlNode &node) {
if (forward.SquareLength() < 1e-4 || up.SquareLength() < 1e-4) {
LogError("A direction vector in <transform> is zero, ignoring trafo");
return m;
=======
bool XGLImporter::ReadElement() {
while (m_reader->read()) {
if (m_reader->getNodeType() == EXN_ELEMENT) {
return true;
}
}
return false;
}
// ------------------------------------------------------------------------------------------------
bool XGLImporter::ReadElementUpToClosing(const char *closetag) {
while (m_reader->read()) {
if (m_reader->getNodeType() == EXN_ELEMENT) {
return true;
} else if (m_reader->getNodeType() == EXN_ELEMENT_END && !ASSIMP_stricmp(m_reader->getNodeName(), closetag)) {
return false;
}
}
LogError("unexpected EOF, expected closing <" + std::string(closetag) + "> tag");
return false;
}
// ------------------------------------------------------------------------------------------------
bool XGLImporter::SkipToText() {
while (m_reader->read()) {
if (m_reader->getNodeType() == EXN_TEXT) {
return true;
} else if (m_reader->getNodeType() == EXN_ELEMENT || m_reader->getNodeType() == EXN_ELEMENT_END) {
ThrowException("expected text contents but found another element (or element end)");
}
}
return false;
}
// ------------------------------------------------------------------------------------------------
std::string XGLImporter::GetElementName() {
const char *s = m_reader->getNodeName();
size_t len = strlen(s);
std::string ret;
ret.resize(len);
std::transform(s, s + len, ret.begin(), ::ToLower<char>);
return ret;
}
// ------------------------------------------------------------------------------------------------
void XGLImporter::ReadWorld(TempScope &scope) {
while (ReadElementUpToClosing("world")) {
const std::string &s = GetElementName();
// XXX right now we'd skip <lighting> if it comes after
// <object> or <mesh>
if (s == "lighting") {
ReadLighting(scope);
} else if (s == "object" || s == "mesh" || s == "mat") {
break;
}
}
aiNode *const nd = ReadObject(scope, true, "world");
if (!nd) {
ThrowException("failure reading <world>");
}
if (!nd->mName.length) {
nd->mName.Set("WORLD");
}
m_scene->mRootNode = nd;
}
// ------------------------------------------------------------------------------------------------
void XGLImporter::ReadLighting(TempScope &scope) {
while (ReadElementUpToClosing("lighting")) {
const std::string &s = GetElementName();
if (s == "directionallight") {
scope.light = ReadDirectionalLight();
} else if (s == "ambient") {
LogWarn("ignoring <ambient> tag");
} else if (s == "spheremap") {
LogWarn("ignoring <spheremap> tag");
}
}
}
// ------------------------------------------------------------------------------------------------
aiLight *XGLImporter::ReadDirectionalLight() {
std::unique_ptr<aiLight> l(new aiLight());
l->mType = aiLightSource_DIRECTIONAL;
while (ReadElementUpToClosing("directionallight")) {
const std::string &s = GetElementName();
if (s == "direction") {
l->mDirection = ReadVec3();
} else if (s == "diffuse") {
l->mColorDiffuse = ReadCol3();
} else if (s == "specular") {
l->mColorSpecular = ReadCol3();
}
}
return l.release();
}
// ------------------------------------------------------------------------------------------------
aiNode *XGLImporter::ReadObject(TempScope &scope, bool skipFirst, const char *closetag) {
aiNode *nd = new aiNode;
std::vector<aiNode *> children;
std::vector<unsigned int> meshes;
try {
while (skipFirst || ReadElementUpToClosing(closetag)) {
skipFirst = false;
const std::string &s = GetElementName();
if (s == "mesh") {
const size_t prev = scope.meshes_linear.size();
if (ReadMesh(scope)) {
const size_t newc = scope.meshes_linear.size();
for (size_t i = 0; i < newc - prev; ++i) {
meshes.push_back(static_cast<unsigned int>(i + prev));
}
}
} else if (s == "mat") {
ReadMaterial(scope);
} else if (s == "object") {
children.push_back(ReadObject(scope));
} else if (s == "objectref") {
// XXX
} else if (s == "meshref") {
const unsigned int id = static_cast<unsigned int>(ReadIndexFromText());
std::multimap<unsigned int, aiMesh *>::iterator it = scope.meshes.find(id), end = scope.meshes.end();
if (it == end) {
ThrowException("<meshref> index out of range");
}
for (; it != end && (*it).first == id; ++it) {
// ok, this is n^2 and should get optimized one day
aiMesh *const m = (*it).second;
unsigned int i = 0, mcount = static_cast<unsigned int>(scope.meshes_linear.size());
for (; i < mcount; ++i) {
if (scope.meshes_linear[i] == m) {
meshes.push_back(i);
break;
}
}
ai_assert(i < mcount);
}
} else if (s == "transform") {
nd->mTransformation = ReadTrafo();
}
}
} catch (...) {
for (aiNode *ch : children) {
delete ch;
}
throw;
}
// FIX: since we used std::multimap<> to keep meshes by id, mesh order now depends on the behaviour
// of the multimap implementation with respect to the ordering of entries with same values.
// C++11 gives the guarantee that it uses insertion order, before it is implementation-specific.
// Sort by material id to always guarantee a deterministic result.
std::sort(meshes.begin(), meshes.end(), SortMeshByMaterialId(scope));
// link meshes to node
nd->mNumMeshes = static_cast<unsigned int>(meshes.size());
if (nd->mNumMeshes) {
nd->mMeshes = new unsigned int[nd->mNumMeshes]();
for (unsigned int i = 0; i < nd->mNumMeshes; ++i) {
nd->mMeshes[i] = meshes[i];
}
}
// link children to parent
nd->mNumChildren = static_cast<unsigned int>(children.size());
if (nd->mNumChildren) {
nd->mChildren = new aiNode *[nd->mNumChildren]();
for (unsigned int i = 0; i < nd->mNumChildren; ++i) {
nd->mChildren[i] = children[i];
children[i]->mParent = nd;
}
}
return nd;
}
// ------------------------------------------------------------------------------------------------
aiMatrix4x4 XGLImporter::ReadTrafo() {
aiVector3D forward, up, right, position;
float scale = 1.0f;
while (ReadElementUpToClosing("transform")) {
const std::string &s = GetElementName();
if (s == "forward") {
forward = ReadVec3();
} else if (s == "up") {
up = ReadVec3();
} else if (s == "position") {
position = ReadVec3();
}
if (s == "scale") {
scale = ReadFloat();
if (scale < 0.f) {
// this is wrong, but we can leave the value and pass it to the caller
LogError("found negative scaling in <transform>, ignoring");
}
}
}
aiMatrix4x4 m;
if (forward.SquareLength() < 1e-4 || up.SquareLength() < 1e-4) {
LogError("A direction vector in <transform> is zero, ignoring trafo");
return m;
>>>>>>> master
}
forward.Normalize();
@ -460,6 +804,7 @@ aiMatrix4x4 XGLImporter::ReadTrafo(XmlNode &node) {
// ------------------------------------------------------------------------------------------------
aiMesh *XGLImporter::ToOutputMesh(const TempMaterialMesh &m) {
<<<<<<< HEAD
std::unique_ptr<aiMesh> mesh(new aiMesh());
mesh->mNumVertices = static_cast<unsigned int>(m.positions.size());
@ -494,6 +839,40 @@ aiMesh *XGLImporter::ToOutputMesh(const TempMaterialMesh &m) {
}
ai_assert(idx == mesh->mNumVertices);
=======
std::unique_ptr<aiMesh> mesh(new aiMesh());
mesh->mNumVertices = static_cast<unsigned int>(m.positions.size());
mesh->mVertices = new aiVector3D[mesh->mNumVertices];
std::copy(m.positions.begin(), m.positions.end(), mesh->mVertices);
if (m.normals.size()) {
mesh->mNormals = new aiVector3D[mesh->mNumVertices];
std::copy(m.normals.begin(), m.normals.end(), mesh->mNormals);
}
if (m.uvs.size()) {
mesh->mNumUVComponents[0] = 2;
mesh->mTextureCoords[0] = new aiVector3D[mesh->mNumVertices];
for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
mesh->mTextureCoords[0][i] = aiVector3D(m.uvs[i].x, m.uvs[i].y, 0.f);
}
}
mesh->mNumFaces = static_cast<unsigned int>(m.vcounts.size());
mesh->mFaces = new aiFace[m.vcounts.size()];
unsigned int idx = 0;
for (unsigned int i = 0; i < mesh->mNumFaces; ++i) {
aiFace &f = mesh->mFaces[i];
f.mNumIndices = m.vcounts[i];
f.mIndices = new unsigned int[f.mNumIndices];
for (unsigned int c = 0; c < f.mNumIndices; ++c) {
f.mIndices[c] = idx++;
}
}
>>>>>>> master
mesh->mPrimitiveTypes = m.pflags;
mesh->mMaterialIndex = m.matid;
@ -502,6 +881,7 @@ aiMesh *XGLImporter::ToOutputMesh(const TempMaterialMesh &m) {
}
// ------------------------------------------------------------------------------------------------
<<<<<<< HEAD
bool XGLImporter::ReadMesh(XmlNode &node, TempScope &scope) {
TempMesh t;
@ -629,9 +1009,137 @@ unsigned int XGLImporter::ResolveMaterialRef(XmlNode &node, TempScope &scope) {
ReadMaterial(node, scope);
return static_cast<unsigned int>(scope.materials_linear.size() - 1);
}
=======
bool XGLImporter::ReadMesh(TempScope &scope) {
TempMesh t;
std::map<unsigned int, TempMaterialMesh> bymat;
const unsigned int mesh_id = ReadIDAttr();
while (ReadElementUpToClosing("mesh")) {
const std::string &s = GetElementName();
if (s == "mat") {
ReadMaterial(scope);
} else if (s == "p") {
if (!m_reader->getAttributeValue("ID")) {
LogWarn("no ID attribute on <p>, ignoring");
} else {
int id = m_reader->getAttributeValueAsInt("ID");
t.points[id] = ReadVec3();
}
} else if (s == "n") {
if (!m_reader->getAttributeValue("ID")) {
LogWarn("no ID attribute on <n>, ignoring");
} else {
int id = m_reader->getAttributeValueAsInt("ID");
t.normals[id] = ReadVec3();
}
} else if (s == "tc") {
if (!m_reader->getAttributeValue("ID")) {
LogWarn("no ID attribute on <tc>, ignoring");
} else {
int id = m_reader->getAttributeValueAsInt("ID");
t.uvs[id] = ReadVec2();
}
} else if (s == "f" || s == "l" || s == "p") {
const unsigned int vcount = s == "f" ? 3 : (s == "l" ? 2 : 1);
unsigned int mid = ~0u;
TempFace tf[3];
bool has[3] = { 0 };
while (ReadElementUpToClosing(s.c_str())) {
const std::string &elemName = GetElementName();
if (elemName == "fv1" || elemName == "lv1" || elemName == "pv1") {
ReadFaceVertex(t, tf[0]);
has[0] = true;
} else if (elemName == "fv2" || elemName == "lv2") {
ReadFaceVertex(t, tf[1]);
has[1] = true;
} else if (elemName == "fv3") {
ReadFaceVertex(t, tf[2]);
has[2] = true;
} else if (elemName == "mat") {
if (mid != ~0u) {
LogWarn("only one material tag allowed per <f>");
}
mid = ResolveMaterialRef(scope);
} else if (elemName == "matref") {
if (mid != ~0u) {
LogWarn("only one material tag allowed per <f>");
}
mid = ResolveMaterialRef(scope);
}
}
if (mid == ~0u) {
ThrowException("missing material index");
}
bool nor = false;
bool uv = false;
for (unsigned int i = 0; i < vcount; ++i) {
if (!has[i]) {
ThrowException("missing face vertex data");
}
nor = nor || tf[i].has_normal;
uv = uv || tf[i].has_uv;
}
if (mid >= (1 << 30)) {
LogWarn("material indices exhausted, this may cause errors in the output");
}
unsigned int meshId = mid | ((nor ? 1 : 0) << 31) | ((uv ? 1 : 0) << 30);
TempMaterialMesh &mesh = bymat[meshId];
mesh.matid = mid;
for (unsigned int i = 0; i < vcount; ++i) {
mesh.positions.push_back(tf[i].pos);
if (nor) {
mesh.normals.push_back(tf[i].normal);
}
if (uv) {
mesh.uvs.push_back(tf[i].uv);
}
mesh.pflags |= 1 << (vcount - 1);
}
mesh.vcounts.push_back(vcount);
}
}
// finally extract output meshes and add them to the scope
typedef std::pair<const unsigned int, TempMaterialMesh> pairt;
for (const pairt &p : bymat) {
aiMesh *const m = ToOutputMesh(p.second);
scope.meshes_linear.push_back(m);
// if this is a definition, keep it on the stack
if (mesh_id != ~0u) {
scope.meshes.insert(std::pair<unsigned int, aiMesh *>(mesh_id, m));
}
}
// no id == not a reference, insert this mesh right *here*
return mesh_id == ~0u;
}
// ----------------------------------------------------------------------------------------------
unsigned int XGLImporter::ResolveMaterialRef(TempScope &scope) {
const std::string &s = GetElementName();
if (s == "mat") {
ReadMaterial(scope);
return static_cast<unsigned int>(scope.materials_linear.size() - 1);
}
>>>>>>> master
const int id = ReadIndexFromText(node);
<<<<<<< HEAD
std::map<unsigned int, aiMaterial *>::iterator it = scope.materials.find(id), end = scope.materials.end();
if (it == end) {
ThrowException("<matref> index out of range");
@ -648,11 +1156,28 @@ unsigned int XGLImporter::ResolveMaterialRef(XmlNode &node, TempScope &scope) {
}
ai_assert(false);
=======
std::map<unsigned int, aiMaterial *>::iterator it = scope.materials.find(id), end = scope.materials.end();
if (it == end) {
ThrowException("<matref> index out of range");
}
// ok, this is n^2 and should get optimized one day
aiMaterial *const m = (*it).second;
unsigned int i = 0, mcount = static_cast<unsigned int>(scope.materials_linear.size());
for (; i < mcount; ++i) {
if (scope.materials_linear[i] == m) {
return i;
}
}
>>>>>>> master
return 0;
}
// ------------------------------------------------------------------------------------------------
<<<<<<< HEAD
void XGLImporter::ReadMaterial(XmlNode &node, TempScope &scope) {
const unsigned int mat_id = ReadIDAttr(node);
@ -801,11 +1326,178 @@ aiVector2D XGLImporter::ReadVec2(XmlNode &node) {
}
vec.x = v[0];
vec.y = v[1];
=======
void XGLImporter::ReadMaterial(TempScope &scope) {
const unsigned int mat_id = ReadIDAttr();
aiMaterial *mat(new aiMaterial);
while (ReadElementUpToClosing("mat")) {
const std::string &s = GetElementName();
if (s == "amb") {
const aiColor3D c = ReadCol3();
mat->AddProperty(&c, 1, AI_MATKEY_COLOR_AMBIENT);
} else if (s == "diff") {
const aiColor3D c = ReadCol3();
mat->AddProperty(&c, 1, AI_MATKEY_COLOR_DIFFUSE);
} else if (s == "spec") {
const aiColor3D c = ReadCol3();
mat->AddProperty(&c, 1, AI_MATKEY_COLOR_SPECULAR);
} else if (s == "emiss") {
const aiColor3D c = ReadCol3();
mat->AddProperty(&c, 1, AI_MATKEY_COLOR_EMISSIVE);
} else if (s == "alpha") {
const float f = ReadFloat();
mat->AddProperty(&f, 1, AI_MATKEY_OPACITY);
} else if (s == "shine") {
const float f = ReadFloat();
mat->AddProperty(&f, 1, AI_MATKEY_SHININESS);
}
}
scope.materials[mat_id] = mat;
scope.materials_linear.push_back(mat);
}
// ----------------------------------------------------------------------------------------------
void XGLImporter::ReadFaceVertex(const TempMesh &t, TempFace &out) {
const std::string &end = GetElementName();
bool havep = false;
while (ReadElementUpToClosing(end.c_str())) {
const std::string &s = GetElementName();
if (s == "pref") {
const unsigned int id = ReadIndexFromText();
std::map<unsigned int, aiVector3D>::const_iterator it = t.points.find(id);
if (it == t.points.end()) {
ThrowException("point index out of range");
}
out.pos = (*it).second;
havep = true;
} else if (s == "nref") {
const unsigned int id = ReadIndexFromText();
std::map<unsigned int, aiVector3D>::const_iterator it = t.normals.find(id);
if (it == t.normals.end()) {
ThrowException("normal index out of range");
}
out.normal = (*it).second;
out.has_normal = true;
} else if (s == "tcref") {
const unsigned int id = ReadIndexFromText();
std::map<unsigned int, aiVector2D>::const_iterator it = t.uvs.find(id);
if (it == t.uvs.end()) {
ThrowException("uv index out of range");
}
out.uv = (*it).second;
out.has_uv = true;
} else if (s == "p") {
out.pos = ReadVec3();
} else if (s == "n") {
out.normal = ReadVec3();
} else if (s == "tc") {
out.uv = ReadVec2();
}
}
if (!havep) {
ThrowException("missing <pref> in <fvN> element");
}
}
// ------------------------------------------------------------------------------------------------
unsigned int XGLImporter::ReadIDAttr() {
for (int i = 0, e = m_reader->getAttributeCount(); i < e; ++i) {
if (!ASSIMP_stricmp(m_reader->getAttributeName(i), "id")) {
return m_reader->getAttributeValueAsInt(i);
}
}
return ~0u;
}
// ------------------------------------------------------------------------------------------------
float XGLImporter::ReadFloat() {
if (!SkipToText()) {
LogError("unexpected EOF reading float element contents");
return 0.f;
}
const char *s = m_reader->getNodeData(), *se;
if (!SkipSpaces(&s)) {
LogError("unexpected EOL, failed to parse float");
return 0.f;
}
float t;
se = fast_atoreal_move(s, t);
if (se == s) {
LogError("failed to read float text");
return 0.f;
}
return t;
}
// ------------------------------------------------------------------------------------------------
unsigned int XGLImporter::ReadIndexFromText() {
if (!SkipToText()) {
LogError("unexpected EOF reading index element contents");
return ~0u;
}
const char *s = m_reader->getNodeData(), *se;
if (!SkipSpaces(&s)) {
LogError("unexpected EOL, failed to parse index element");
return ~0u;
}
const unsigned int t = strtoul10(s, &se);
if (se == s) {
LogError("failed to read index");
return ~0u;
}
return t;
}
// ------------------------------------------------------------------------------------------------
aiVector2D XGLImporter::ReadVec2() {
aiVector2D vec;
if (!SkipToText()) {
LogError("unexpected EOF reading vec2 contents");
return vec;
}
const char *s = m_reader->getNodeData();
ai_real v[2];
for (int i = 0; i < 2; ++i) {
if (!SkipSpaces(&s)) {
LogError("unexpected EOL, failed to parse vec2");
return vec;
}
v[i] = fast_atof(&s);
SkipSpaces(&s);
if (i != 1 && *s != ',') {
LogError("expected comma, failed to parse vec2");
return vec;
}
++s;
}
vec.x = v[0];
vec.y = v[1];
>>>>>>> master
return vec;
}
// ------------------------------------------------------------------------------------------------
<<<<<<< HEAD
aiVector3D XGLImporter::ReadVec3(XmlNode &node) {
aiVector3D vec;
const char *s = node.value();
@ -834,6 +1526,42 @@ aiColor3D XGLImporter::ReadCol3(XmlNode &node) {
LogWarn("color values out of range, ignoring");
}
return aiColor3D(v.x, v.y, v.z);
=======
aiVector3D XGLImporter::ReadVec3() {
aiVector3D vec;
if (!SkipToText()) {
LogError("unexpected EOF reading vec3 contents");
return vec;
}
const char *s = m_reader->getNodeData();
for (int i = 0; i < 3; ++i) {
if (!SkipSpaces(&s)) {
LogError("unexpected EOL, failed to parse vec3");
return vec;
}
vec[i] = fast_atof(&s);
SkipSpaces(&s);
if (i != 2 && *s != ',') {
LogError("expected comma, failed to parse vec3");
return vec;
}
++s;
}
return vec;
}
// ------------------------------------------------------------------------------------------------
aiColor3D XGLImporter::ReadCol3() {
const aiVector3D &v = ReadVec3();
if (v.x < 0.f || v.x > 1.0f || v.y < 0.f || v.y > 1.0f || v.z < 0.f || v.z > 1.0f) {
LogWarn("color values out of range, ignoring");
}
return aiColor3D(v.x, v.y, v.z);
>>>>>>> master
}
#endif

View File

@ -47,15 +47,24 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define AI_XGLLOADER_H_INCLUDED
#include <assimp/BaseImporter.h>
<<<<<<< HEAD
#include <assimp/XmlParser.h>
=======
>>>>>>> master
#include <assimp/LogAux.h>
#include <assimp/irrXMLWrapper.h>
#include <assimp/light.h>
#include <assimp/material.h>
#include <assimp/Importer.hpp>
#include <assimp/mesh.h>
<<<<<<< HEAD
#include <assimp/light.h>
#include <memory>
=======
#include <assimp/Importer.hpp>
>>>>>>> master
#include <map>
#include <memory>
struct aiNode;
@ -71,6 +80,10 @@ public:
XGLImporter();
~XGLImporter();
<<<<<<< HEAD
=======
public:
>>>>>>> master
// -------------------------------------------------------------------
/** Returns whether the class can handle the format of the given file.
* See BaseImporter::CanRead() for details. */
@ -78,7 +91,6 @@ public:
bool checkSig) const;
protected:
// -------------------------------------------------------------------
/** Return importer meta information.
* See #BaseImporter::GetInfo for the details */
@ -91,6 +103,7 @@ protected:
IOSystem *pIOHandler);
private:
<<<<<<< HEAD
struct TempScope
{
TempScope()
@ -100,6 +113,14 @@ private:
~TempScope()
{
for(aiMesh* m : meshes_linear) {
=======
struct TempScope {
TempScope() :
light() {}
~TempScope() {
for (aiMesh *m : meshes_linear) {
>>>>>>> master
delete m;
}
@ -111,7 +132,7 @@ private:
}
void dismiss() {
light = NULL;
light = nullptr;
meshes_linear.clear();
materials_linear.clear();
meshes.clear();
@ -127,9 +148,9 @@ private:
aiLight *light;
};
struct SortMeshByMaterialId {
SortMeshByMaterialId(const TempScope& scope) : scope(scope) {}
SortMeshByMaterialId(const TempScope &scope) :
scope(scope) {}
bool operator()(unsigned int a, unsigned int b) const {
return scope.meshes_linear[a]->mMaterialIndex < scope.meshes_linear[b]->mMaterialIndex;
};
@ -137,19 +158,15 @@ private:
const TempScope &scope;
};
struct TempMesh
{
struct TempMesh {
std::map<unsigned int, aiVector3D> points;
std::map<unsigned int, aiVector3D> normals;
std::map<unsigned int, aiVector2D> uvs;
};
struct TempMaterialMesh
{
TempMaterialMesh()
: pflags()
, matid()
{}
struct TempMaterialMesh {
TempMaterialMesh() :
pflags(), matid() {}
std::vector<aiVector3D> positions, normals;
std::vector<aiVector2D> uvs;
@ -159,12 +176,9 @@ private:
unsigned int matid;
};
struct TempFace
{
TempFace()
: has_uv()
, has_normal()
{}
struct TempFace {
TempFace() :
has_uv(), has_normal() {}
aiVector3D pos;
aiVector3D normal;
@ -176,6 +190,7 @@ private:
private:
void Cleanup();
<<<<<<< HEAD
unsigned int ReadIDAttr(XmlNode &node);
void ReadWorld(TempScope& scope);
@ -199,6 +214,34 @@ private:
//std::shared_ptr<irr::io::IrrXMLReader> m_reader;
XmlParser *m_xmlParser;
aiScene* m_scene;
=======
std::string GetElementName();
bool ReadElement();
bool ReadElementUpToClosing(const char *closetag);
bool SkipToText();
unsigned int ReadIDAttr();
void ReadWorld(TempScope &scope);
void ReadLighting(TempScope &scope);
aiLight *ReadDirectionalLight();
aiNode *ReadObject(TempScope &scope, bool skipFirst = false, const char *closetag = "object");
bool ReadMesh(TempScope &scope);
void ReadMaterial(TempScope &scope);
aiVector2D ReadVec2();
aiVector3D ReadVec3();
aiColor3D ReadCol3();
aiMatrix4x4 ReadTrafo();
unsigned int ReadIndexFromText();
float ReadFloat();
aiMesh *ToOutputMesh(const TempMaterialMesh &m);
void ReadFaceVertex(const TempMesh &t, TempFace &out);
unsigned int ResolveMaterialRef(TempScope &scope);
private:
std::shared_ptr<irr::io::IrrXMLReader> m_reader;
aiScene *m_scene;
>>>>>>> master
};
} // end of namespace Assimp

Some files were not shown because too many files have changed in this diff Show More