Merge branch 'master' into fix/collada_parser_sid

This commit is contained in:
Kim Kulling
2022-07-29 19:17:43 +02:00
committed by GitHub
37 changed files with 775 additions and 444 deletions
+2
View File
@@ -74,6 +74,8 @@ namespace XmlTag {
const char* const pid = "pid";
const char* const pindex = "pindex";
const char* const p1 = "p1";
const char *const p2 = "p2";
const char *const p3 = "p3";
const char* const name = "name";
const char* const type = "type";
const char* const build = "build";
+3
View File
@@ -186,6 +186,9 @@ D3MFOpcPackage::D3MFOpcPackage(IOSystem *pIOHandler, const std::string &rFile) :
D3MFOpcPackage::~D3MFOpcPackage() {
mZipArchive->Close(mRootStream);
delete mZipArchive;
for (auto tex : mEmbeddedTextures) {
delete tex;
}
}
IOStream *D3MFOpcPackage::RootStream() const {
+31 -8
View File
@@ -64,7 +64,7 @@ bool validateColorString(const char *color) {
return true;
}
aiFace ReadTriangle(XmlNode &node) {
aiFace ReadTriangle(XmlNode &node, int &texId0, int &texId1, int &texId2) {
aiFace face;
face.mNumIndices = 3;
@@ -73,6 +73,11 @@ aiFace ReadTriangle(XmlNode &node) {
face.mIndices[1] = static_cast<unsigned int>(std::atoi(node.attribute(XmlTag::v2).as_string()));
face.mIndices[2] = static_cast<unsigned int>(std::atoi(node.attribute(XmlTag::v3).as_string()));
texId0 = texId1 = texId2 = -1;
XmlParser::getIntAttribute(node, XmlTag::p1, texId0);
XmlParser::getIntAttribute(node, XmlTag::p2, texId1);
XmlParser::getIntAttribute(node, XmlTag::p3, texId2);
return face;
}
@@ -412,6 +417,9 @@ void XmlSerializer::ImportTriangles(XmlNode &node, aiMesh *mesh) {
bool hasPid = getNodeAttribute(currentNode, D3MF::XmlTag::pid, pid);
bool hasP1 = getNodeAttribute(currentNode, D3MF::XmlTag::p1, p1);
int texId[3];
Texture2DGroup *group = nullptr;
aiFace face = ReadTriangle(currentNode, texId[0], texId[1], texId[2]);
if (hasPid && hasP1) {
auto it = mResourcesDictionnary.find(pid);
if (it != mResourcesDictionnary.end()) {
@@ -420,23 +428,34 @@ void XmlSerializer::ImportTriangles(XmlNode &node, aiMesh *mesh) {
mesh->mMaterialIndex = baseMaterials->mMaterialIndex[p1];
} else if (it->second->getType() == ResourceType::RT_Texture2DGroup) {
if (mesh->mTextureCoords[0] == nullptr) {
Texture2DGroup *group = static_cast<Texture2DGroup *>(it->second);
mesh->mNumUVComponents[0] = 2;
for (unsigned int i = 1; i < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++i) {
mesh->mNumUVComponents[i] = 0;
}
group = static_cast<Texture2DGroup *>(it->second);
const std::string name = ai_to_string(group->mTexId);
for (size_t i = 0; i < mMaterials.size(); ++i) {
if (name == mMaterials[i]->GetName().C_Str()) {
mesh->mMaterialIndex = static_cast<unsigned int>(i);
}
}
mesh->mTextureCoords[0] = new aiVector3D[group->mTex2dCoords.size()];
for (unsigned int i = 0; i < group->mTex2dCoords.size(); ++i) {
mesh->mTextureCoords[0][i] = aiVector3D(group->mTex2dCoords[i].x, group->mTex2dCoords[i].y, 0);
}
mesh->mTextureCoords[0] = new aiVector3D[mesh->mNumVertices];
}
}
}
}
aiFace face = ReadTriangle(currentNode);
// Load texture coordinates into mesh, when any
if (group != nullptr) {
size_t i0 = face.mIndices[0];
size_t i1 = face.mIndices[1];
size_t i2 = face.mIndices[2];
mesh->mTextureCoords[0][i0] = aiVector3D(group->mTex2dCoords[texId[0]].x, group->mTex2dCoords[texId[0]].y, 0.0f);
mesh->mTextureCoords[0][i1] = aiVector3D(group->mTex2dCoords[texId[1]].x, group->mTex2dCoords[texId[1]].y, 0.0f);
mesh->mTextureCoords[0][i2] = aiVector3D(group->mTex2dCoords[texId[2]].x, group->mTex2dCoords[texId[2]].y, 0.0f);
}
faces.push_back(face);
}
}
@@ -578,11 +597,15 @@ aiMaterial *XmlSerializer::readMaterialDef(XmlNode &node, unsigned int basemater
}
void XmlSerializer::StoreMaterialsInScene(aiScene *scene) {
if (nullptr == scene || mMaterials.empty()) {
if (nullptr == scene) {
return;
}
scene->mNumMaterials = static_cast<unsigned int>(mMaterials.size());
if (scene->mNumMaterials == 0) {
return;
}
scene->mMaterials = new aiMaterial *[scene->mNumMaterials];
for (size_t i = 0; i < mMaterials.size(); ++i) {
scene->mMaterials[i] = mMaterials[i];
+5
View File
@@ -621,6 +621,11 @@ struct Animation {
for (std::vector<Animation *>::iterator it = pParent->mSubAnims.begin(); it != pParent->mSubAnims.end();) {
Animation *anim = *it;
// Assign the first animation name to the parent if empty.
// This prevents the animation name from being lost when animations are combined
if (mName.empty()) {
mName = anim->mName;
}
CombineSingleChannelAnimationsRecursively(anim);
if (childrenAnimationsHaveDifferentChannels && anim->mChannels.size() == 1 &&
+6 -3
View File
@@ -102,6 +102,7 @@ ColladaLoader::ColladaLoader() :
mTextures(),
mAnims(),
noSkeletonMesh(false),
removeEmptyBones(false),
ignoreUpDirection(false),
useColladaName(false),
mNodeNameCounter(0) {
@@ -130,6 +131,7 @@ bool ColladaLoader::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool
// ------------------------------------------------------------------------------------------------
void ColladaLoader::SetupProperties(const Importer *pImp) {
noSkeletonMesh = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_NO_SKELETON_MESHES, 0) != 0;
removeEmptyBones = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_REMOVE_EMPTY_BONES, true) != 0;
ignoreUpDirection = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_COLLADA_IGNORE_UP_DIRECTION, 0) != 0;
useColladaName = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_COLLADA_USE_COLLADA_NAMES, 0) != 0;
}
@@ -798,9 +800,10 @@ aiMesh *ColladaLoader::CreateMesh(const ColladaParser &pParser, const Mesh *pSrc
// count the number of bones which influence vertices of the current submesh
size_t numRemainingBones = 0;
for (const auto & dstBone : dstBones) {
if (!dstBone.empty()) {
++numRemainingBones;
if (dstBone.empty() && removeEmptyBones) {
continue;
}
++numRemainingBones;
}
// create bone array and copy bone weights one by one
@@ -809,7 +812,7 @@ aiMesh *ColladaLoader::CreateMesh(const ColladaParser &pParser, const Mesh *pSrc
size_t boneCount = 0;
for (size_t a = 0; a < numBones; ++a) {
// omit bones without weights
if (dstBones[a].empty()) {
if (dstBones[a].empty() && removeEmptyBones) {
continue;
}
+1
View File
@@ -237,6 +237,7 @@ protected:
std::vector<aiAnimation *> mAnims;
bool noSkeletonMesh;
bool removeEmptyBones;
bool ignoreUpDirection;
bool useColladaName;
+3 -1
View File
@@ -368,7 +368,9 @@ void DXFImporter::ExpandBlockReferences(DXF::Block& bl,const DXF::BlockMap& bloc
// XXX this would be the place to implement recursive expansion if needed.
const DXF::Block& bl_src = *(*it).second;
for (std::shared_ptr<const DXF::PolyLine> pl_in : bl_src.lines) {
const size_t size = bl_src.lines.size(); // the size may increase in the loop
for (size_t i = 0; i < size; ++i) {
std::shared_ptr<const DXF::PolyLine> pl_in = bl_src.lines[i];
if (!pl_in) {
ASSIMP_LOG_ERROR("DXF: PolyLine instance is nullptr, skipping.");
continue;
+4
View File
@@ -3377,6 +3377,10 @@ FBXConverter::KeyFrameListList FBXConverter::GetRotationKeyframeList(const std::
Keys->push_back(tnew);
Values->push_back(vnew);
}
else {
// Something broke
break;
}
tp = tnew;
vp = vnew;
}
+1 -1
View File
@@ -874,7 +874,7 @@ void IRRImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
// Batch loader used to load external models
BatchLoader batch(pIOHandler);
// batch.SetBasePath(pFile);
//batch.SetBasePath(pFile);
cameras.reserve(5);
lights.reserve(5);
+1 -2
View File
@@ -287,7 +287,7 @@ void LWOImporter::InternReadFile(const std::string &pFile,
if (UINT_MAX == iDefaultSurface) {
pSorted.erase(pSorted.end() - 1);
}
for (unsigned int p = 0, j = 0; j < mSurfaces->size(); ++j) {
for (unsigned int j = 0; j < mSurfaces->size(); ++j) {
SortedRep &sorted = pSorted[j];
if (sorted.empty())
continue;
@@ -425,7 +425,6 @@ void LWOImporter::InternReadFile(const std::string &pFile,
} else {
ASSIMP_LOG_VERBOSE_DEBUG("LWO2: No need to compute normals, they're already there");
}
++p;
}
}
+3
View File
@@ -313,6 +313,9 @@ void LWSImporter::SetupNodeName(aiNode *nd, LWS::NodeDesc &src) {
std::string::size_type t = src.path.substr(s).find_last_of('.');
nd->mName.length = ::ai_snprintf(nd->mName.data, MAXLEN, "%s_(%08X)", src.path.substr(s).substr(0, t).c_str(), combined);
if (nd->mName.length > MAXLEN) {
nd->mName.length = MAXLEN;
}
return;
}
}
+3
View File
@@ -449,6 +449,9 @@ void MDLImporter::ParseSkinLump_3DGS_MDL7(
unsigned int iWidth,
unsigned int iHeight) {
std::unique_ptr<aiTexture> pcNew;
if (szCurrent == nullptr) {
return;
}
// get the type of the skin
unsigned int iMasked = (unsigned int)(iType & 0xF);
+3 -1
View File
@@ -136,7 +136,9 @@ void NDOImporter::InternReadFile( const std::string& pFile,
ASSIMP_LOG_INFO("NDO file format is 1.2");
}
else {
ASSIMP_LOG_WARN( "Unrecognized nendo file format version, continuing happily ... :", (head+6));
char buff[4] = {0};
memcpy(buff, head+6, 3);
ASSIMP_LOG_WARN( "Unrecognized nendo file format version, continuing happily ... :", buff);
}
reader.IncPtr(2); /* skip flags */
+32 -16
View File
@@ -126,17 +126,21 @@ void ObjFileMtlImporter::load() {
if (*m_DataIt == 'a') // Ambient color
{
++m_DataIt;
getColorRGBA(&m_pModel->m_pCurrentMaterial->ambient);
if (m_pModel->m_pCurrentMaterial != nullptr)
getColorRGBA(&m_pModel->m_pCurrentMaterial->ambient);
} else if (*m_DataIt == 'd') {
// Diffuse color
++m_DataIt;
getColorRGBA(&m_pModel->m_pCurrentMaterial->diffuse);
if (m_pModel->m_pCurrentMaterial != nullptr)
getColorRGBA(&m_pModel->m_pCurrentMaterial->diffuse);
} else if (*m_DataIt == 's') {
++m_DataIt;
getColorRGBA(&m_pModel->m_pCurrentMaterial->specular);
if (m_pModel->m_pCurrentMaterial != nullptr)
getColorRGBA(&m_pModel->m_pCurrentMaterial->specular);
} else if (*m_DataIt == 'e') {
++m_DataIt;
getColorRGBA(&m_pModel->m_pCurrentMaterial->emissive);
if (m_pModel->m_pCurrentMaterial != nullptr)
getColorRGBA(&m_pModel->m_pCurrentMaterial->emissive);
}
m_DataIt = skipLine<DataArrayIt>(m_DataIt, m_DataItEnd, m_uiLine);
} break;
@@ -145,13 +149,15 @@ void ObjFileMtlImporter::load() {
// Material transmission color
if (*m_DataIt == 'f') {
++m_DataIt;
getColorRGBA(&m_pModel->m_pCurrentMaterial->transparent);
if (m_pModel->m_pCurrentMaterial != nullptr)
getColorRGBA(&m_pModel->m_pCurrentMaterial->transparent);
} else if (*m_DataIt == 'r') {
// Material transmission alpha value
++m_DataIt;
ai_real d;
getFloatValue(d);
m_pModel->m_pCurrentMaterial->alpha = static_cast<ai_real>(1.0) - d;
if (m_pModel->m_pCurrentMaterial != nullptr)
m_pModel->m_pCurrentMaterial->alpha = static_cast<ai_real>(1.0) - d;
}
m_DataIt = skipLine<DataArrayIt>(m_DataIt, m_DataItEnd, m_uiLine);
} break;
@@ -162,7 +168,8 @@ void ObjFileMtlImporter::load() {
} else {
// Alpha value
++m_DataIt;
getFloatValue(m_pModel->m_pCurrentMaterial->alpha);
if (m_pModel->m_pCurrentMaterial != nullptr)
getFloatValue(m_pModel->m_pCurrentMaterial->alpha);
m_DataIt = skipLine<DataArrayIt>(m_DataIt, m_DataItEnd, m_uiLine);
}
} break;
@@ -173,11 +180,13 @@ void ObjFileMtlImporter::load() {
switch (*m_DataIt) {
case 's': // Specular exponent
++m_DataIt;
getFloatValue(m_pModel->m_pCurrentMaterial->shineness);
if (m_pModel->m_pCurrentMaterial != nullptr)
getFloatValue(m_pModel->m_pCurrentMaterial->shineness);
break;
case 'i': // Index Of refraction
++m_DataIt;
getFloatValue(m_pModel->m_pCurrentMaterial->ior);
if (m_pModel->m_pCurrentMaterial != nullptr)
getFloatValue(m_pModel->m_pCurrentMaterial->ior);
break;
case 'e': // New material
createMaterial();
@@ -197,23 +206,28 @@ void ObjFileMtlImporter::load() {
{
case 'r':
++m_DataIt;
getFloatValue(m_pModel->m_pCurrentMaterial->roughness);
if (m_pModel->m_pCurrentMaterial != nullptr)
getFloatValue(m_pModel->m_pCurrentMaterial->roughness);
break;
case 'm':
++m_DataIt;
getFloatValue(m_pModel->m_pCurrentMaterial->metallic);
if (m_pModel->m_pCurrentMaterial != nullptr)
getFloatValue(m_pModel->m_pCurrentMaterial->metallic);
break;
case 's':
++m_DataIt;
getColorRGBA(m_pModel->m_pCurrentMaterial->sheen);
if (m_pModel->m_pCurrentMaterial != nullptr)
getColorRGBA(m_pModel->m_pCurrentMaterial->sheen);
break;
case 'c':
++m_DataIt;
if (*m_DataIt == 'r') {
++m_DataIt;
getFloatValue(m_pModel->m_pCurrentMaterial->clearcoat_roughness);
if (m_pModel->m_pCurrentMaterial != nullptr)
getFloatValue(m_pModel->m_pCurrentMaterial->clearcoat_roughness);
} else {
getFloatValue(m_pModel->m_pCurrentMaterial->clearcoat_thickness);
if (m_pModel->m_pCurrentMaterial != nullptr)
getFloatValue(m_pModel->m_pCurrentMaterial->clearcoat_thickness);
}
break;
}
@@ -232,7 +246,8 @@ void ObjFileMtlImporter::load() {
case 'i': // Illumination model
{
m_DataIt = getNextToken<DataArrayIt>(m_DataIt, m_DataItEnd);
getIlluminationModel(m_pModel->m_pCurrentMaterial->illumination_model);
if (m_pModel->m_pCurrentMaterial != nullptr)
getIlluminationModel(m_pModel->m_pCurrentMaterial->illumination_model);
m_DataIt = skipLine<DataArrayIt>(m_DataIt, m_DataItEnd, m_uiLine);
} break;
@@ -240,7 +255,8 @@ void ObjFileMtlImporter::load() {
{
++m_DataIt;
getFloatValue(m_pModel->m_pCurrentMaterial->anisotropy);
m_DataIt = skipLine<DataArrayIt>(m_DataIt, m_DataItEnd, m_uiLine);
if (m_pModel->m_pCurrentMaterial != nullptr)
m_DataIt = skipLine<DataArrayIt>(m_DataIt, m_DataItEnd, m_uiLine);
} break;
default: {
+2 -1
View File
@@ -458,7 +458,8 @@ void ObjFileParser::getFace(aiPrimitiveType type) {
iPos = 0;
} else {
//OBJ USES 1 Base ARRAYS!!!!
const int iVal(::atoi(&(*m_DataIt)));
std::string number(&(*m_DataIt), m_DataItEnd - m_DataIt);
const int iVal(::atoi(number.c_str()));
// increment iStep position based off of the sign and # of digits
int tmp = iVal;
+21 -29
View File
@@ -151,45 +151,46 @@ namespace Grammar {
}
static TokenType matchTokenType(const char *tokenType) {
if (MetricType == tokenType) {
const size_t len = std::strlen(tokenType);
if (0 == strncmp(MetricType, tokenType, len)) {
return MetricToken;
} else if (NameType == tokenType) {
} else if (0 == strncmp(NameType, tokenType, len)) {
return NameToken;
} else if (ObjectRefType == tokenType) {
} else if (0 == strncmp(ObjectRefType, tokenType, len)) {
return ObjectRefToken;
} else if (MaterialRefType == tokenType) {
} else if (0 == strncmp(MaterialRefType, tokenType, len)) {
return MaterialRefToken;
} else if (MetricKeyType == tokenType) {
} else if (0 == strncmp(MetricKeyType, tokenType, len)) {
return MetricKeyToken;
} else if (GeometryNodeType == tokenType) {
} else if (0 == strncmp(GeometryNodeType, tokenType, len)) {
return GeometryNodeToken;
} else if (CameraNodeType == tokenType) {
} else if (0 == strncmp(CameraNodeType, tokenType, len)) {
return CameraNodeToken;
} else if (LightNodeType == tokenType) {
} else if (0 == strncmp(LightNodeType, tokenType, len)) {
return LightNodeToken;
} else if (GeometryObjectType == tokenType) {
} else if (0 == strncmp(GeometryObjectType, tokenType, len)) {
return GeometryObjectToken;
} else if (CameraObjectType == tokenType) {
} else if (0 == strncmp(CameraObjectType, tokenType, len)) {
return CameraObjectToken;
} else if (LightObjectType == tokenType) {
} else if (0 == strncmp(LightObjectType, tokenType, len)) {
return LightObjectToken;
} else if (TransformType == tokenType) {
} else if (0 == strncmp(TransformType, tokenType, len)) {
return TransformToken;
} else if (MeshType == tokenType) {
} else if (0 == strncmp(MeshType, tokenType, len)) {
return MeshToken;
} else if (VertexArrayType == tokenType) {
} else if (0 == strncmp(VertexArrayType, tokenType, len)) {
return VertexArrayToken;
} else if (IndexArrayType == tokenType) {
} else if (0 == strncmp(IndexArrayType, tokenType, len)) {
return IndexArrayToken;
} else if (MaterialType == tokenType) {
} else if (0 == strncmp(MaterialType, tokenType, len)) {
return MaterialToken;
} else if (ColorType == tokenType) {
} else if (0 == strncmp(ColorType, tokenType, len)) {
return ColorToken;
} else if (ParamType == tokenType) {
} else if (0 == strncmp(ParamType, tokenType, len)) {
return ParamToken;
} else if (TextureType == tokenType) {
} else if (0 == strncmp(TextureType, tokenType, len)) {
return TextureToken;
} else if (AttenType == tokenType) {
} else if (0 == strncmp(AttenType, tokenType, len)) {
return AttenToken;
}
@@ -256,11 +257,6 @@ OpenGEXImporter::RefInfo::RefInfo(aiNode *node, Type type, std::vector<std::stri
// empty
}
//------------------------------------------------------------------------------------------------
OpenGEXImporter::RefInfo::~RefInfo() {
// empty
}
//------------------------------------------------------------------------------------------------
OpenGEXImporter::OpenGEXImporter() :
m_root(nullptr),
@@ -285,10 +281,6 @@ OpenGEXImporter::OpenGEXImporter() :
// empty
}
//------------------------------------------------------------------------------------------------
OpenGEXImporter::~OpenGEXImporter() {
}
//------------------------------------------------------------------------------------------------
bool OpenGEXImporter::CanRead(const std::string &file, IOSystem *pIOHandler, bool /*checkSig*/) const {
static const char *tokens[] = { "Metric", "GeometryNode", "VertexArray (attrib", "IndexArray" };
+3 -8
View File
@@ -79,12 +79,7 @@ struct MetricInfo {
float m_floatValue;
int m_intValue;
MetricInfo()
: m_stringValue( )
, m_floatValue( 0.0f )
, m_intValue( -1 ) {
// empty
}
MetricInfo(): m_stringValue( ), m_floatValue( 0.0f ), m_intValue( -1 ) {}
};
/** @brief This class is used to implement the OpenGEX importer
@@ -97,7 +92,7 @@ public:
OpenGEXImporter();
/// The class destructor.
~OpenGEXImporter() override;
~OpenGEXImporter() override = default;
/// BaseImporter override.
bool CanRead( const std::string &file, IOSystem *pIOHandler, bool checkSig ) const override;
@@ -170,7 +165,7 @@ private:
std::vector<std::string> m_Names;
RefInfo( aiNode *node, Type type, std::vector<std::string> &names );
~RefInfo();
~RefInfo() = default;
RefInfo( const RefInfo & ) = delete;
RefInfo &operator = ( const RefInfo & ) = delete;
+12 -2
View File
@@ -129,10 +129,20 @@ void Q3DImporter::InternReadFile(const std::string &pFile,
unsigned int numTextures = (unsigned int)stream.GetI4();
std::vector<Material> materials;
materials.reserve(numMats);
try {
materials.reserve(numMats);
} catch(const std::bad_alloc&) {
ASSIMP_LOG_ERROR("Invalid alloc for materials.");
throw DeadlyImportError("Invalid Quick3D-file, material allocation failed.");
}
std::vector<Mesh> meshes;
meshes.reserve(numMeshes);
try {
meshes.reserve(numMeshes);
} catch(const std::bad_alloc&) {
ASSIMP_LOG_ERROR("Invalid alloc for meshes.");
throw DeadlyImportError("Invalid Quick3D-file, mesh allocation failed.");
}
// Allocate the scene root node
pScene->mRootNode = new aiNode();
+19 -19
View File
@@ -73,7 +73,7 @@ static const aiImporterDesc desc = {
// 1) 80 byte header
// 2) 4 byte face count
// 3) 50 bytes per face
static bool IsBinarySTL(const char *buffer, unsigned int fileSize) {
static bool IsBinarySTL(const char *buffer, size_t fileSize) {
if (fileSize < 84) {
return false;
}
@@ -92,7 +92,7 @@ static const char UnicodeBoundary = 127;
// An ascii STL buffer will begin with "solid NAME", where NAME is optional.
// Note: The "solid NAME" check is necessary, but not sufficient, to determine
// if the buffer is ASCII; a binary header could also begin with "solid NAME".
static bool IsAsciiSTL(const char *buffer, unsigned int fileSize) {
static bool IsAsciiSTL(const char *buffer, size_t fileSize) {
if (IsBinarySTL(buffer, fileSize))
return false;
@@ -172,7 +172,7 @@ void STLImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
throw DeadlyImportError("Failed to open STL file ", pFile, ".");
}
mFileSize = (unsigned int)file->FileSize();
mFileSize = file->FileSize();
// allocate storage and copy the contents of the file to a memory buffer
// (terminate it with zero)
@@ -233,7 +233,7 @@ void STLImporter::LoadASCIIFile(aiNode *root) {
// try to guess how many vertices we could have
// assume we'll need 160 bytes for each face
size_t sizeEstimate = std::max(1u, mFileSize / 160u) * 3;
size_t sizeEstimate = std::max(1ull, mFileSize / 160ull) * 3ull;
positionBuffer.reserve(sizeEstimate);
normalBuffer.reserve(sizeEstimate);
@@ -284,8 +284,6 @@ void STLImporter::LoadASCIIFile(aiNode *root) {
ASSIMP_LOG_WARN("STL: A new facet begins but the old is not yet complete");
}
faceVertexCounter = 0;
normalBuffer.push_back(aiVector3D());
aiVector3D *vn = &normalBuffer.back();
sz += 6;
SkipSpaces(&sz);
@@ -295,15 +293,17 @@ void STLImporter::LoadASCIIFile(aiNode *root) {
if (sz[6] == '\0') {
throw DeadlyImportError("STL: unexpected EOF while parsing facet");
}
aiVector3D vn;
sz += 7;
SkipSpaces(&sz);
sz = fast_atoreal_move<ai_real>(sz, (ai_real &)vn->x);
sz = fast_atoreal_move<ai_real>(sz, (ai_real &)vn.x);
SkipSpaces(&sz);
sz = fast_atoreal_move<ai_real>(sz, (ai_real &)vn->y);
sz = fast_atoreal_move<ai_real>(sz, (ai_real &)vn.y);
SkipSpaces(&sz);
sz = fast_atoreal_move<ai_real>(sz, (ai_real &)vn->z);
normalBuffer.push_back(*vn);
normalBuffer.push_back(*vn);
sz = fast_atoreal_move<ai_real>(sz, (ai_real &)vn.z);
normalBuffer.emplace_back(vn);
normalBuffer.emplace_back(vn);
normalBuffer.emplace_back(vn);
}
} else if (!strncmp(sz, "vertex", 6) && ::IsSpaceOrNewLine(*(sz + 6))) { // vertex 1.50000 1.50000 0.00000
if (faceVertexCounter >= 3) {
@@ -315,7 +315,7 @@ void STLImporter::LoadASCIIFile(aiNode *root) {
}
sz += 7;
SkipSpaces(&sz);
positionBuffer.push_back(aiVector3D());
positionBuffer.emplace_back();
aiVector3D *vn = &positionBuffer.back();
sz = fast_atoreal_move<ai_real>(sz, (ai_real &)vn->x);
SkipSpaces(&sz);
@@ -439,7 +439,7 @@ bool STLImporter::LoadBinaryFile() {
pMesh->mNumFaces = *((uint32_t *)sz);
sz += 4;
if (mFileSize < 84 + pMesh->mNumFaces * 50) {
if (mFileSize < 84ull + pMesh->mNumFaces * 50ull) {
throw DeadlyImportError("STL: file is too small to hold all facets");
}
@@ -517,13 +517,13 @@ bool STLImporter::LoadBinaryFile() {
const ai_real invVal((ai_real)1.0 / (ai_real)31.0);
if (bIsMaterialise) // this is reversed
{
clr->r = (color & 0x31u) * invVal;
clr->g = ((color & (0x31u << 5)) >> 5u) * invVal;
clr->b = ((color & (0x31u << 10)) >> 10u) * invVal;
clr->r = (color & 0x1fu) * invVal;
clr->g = ((color & (0x1fu << 5)) >> 5u) * invVal;
clr->b = ((color & (0x1fu << 10)) >> 10u) * invVal;
} else {
clr->b = (color & 0x31u) * invVal;
clr->g = ((color & (0x31u << 5)) >> 5u) * invVal;
clr->r = ((color & (0x31u << 10)) >> 10u) * invVal;
clr->b = (color & 0x1fu) * invVal;
clr->g = ((color & (0x1fu << 5)) >> 5u) * invVal;
clr->r = ((color & (0x1fu << 10)) >> 10u) * invVal;
}
// assign the color to all vertices of the face
*(clr + 1) = *clr;
+1 -1
View File
@@ -109,7 +109,7 @@ protected:
const char* mBuffer;
/** Size of the file, in bytes */
unsigned int mFileSize;
size_t mFileSize;
/** Output scene */
aiScene* mScene;
+46 -94
View File
@@ -2,8 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2020, assimp team
Copyright (c) 2006-2022, assimp team
All rights reserved.
@@ -59,7 +58,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# pragma warning(disable : 4127 4456 4245 4512 )
#endif // _MSC_VER
//
#if _MSC_VER > 1500 || (defined __GNUC___)
# define ASSIMP_STEP_USE_UNORDERED_MULTIMAP
#else
@@ -99,13 +97,9 @@ namespace EXPRESS {
class DataType;
class UNSET; /*: public DataType */
class ISDERIVED; /*: public DataType */
// class REAL; /*: public DataType */
class ENUM; /*: public DataType */
// class STRING; /*: public DataType */
// class INTEGER; /*: public DataType */
class ENTITY; /*: public DataType */
class LIST; /*: public DataType */
// class SELECT; /*: public DataType */
// a conversion schema is not exactly an EXPRESS schema, rather it
// is a list of pointers to conversion functions to build up the
@@ -127,7 +121,8 @@ namespace STEP {
// -------------------------------------------------------------------------------
/** Exception class used by the STEP loading & parsing code. It is typically
* coupled with a line number. */
* coupled with a line number.
*/
// -------------------------------------------------------------------------------
struct SyntaxError : DeadlyImportError {
enum : uint64_t {
@@ -139,8 +134,9 @@ struct SyntaxError : DeadlyImportError {
// -------------------------------------------------------------------------------
/** Exception class used by the STEP loading & parsing code when a type
* error (i.e. an entity expects a string but receives a bool) occurs.
* It is typically coupled with both an entity id and a line number.*/
* error (i.e. an entity expects a string but receives a bool) occurs.
* It is typically coupled with both an entity id and a line number.
*/
// -------------------------------------------------------------------------------
struct TypeError : DeadlyImportError {
enum : uint64_t {
@@ -167,10 +163,8 @@ public:
typedef std::shared_ptr<const DataType> Out;
public:
virtual ~DataType() {
}
virtual ~DataType() = default;
public:
template <typename T>
const T &To() const {
return dynamic_cast<const T &>(*this);
@@ -206,16 +200,14 @@ public:
public:
/** parse a variable from a string and set 'inout' to the character
* behind the last consumed character. An optional schema enables,
* if specified, automatic conversion of custom data types.
*
* @throw SyntaxError
*/
* behind the last consumed character. An optional schema enables,
* if specified, automatic conversion of custom data types.
*
* @throw SyntaxError
*/
static std::shared_ptr<const EXPRESS::DataType> Parse(const char *&inout,
uint64_t line = SyntaxError::LINE_NOT_SPECIFIED,
const EXPRESS::ConversionSchema *schema = NULL);
public:
};
typedef DataType SELECT;
@@ -238,7 +230,8 @@ private:
};
// -------------------------------------------------------------------------------
/** Shared implementation for some of the primitive data type, i.e. int, float */
/** Shared implementation for some of the primitive data type, i.e. int, float
*/
// -------------------------------------------------------------------------------
template <typename T>
class PrimitiveDataType : public DataType {
@@ -247,7 +240,7 @@ public:
// expose this data type to the user.
typedef T Out;
PrimitiveDataType() {}
PrimitiveDataType() = default;
PrimitiveDataType(const T &val) :
val(val) {}
@@ -280,28 +273,18 @@ class ENUMERATION : public STRING {
public:
ENUMERATION(const std::string &val) :
STRING(val) {}
private:
};
typedef ENUMERATION BOOLEAN;
// -------------------------------------------------------------------------------
/** This is just a reference to an entity/object somewhere else */
/** This is just a reference to an entity/object somewhere else
*/
// -------------------------------------------------------------------------------
class ENTITY : public PrimitiveDataType<uint64_t> {
public:
ENTITY(uint64_t val) :
PrimitiveDataType<uint64_t>(val) {
ai_assert(val != 0);
}
ENTITY() :
PrimitiveDataType<uint64_t>(TypeError::ENTITY_NOT_SPECIFIED) {
// empty
}
private:
ENTITY(uint64_t val) : PrimitiveDataType<uint64_t>(val) {}
ENTITY() : PrimitiveDataType<uint64_t>(TypeError::ENTITY_NOT_SPECIFIED) {}
};
// -------------------------------------------------------------------------------
@@ -319,7 +302,8 @@ public:
}
public:
/** @see DaraType::Parse */
/** @see DaraType::Parse
*/
static std::shared_ptr<const EXPRESS::LIST> Parse(const char *&inout,
uint64_t line = SyntaxError::LINE_NOT_SPECIFIED,
const EXPRESS::ConversionSchema *schema = NULL);
@@ -331,29 +315,20 @@ private:
class BINARY : public PrimitiveDataType<uint32_t> {
public:
BINARY(uint32_t val) :
PrimitiveDataType<uint32_t>(val) {
// empty
}
BINARY() :
PrimitiveDataType<uint32_t>(TypeError::ENTITY_NOT_SPECIFIED_32) {
// empty
}
BINARY(uint32_t val) : PrimitiveDataType<uint32_t>(val) {}
BINARY() : PrimitiveDataType<uint32_t>(TypeError::ENTITY_NOT_SPECIFIED_32) {}
};
// -------------------------------------------------------------------------------
/* Not exactly a full EXPRESS schema but rather a list of conversion functions
* to extract valid C++ objects out of a STEP file. Those conversion functions
* may, however, perform further schema validations. */
* to extract valid C++ objects out of a STEP file. Those conversion functions
* may, however, perform further schema validations.
*/
// -------------------------------------------------------------------------------
class ConversionSchema {
public:
struct SchemaEntry {
SchemaEntry(const char *name, ConvertObjectProc func) :
mName(name), mFunc(func) {
// empty
}
SchemaEntry(const char *name, ConvertObjectProc func) : mName(name), mFunc(func) {}
const char *mName;
ConvertObjectProc mFunc;
@@ -366,8 +341,7 @@ public:
*this = schemas;
}
ConversionSchema() {
}
ConversionSchema() = default;
ConvertObjectProc GetConverterProc(const std::string &name) const {
ConverterMap::const_iterator it = converters.find(name);
@@ -399,8 +373,9 @@ private:
// ------------------------------------------------------------------------------
/** Bundle all the relevant info from a STEP header, parts of which may later
* be plainly dumped to the logfile, whereas others may help the caller pick an
* appropriate loading strategy.*/
* be plainly dumped to the logfile, whereas others may help the caller pick an
* appropriate loading strategy.
*/
// ------------------------------------------------------------------------------
struct HeaderInfo {
std::string timestamp;
@@ -409,18 +384,14 @@ struct HeaderInfo {
};
// ------------------------------------------------------------------------------
/** Base class for all concrete object instances */
/** Base class for all concrete object instances
*/
// ------------------------------------------------------------------------------
class Object {
public:
Object(const char *classname = "unknown") :
id(0), classname(classname) {
// empty
}
Object(const char *classname = "unknown") : id(0), classname(classname) {}
virtual ~Object() {
// empty
}
virtual ~Object() = default;
// utilities to simplify casting to concrete types
template <typename T>
@@ -469,26 +440,15 @@ size_t GenericFill(const STEP::DB &db, const EXPRESS::LIST &params, T *in);
// ------------------------------------------------------------------------------
template <typename TDerived, size_t arg_count>
struct ObjectHelper : virtual Object {
ObjectHelper() :
aux_is_derived(0) {
// empty
}
ObjectHelper() : aux_is_derived(0) {}
static Object *Construct(const STEP::DB &db, const EXPRESS::LIST &params) {
// make sure we don't leak if Fill() throws an exception
std::unique_ptr<TDerived> impl(new TDerived());
// GenericFill<T> is undefined so we need to have a specialization
const size_t num_args = GenericFill<TDerived>(db, params, &*impl);
(void)num_args;
static_cast<void>(GenericFill<TDerived>(db, params, &*impl));
// the following check is commented because it will always trigger if
// parts of the entities are generated with dummy wrapper code.
// This is currently done to reduce the size of the loader
// code.
//if (num_args != params.GetSize() && impl->GetClassName() != "NotImplemented") {
// DefaultLogger::get()->debug("STEP: not all parameters consumed");
//}
return impl.release();
}
@@ -502,15 +462,9 @@ struct ObjectHelper : virtual Object {
// ------------------------------------------------------------------------------
template <typename T>
struct Maybe {
Maybe() :
have() {
// empty
}
Maybe() : have() {}
explicit Maybe(const T &ptr) :
ptr(ptr), have(true) {
// empty
}
explicit Maybe(const T &ptr) : ptr(ptr), have(true) {}
void flag_invalid() {
have = false;
@@ -557,7 +511,8 @@ private:
// ------------------------------------------------------------------------------
/** A LazyObject is created when needed. Before this happens, we just keep
the text line that contains the object definition. */
* the text line that contains the object definition.
*/
// -------------------------------------------------------------------------------
class LazyObject {
friend class DB;
@@ -649,10 +604,7 @@ inline bool operator==(const std::pair<uint64_t, std::shared_ptr<LazyObject>> &l
template <typename T>
struct Lazy {
typedef Lazy Out;
Lazy(const LazyObject *obj = nullptr) :
obj(obj) {
// empty
}
Lazy(const LazyObject *obj = nullptr) : obj(obj) {}
operator const T *() const {
return obj->ToPtr<T>();
@@ -785,8 +737,9 @@ inline void GenericConvert(ListOf<T1, N1, N2> &a, const std::shared_ptr<const EX
// ------------------------------------------------------------------------------
/** Lightweight manager class that holds the map of all objects in a
* STEP file. DB's are exclusively maintained by the functions in
* STEPFileReader.h*/
* STEP file. DB's are exclusively maintained by the functions in
* STEPFileReader.h
*/
// -------------------------------------------------------------------------------
class DB {
friend DB *ReadFileHeader(std::shared_ptr<IOStream> stream);
@@ -873,7 +826,7 @@ public:
if (it != objects_bytype.end() && (*it).second.size()) {
return *(*it).second.begin();
}
return NULL;
return nullptr;
}
// same, but raise an exception if the object doesn't exist and return a reference
@@ -965,7 +918,6 @@ private:
#endif // _MSC_VER
} // namespace STEP
} // namespace Assimp
#endif // INCLUDED_AI_STEPFILE_H
+1 -1
View File
@@ -683,7 +683,7 @@ bool glTF2Exporter::GetMatSheen(const aiMaterial &mat, glTF2::MaterialSheen &she
}
// Default Sheen color factor {0,0,0} disables Sheen, so do not export
if (sheen.sheenColorFactor == defaultSheenFactor) {
if (sheen.sheenColorFactor[0] == defaultSheenFactor[0] && sheen.sheenColorFactor[1] == defaultSheenFactor[1] && sheen.sheenColorFactor[2] == defaultSheenFactor[2]) {
return false;
}
+10 -3
View File
@@ -63,7 +63,7 @@ inline int select_fseek(FILE *file, int64_t offset, int origin) {
#if defined _WIN64 && (!defined __GNUC__ || __MSVCRT_VERSION__ >= 0x0601)
#if defined _WIN32 && (!defined __GNUC__ || !defined __CLANG__ && __MSVCRT_VERSION__ >= 0x0601)
template <>
inline size_t select_ftell<8>(FILE *file) {
return (size_t)::_ftelli64(file);
@@ -74,7 +74,7 @@ inline int select_fseek<8>(FILE *file, int64_t offset, int origin) {
return ::_fseeki64(file, offset, origin);
}
#endif // #if defined _WIN32 && (!defined __GNUC__ || __MSVCRT_VERSION__ >= 0x0601)
#endif
} // namespace
@@ -149,13 +149,20 @@ size_t DefaultIOStream::FileSize() const {
//
// See here for details:
// https://www.securecoding.cert.org/confluence/display/seccode/FIO19-C.+Do+not+use+fseek()+and+ftell()+to+compute+the+size+of+a+regular+file
#if defined _WIN64 && (!defined __GNUC__ || __MSVCRT_VERSION__ >= 0x0601)
#if defined _WIN32 && (!defined __GNUC__ || !defined __CLANG__ && __MSVCRT_VERSION__ >= 0x0601)
struct __stat64 fileStat;
//using fileno + fstat avoids having to handle the filename
int err = _fstat64(_fileno(mFile), &fileStat);
if (0 != err)
return 0;
mCachedSize = (size_t)(fileStat.st_size);
#elif defined _WIN32
struct _stat32 fileStat;
//using fileno + fstat avoids having to handle the filename
int err = _fstat32(_fileno(mFile), &fileStat);
if (0 != err)
return 0;
mCachedSize = (size_t)(fileStat.st_size);
#elif defined __GNUC__ || defined __APPLE__ || defined __MACH__ || defined __FreeBSD__
struct stat fileStat;
int err = stat(mFilename.c_str(), &fileStat);
+30 -27
View File
@@ -105,36 +105,39 @@ void ScenePreprocessor::ProcessMesh(aiMesh *mesh) {
for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++i) {
if (!mesh->mTextureCoords[i]) {
mesh->mNumUVComponents[i] = 0;
} else {
if (!mesh->mNumUVComponents[i]) {
mesh->mNumUVComponents[i] = 2;
continue;
}
if (!mesh->mNumUVComponents[i]) {
mesh->mNumUVComponents[i] = 2;
}
aiVector3D *p = mesh->mTextureCoords[i], *end = p + mesh->mNumVertices;
// Ensure unused components are zeroed. This will make 1D texture channels work
// as if they were 2D channels .. just in case an application doesn't handle
// this case
if (2 == mesh->mNumUVComponents[i]) {
size_t num = 0;
for (; p != end; ++p) {
p->z = 0.f;
num++;
}
aiVector3D *p = mesh->mTextureCoords[i], *end = p + mesh->mNumVertices;
// Ensure unused components are zeroed. This will make 1D texture channels work
// as if they were 2D channels .. just in case an application doesn't handle
// this case
if (2 == mesh->mNumUVComponents[i]) {
for (; p != end; ++p) {
p->z = 0.f;
}
} else if (1 == mesh->mNumUVComponents[i]) {
for (; p != end; ++p) {
p->z = p->y = 0.f;
}
} else if (3 == mesh->mNumUVComponents[i]) {
// Really 3D coordinates? Check whether the third coordinate is != 0 for at least one element
for (; p != end; ++p) {
if (p->z != 0) {
break;
}
}
if (p == end) {
ASSIMP_LOG_WARN("ScenePreprocessor: UVs are declared to be 3D but they're obviously not. Reverting to 2D.");
mesh->mNumUVComponents[i] = 2;
} else if (1 == mesh->mNumUVComponents[i]) {
for (; p != end; ++p) {
p->z = p->y = 0.f;
}
} else if (3 == mesh->mNumUVComponents[i]) {
// Really 3D coordinates? Check whether the third coordinate is != 0 for at least one element
for (; p != end; ++p) {
if (p->z != 0) {
break;
}
}
if (p == end) {
ASSIMP_LOG_WARN("ScenePreprocessor: UVs are declared to be 3D but they're obviously not. Reverting to 2D.");
mesh->mNumUVComponents[i] = 2;
}
}
}
+2
View File
@@ -196,7 +196,9 @@ zlib_filefunc_def IOSystem2Unzip::get(IOSystem *pIOHandler) {
zlib_filefunc_def mapping;
mapping.zopen_file = (open_file_func)open;
#ifdef _UNZ_H
mapping.zopendisk_file = (opendisk_file_func)opendisk;
#endif
mapping.zread_file = (read_file_func)read;
mapping.zwrite_file = (write_file_func)write;
mapping.ztell_file = (tell_file_func)tell;
+1 -1
View File
@@ -128,7 +128,7 @@ bool EmbedTexturesProcess::addTexture(aiScene *pScene, const std::string &path)
aiTexel* imageContent = new aiTexel[ 1ul + static_cast<unsigned long>( imageSize ) / sizeof(aiTexel)];
pFile->Seek(0, aiOrigin_SET);
pFile->Read(reinterpret_cast<char*>(imageContent), imageSize, 1);
pFile->Read(reinterpret_cast<char*>(imageContent), static_cast<size_t>(imageSize), 1);
mIOHandler->Close(pFile);
// Enlarging the textures table
+4
View File
@@ -1,5 +1,9 @@
#include "revision.h"
#ifdef __GNUC__
#include "winresrc.h"
#else
#include "winres.h"
#endif
LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
#pragma code_page(1252)