Merge branch 'kimkulling/link_stb_image_statically_issue_4467' of https://github.com/assimp/assimp into kimkulling/link_stb_image_statically_issue_4467

This commit is contained in:
Kim Kulling
2022-05-31 20:08:39 +02:00
203 changed files with 9629 additions and 38677 deletions

View File

@@ -106,7 +106,7 @@ bool getNodeAttribute(const XmlNode &node, const std::string &attribute, int &va
return false;
}
aiMatrix4x4 parseTransformMatrix(std::string matrixStr) {
aiMatrix4x4 parseTransformMatrix(const std::string& matrixStr) {
// split the string
std::vector<float> numbers;
std::string currentNumber;

View File

@@ -646,10 +646,13 @@ void Parser::ParseLV2MaterialBlock(ASE::Material &mat) {
}
// get a reference to the material
Material &sMat = mat.avSubMaterials[iIndex];
if (iIndex < mat.avSubMaterials.size()) {
Material &sMat = mat.avSubMaterials[iIndex];
// parse the material block
ParseLV2MaterialBlock(sMat);
}
// parse the material block
ParseLV2MaterialBlock(sMat);
continue;
}
}

View File

@@ -365,7 +365,7 @@ static void WriteDump(const char *pFile, const char *cmd, const aiScene *scene,
ioprintf(io, "\t\t\t<MatProperty key=\"%s\" \n\t\t\ttype=\"%s\" tex_usage=\"%s\" tex_index=\"%u\"",
prop->mKey.data, sz,
::TextureTypeToString((aiTextureType)prop->mSemantic), prop->mIndex);
::aiTextureTypeToString((aiTextureType)prop->mSemantic), prop->mIndex);
if (prop->mType == aiPTI_Float) {
ioprintf(io, " size=\"%i\">\n\t\t\t\t",

View File

@@ -281,7 +281,7 @@ void BlenderImporter::ExtractScene(Scene &out, const FileDatabase &file) {
}
// ------------------------------------------------------------------------------------------------
void BlenderImporter::ParseSubCollection(const Blender::Scene &in, aiNode *root, std::shared_ptr<Collection> collection, ConversionData &conv_data) {
void BlenderImporter::ParseSubCollection(const Blender::Scene &in, aiNode *root, const std::shared_ptr<Collection>& collection, ConversionData &conv_data) {
std::deque<Object *> root_objects;
// Count number of objects

View File

@@ -117,7 +117,7 @@ protected:
void InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler) override;
void ParseBlendFile(Blender::FileDatabase &out, std::shared_ptr<IOStream> stream);
void ExtractScene(Blender::Scene &out, const Blender::FileDatabase &file);
void ParseSubCollection(const Blender::Scene &in, aiNode *root, std::shared_ptr<Blender::Collection> collection, Blender::ConversionData &conv_data);
void ParseSubCollection(const Blender::Scene &in, aiNode *root, const std::shared_ptr<Blender::Collection>& collection, Blender::ConversionData &conv_data);
void ConvertBlendFile(aiScene *out, const Blender::Scene &in, const Blender::FileDatabase &file);
private:

View File

@@ -232,7 +232,6 @@ void FBXConverter::ConvertNodes(uint64_t id, aiNode *parent, aiNode *root_node)
nodes_chain.clear();
post_nodes_chain.clear();
aiMatrix4x4 new_abs_transform = parent->mTransformation;
std::string node_name = FixNodeName(model->Name());
// even though there is only a single input node, the design of
// assimp (or rather: the complicated transformation chain that
@@ -266,12 +265,10 @@ void FBXConverter::ConvertNodes(uint64_t id, aiNode *parent, aiNode *root_node)
child->mParent = last_parent;
last_parent = child.mNode;
new_abs_transform *= child->mTransformation;
}
// attach geometry
ConvertModel(*model, nodes_chain.back().mNode, root_node, new_abs_transform);
ConvertModel(*model, nodes_chain.back().mNode, root_node);
// check if there will be any child nodes
const std::vector<const Connection *> &child_conns = doc.GetConnectionsByDestinationSequenced(model->ID(), "Model");
@@ -290,8 +287,6 @@ void FBXConverter::ConvertNodes(uint64_t id, aiNode *parent, aiNode *root_node)
postnode->mParent = last_parent;
last_parent = postnode.mNode;
new_abs_transform *= postnode->mTransformation;
}
} else {
// free the nodes we allocated as we don't need them
@@ -899,8 +894,7 @@ void FBXConverter::SetupNodeMetadata(const Model &model, aiNode &nd) {
}
}
void FBXConverter::ConvertModel(const Model &model, aiNode *parent, aiNode *root_node,
const aiMatrix4x4 &absolute_transform) {
void FBXConverter::ConvertModel(const Model &model, aiNode *parent, aiNode *root_node) {
const std::vector<const Geometry *> &geos = model.GetGeometry();
std::vector<unsigned int> meshes;
@@ -911,8 +905,7 @@ void FBXConverter::ConvertModel(const Model &model, aiNode *parent, aiNode *root
const MeshGeometry *const mesh = dynamic_cast<const MeshGeometry *>(geo);
const LineGeometry *const line = dynamic_cast<const LineGeometry *>(geo);
if (mesh) {
const std::vector<unsigned int> &indices = ConvertMesh(*mesh, model, parent, root_node,
absolute_transform);
const std::vector<unsigned int> &indices = ConvertMesh(*mesh, model, parent, root_node);
std::copy(indices.begin(), indices.end(), std::back_inserter(meshes));
} else if (line) {
const std::vector<unsigned int> &indices = ConvertLine(*line, root_node);
@@ -933,8 +926,7 @@ void FBXConverter::ConvertModel(const Model &model, aiNode *parent, aiNode *root
}
std::vector<unsigned int>
FBXConverter::ConvertMesh(const MeshGeometry &mesh, const Model &model, aiNode *parent, aiNode *root_node,
const aiMatrix4x4 &absolute_transform) {
FBXConverter::ConvertMesh(const MeshGeometry &mesh, const Model &model, aiNode *parent, aiNode *root_node) {
std::vector<unsigned int> temp;
MeshMap::const_iterator it = meshes_converted.find(&mesh);
@@ -957,13 +949,13 @@ FBXConverter::ConvertMesh(const MeshGeometry &mesh, const Model &model, aiNode *
const MatIndexArray::value_type base = mindices[0];
for (MatIndexArray::value_type index : mindices) {
if (index != base) {
return ConvertMeshMultiMaterial(mesh, model, parent, root_node, absolute_transform);
return ConvertMeshMultiMaterial(mesh, model, parent, root_node);
}
}
}
// faster code-path, just copy the data
temp.push_back(ConvertMeshSingleMaterial(mesh, model, absolute_transform, parent, root_node));
temp.push_back(ConvertMeshSingleMaterial(mesh, model, parent, root_node));
return temp;
}
@@ -1032,8 +1024,7 @@ aiMesh *FBXConverter::SetupEmptyMesh(const Geometry &mesh, aiNode *parent) {
}
unsigned int FBXConverter::ConvertMeshSingleMaterial(const MeshGeometry &mesh, const Model &model,
const aiMatrix4x4 &absolute_transform, aiNode *parent,
aiNode *) {
aiNode *parent, aiNode *) {
const MatIndexArray &mindices = mesh.GetMaterialIndices();
aiMesh *const out_mesh = SetupEmptyMesh(mesh, parent);
@@ -1152,7 +1143,7 @@ unsigned int FBXConverter::ConvertMeshSingleMaterial(const MeshGeometry &mesh, c
}
if (doc.Settings().readWeights && mesh.DeformerSkin() != nullptr) {
ConvertWeights(out_mesh, mesh, absolute_transform, parent, NO_MATERIAL_SEPARATION, nullptr);
ConvertWeights(out_mesh, mesh, parent, NO_MATERIAL_SEPARATION, nullptr);
}
std::vector<aiAnimMesh *> animMeshes;
@@ -1200,8 +1191,7 @@ unsigned int FBXConverter::ConvertMeshSingleMaterial(const MeshGeometry &mesh, c
std::vector<unsigned int>
FBXConverter::ConvertMeshMultiMaterial(const MeshGeometry &mesh, const Model &model, aiNode *parent,
aiNode *root_node,
const aiMatrix4x4 &absolute_transform) {
aiNode *root_node) {
const MatIndexArray &mindices = mesh.GetMaterialIndices();
ai_assert(mindices.size());
@@ -1211,7 +1201,7 @@ FBXConverter::ConvertMeshMultiMaterial(const MeshGeometry &mesh, const Model &mo
for (MatIndexArray::value_type index : mindices) {
if (had.find(index) == had.end()) {
indices.push_back(ConvertMeshMultiMaterial(mesh, model, index, parent, root_node, absolute_transform));
indices.push_back(ConvertMeshMultiMaterial(mesh, model, index, parent, root_node));
had.insert(index);
}
}
@@ -1221,8 +1211,7 @@ FBXConverter::ConvertMeshMultiMaterial(const MeshGeometry &mesh, const Model &mo
unsigned int FBXConverter::ConvertMeshMultiMaterial(const MeshGeometry &mesh, const Model &model,
MatIndexArray::value_type index,
aiNode *parent, aiNode *,
const aiMatrix4x4 &absolute_transform) {
aiNode *parent, aiNode *) {
aiMesh *const out_mesh = SetupEmptyMesh(mesh, parent);
const MatIndexArray &mindices = mesh.GetMaterialIndices();
@@ -1385,7 +1374,7 @@ unsigned int FBXConverter::ConvertMeshMultiMaterial(const MeshGeometry &mesh, co
ConvertMaterialForMesh(out_mesh, model, mesh, index);
if (process_weights) {
ConvertWeights(out_mesh, mesh, absolute_transform, parent, index, &reverseMapping);
ConvertWeights(out_mesh, mesh, parent, index, &reverseMapping);
}
std::vector<aiAnimMesh *> animMeshes;
@@ -1436,7 +1425,6 @@ unsigned int FBXConverter::ConvertMeshMultiMaterial(const MeshGeometry &mesh, co
}
void FBXConverter::ConvertWeights(aiMesh *out, const MeshGeometry &geo,
const aiMatrix4x4 &absolute_transform,
aiNode *parent, unsigned int materialIndex,
std::vector<unsigned int> *outputVertStartIndices) {
ai_assert(geo.DeformerSkin());
@@ -1508,7 +1496,7 @@ void FBXConverter::ConvertWeights(aiMesh *out, const MeshGeometry &geo,
// XXX this could be heavily simplified by collecting the bone
// data in a single step.
ConvertCluster(bones, cluster, out_indices, index_out_indices,
count_out_indices, absolute_transform, parent);
count_out_indices, parent);
}
bone_map.clear();
@@ -1537,8 +1525,7 @@ const aiNode *GetNodeByName(aiNode *current_node) {
void FBXConverter::ConvertCluster(std::vector<aiBone *> &local_mesh_bones, const Cluster *cl,
std::vector<size_t> &out_indices, std::vector<size_t> &index_out_indices,
std::vector<size_t> &count_out_indices, const aiMatrix4x4 &absolute_transform,
aiNode *) {
std::vector<size_t> &count_out_indices, aiNode *) {
ai_assert(cl); // make sure cluster valid
std::string deformer_name = cl->TargetNode()->Name();
aiString bone_name = aiString(FixNodeName(deformer_name));
@@ -1553,14 +1540,16 @@ void FBXConverter::ConvertCluster(std::vector<aiBone *> &local_mesh_bones, const
bone = new aiBone();
bone->mName = bone_name;
bone->mOffsetMatrix = cl->Transform();
// store local transform link for post processing
/*
bone->mOffsetMatrix = cl->TransformLink();
bone->mOffsetMatrix.Inverse();
aiMatrix4x4 matrix = (aiMatrix4x4)absolute_transform;
bone->mOffsetMatrix = bone->mOffsetMatrix * matrix; // * mesh_offset
*/
//
// Now calculate the aiVertexWeights
//

View File

@@ -180,14 +180,12 @@ private:
void SetupNodeMetadata(const Model& model, aiNode& nd);
// ------------------------------------------------------------------------------------------------
void ConvertModel(const Model &model, aiNode *parent, aiNode *root_node,
const aiMatrix4x4 &absolute_transform);
void ConvertModel(const Model &model, aiNode *parent, aiNode *root_node);
// ------------------------------------------------------------------------------------------------
// MeshGeometry -> aiMesh, return mesh index + 1 or 0 if the conversion failed
std::vector<unsigned int>
ConvertMesh(const MeshGeometry &mesh, const Model &model, aiNode *parent, aiNode *root_node,
const aiMatrix4x4 &absolute_transform);
ConvertMesh(const MeshGeometry &mesh, const Model &model, aiNode *parent, aiNode *root_node);
// ------------------------------------------------------------------------------------------------
std::vector<unsigned int> ConvertLine(const LineGeometry& line, aiNode *root_node);
@@ -197,17 +195,15 @@ private:
// ------------------------------------------------------------------------------------------------
unsigned int ConvertMeshSingleMaterial(const MeshGeometry &mesh, const Model &model,
const aiMatrix4x4 &absolute_transform, aiNode *parent,
aiNode *root_node);
aiNode *parent, aiNode *root_node);
// ------------------------------------------------------------------------------------------------
std::vector<unsigned int>
ConvertMeshMultiMaterial(const MeshGeometry &mesh, const Model &model, aiNode *parent, aiNode *root_node,
const aiMatrix4x4 &absolute_transform);
ConvertMeshMultiMaterial(const MeshGeometry &mesh, const Model &model, aiNode *parent, aiNode *root_node);
// ------------------------------------------------------------------------------------------------
unsigned int ConvertMeshMultiMaterial(const MeshGeometry &mesh, const Model &model, MatIndexArray::value_type index,
aiNode *parent, aiNode *root_node, const aiMatrix4x4 &absolute_transform);
aiNode *parent, aiNode *root_node);
// ------------------------------------------------------------------------------------------------
static const unsigned int NO_MATERIAL_SEPARATION = /* std::numeric_limits<unsigned int>::max() */
@@ -220,15 +216,14 @@ private:
* - outputVertStartIndices is only used when a material index is specified, it gives for
* each output vertex the DOM index it maps to.
*/
void ConvertWeights(aiMesh *out, const MeshGeometry &geo, const aiMatrix4x4 &absolute_transform,
aiNode *parent = nullptr, unsigned int materialIndex = NO_MATERIAL_SEPARATION,
void ConvertWeights(aiMesh *out, const MeshGeometry &geo, 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,
std::vector<size_t> &out_indices, std::vector<size_t> &index_out_indices,
std::vector<size_t> &count_out_indices, const aiMatrix4x4 &absolute_transform,
aiNode *parent );
std::vector<size_t> &count_out_indices, aiNode *parent );
// ------------------------------------------------------------------------------------------------
void ConvertMaterialForMesh(aiMesh* out, const Model& model, const MeshGeometry& geo,

View File

@@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2022, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
@@ -51,7 +50,6 @@ namespace Assimp {
namespace IFC {
namespace {
// --------------------------------------------------------------------------------
// Conic is the base class for Circle and Ellipse
// --------------------------------------------------------------------------------
@@ -546,8 +544,10 @@ IfcFloat RecursiveSearch(const Curve* cv, const IfcVector3& val, IfcFloat a, Ifc
}
}
#ifndef __INTEL_LLVM_COMPILER
ai_assert( min_diff[ 0 ] != inf );
ai_assert( min_diff[ 1 ] != inf );
#endif // __INTEL_LLVM_COMPILER
if ( std::fabs(a-min_point[0]) < threshold || recurse >= max_recurse) {
return min_point[0];
}
@@ -606,8 +606,10 @@ bool BoundedCurve::IsClosed() const {
// ------------------------------------------------------------------------------------------------
void BoundedCurve::SampleDiscrete(TempMesh& out) const {
const ParamRange& range = GetParametricRange();
#ifndef __INTEL_LLVM_COMPILER
ai_assert( range.first != std::numeric_limits<IfcFloat>::infinity() );
ai_assert( range.second != std::numeric_limits<IfcFloat>::infinity() );
#endif // __INTEL_LLVM_COMPILER
return SampleDiscrete(out,range.first,range.second);
}

View File

@@ -1428,7 +1428,7 @@ bool GenerateOpenings(std::vector<TempOpening>& openings,
return true;
}
std::vector<IfcVector2> GetContourInPlane2D(std::shared_ptr<TempMesh> mesh,IfcMatrix3 planeSpace,
std::vector<IfcVector2> GetContourInPlane2D(const std::shared_ptr<TempMesh>& mesh,IfcMatrix3 planeSpace,
IfcVector3 planeNor,IfcFloat planeOffset,
IfcVector3 extrusionDir,IfcVector3& wall_extrusion,bool& first,bool& ok) {
std::vector<IfcVector2> contour;
@@ -1491,7 +1491,7 @@ static void logSegment(std::pair<IfcVector2,IfcVector2> segment) {
IFCImporter::LogInfo(msg2.str().c_str());
}
std::vector<std::vector<IfcVector2>> GetContoursInPlane3D(std::shared_ptr<TempMesh> mesh,IfcMatrix3 planeSpace,
std::vector<std::vector<IfcVector2>> GetContoursInPlane3D(const std::shared_ptr<TempMesh>& mesh,IfcMatrix3 planeSpace,
IfcFloat planeOffset) {
{
@@ -1676,7 +1676,7 @@ std::vector<std::vector<IfcVector2>> GetContoursInPlane3D(std::shared_ptr<TempMe
std::stringstream msg;
msg << "GetContoursInPlane3D: found " << contours.size() << " contours:\n";
for(auto c : contours) {
for(const auto& c : contours) {
msg << " Contour: \n";
for(auto p : c) {
msg << " " << p.x << " " << p.y << " \n";
@@ -1690,7 +1690,7 @@ std::vector<std::vector<IfcVector2>> GetContoursInPlane3D(std::shared_ptr<TempMe
return contours;
}
std::vector<std::vector<IfcVector2>> GetContoursInPlane(std::shared_ptr<TempMesh> mesh,IfcMatrix3 planeSpace,
std::vector<std::vector<IfcVector2>> GetContoursInPlane(const std::shared_ptr<TempMesh>& mesh,IfcMatrix3 planeSpace,
IfcVector3 planeNor,IfcFloat planeOffset,
IfcVector3 extrusionDir,IfcVector3& wall_extrusion,bool& first) {

View File

@@ -57,12 +57,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Assimp specific M3D configuration. Comment out these defines to remove functionality
//#define ASSIMP_USE_M3D_READFILECB
// Share stb_image's PNG loader with other importers/exporters instead of bringing our own copy.
#define STBI_ONLY_PNG
#if ASSIMP_NEEDS_STB_IMAGE
#include "Common/StbCommon.h"
#endif
#include "m3d.h"

View File

@@ -52,9 +52,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/scene.h>
#include <assimp/Importer.hpp>
#include <fstream>
#include <iomanip>
#include <memory>
#include <sstream>
static const aiImporterDesc desc = { "MMD Importer",
"",
@@ -102,26 +103,32 @@ const aiImporterDesc *MMDImporter::GetInfo() const {
// ------------------------------------------------------------------------------------------------
// MMD import implementation
void MMDImporter::InternReadFile(const std::string &file, aiScene *pScene,
IOSystem * /*pIOHandler*/) {
// Read file by istream
std::filebuf fb;
if (!fb.open(file, std::ios::in | std::ios::binary)) {
IOSystem* pIOHandler) {
auto streamCloser = [&](IOStream *pStream) {
pIOHandler->Close(pStream);
};
static const std::string mode = "rb";
const std::unique_ptr<IOStream, decltype(streamCloser)> fileStream(pIOHandler->Open(file, mode), streamCloser);
if (fileStream == nullptr) {
throw DeadlyImportError("Failed to open file ", file, ".");
}
std::istream fileStream(&fb);
// Get the file-size and validate it, throwing an exception when fails
fileStream.seekg(0, fileStream.end);
size_t fileSize = static_cast<size_t>(fileStream.tellg());
fileStream.seekg(0, fileStream.beg);
if (fileSize < sizeof(pmx::PmxModel)) {
const size_t fileSize = fileStream->FileSize();
if (fileSize < sizeof(pmx::PmxModel))
{
throw DeadlyImportError(file, " is too small.");
}
std::vector<char> contents(fileStream->FileSize());
fileStream->Read(contents.data(), 1, contents.size());
std::istringstream iss(std::string(contents.begin(), contents.end()));
pmx::PmxModel model;
model.Read(&fileStream);
model.Read(&iss);
CreateDataFromImport(&model, pScene);
}

View File

@@ -47,6 +47,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/types.h>
#include <map>
#include <vector>
#include "Common/Maybe.h"
namespace Assimp {
namespace ObjFile {
@@ -183,15 +184,15 @@ struct Material {
aiColor3D transparent;
//! PBR Roughness
ai_real roughness;
Maybe<ai_real> roughness;
//! PBR Metallic
ai_real metallic;
Maybe<ai_real> metallic;
//! PBR Metallic
aiColor3D sheen;
Maybe<aiColor3D> sheen;
//! PBR Clearcoat Thickness
ai_real clearcoat_thickness;
Maybe<ai_real> clearcoat_thickness;
//! PBR Clearcoat Rougness
ai_real clearcoat_roughness;
Maybe<ai_real> clearcoat_roughness;
//! PBR Anisotropy
ai_real anisotropy;
@@ -206,11 +207,11 @@ struct Material {
illumination_model(1),
ior(ai_real(1.0)),
transparent(ai_real(1.0), ai_real(1.0), ai_real(1.0)),
roughness(ai_real(1.0)),
metallic(ai_real(0.0)),
sheen(ai_real(1.0), ai_real(1.0), ai_real(1.0)),
clearcoat_thickness(ai_real(0.0)),
clearcoat_roughness(ai_real(0.0)),
roughness(),
metallic(),
sheen(),
clearcoat_thickness(),
clearcoat_roughness(),
anisotropy(ai_real(0.0)),
bump_multiplier(ai_real(1.0)) {
std::fill_n(clamp, static_cast<unsigned int>(TextureTypeCount), false);

View File

@@ -616,11 +616,16 @@ void ObjFileImporter::createMaterials(const ObjFile::Model *pModel, aiScene *pSc
mat->AddProperty(&pCurrentMaterial->shineness, 1, AI_MATKEY_SHININESS);
mat->AddProperty(&pCurrentMaterial->alpha, 1, AI_MATKEY_OPACITY);
mat->AddProperty(&pCurrentMaterial->transparent, 1, AI_MATKEY_COLOR_TRANSPARENT);
mat->AddProperty(&pCurrentMaterial->roughness, 1, AI_MATKEY_ROUGHNESS_FACTOR);
mat->AddProperty(&pCurrentMaterial->metallic, 1, AI_MATKEY_METALLIC_FACTOR);
mat->AddProperty(&pCurrentMaterial->sheen, 1, AI_MATKEY_SHEEN_COLOR_FACTOR);
mat->AddProperty(&pCurrentMaterial->clearcoat_thickness, 1, AI_MATKEY_CLEARCOAT_FACTOR);
mat->AddProperty(&pCurrentMaterial->clearcoat_roughness, 1, AI_MATKEY_CLEARCOAT_ROUGHNESS_FACTOR);
if (pCurrentMaterial->roughness)
mat->AddProperty(&pCurrentMaterial->roughness.Get(), 1, AI_MATKEY_ROUGHNESS_FACTOR);
if (pCurrentMaterial->metallic)
mat->AddProperty(&pCurrentMaterial->metallic.Get(), 1, AI_MATKEY_METALLIC_FACTOR);
if (pCurrentMaterial->sheen)
mat->AddProperty(&pCurrentMaterial->sheen.Get(), 1, AI_MATKEY_SHEEN_COLOR_FACTOR);
if (pCurrentMaterial->clearcoat_thickness)
mat->AddProperty(&pCurrentMaterial->clearcoat_thickness.Get(), 1, AI_MATKEY_CLEARCOAT_FACTOR);
if (pCurrentMaterial->clearcoat_roughness)
mat->AddProperty(&pCurrentMaterial->clearcoat_roughness.Get(), 1, AI_MATKEY_CLEARCOAT_ROUGHNESS_FACTOR);
mat->AddProperty(&pCurrentMaterial->anisotropy, 1, AI_MATKEY_ANISOTROPY_FACTOR);
// Adding refraction index

View File

@@ -205,7 +205,7 @@ void ObjFileMtlImporter::load() {
break;
case 's':
++m_DataIt;
getColorRGBA(&m_pModel->m_pCurrentMaterial->sheen);
getColorRGBA(m_pModel->m_pCurrentMaterial->sheen);
break;
case 'c':
++m_DataIt;
@@ -268,6 +268,12 @@ void ObjFileMtlImporter::getColorRGBA(aiColor3D *pColor) {
pColor->b = b;
}
void ObjFileMtlImporter::getColorRGBA(Maybe<aiColor3D> &value) {
aiColor3D v;
getColorRGBA(&v);
value = Maybe<aiColor3D>(v);
}
// -------------------------------------------------------------------
// Loads the kind of illumination model.
void ObjFileMtlImporter::getIlluminationModel(int &illum_model) {
@@ -275,6 +281,7 @@ void ObjFileMtlImporter::getIlluminationModel(int &illum_model) {
illum_model = atoi(&m_buffer[0]);
}
// -------------------------------------------------------------------
// Loads a single float value.
void ObjFileMtlImporter::getFloatValue(ai_real &value) {
@@ -284,10 +291,19 @@ void ObjFileMtlImporter::getFloatValue(ai_real &value) {
value = 0.0f;
return;
}
value = (ai_real)fast_atof(&m_buffer[0]);
}
void ObjFileMtlImporter::getFloatValue(Maybe<ai_real> &value) {
m_DataIt = CopyNextWord<DataArrayIt>(m_DataIt, m_DataItEnd, &m_buffer[0], BUFFERSIZE);
size_t len = std::strlen(&m_buffer[0]);
if (len)
value = Maybe<ai_real>(fast_atof(&m_buffer[0]));
else
value = Maybe<ai_real>();
}
// -------------------------------------------------------------------
// Creates a material from loaded data.
void ObjFileMtlImporter::createMaterial() {

View File

@@ -43,6 +43,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/defs.h>
#include <string>
#include <vector>
#include "Common/Maybe.h"
struct aiColor3D;
struct aiString;
@@ -81,10 +82,12 @@ private:
void load();
/// Get color data.
void getColorRGBA(aiColor3D *pColor);
void getColorRGBA(Maybe<aiColor3D> &value);
/// Get illumination model from loaded data
void getIlluminationModel(int &illum_model);
/// Gets a float value from data.
void getFloatValue(ai_real &value);
void getFloatValue(Maybe<ai_real> &value);
/// Creates a new material from loaded data.
void createMaterial();
/// Get texture name from loaded data.

View File

@@ -248,6 +248,7 @@ void OgreXmlSerializer::ReadMesh(MeshXml *mesh) {
} else if (currentName == nnBoneAssignments) {
ReadBoneAssignments(currentNode, mesh->sharedVertexData);
} else if (currentName == nnSkeletonLink) {
mesh->skeletonRef = currentNode.attribute("name").as_string();
}
}
@@ -488,6 +489,15 @@ bool OgreXmlSerializer::ImportSkeleton(Assimp::IOSystem *pIOHandler, MeshXml *me
Skeleton *skeleton = new Skeleton();
OgreXmlSerializer serializer(xmlParser.get());
XmlNode root = xmlParser->getRootNode();
if (std::string(root.name()) != nnSkeleton) {
printf("\nSkeleton is not a valid root: %s\n", root.name());
for (auto &a : root.children()) {
if (std::string(a.name()) == nnSkeleton) {
root = a;
break;
}
}
}
serializer.ReadSkeleton(root, skeleton);
mesh->skeleton = skeleton;
return true;
@@ -537,7 +547,7 @@ XmlParserPtr OgreXmlSerializer::OpenXmlParser(Assimp::IOSystem *pIOHandler, cons
}
void OgreXmlSerializer::ReadSkeleton(XmlNode &node, Skeleton *skeleton) {
if (node.name() != nnSkeleton) {
if (std::string(node.name()) != nnSkeleton) {
throw DeadlyImportError("Root node is <" + std::string(node.name()) + "> expecting <skeleton>");
}
@@ -574,14 +584,14 @@ void OgreXmlSerializer::ReadAnimations(XmlNode &node, Skeleton *skeleton) {
anim->name = ReadAttribute<std::string>(currentNode, "name");
anim->length = ReadAttribute<float>(currentNode, "length");
for (XmlNode &currentChildNode : currentNode.children()) {
const std::string currentChildName = currentNode.name();
const std::string currentChildName = currentChildNode.name();
if (currentChildName == nnTracks) {
ReadAnimationTracks(currentChildNode, anim);
skeleton->animations.push_back(anim);
} else {
throw DeadlyImportError("No <tracks> found in <animation> ", anim->name);
}
}
skeleton->animations.push_back(anim);
}
}
}
@@ -594,14 +604,14 @@ void OgreXmlSerializer::ReadAnimationTracks(XmlNode &node, Animation *dest) {
track.type = VertexAnimationTrack::VAT_TRANSFORM;
track.boneName = ReadAttribute<std::string>(currentNode, "bone");
for (XmlNode &currentChildNode : currentNode.children()) {
const std::string currentChildName = currentNode.name();
const std::string currentChildName = currentChildNode.name();
if (currentChildName == nnKeyFrames) {
ReadAnimationKeyFrames(currentChildNode, dest, &track);
dest->tracks.push_back(track);
} else {
throw DeadlyImportError("No <keyframes> found in <track> ", dest->name);
}
}
dest->tracks.push_back(track);
}
}
}
@@ -614,15 +624,15 @@ void OgreXmlSerializer::ReadAnimationKeyFrames(XmlNode &node, Animation *anim, V
if (currentName == nnKeyFrame) {
keyframe.timePos = ReadAttribute<float>(currentNode, "time");
for (XmlNode &currentChildNode : currentNode.children()) {
const std::string currentChildName = currentNode.name();
const std::string currentChildName = currentChildNode.name();
if (currentChildName == nnTranslate) {
keyframe.position.x = ReadAttribute<float>(currentChildNode, anX);
keyframe.position.y = ReadAttribute<float>(currentChildNode, anY);
keyframe.position.z = ReadAttribute<float>(currentChildNode, anZ);
} else if (currentChildName == nnRotate) {
float angle = ReadAttribute<float>(currentChildNode, "angle");
for (XmlNode &currentChildChildNode : currentNode.children()) {
const std::string currentChildChildName = currentNode.name();
for (XmlNode &currentChildChildNode : currentChildNode.children()) {
const std::string currentChildChildName = currentChildChildNode.name();
if (currentChildChildName == nnAxis) {
aiVector3D axis;
axis.x = ReadAttribute<float>(currentChildChildNode, anX);
@@ -695,12 +705,12 @@ void OgreXmlSerializer::ReadBones(XmlNode &node, Skeleton *skeleton) {
bone->id = ReadAttribute<uint16_t>(currentNode, "id");
bone->name = ReadAttribute<std::string>(currentNode, "name");
for (XmlNode &currentChildNode : currentNode.children()) {
const std::string currentChildName = currentNode.name();
if (currentChildName == nnRotation) {
const std::string currentChildName = currentChildNode.name();
if (currentChildName == nnPosition) {
bone->position.x = ReadAttribute<float>(currentChildNode, anX);
bone->position.y = ReadAttribute<float>(currentChildNode, anY);
bone->position.z = ReadAttribute<float>(currentChildNode, anZ);
} else if (currentChildName == nnScale) {
} else if (currentChildName == nnRotation) {
float angle = ReadAttribute<float>(currentChildNode, "angle");
for (XmlNode currentChildChildNode : currentChildNode.children()) {
const std::string &currentChildChildName = currentChildChildNode.name();

View File

@@ -333,7 +333,7 @@ void X3DImporter::readHead(XmlNode &node) {
}
mScene->mMetaData = aiMetadata::Alloc(static_cast<unsigned int>(metaArray.size()));
unsigned int i = 0;
for (auto currentMeta : metaArray) {
for (const auto& currentMeta : metaArray) {
mScene->mMetaData->Set(i, currentMeta.name, aiString(currentMeta.value));
++i;
}

View File

@@ -284,7 +284,7 @@ static aiMaterial *ImportMaterial(std::vector<int> &embeddedTexIdxs, Asset &r, M
aimat->AddProperty(&alphaMode, AI_MATKEY_GLTF_ALPHAMODE);
aimat->AddProperty(&mat.alphaCutoff, 1, AI_MATKEY_GLTF_ALPHACUTOFF);
//pbrSpecularGlossiness
// pbrSpecularGlossiness
if (mat.pbrSpecularGlossiness.isPresent) {
PbrSpecularGlossiness &pbrSG = mat.pbrSpecularGlossiness.value;
@@ -606,7 +606,10 @@ void glTF2Importer::ImportMeshes(glTF2::Asset &r) {
}
}
if (needTangents) {
if (target.tangent[0]->count != aim->mNumVertices) {
if (!aiAnimMesh.HasNormals()) {
// prevent nullptr access to aiAnimMesh.mNormals below when no normals are available
ASSIMP_LOG_WARN("Bitangents of target ", i, " in mesh \"", mesh.name, "\" can't be computed, because mesh has no normals.");
} else if (target.tangent[0]->count != aim->mNumVertices) {
ASSIMP_LOG_WARN("Tangents of target ", i, " in mesh \"", mesh.name, "\" does not match the vertex count");
} else {
Tangent *tangent = nullptr;
@@ -698,12 +701,12 @@ void glTF2Importer::ImportMeshes(glTF2::Asset &r) {
nFaces = count - 2;
facePtr = faces = new aiFace[nFaces];
for (unsigned int i = 0; i < nFaces; ++i) {
//The ordering is to ensure that the triangles are all drawn with the same orientation
// The ordering is to ensure that the triangles are all drawn with the same orientation
if ((i + 1) % 2 == 0) {
//For even n, vertices n + 1, n, and n + 2 define triangle n
// For even n, vertices n + 1, n, and n + 2 define triangle n
SetFaceAndAdvance3(facePtr, aim->mNumVertices, data.GetUInt(i + 1), data.GetUInt(i), data.GetUInt(i + 2));
} else {
//For odd n, vertices n, n+1, and n+2 define triangle n
// For odd n, vertices n, n+1, and n+2 define triangle n
SetFaceAndAdvance3(facePtr, aim->mNumVertices, data.GetUInt(i), data.GetUInt(i + 1), data.GetUInt(i + 2));
}
}
@@ -776,12 +779,12 @@ void glTF2Importer::ImportMeshes(glTF2::Asset &r) {
nFaces = count - 2;
facePtr = faces = new aiFace[nFaces];
for (unsigned int i = 0; i < nFaces; ++i) {
//The ordering is to ensure that the triangles are all drawn with the same orientation
// The ordering is to ensure that the triangles are all drawn with the same orientation
if ((i + 1) % 2 == 0) {
//For even n, vertices n + 1, n, and n + 2 define triangle n
// For even n, vertices n + 1, n, and n + 2 define triangle n
SetFaceAndAdvance3(facePtr, aim->mNumVertices, i + 1, i, i + 2);
} else {
//For odd n, vertices n, n+1, and n+2 define triangle n
// For odd n, vertices n, n+1, and n+2 define triangle n
SetFaceAndAdvance3(facePtr, aim->mNumVertices, i, i + 1, i + 2);
}
}
@@ -904,14 +907,14 @@ void glTF2Importer::ImportLights(glTF2::Asset &r) {
ail->mAttenuationLinear = 0.0;
ail->mAttenuationQuadratic = 0.0;
} else {
//in PBR attenuation is calculated using inverse square law which can be expressed
//using assimps equation: 1/(att0 + att1 * d + att2 * d*d) with the following parameters
//this is correct equation for the case when range (see
//https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_lights_punctual)
//is not present. When range is not present it is assumed that it is infinite and so numerator is 1.
//When range is present then numerator might be any value in range [0,1] and then assimps equation
//will not suffice. In this case range is added into metadata in ImportNode function
//and its up to implementation to read it when it wants to
// in PBR attenuation is calculated using inverse square law which can be expressed
// using assimps equation: 1/(att0 + att1 * d + att2 * d*d) with the following parameters
// this is correct equation for the case when range (see
// https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_lights_punctual)
// is not present. When range is not present it is assumed that it is infinite and so numerator is 1.
// When range is present then numerator might be any value in range [0,1] and then assimps equation
// will not suffice. In this case range is added into metadata in ImportNode function
// and its up to implementation to read it when it wants to
ail->mAttenuationConstant = 0.0;
ail->mAttenuationLinear = 0.0;
ail->mAttenuationQuadratic = 1.0;
@@ -1161,8 +1164,8 @@ aiNode *ImportNode(aiScene *pScene, glTF2::Asset &r, std::vector<unsigned int> &
if (node.light) {
pScene->mLights[node.light.GetIndex()]->mName = ainode->mName;
//range is optional - see https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_lights_punctual
//it is added to meta data of parent node, because there is no other place to put it
// range is optional - see https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_lights_punctual
// it is added to meta data of parent node, because there is no other place to put it
if (node.light->range.isPresent) {
if (!ainode->mMetaData) {
ainode->mMetaData = aiMetadata::Alloc(1);
@@ -1556,9 +1559,9 @@ void glTF2Importer::ImportEmbeddedTextures(glTF2::Asset &r) {
if (ext) {
if (strcmp(ext, "jpeg") == 0) {
ext = "jpg";
} else if (strcmp(ext, "ktx2") == 0) { //basisu: ktx remains
} else if (strcmp(ext, "ktx2") == 0) { // basisu: ktx remains
ext = "kx2";
} else if (strcmp(ext, "basis") == 0) { //basisu
} else if (strcmp(ext, "basis") == 0) { // basisu
ext = "bu";
}

View File

@@ -150,7 +150,7 @@ SET( Core_SRCS
Common/Assimp.cpp
)
IF(MSVC)
IF(MSVC OR (MINGW AND BUILD_SHARED_LIBS))
list(APPEND Core_SRCS "res/assimp.rc")
ENDIF()
@@ -183,6 +183,7 @@ SET( Common_SRCS
Common/DefaultIOSystem.cpp
Common/ZipArchiveIOSystem.cpp
Common/PolyTools.h
Common/Maybe.h
Common/Importer.cpp
Common/IFF.h
Common/SGSpatialSort.cpp
@@ -1054,7 +1055,9 @@ ENDIF()
# Check dependencies for glTF importer with Open3DGC-compression.
# RT-extensions is used in "contrib/Open3DGC/o3dgcTimer.h" for collecting statistics. Pointed file
# has implementation for different platforms: WIN32, __MACH__ and other ("else" block).
FIND_PACKAGE(RT QUIET)
IF (NOT WIN32)
FIND_PACKAGE(RT QUIET)
ENDIF ()
IF (NOT ASSIMP_HUNTER_ENABLED AND (RT_FOUND OR WIN32))
SET( ASSIMP_IMPORTER_GLTF_USE_OPEN3DGC 1 )
ADD_DEFINITIONS( -DASSIMP_IMPORTER_GLTF_USE_OPEN3DGC=1 )
@@ -1177,11 +1180,13 @@ ADD_LIBRARY(assimp::assimp ALIAS assimp)
TARGET_USE_COMMON_OUTPUT_DIRECTORY(assimp)
# enable warnings as errors ########################################
IF (MSVC)
TARGET_COMPILE_OPTIONS(assimp PRIVATE /WX)
ELSE()
TARGET_COMPILE_OPTIONS(assimp PRIVATE -Werror)
IF (ASSIMP_WARNINGS_AS_ERRORS)
MESSAGE(STATUS "Treating all warnings as errors (for assimp library only)")
IF (MSVC)
TARGET_COMPILE_OPTIONS(assimp PRIVATE /W4 /WX)
ELSE()
TARGET_COMPILE_OPTIONS(assimp PRIVATE -Wall -Werror)
ENDIF()
ENDIF()
# adds C_FLAGS required to compile zip.c on old GCC 4.x compiler
@@ -1264,6 +1269,16 @@ if( MSVC )
set(LIBRARY_SUFFIX "${ASSIMP_LIBRARY_SUFFIX}-${MSVC_PREFIX}-mt" CACHE STRING "the suffix for the assimp windows library")
endif()
if (MINGW)
set(LIBRARY_SUFFIX "-${ASSIMP_SOVERSION}" CACHE STRING "the suffix for the assimp MinGW shared library")
SET_TARGET_PROPERTIES( assimp PROPERTIES
ARCHIVE_OUTPUT_NAME assimp
)
if (NOT BUILD_SHARED_LIBS)
TARGET_LINK_LIBRARIES ( assimp -static-libgcc -static-libstdc++ -Wl,-Bstatic -lstdc++ -lwinpthread ) # winpthread is for libminizip.
endif ()
endif()
if (${CMAKE_SYSTEM_NAME} MATCHES "WindowsStore")
target_compile_definitions(assimp PUBLIC WindowsStore)
TARGET_LINK_LIBRARIES(assimp advapi32)
@@ -1275,12 +1290,6 @@ SET_TARGET_PROPERTIES( assimp PROPERTIES
OUTPUT_NAME assimp${LIBRARY_SUFFIX}
)
if (WIN32 AND CMAKE_COMPILER_IS_GNUCXX AND BUILD_SHARED_LIBS)
set_target_properties(assimp PROPERTIES
SUFFIX "-${ASSIMP_SOVERSION}${CMAKE_SHARED_LIBRARY_SUFFIX}"
)
endif()
if (APPLE)
if (ASSIMP_BUILD_FRAMEWORK)
SET_TARGET_PROPERTIES( assimp PROPERTIES

View File

@@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2022, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
@@ -1282,6 +1280,11 @@ ASSIMP_API void aiQuaternionInterpolate(
# define STBI_ONLY_PNG
#endif
// Ensure all symbols are linked correctly
#if ASSIMP_NEEDS_STB_IMAGE
#include "Common/StbCommon.h"
// Share stb_image's PNG loader with other importers/exporters instead of bringing our own copy.
# define STBI_ONLY_PNG
# define STB_IMAGE_STATIC
# define STB_IMAGE_IMPLEMENTATION
# include "Common/StbCommon.h"
#endif

View File

@@ -63,7 +63,7 @@ inline int select_fseek(FILE *file, int64_t offset, int origin) {
#if defined _WIN32 && (!defined __GNUC__ || __MSVCRT_VERSION__ >= 0x0601)
#if defined _WIN64 && (!defined __GNUC__ || __MSVCRT_VERSION__ >= 0x0601)
template <>
inline size_t select_ftell<8>(FILE *file) {
return (size_t)::_ftelli64(file);
@@ -149,7 +149,7 @@ 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 _WIN32 && (!defined __GNUC__ || __MSVCRT_VERSION__ >= 0x0601)
#if defined _WIN64 && (!defined __GNUC__ || __MSVCRT_VERSION__ >= 0x0601)
struct __stat64 fileStat;
//using fileno + fstat avoids having to handle the filename
int err = _fstat64(_fileno(mFile), &fileStat);

29
code/Common/Maybe.h Normal file
View File

@@ -0,0 +1,29 @@
#pragma once
#include <assimp/ai_assert.h>
template <typename T>
struct Maybe {
private:
T _val;
bool _valid;
public:
Maybe() :
_valid(false) {}
explicit Maybe(const T &val) :
_val(val), _valid(true) {
}
operator bool() const {
return _valid;
}
const T &Get() const {
ai_assert(_valid);
return _val;
}
private:
Maybe &operator&() = delete;
};

View File

@@ -48,8 +48,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#pragma GCC diagnostic ignored "-Wunused-function"
#endif
#define STB_IMAGE_STATIC
#define STB_IMAGE_IMPLEMENTATION
#include "stb/stb_image.h"
#if _MSC_VER

View File

@@ -46,7 +46,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/material.h>
// -------------------------------------------------------------------------------
const char *TextureTypeToString(aiTextureType in) {
const char *aiTextureTypeToString(aiTextureType in) {
switch (in) {
case aiTextureType_NONE:
return "n/a";

View File

@@ -83,7 +83,9 @@ Other:
#include <sstream>
#include <string>
#if ASSIMP_NEEDS_STB_IMAGE
#include "Common/StbCommon.h"
#endif
using namespace Assimp;
@@ -590,7 +592,7 @@ void PbrtExporter::WriteMaterial(int m) {
for (int i = 1; i <= aiTextureType_UNKNOWN; i++) {
int count = material->GetTextureCount(aiTextureType(i));
if (count > 0)
mOutput << TextureTypeToString(aiTextureType(i)) << ": " << count << " ";
mOutput << aiTextureTypeToString(aiTextureType(i)) << ": " << count << " ";
}
mOutput << "\n";

View File

@@ -415,7 +415,7 @@ void ComputeUVMappingProcess::Execute( aiScene* pScene)
if (!DefaultLogger::isNullLogger())
{
ai_snprintf(buffer, 1024, "Found non-UV mapped texture (%s,%u). Mapping type: %s",
TextureTypeToString((aiTextureType)prop->mSemantic),prop->mIndex,
aiTextureTypeToString((aiTextureType)prop->mSemantic),prop->mIndex,
MappingTypeToString(mapping));
ASSIMP_LOG_INFO(buffer);

View File

@@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2022, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
@@ -45,41 +43,38 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* for all imported meshes
*/
#ifndef ASSIMP_BUILD_NO_JOINVERTICES_PROCESS
#include "JoinVerticesProcess.h"
#include "ProcessHelper.h"
#include <assimp/Vertex.h>
#include <assimp/TinyFormatter.h>
#include <stdio.h>
#include <unordered_set>
#include <unordered_map>
using namespace Assimp;
// ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer
JoinVerticesProcess::JoinVerticesProcess()
{
JoinVerticesProcess::JoinVerticesProcess() {
// nothing to do here
}
// ------------------------------------------------------------------------------------------------
// Destructor, private as well
JoinVerticesProcess::~JoinVerticesProcess()
{
JoinVerticesProcess::~JoinVerticesProcess() {
// nothing to do here
}
// ------------------------------------------------------------------------------------------------
// Returns whether the processing step is present in the given flag field.
bool JoinVerticesProcess::IsActive( unsigned int pFlags) const
{
bool JoinVerticesProcess::IsActive( unsigned int pFlags) const {
return (pFlags & aiProcess_JoinIdenticalVertices) != 0;
}
// ------------------------------------------------------------------------------------------------
// Executes the post processing step on the given imported data.
void JoinVerticesProcess::Execute( aiScene* pScene)
{
void JoinVerticesProcess::Execute( aiScene* pScene) {
ASSIMP_LOG_DEBUG("JoinVerticesProcess begin");
// get the total number of vertices BEFORE the step is executed
@@ -92,27 +87,29 @@ void JoinVerticesProcess::Execute( aiScene* pScene)
// execute the step
int iNumVertices = 0;
for( unsigned int a = 0; a < pScene->mNumMeshes; a++)
for( unsigned int a = 0; a < pScene->mNumMeshes; a++) {
iNumVertices += ProcessMesh( pScene->mMeshes[a],a);
}
pScene->mFlags |= AI_SCENE_FLAGS_NON_VERBOSE_FORMAT;
// if logging is active, print detailed statistics
if (!DefaultLogger::isNullLogger()) {
if (iNumOldVertices == iNumVertices) {
ASSIMP_LOG_DEBUG("JoinVerticesProcess finished ");
} else {
ASSIMP_LOG_INFO("JoinVerticesProcess finished | Verts in: ", iNumOldVertices,
" out: ", iNumVertices, " | ~",
((iNumOldVertices - iNumVertices) / (float)iNumOldVertices) * 100.f );
return;
}
// Show statistics
ASSIMP_LOG_INFO("JoinVerticesProcess finished | Verts in: ", iNumOldVertices,
" out: ", iNumVertices, " | ~",
((iNumOldVertices - iNumVertices) / (float)iNumOldVertices) * 100.f );
}
pScene->mFlags |= AI_SCENE_FLAGS_NON_VERBOSE_FORMAT;
}
namespace {
bool areVerticesEqual(const Vertex &lhs, const Vertex &rhs, bool complex)
{
bool areVerticesEqual(const Vertex &lhs, const Vertex &rhs, bool complex) {
// A little helper to find locally close vertices faster.
// Try to reuse the lookup table from the last step.
const static float epsilon = 1e-5f;
@@ -171,8 +168,7 @@ void updateXMeshVertices(XMesh *pMesh, std::vector<Vertex> &uniqueVertices) {
// ----------------------------------------------------------------------------
// Position, if present (check made for aiAnimMesh)
if (pMesh->mVertices)
{
if (pMesh->mVertices) {
delete [] pMesh->mVertices;
pMesh->mVertices = new aiVector3D[pMesh->mNumVertices];
for (unsigned int a = 0; a < pMesh->mNumVertices; a++) {
@@ -181,8 +177,7 @@ void updateXMeshVertices(XMesh *pMesh, std::vector<Vertex> &uniqueVertices) {
}
// Normals, if present
if (pMesh->mNormals)
{
if (pMesh->mNormals) {
delete [] pMesh->mNormals;
pMesh->mNormals = new aiVector3D[pMesh->mNumVertices];
for( unsigned int a = 0; a < pMesh->mNumVertices; a++) {
@@ -190,8 +185,7 @@ void updateXMeshVertices(XMesh *pMesh, std::vector<Vertex> &uniqueVertices) {
}
}
// Tangents, if present
if (pMesh->mTangents)
{
if (pMesh->mTangents) {
delete [] pMesh->mTangents;
pMesh->mTangents = new aiVector3D[pMesh->mNumVertices];
for (unsigned int a = 0; a < pMesh->mNumVertices; a++) {
@@ -199,8 +193,7 @@ void updateXMeshVertices(XMesh *pMesh, std::vector<Vertex> &uniqueVertices) {
}
}
// Bitangents as well
if (pMesh->mBitangents)
{
if (pMesh->mBitangents) {
delete [] pMesh->mBitangents;
pMesh->mBitangents = new aiVector3D[pMesh->mNumVertices];
for (unsigned int a = 0; a < pMesh->mNumVertices; a++) {
@@ -208,8 +201,7 @@ void updateXMeshVertices(XMesh *pMesh, std::vector<Vertex> &uniqueVertices) {
}
}
// Vertex colors
for (unsigned int a = 0; pMesh->HasVertexColors(a); a++)
{
for (unsigned int a = 0; pMesh->HasVertexColors(a); a++) {
delete [] pMesh->mColors[a];
pMesh->mColors[a] = new aiColor4D[pMesh->mNumVertices];
for( unsigned int b = 0; b < pMesh->mNumVertices; b++) {
@@ -217,8 +209,7 @@ void updateXMeshVertices(XMesh *pMesh, std::vector<Vertex> &uniqueVertices) {
}
}
// Texture coords
for (unsigned int a = 0; pMesh->HasTextureCoords(a); a++)
{
for (unsigned int a = 0; pMesh->HasTextureCoords(a); a++) {
delete [] pMesh->mTextureCoords[a];
pMesh->mTextureCoords[a] = new aiVector3D[pMesh->mNumVertices];
for (unsigned int b = 0; b < pMesh->mNumVertices; b++) {
@@ -226,12 +217,40 @@ void updateXMeshVertices(XMesh *pMesh, std::vector<Vertex> &uniqueVertices) {
}
}
}
} // namespace
// ------------------------------------------------------------------------------------------------
// Unites identical vertices in the given mesh
int JoinVerticesProcess::ProcessMesh( aiMesh* pMesh, unsigned int meshIndex)
{
// combine hashes
inline void hash_combine(std::size_t &) {
// empty
}
template <typename T, typename... Rest>
inline void hash_combine(std::size_t& seed, const T& v, Rest... rest) {
std::hash<T> hasher;
seed ^= hasher(v) + 0x9e3779b9 + (seed<<6) + (seed>>2);
hash_combine(seed, rest...);
}
//template specialization for std::hash for Vertex
template<>
struct std::hash<Vertex> {
std::size_t operator()(Vertex const& v) const noexcept {
size_t seed = 0;
hash_combine(seed, v.position.x ,v.position.y,v.position.z);
return seed;
}
};
//template specialization for std::equal_to for Vertex
template<>
struct std::equal_to<Vertex> {
bool operator()(const Vertex &lhs, const Vertex &rhs) const {
return areVerticesEqual(lhs, rhs, false);
}
};
// now start the JoinVerticesProcess
int JoinVerticesProcess::ProcessMesh( aiMesh* pMesh, unsigned int meshIndex) {
static_assert( AI_MAX_NUMBER_OF_COLOR_SETS == 8, "AI_MAX_NUMBER_OF_COLOR_SETS == 8");
static_assert( AI_MAX_NUMBER_OF_TEXTURECOORDS == 8, "AI_MAX_NUMBER_OF_TEXTURECOORDS == 8");
@@ -245,8 +264,7 @@ int JoinVerticesProcess::ProcessMesh( aiMesh* pMesh, unsigned int meshIndex)
// multiple meshes)
std::unordered_set<unsigned int> usedVertexIndices;
usedVertexIndices.reserve(pMesh->mNumVertices);
for( unsigned int a = 0; a < pMesh->mNumFaces; a++)
{
for( unsigned int a = 0; a < pMesh->mNumFaces; a++) {
aiFace& face = pMesh->mFaces[a];
for( unsigned int b = 0; b < face.mNumIndices; b++) {
usedVertexIndices.insert(face.mIndices[b]);
@@ -292,7 +310,6 @@ int JoinVerticesProcess::ProcessMesh( aiMesh* pMesh, unsigned int meshIndex)
// Run an optimized code path if we don't have multiple UVs or vertex colors.
// This should yield false in more than 99% of all imports ...
const bool complex = ( pMesh->GetNumColorChannels() > 0 || pMesh->GetNumUVChannels() > 1);
const bool hasAnimMeshes = pMesh->mNumAnimMeshes > 0;
// We'll never have more vertices afterwards.
@@ -303,72 +320,38 @@ int JoinVerticesProcess::ProcessMesh( aiMesh* pMesh, unsigned int meshIndex)
uniqueAnimatedVertices[animMeshIndex].reserve(pMesh->mNumVertices);
}
}
// a map that maps a vertix to its new index
std::unordered_map<Vertex,int> vertex2Index;
// we can not end up with more vertices than we started with
vertex2Index.reserve(pMesh->mNumVertices);
// Now check each vertex if it brings something new to the table
int newIndex = 0;
for( unsigned int a = 0; a < pMesh->mNumVertices; a++) {
// if the vertex is unused Do nothing
if (usedVertexIndices.find(a) == usedVertexIndices.end()) {
continue;
}
// collect the vertex data
Vertex v(pMesh,a);
// collect all vertices that are close enough to the given position
vertexFinder->FindIdenticalPositions( v.position, verticesFound);
unsigned int matchIndex = 0xffffffff;
// check all unique vertices close to the position if this vertex is already present among them
for( unsigned int b = 0; b < verticesFound.size(); b++) {
const unsigned int vidx = verticesFound[b];
const unsigned int uidx = replaceIndex[ vidx];
if( uidx & 0x80000000)
continue;
const Vertex& uv = uniqueVertices[ uidx];
if (!areVerticesEqual(v, uv, complex)) {
continue;
}
if (hasAnimMeshes) {
// If given vertex is animated, then it has to be preserver 1 to 1 (base mesh and animated mesh require same topology)
// NOTE: not doing this totaly breaks anim meshes as they don't have their own faces (they use pMesh->mFaces)
bool breaksAnimMesh = false;
for (unsigned int animMeshIndex = 0; animMeshIndex < pMesh->mNumAnimMeshes; animMeshIndex++) {
const Vertex& animatedUV = uniqueAnimatedVertices[animMeshIndex][ uidx];
Vertex aniMeshVertex(pMesh->mAnimMeshes[animMeshIndex], a);
if (!areVerticesEqual(aniMeshVertex, animatedUV, complex)) {
breaksAnimMesh = true;
break;
}
}
if (breaksAnimMesh) {
continue;
}
}
// we're still here -> this vertex perfectly matches our given vertex
matchIndex = uidx;
break;
}
// found a replacement vertex among the uniques?
if( matchIndex != 0xffffffff)
{
// store where to found the matching unique vertex
replaceIndex[a] = matchIndex | 0x80000000;
}
else
{
// no unique vertex matches it up to now -> so add it
replaceIndex[a] = (unsigned int)uniqueVertices.size();
uniqueVertices.push_back( v);
// is the vertex already in the map?
auto it = vertex2Index.find(v);
// if the vertex is not in the map then it is a new vertex add it.
if (it == vertex2Index.end()) {
// this is a new vertex give it a new index
vertex2Index[v] = newIndex;
//keep track of its index and increment 1
replaceIndex[a] = newIndex++;
// add the vertex to the unique vertices
uniqueVertices.push_back(v);
if (hasAnimMeshes) {
for (unsigned int animMeshIndex = 0; animMeshIndex < pMesh->mNumAnimMeshes; animMeshIndex++) {
Vertex aniMeshVertex(pMesh->mAnimMeshes[animMeshIndex], a);
uniqueAnimatedVertices[animMeshIndex].push_back(aniMeshVertex);
uniqueAnimatedVertices[animMeshIndex].push_back(v);
}
}
} else{
// if the vertex is already there just find the replace index that is appropriate to it
replaceIndex[a] = it->second;
}
}
@@ -394,8 +377,7 @@ int JoinVerticesProcess::ProcessMesh( aiMesh* pMesh, unsigned int meshIndex)
}
// adjust the indices in all faces
for( unsigned int a = 0; a < pMesh->mNumFaces; a++)
{
for( unsigned int a = 0; a < pMesh->mNumFaces; a++) {
aiFace& face = pMesh->mFaces[a];
for( unsigned int b = 0; b < face.mNumIndices; b++) {
face.mIndices[b] = replaceIndex[face.mIndices[b]] & ~0x80000000;

View File

@@ -521,7 +521,7 @@ void ValidateDSProcess::Validate(const aiAnimation *pAnimation) {
// ------------------------------------------------------------------------------------------------
void ValidateDSProcess::SearchForInvalidTextures(const aiMaterial *pMaterial,
aiTextureType type) {
const char *szType = TextureTypeToString(type);
const char *szType = aiTextureTypeToString(type);
// ****************************************************************************
// Search all keys of the material ...

View File

@@ -1,80 +1,37 @@
// Microsoft Visual C++ generated resource script.
//
#include "resource.h"
#include "revision.h"
#include "winres.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#define APSTUDIO_HIDDEN_SYMBOLS
#include "windows.h"
#undef APSTUDIO_HIDDEN_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// Deutsch (Deutschland) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_DEU)
#ifdef _WIN32
LANGUAGE LANG_GERMAN, SUBLANG_GERMAN
LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
#pragma code_page(1252)
#endif //_WIN32
/////////////////////////////////////////////////////////////////////////////
//
// Version
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION VER_FILEVERSION
PRODUCTVERSION VER_FILEVERSION
FILEFLAGSMASK 0x17L
FILEFLAGSMASK VS_FF_DEBUG
#ifdef _DEBUG
FILEFLAGS 0x1L
#else
FILEFLAGS 0x0L
FILEFLAGS VS_FF_DEBUG
#endif
FILEOS 0x4L
FILETYPE 0x7L
FILESUBTYPE 0x0L
FILEOS VOS_NT
FILETYPE VFT_DLL
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040704b0"
BLOCK "000004B0"
BEGIN
VALUE "Comments", "Licensed under a 3-clause BSD license"
VALUE "CompanyName", "assimp team"
VALUE "CompanyName", "ASSIMP Team"
VALUE "FileDescription", "Open Asset Import Library"
VALUE "FileVersion", VER_FILEVERSION
VALUE "InternalName", "assimp "
VALUE "LegalCopyright", "Copyright (C) 2006-2020"
VALUE "FileVersion", VER_FILEVERSION_STR
VALUE "InternalName", "assimp"
VALUE "LegalCopyright", VER_COPYRIGHT_STR
VALUE "OriginalFilename", VER_ORIGINAL_FILENAME_STR
VALUE "ProductName", "Open Asset Import Library"
VALUE "ProductVersion", VER_FILEVERSION_STR
,0
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x407, 1200
VALUE "Translation", 0x0, 65001
END
END
#endif // Deutsch (Deutschland) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED

View File

@@ -1,14 +0,0 @@
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by assimp.rc
// Next standard values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 101
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1001
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif