next fixed warnings

pull/3012/head
Kim Kulling 2020-03-01 13:15:45 +01:00
parent fb3c3048a5
commit 920535165d
41 changed files with 4124 additions and 4618 deletions

View File

@ -341,6 +341,20 @@ struct Texture {
mTextureBlend = get_qnan();
}
Texture(const Texture &other) :
mTextureBlend(other.mTextureBlend),
mMapName(other.mMapName),
mOffsetU(other.mOffsetU),
mOffsetV(other.mOffsetV),
mScaleU(other.mScaleU),
mScaleV(other.mScaleV),
mRotation(other.mRotation),
mMapMode(other.mMapMode),
bPrivate(other.bPrivate),
iUVSrc(other.iUVSrc) {
// empty
}
Texture(Texture &&other) AI_NO_EXCEPT : mTextureBlend(std::move(other.mTextureBlend)),
mMapName(std::move(mMapName)),
mOffsetU(std::move(mOffsetU)),
@ -400,18 +414,29 @@ struct Texture {
/** Helper structure representing a 3ds material */
struct Material {
//! Default constructor has been deleted
Material() = delete;
//! Constructor with explicit name
explicit Material(const std::string &name) :
mName(name), mDiffuse(ai_real(0.6), ai_real(0.6), ai_real(0.6)) // FIX ... we won't want object to be black
,
Material() :
mName(),
mDiffuse(ai_real(0.6), ai_real(0.6), ai_real(0.6)),
mSpecularExponent(ai_real(0.0)),
mShininessStrength(ai_real(1.0)),
mShading(Discreet3DS::Gouraud),
mTransparency(ai_real(1.0)),
mBumpHeight(ai_real(1.0)),
mTwoSided(false) {
// empty
}
//! Constructor with explicit name
explicit Material(const std::string &name) :
mName(name),
mDiffuse(ai_real(0.6), ai_real(0.6), ai_real(0.6)),
mSpecularExponent(ai_real(0.0)),
mShininessStrength(ai_real(1.0)),
mShading(Discreet3DS::Gouraud),
mTransparency(ai_real(1.0)),
mBumpHeight(ai_real(1.0)),
mTwoSided(false) {
// empty
}
Material(const Material &other) = default;
@ -468,7 +493,9 @@ struct Material {
return *this;
}
virtual ~Material() {}
virtual ~Material() {
// empty
}
//! Name of the material
std::string mName;

View File

@ -1,4 +1,3 @@
/*
---------------------------------------------------------------------------
Open Asset Import Library (assimp)
@ -6,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,
@ -80,46 +77,59 @@ static const aiImporterDesc desc = {
// ------------------------------------------------------------------------------------------------
// skip to the next token
#define AI_AC_SKIP_TO_NEXT_TOKEN() \
if (!SkipSpaces(&buffer)) { \
ASSIMP_LOG_ERROR("AC3D: Unexpected EOF/EOL"); \
continue; \
inline
const char *AcSkipToNextToken( const char *buffer ) {
if (!SkipSpaces( &buffer )) {
ASSIMP_LOG_ERROR("AC3D: Unexpected EOF/EOL");
}
return buffer;
}
// ------------------------------------------------------------------------------------------------
// read a string (may be enclosed in double quotation marks). buffer must point to "
#define AI_AC_GET_STRING(out) \
if (*buffer == '\0') { \
throw DeadlyImportError("AC3D: Unexpected EOF in string"); \
} \
++buffer; \
const char *sz = buffer; \
while ('\"' != *buffer) { \
if (IsLineEnd(*buffer)) { \
ASSIMP_LOG_ERROR("AC3D: Unexpected EOF/EOL in string"); \
out = "ERROR"; \
break; \
} \
++buffer; \
} \
if (IsLineEnd(*buffer)) continue; \
out = std::string(sz, (unsigned int)(buffer - sz)); \
inline
const char *AcGetString(const char *buffer, std::string &out) {
if (*buffer == '\0') {
throw DeadlyImportError("AC3D: Unexpected EOF in string");
}
++buffer;
const char *sz = buffer;
while ('\"' != *buffer) {
if (IsLineEnd(*buffer)) {
ASSIMP_LOG_ERROR("AC3D: Unexpected EOF/EOL in string");
out = "ERROR";
break;
}
++buffer;
}
if (IsLineEnd(*buffer)) {
return buffer;
}
out = std::string(sz, (unsigned int)(buffer - sz));
++buffer;
return buffer;
}
// ------------------------------------------------------------------------------------------------
// read 1 to n floats prefixed with an optional predefined identifier
#define AI_AC_CHECKED_LOAD_FLOAT_ARRAY(name, name_length, num, out) \
AI_AC_SKIP_TO_NEXT_TOKEN(); \
if (name_length) { \
if (strncmp(buffer, name, name_length) || !IsSpace(buffer[name_length])) { \
ASSIMP_LOG_ERROR("AC3D: Unexpexted token. " name " was expected."); \
continue; \
} \
buffer += name_length + 1; \
} \
for (unsigned int _i = 0; _i < num; ++_i) { \
AI_AC_SKIP_TO_NEXT_TOKEN(); \
buffer = fast_atoreal_move<float>(buffer, ((float *)out)[_i]); \
template<class T>
inline
const char *TAcCheckedLoadFloatArray(const char *buffer, const char *name, size_t name_length, size_t num, T *out) {
AcSkipToNextToken(buffer);
if (0 != name_length) {
if (0 != strncmp(buffer, name, name_length) || !IsSpace(buffer[name_length])) {
ASSIMP_LOG_ERROR("AC3D: Unexpexted token. " + std::string( name ) + " was expected.");
return buffer;
}
buffer += name_length + 1;
}
for (unsigned int _i = 0; _i < num; ++_i) {
AcSkipToNextToken(buffer);
buffer = fast_atoreal_move<float>(buffer, ((float *)out)[_i]);
}
return buffer;
}
// ------------------------------------------------------------------------------------------------
@ -222,7 +232,7 @@ void AC3DImporter::LoadObjectSection(std::vector<Object> &objects) {
return;
} else if (TokenMatch(buffer, "name", 4)) {
SkipSpaces(&buffer);
AI_AC_GET_STRING(obj.name);
buffer = AcGetString(buffer, obj.name);
// If this is a light source, we'll also need to store
// the name of the node in it.
@ -231,21 +241,21 @@ void AC3DImporter::LoadObjectSection(std::vector<Object> &objects) {
}
} else if (TokenMatch(buffer, "texture", 7)) {
SkipSpaces(&buffer);
AI_AC_GET_STRING(obj.texture);
buffer = AcGetString(buffer, obj.texture);
} else if (TokenMatch(buffer, "texrep", 6)) {
SkipSpaces(&buffer);
AI_AC_CHECKED_LOAD_FLOAT_ARRAY("", 0, 2, &obj.texRepeat);
buffer = TAcCheckedLoadFloatArray(buffer, "", 0, 2, &obj.texRepeat);
if (!obj.texRepeat.x || !obj.texRepeat.y)
obj.texRepeat = aiVector2D(1.f, 1.f);
} else if (TokenMatch(buffer, "texoff", 6)) {
SkipSpaces(&buffer);
AI_AC_CHECKED_LOAD_FLOAT_ARRAY("", 0, 2, &obj.texOffset);
buffer = TAcCheckedLoadFloatArray(buffer, "", 0, 2, &obj.texOffset);
} else if (TokenMatch(buffer, "rot", 3)) {
SkipSpaces(&buffer);
AI_AC_CHECKED_LOAD_FLOAT_ARRAY("", 0, 9, &obj.rotation);
buffer = TAcCheckedLoadFloatArray(buffer, "", 0, 9, &obj.rotation);
} else if (TokenMatch(buffer, "loc", 3)) {
SkipSpaces(&buffer);
AI_AC_CHECKED_LOAD_FLOAT_ARRAY("", 0, 3, &obj.translation);
buffer = TAcCheckedLoadFloatArray(buffer, "", 0, 3, &obj.translation);
} else if (TokenMatch(buffer, "subdiv", 6)) {
SkipSpaces(&buffer);
obj.subDiv = strtoul10(buffer, &buffer);
@ -271,7 +281,7 @@ void AC3DImporter::LoadObjectSection(std::vector<Object> &objects) {
}
obj.vertices.push_back(aiVector3D());
aiVector3D &v = obj.vertices.back();
AI_AC_CHECKED_LOAD_FLOAT_ARRAY("", 0, 3, &v.x);
buffer = TAcCheckedLoadFloatArray(buffer, "", 0, 3, &v.x);
}
} else if (TokenMatch(buffer, "numsurf", 7)) {
SkipSpaces(&buffer);
@ -331,10 +341,9 @@ void AC3DImporter::LoadObjectSection(std::vector<Object> &objects) {
entry.first = strtoul10(buffer, &buffer);
SkipSpaces(&buffer);
AI_AC_CHECKED_LOAD_FLOAT_ARRAY("", 0, 2, &entry.second);
buffer = TAcCheckedLoadFloatArray(buffer, "", 0, 2, &entry.second);
}
} else {
--buffer; // make sure the line is processed a second time
break;
}
@ -496,7 +505,9 @@ aiNode *AC3DImporter::ConvertObjectSection(Object &object,
const size_t oldm = meshes.size();
for (MatTable::const_iterator cit = needMat.begin(), cend = needMat.end();
cit != cend; ++cit, ++mat) {
if (!(*cit).first) continue;
if (!(*cit).first) {
continue;
}
// allocate a new aiMesh object
*pip++ = (unsigned int)meshes.size();
@ -541,7 +552,8 @@ aiNode *AC3DImporter::ConvertObjectSection(Object &object,
unsigned int type = (*it).flags & 0xf;
if (!type) {
aiFace &face = *faces++;
if ((face.mNumIndices = (unsigned int)src.entries.size())) {
face.mNumIndices = (unsigned int)src.entries.size();
if (0 != face.mNumIndices) {
face.mIndices = new unsigned int[face.mNumIndices];
for (unsigned int i = 0; i < face.mNumIndices; ++i, ++vertices) {
const Surface::SurfaceEntry &entry = src.entries[i];
@ -726,18 +738,18 @@ void AC3DImporter::InternReadFile(const std::string &pFile,
// manually parse the material ... sscanf would use the buldin atof ...
// Format: (name) rgb %f %f %f amb %f %f %f emis %f %f %f spec %f %f %f shi %d trans %f
AI_AC_SKIP_TO_NEXT_TOKEN();
buffer = AcSkipToNextToken(buffer);
if ('\"' == *buffer) {
AI_AC_GET_STRING(mat.name);
AI_AC_SKIP_TO_NEXT_TOKEN();
buffer = AcGetString(buffer, mat.name);
buffer = AcSkipToNextToken(buffer);
}
AI_AC_CHECKED_LOAD_FLOAT_ARRAY("rgb", 3, 3, &mat.rgb);
AI_AC_CHECKED_LOAD_FLOAT_ARRAY("amb", 3, 3, &mat.amb);
AI_AC_CHECKED_LOAD_FLOAT_ARRAY("emis", 4, 3, &mat.emis);
AI_AC_CHECKED_LOAD_FLOAT_ARRAY("spec", 4, 3, &mat.spec);
AI_AC_CHECKED_LOAD_FLOAT_ARRAY("shi", 3, 1, &mat.shin);
AI_AC_CHECKED_LOAD_FLOAT_ARRAY("trans", 5, 1, &mat.trans);
buffer = TAcCheckedLoadFloatArray(buffer, "rgb", 3, 3, &mat.rgb);
buffer = TAcCheckedLoadFloatArray(buffer, "amb", 3, 3, &mat.amb);
buffer = TAcCheckedLoadFloatArray(buffer, "emis", 4, 3, &mat.emis);
buffer = TAcCheckedLoadFloatArray(buffer, "spec", 4, 3, &mat.spec);
buffer = TAcCheckedLoadFloatArray(buffer, "shi", 3, 1, &mat.shin);
buffer = TAcCheckedLoadFloatArray(buffer, "trans", 5, 1, &mat.trans);
}
LoadObjectSection(rootObjects);
}

View File

@ -68,8 +68,6 @@ public:
AC3DImporter();
~AC3DImporter();
// Represents an AC3D material
struct Material
{
@ -245,8 +243,6 @@ private:
aiMaterial& matDest);
private:
// points to the next data line
const char* buffer;

View File

@ -429,7 +429,7 @@ void BlenderImporter::ResolveImage(aiMaterial* out, const Material* mat, const M
name.length = 1+ ASSIMP_itoa10(name.data+1,static_cast<unsigned int>(MAXLEN-1), static_cast<int32_t>(conv_data.textures->size()));
conv_data.textures->push_back(new aiTexture());
aiTexture* tex = conv_data.textures->back();
aiTexture* curTex = conv_data.textures->back();
// usually 'img->name' will be the original file name of the embedded textures,
// so we can extract the file extension from it.
@ -439,19 +439,19 @@ void BlenderImporter::ResolveImage(aiMaterial* out, const Material* mat, const M
--s;
}
tex->achFormatHint[0] = s+1>e ? '\0' : ::tolower( s[1] );
tex->achFormatHint[1] = s+2>e ? '\0' : ::tolower( s[2] );
tex->achFormatHint[2] = s+3>e ? '\0' : ::tolower( s[3] );
tex->achFormatHint[3] = '\0';
curTex->achFormatHint[0] = s + 1 > e ? '\0' : (char)::tolower(s[1]);
curTex->achFormatHint[1] = s + 2 > e ? '\0' : (char)::tolower(s[2]);
curTex->achFormatHint[2] = s + 3 > e ? '\0' : (char)::tolower(s[3]);
curTex->achFormatHint[3] = '\0';
// tex->mHeight = 0;
tex->mWidth = img->packedfile->size;
uint8_t* ch = new uint8_t[tex->mWidth];
curTex->mWidth = img->packedfile->size;
uint8_t *ch = new uint8_t[curTex->mWidth];
conv_data.db.reader->SetCurrentPos(static_cast<size_t>( img->packedfile->data->val));
conv_data.db.reader->CopyAndAdvance(ch,tex->mWidth);
conv_data.db.reader->CopyAndAdvance(ch, curTex->mWidth);
tex->pcData = reinterpret_cast<aiTexel*>(ch);
curTex->pcData = reinterpret_cast<aiTexel *>(ch);
LogInfo("Reading embedded texture, original file was "+std::string(img->name));
} else {
@ -1078,9 +1078,9 @@ void BlenderImporter::ConvertMesh(const Scene& /*in*/, const Object* /*obj*/, co
const aiFace& f = out->mFaces[out->mNumFaces++];
aiVector3D* vo = &out->mTextureCoords[0][out->mNumVertices];
for (unsigned int i = 0; i < f.mNumIndices; ++i,++vo,++out->mNumVertices) {
vo->x = v->uv[i][0];
vo->y = v->uv[i][1];
for (unsigned int j = 0; j < f.mNumIndices; ++j,++vo,++out->mNumVertices) {
vo->x = v->uv[j][0];
vo->y = v->uv[j][1];
}
}
@ -1098,8 +1098,7 @@ void BlenderImporter::ConvertMesh(const Scene& /*in*/, const Object* /*obj*/, co
vo->x = uv.uv[0];
vo->y = uv.uv[1];
}
}
else {
} else {
// create textureCoords for every mapped tex
for (uint32_t m = 0; m < itMatTexUvMapping->second.size(); ++m) {
const MLoopUV *tm = itMatTexUvMapping->second[m];
@ -1139,9 +1138,9 @@ void BlenderImporter::ConvertMesh(const Scene& /*in*/, const Object* /*obj*/, co
const aiFace& f = out->mFaces[out->mNumFaces++];
aiVector3D* vo = &out->mTextureCoords[0][out->mNumVertices];
for (unsigned int i = 0; i < f.mNumIndices; ++i,++vo,++out->mNumVertices) {
vo->x = v->uv[i][0];
vo->y = v->uv[i][1];
for (unsigned int j = 0; j < f.mNumIndices; ++j,++vo,++out->mNumVertices) {
vo->x = v->uv[j][0];
vo->y = v->uv[j][1];
}
}
}

View File

@ -57,7 +57,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
using namespace Assimp;
using namespace Assimp::Blender;
template <typename T> BlenderModifier* god() {
template <typename T>
BlenderModifier *god() {
return new T();
}
@ -71,14 +72,12 @@ static const fpCreateModifier creators[] = {
};
// ------------------------------------------------------------------------------------------------
struct SharedModifierData : ElemBase
{
struct SharedModifierData : ElemBase {
ModifierData modifier;
};
// ------------------------------------------------------------------------------------------------
void BlenderModifierShowcase::ApplyModifiers(aiNode& out, ConversionData& conv_data, const Scene& in, const Object& orig_object )
{
void BlenderModifierShowcase::ApplyModifiers(aiNode &out, ConversionData &conv_data, const Scene &in, const Object &orig_object) {
size_t cnt = 0u, ful = 0u;
// NOTE: this cast is potentially unsafe by design, so we need to perform type checks before
@ -146,19 +145,15 @@ void BlenderModifierShowcase::ApplyModifiers(aiNode& out, ConversionData& conv_d
}
}
// ------------------------------------------------------------------------------------------------
bool BlenderModifier_Mirror :: IsActive (const ModifierData& modin)
{
bool BlenderModifier_Mirror ::IsActive(const ModifierData &modin) {
return modin.type == ModifierData::eModifierType_Mirror;
}
// ------------------------------------------------------------------------------------------------
void BlenderModifier_Mirror ::DoIt(aiNode &out, ConversionData &conv_data, const ElemBase &orig_modifier,
const Scene & /*in*/,
const Object& orig_object )
{
const Object &orig_object) {
// hijacking the ABI, see the big note in BlenderModifierShowcase::ApplyModifiers()
const MirrorModifierData &mir = static_cast<const MirrorModifierData &>(orig_modifier);
ai_assert(mir.modifier.type == ModifierData::eModifierType_Mirror);
@ -178,39 +173,46 @@ void BlenderModifier_Mirror :: DoIt(aiNode& out, ConversionData& conv_data, co
if (mir.mirror_ob) {
const aiVector3D center(mir.mirror_ob->obmat[3][0], mir.mirror_ob->obmat[3][1], mir.mirror_ob->obmat[3][2]);
for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
aiVector3D& v = mesh->mVertices[i];
for (unsigned int j = 0; j < mesh->mNumVertices; ++j) {
aiVector3D &v = mesh->mVertices[j];
v.x = center.x + xs * (center.x - v.x);
v.y = center.y + ys * (center.y - v.y);
v.z = center.z + zs * (center.z - v.z);
}
}
else {
for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
aiVector3D& v = mesh->mVertices[i];
v.x *= xs;v.y *= ys;v.z *= zs;
} else {
for (unsigned int j = 0; j < mesh->mNumVertices; ++j) {
aiVector3D &v = mesh->mVertices[j];
v.x *= xs;
v.y *= ys;
v.z *= zs;
}
}
if (mesh->mNormals) {
for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
aiVector3D& v = mesh->mNormals[i];
v.x *= xs;v.y *= ys;v.z *= zs;
for (unsigned int j = 0; j < mesh->mNumVertices; ++j) {
aiVector3D &v = mesh->mNormals[j];
v.x *= xs;
v.y *= ys;
v.z *= zs;
}
}
if (mesh->mTangents) {
for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
aiVector3D& v = mesh->mTangents[i];
v.x *= xs;v.y *= ys;v.z *= zs;
for (unsigned int j = 0; j < mesh->mNumVertices; ++j) {
aiVector3D &v = mesh->mTangents[j];
v.x *= xs;
v.y *= ys;
v.z *= zs;
}
}
if (mesh->mBitangents) {
for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
aiVector3D& v = mesh->mBitangents[i];
v.x *= xs;v.y *= ys;v.z *= zs;
for (unsigned int j = 0; j < mesh->mNumVertices; ++j) {
aiVector3D &v = mesh->mBitangents[j];
v.x *= xs;
v.y *= ys;
v.z *= zs;
}
}
@ -218,16 +220,17 @@ void BlenderModifier_Mirror :: DoIt(aiNode& out, ConversionData& conv_data, co
const float vs = mir.flag & MirrorModifierData::Flags_MIRROR_V ? -1.f : 1.f;
for (unsigned int n = 0; mesh->HasTextureCoords(n); ++n) {
for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
aiVector3D& v = mesh->mTextureCoords[n][i];
v.x *= us;v.y *= vs;
for (unsigned int j = 0; j < mesh->mNumVertices; ++j) {
aiVector3D &v = mesh->mTextureCoords[n][j];
v.x *= us;
v.y *= vs;
}
}
// Only reverse the winding order if an odd number of axes were mirrored.
if (xs * ys * zs < 0) {
for( unsigned int i = 0; i < mesh->mNumFaces; i++) {
aiFace& face = mesh->mFaces[i];
for (unsigned int j = 0; j < mesh->mNumFaces; ++j ) {
aiFace &face = mesh->mFaces[j];
for (unsigned int fi = 0; fi < face.mNumIndices / 2; ++fi)
std::swap(face.mIndices[fi], face.mIndices[face.mNumIndices - 1 - fi]);
}
@ -250,23 +253,20 @@ void BlenderModifier_Mirror :: DoIt(aiNode& out, ConversionData& conv_data, co
}
// ------------------------------------------------------------------------------------------------
bool BlenderModifier_Subdivision :: IsActive (const ModifierData& modin)
{
bool BlenderModifier_Subdivision ::IsActive(const ModifierData &modin) {
return modin.type == ModifierData::eModifierType_Subsurf;
}
// ------------------------------------------------------------------------------------------------
void BlenderModifier_Subdivision ::DoIt(aiNode &out, ConversionData &conv_data, const ElemBase &orig_modifier,
const Scene & /*in*/,
const Object& orig_object )
{
const Object &orig_object) {
// hijacking the ABI, see the big note in BlenderModifierShowcase::ApplyModifiers()
const SubsurfModifierData &mir = static_cast<const SubsurfModifierData &>(orig_modifier);
ai_assert(mir.modifier.type == ModifierData::eModifierType_Subsurf);
Subdivider::Algorithm algo;
switch (mir.subdivType)
{
switch (mir.subdivType) {
case SubsurfModifierData::TYPE_CatmullClarke:
algo = Subdivider::CATMULL_CLARKE;
break;

View File

@ -1015,8 +1015,8 @@ void COBImporter::ReadPolH_Binary(COB::Scene& out, StreamReaderLE& reader, const
// XXX backface culling flag is 0x10 in flags
// hole?
bool hole;
if ((hole = (reader.GetI1() & 0x08) != 0)) {
bool hole = (reader.GetI1() & 0x08) != 0;
if ( hole ) {
// XXX Basically this should just work fine - then triangulator
// should output properly triangulated data even for polygons
// with holes. Test data specific to COB is needed to confirm it.

View File

@ -75,10 +75,10 @@ struct Face
// ------------------
/** COB chunk header information */
const unsigned int NO_SIZE = UINT_MAX;
struct ChunkInfo
{
enum {NO_SIZE=UINT_MAX};
ChunkInfo ()
: id (0)
, parent_id (0)

View File

@ -714,8 +714,8 @@ void ColladaParser::ReadAnimation(Collada::Animation* pParent)
else if (IsElement("sampler"))
{
// read the ID to assign the corresponding collada channel afterwards.
int indexID = GetAttribute("id");
std::string id = mReader->getAttributeValue(indexID);
int indexId = GetAttribute("id");
std::string id = mReader->getAttributeValue(indexId);
ChannelMap::iterator newChannel = channels.insert(std::make_pair(id, AnimationChannel())).first;
// have it read into a channel
@ -3339,13 +3339,12 @@ void ColladaParser::TestClosing(const char* pName) {
// Returns the index of the named attribute or -1 if not found. Does not throw, therefore useful for optional attributes
int ColladaParser::GetAttribute(const char* pAttr) const {
int index = TestAttribute(pAttr);
if (index != -1) {
return index;
if (index == -1) {
ThrowException(format() << "Expected attribute \"" << pAttr << "\" for element <" << mReader->getNodeName() << ">.");
}
// attribute not found -> throw an exception
ThrowException(format() << "Expected attribute \"" << pAttr << "\" for element <" << mReader->getNodeName() << ">.");
return -1;
return index;
}
// ------------------------------------------------------------------------------------------------

View File

@ -428,8 +428,8 @@ void Document::ReadPropertyTemplates()
const ElementCollection otypes = sdefs.GetCollection("ObjectType");
for(ElementMap::const_iterator it = otypes.first; it != otypes.second; ++it) {
const Element& el = *(*it).second;
const Scope* sc = el.Compound();
if(!sc) {
const Scope* curSc = el.Compound();
if (!curSc) {
DOMWarning("expected nested scope in ObjectType, ignoring",&el);
continue;
}
@ -442,24 +442,24 @@ void Document::ReadPropertyTemplates()
const std::string& oname = ParseTokenAsString(*tok[0]);
const ElementCollection templs = sc->GetCollection("PropertyTemplate");
for(ElementMap::const_iterator it = templs.first; it != templs.second; ++it) {
const Element& el = *(*it).second;
const Scope* sc = el.Compound();
if(!sc) {
const ElementCollection templs = curSc->GetCollection("PropertyTemplate");
for (ElementMap::const_iterator elemIt = templs.first; elemIt != templs.second; ++elemIt) {
const Element &innerEl = *(*elemIt).second;
const Scope *innerSc = innerEl.Compound();
if (!innerSc) {
DOMWarning("expected nested scope in PropertyTemplate, ignoring",&el);
continue;
}
const TokenList& tok = el.Tokens();
if(tok.empty()) {
const TokenList &curTok = innerEl.Tokens();
if (curTok.empty()) {
DOMWarning("expected name for PropertyTemplate element, ignoring",&el);
continue;
}
const std::string& pname = ParseTokenAsString(*tok[0]);
const std::string &pname = ParseTokenAsString(*curTok[0]);
const Element* Properties70 = (*sc)["Properties70"];
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))
@ -529,8 +529,8 @@ const std::vector<const AnimationStack*>& Document::AnimationStacks() const
animationStacksResolved.reserve(animationStacks.size());
for(uint64_t id : animationStacks) {
LazyObject* const lazy = GetObject(id);
const AnimationStack* stack;
if(!lazy || !(stack = lazy->Get<AnimationStack>())) {
const AnimationStack *stack = lazy->Get<AnimationStack>();
if(!lazy || nullptr == stack ) {
DOMWarning("failed to read AnimationStack object");
continue;
}

View File

@ -44,7 +44,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* @brief Implementation of the Industry Foundation Classes loader.
*/
#ifndef ASSIMP_BUILD_NO_IFC_IMPORTER
#include <iterator>
@ -59,24 +58,23 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endif
#endif
#include "IFCLoader.h"
#include "../STEPParser/STEPFileReader.h"
#include "IFCLoader.h"
#include "IFCUtil.h"
#include <assimp/MemoryIOWrapper.h>
#include <assimp/importerdesc.h>
#include <assimp/scene.h>
#include <assimp/Importer.hpp>
#include <assimp/importerdesc.h>
namespace Assimp {
template<> const char* LogFunctions<IFCImporter>::Prefix()
{
template <>
const char *LogFunctions<IFCImporter>::Prefix() {
static auto prefix = "IFC: ";
return prefix;
}
}
} // namespace Assimp
using namespace Assimp;
using namespace Assimp::Formatter;
@ -98,7 +96,6 @@ using namespace Assimp::IFC;
namespace {
// forward declarations
void SetUnits(ConversionData &conv);
void SetCoordinateSpace(ConversionData &conv);
@ -106,7 +103,7 @@ void ProcessSpatialStructures(ConversionData& conv);
void MakeTreeRelative(ConversionData &conv);
void ConvertUnit(const ::Assimp::STEP::EXPRESS::DataType &dt, ConversionData &conv);
} // anon
} // namespace
static const aiImporterDesc desc = {
"Industry Foundation Classes (IFC) Importer",
@ -121,22 +118,18 @@ static const aiImporterDesc desc = {
"ifc ifczip stp"
};
// ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer
IFCImporter::IFCImporter()
{}
IFCImporter::IFCImporter() {}
// ------------------------------------------------------------------------------------------------
// Destructor, private as well
IFCImporter::~IFCImporter()
{
IFCImporter::~IFCImporter() {
}
// ------------------------------------------------------------------------------------------------
// Returns whether the class can handle the format of the given file.
bool IFCImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
{
bool IFCImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool checkSig) const {
const std::string &extension = GetExtension(pFile);
if (extension == "ifc" || extension == "ifczip") {
return true;
@ -153,15 +146,13 @@ bool IFCImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool
// ------------------------------------------------------------------------------------------------
// List all extensions handled by this loader
const aiImporterDesc* IFCImporter::GetInfo () const
{
const aiImporterDesc *IFCImporter::GetInfo() const {
return &desc;
}
// ------------------------------------------------------------------------------------------------
// Setup configuration properties for the loader
void IFCImporter::SetupProperties(const Importer* pImp)
{
void IFCImporter::SetupProperties(const Importer *pImp) {
settings.skipSpaceRepresentations = pImp->GetPropertyBool(AI_CONFIG_IMPORT_IFC_SKIP_SPACE_REPRESENTATIONS, true);
settings.useCustomTriangulation = pImp->GetPropertyBool(AI_CONFIG_IMPORT_IFC_CUSTOM_TRIANGULATION, true);
settings.conicSamplingAngle = std::min(std::max((float)pImp->GetPropertyFloat(AI_CONFIG_IMPORT_IFC_SMOOTHING_ANGLE, AI_IMPORT_IFC_DEFAULT_SMOOTHING_ANGLE), 5.0f), 120.0f);
@ -169,17 +160,14 @@ void IFCImporter::SetupProperties(const Importer* pImp)
settings.skipAnnotations = true;
}
// ------------------------------------------------------------------------------------------------
// Imports the given file into the given scene structure.
void IFCImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler)
{
void IFCImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler) {
std::shared_ptr<IOStream> stream(pIOHandler->Open(pFile));
if (!stream) {
ThrowException("Could not open file for reading");
}
// if this is a ifczip file, decompress its contents first
if (GetExtension(pFile) == "ifczip") {
#ifndef ASSIMP_BUILD_NO_COMPRESSED_IFC
@ -225,22 +213,19 @@ void IFCImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOS
free(buffer);
} while (read > 0);
size_t filesize = fileInfo.uncompressed_size;
if (total == 0 || size_t(total) != filesize)
{
if (total == 0 || size_t(total) != filesize) {
delete[] buff;
ThrowException("Failed to decompress IFC ZIP file");
}
unzCloseCurrentFile(zip);
stream.reset(new MemoryIOStream(buff, fileInfo.uncompressed_size, true));
break;
if (unzGoToNextFile(zip) == UNZ_END_OF_LIST_OF_FILE) {
ThrowException("Found no IFC file member in IFCZIP file (1)");
}
break;
} while (true);
}
else {
} else {
ThrowException("Found no IFC file member in IFCZIP file (2)");
}
@ -336,10 +321,8 @@ void IFCImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOS
namespace {
// ------------------------------------------------------------------------------------------------
void ConvertUnit(const Schema_2x3::IfcNamedUnit& unit,ConversionData& conv)
{
void ConvertUnit(const Schema_2x3::IfcNamedUnit &unit, ConversionData &conv) {
if (const Schema_2x3::IfcSIUnit *const si = unit.ToPtr<Schema_2x3::IfcSIUnit>()) {
if (si->UnitType == "LENGTHUNIT") {
conv.len_scale = si->Prefix ? ConvertSIPrefix(si->Prefix) : 1.f;
@ -350,15 +333,13 @@ void ConvertUnit(const Schema_2x3::IfcNamedUnit& unit,ConversionData& conv)
IFCImporter::LogWarn("expected base unit for angles to be radian");
}
}
}
else if(const Schema_2x3::IfcConversionBasedUnit* const convu = unit.ToPtr<Schema_2x3::IfcConversionBasedUnit>()) {
} else if (const Schema_2x3::IfcConversionBasedUnit *const convu = unit.ToPtr<Schema_2x3::IfcConversionBasedUnit>()) {
if (convu->UnitType == "PLANEANGLEUNIT") {
try {
conv.angle_scale = convu->ConversionFactor->ValueComponent->To<::Assimp::STEP::EXPRESS::REAL>();
ConvertUnit(*convu->ConversionFactor->UnitComponent, conv);
IFCImporter::LogDebug("got units used for angles");
}
catch(std::bad_cast&) {
} catch (std::bad_cast &) {
IFCImporter::LogError("skipping unknown IfcConversionBasedUnit.ValueComponent entry - expected REAL");
}
}
@ -366,8 +347,7 @@ void ConvertUnit(const Schema_2x3::IfcNamedUnit& unit,ConversionData& conv)
}
// ------------------------------------------------------------------------------------------------
void ConvertUnit(const ::Assimp::STEP::EXPRESS::DataType& dt,ConversionData& conv)
{
void ConvertUnit(const ::Assimp::STEP::EXPRESS::DataType &dt, ConversionData &conv) {
try {
const ::Assimp::STEP::EXPRESS::ENTITY &e = dt.To<::Assimp::STEP::EXPRESS::ENTITY>();
@ -377,26 +357,22 @@ void ConvertUnit(const ::Assimp::STEP::EXPRESS::DataType& dt,ConversionData& con
}
ConvertUnit(unit, conv);
}
catch(std::bad_cast&) {
} catch (std::bad_cast &) {
// not entity, somehow
IFCImporter::LogError("skipping unknown IfcUnit entry - expected entity");
}
}
// ------------------------------------------------------------------------------------------------
void SetUnits(ConversionData& conv)
{
void SetUnits(ConversionData &conv) {
// see if we can determine the coordinate space used to express.
for (size_t i = 0; i < conv.proj.UnitsInContext->Units.size(); ++i) {
ConvertUnit(*conv.proj.UnitsInContext->Units[i], conv);
}
}
// ------------------------------------------------------------------------------------------------
void SetCoordinateSpace(ConversionData& conv)
{
void SetCoordinateSpace(ConversionData &conv) {
const Schema_2x3::IfcRepresentationContext *fav = NULL;
for (const Schema_2x3::IfcRepresentationContext &v : conv.proj.RepresentationContexts) {
fav = &v;
@ -413,10 +389,8 @@ void SetCoordinateSpace(ConversionData& conv)
}
}
// ------------------------------------------------------------------------------------------------
void ResolveObjectPlacement(aiMatrix4x4& m, const Schema_2x3::IfcObjectPlacement& place, ConversionData& conv)
{
void ResolveObjectPlacement(aiMatrix4x4 &m, const Schema_2x3::IfcObjectPlacement &place, ConversionData &conv) {
if (const Schema_2x3::IfcLocalPlacement *const local = place.ToPtr<Schema_2x3::IfcLocalPlacement>()) {
IfcMatrix4 tmp;
ConvertAxisPlacement(tmp, *local->RelativePlacement, conv);
@ -424,19 +398,17 @@ void ResolveObjectPlacement(aiMatrix4x4& m, const Schema_2x3::IfcObjectPlacement
m = static_cast<aiMatrix4x4>(tmp);
if (local->PlacementRelTo) {
aiMatrix4x4 tmp;
ResolveObjectPlacement(tmp,local->PlacementRelTo.Get(),conv);
m = tmp * m;
aiMatrix4x4 tmpM;
ResolveObjectPlacement(tmpM, local->PlacementRelTo.Get(), conv);
m = tmpM * m;
}
}
else {
} else {
IFCImporter::LogWarn("skipping unknown IfcObjectPlacement entity, type is " + place.GetClassName());
}
}
// ------------------------------------------------------------------------------------------------
bool ProcessMappedItem(const Schema_2x3::IfcMappedItem& mapped, aiNode* nd_src, std::vector< aiNode* >& subnodes_src, unsigned int matid, ConversionData& conv)
{
bool ProcessMappedItem(const Schema_2x3::IfcMappedItem &mapped, aiNode *nd_src, std::vector<aiNode *> &subnodes_src, unsigned int matid, ConversionData &conv) {
// insert a custom node here, the carthesian transform operator is simply a conventional transformation matrix
std::unique_ptr<aiNode> nd(new aiNode());
nd->mName.Set("IfcMappedItem");
@ -467,8 +439,8 @@ bool ProcessMappedItem(const Schema_2x3::IfcMappedItem& mapped, aiNode* nd_src,
for (const Schema_2x3::IfcRepresentationItem &item : repr.Items) {
if (!ProcessRepresentationItem(item, localmatid, meshes, conv)) {
IFCImporter::LogWarn("skipping mapped entity of type " + item.GetClassName() + ", no representations could be generated");
}
else got = true;
} else
got = true;
}
if (!got) {
@ -504,7 +476,6 @@ struct RateRepresentationPredicate {
return 0;
}
const std::string &name = r->RepresentationIdentifier.Get();
if (name == "MappedRepresentation") {
if (!r->Items.empty()) {
@ -557,8 +528,7 @@ struct RateRepresentationPredicate {
};
// ------------------------------------------------------------------------------------------------
void ProcessProductRepresentation(const Schema_2x3::IfcProduct& el, aiNode* nd, std::vector< aiNode* >& subnodes, ConversionData& conv)
{
void ProcessProductRepresentation(const Schema_2x3::IfcProduct &el, aiNode *nd, std::vector<aiNode *> &subnodes, ConversionData &conv) {
if (!el.Representation) {
return;
}
@ -581,8 +551,7 @@ void ProcessProductRepresentation(const Schema_2x3::IfcProduct& el, aiNode* nd,
for (const Schema_2x3::IfcRepresentationItem &item : repr->Items) {
if (const Schema_2x3::IfcMappedItem *const geo = item.ToPtr<Schema_2x3::IfcMappedItem>()) {
res = ProcessMappedItem(*geo, nd, subnodes, matid, conv) || res;
}
else {
} else {
res = ProcessRepresentationItem(item, matid, meshes, conv) || res;
}
}
@ -607,22 +576,19 @@ void ProcessMetadata(const Schema_2x3::ListOf< Schema_2x3::Lazy< Schema_2x3::Ifc
if (const ::Assimp::STEP::EXPRESS::STRING *str = singleValue->NominalValue.Get()->ToPtr<::Assimp::STEP::EXPRESS::STRING>()) {
std::string value = static_cast<std::string>(*str);
properties[key] = value;
}
else if (const ::Assimp::STEP::EXPRESS::REAL* val = singleValue->NominalValue.Get()->ToPtr<::Assimp::STEP::EXPRESS::REAL>()) {
float value = static_cast<float>(*val);
} else if (const ::Assimp::STEP::EXPRESS::REAL *val1 = singleValue->NominalValue.Get()->ToPtr<::Assimp::STEP::EXPRESS::REAL>()) {
float value = static_cast<float>(*val1);
std::stringstream s;
s << value;
properties[key] = s.str();
}
else if (const ::Assimp::STEP::EXPRESS::INTEGER* val = singleValue->NominalValue.Get()->ToPtr<::Assimp::STEP::EXPRESS::INTEGER>()) {
int64_t value = static_cast<int64_t>(*val);
} else if (const ::Assimp::STEP::EXPRESS::INTEGER *val2 = singleValue->NominalValue.Get()->ToPtr<::Assimp::STEP::EXPRESS::INTEGER>()) {
int64_t curValue = static_cast<int64_t>(*val2);
std::stringstream s;
s << value;
s << curValue;
properties[key] = s.str();
}
}
}
else if (const Schema_2x3::IfcPropertyListValue* const listValue = property.ToPtr<Schema_2x3::IfcPropertyListValue>()) {
} else if (const Schema_2x3::IfcPropertyListValue *const listValue = property.ToPtr<Schema_2x3::IfcPropertyListValue>()) {
std::stringstream ss;
ss << "[";
unsigned index = 0;
@ -631,13 +597,11 @@ void ProcessMetadata(const Schema_2x3::ListOf< Schema_2x3::Lazy< Schema_2x3::Ifc
if (const ::Assimp::STEP::EXPRESS::STRING *str = v->ToPtr<::Assimp::STEP::EXPRESS::STRING>()) {
std::string value = static_cast<std::string>(*str);
ss << "'" << value << "'";
}
else if (const ::Assimp::STEP::EXPRESS::REAL* val = v->ToPtr<::Assimp::STEP::EXPRESS::REAL>()) {
float value = static_cast<float>(*val);
} else if (const ::Assimp::STEP::EXPRESS::REAL *val1 = v->ToPtr<::Assimp::STEP::EXPRESS::REAL>()) {
float value = static_cast<float>(*val1);
ss << value;
}
else if (const ::Assimp::STEP::EXPRESS::INTEGER* val = v->ToPtr<::Assimp::STEP::EXPRESS::INTEGER>()) {
int64_t value = static_cast<int64_t>(*val);
} else if (const ::Assimp::STEP::EXPRESS::INTEGER *val2 = v->ToPtr<::Assimp::STEP::EXPRESS::INTEGER>()) {
int64_t value = static_cast<int64_t>(*val2);
ss << value;
}
if (index + 1 < listValue->ListValues.size()) {
@ -647,25 +611,20 @@ void ProcessMetadata(const Schema_2x3::ListOf< Schema_2x3::Lazy< Schema_2x3::Ifc
}
ss << "]";
properties[key] = ss.str();
}
else if (const Schema_2x3::IfcComplexProperty* const complexProp = property.ToPtr<Schema_2x3::IfcComplexProperty>()) {
} else if (const Schema_2x3::IfcComplexProperty *const complexProp = property.ToPtr<Schema_2x3::IfcComplexProperty>()) {
if (nest > 2) { // mostly arbitrary limit to prevent stack overflow vulnerabilities
IFCImporter::LogError("maximum nesting level for IfcComplexProperty reached, skipping this property.");
}
else {
} else {
ProcessMetadata(complexProp->HasProperties, conv, properties, key, nest + 1);
}
}
else {
} else {
properties[key] = "";
}
}
}
// ------------------------------------------------------------------------------------------------
void ProcessMetadata(uint64_t relDefinesByPropertiesID, ConversionData& conv, Metadata& properties)
{
void ProcessMetadata(uint64_t relDefinesByPropertiesID, ConversionData &conv, Metadata &properties) {
if (const Schema_2x3::IfcRelDefinesByProperties *const pset = conv.db.GetObject(relDefinesByPropertiesID)->ToPtr<Schema_2x3::IfcRelDefinesByProperties>()) {
if (const Schema_2x3::IfcPropertySet *const set = conv.db.GetObject(pset->RelatingPropertyDefinition->GetID())->ToPtr<Schema_2x3::IfcPropertySet>()) {
ProcessMetadata(set->HasProperties, conv, properties);
@ -790,7 +749,6 @@ aiNode* ProcessSpatialStructure(aiNode* parent, const Schema_2x3::IfcProduct& el
nd_aggr->mNumChildren = 1;
nd_aggr->mChildren = new aiNode *[1]();
nd_aggr->mChildren[0] = ndnew;
if (openings_local.size()) {
@ -872,11 +830,9 @@ aiNode* ProcessSpatialStructure(aiNode* parent, const Schema_2x3::IfcProduct& el
}
// ------------------------------------------------------------------------------------------------
void ProcessSpatialStructures(ConversionData& conv)
{
void ProcessSpatialStructures(ConversionData &conv) {
// XXX add support for multiple sites (i.e. IfcSpatialStructureElements with composition == COMPLEX)
// process all products in the file. it is reasonable to assume that a
// file that is relevant for us contains at least a site or a building.
const STEP::DB::ObjectMapByType &map = conv.db.GetObjectsByType();
@ -939,8 +895,7 @@ void ProcessSpatialStructures(ConversionData& conv)
if (nb_nodes == 1) {
conv.out->mRootNode = nodes[0];
}
else if (nb_nodes > 1) {
} else if (nb_nodes > 1) {
conv.out->mRootNode = new aiNode("Root");
conv.out->mRootNode->mParent = NULL;
conv.out->mRootNode->mNumChildren = static_cast<unsigned int>(nb_nodes);
@ -953,15 +908,13 @@ void ProcessSpatialStructures(ConversionData& conv)
conv.out->mRootNode->mChildren[i] = node;
}
}
else {
} else {
IFCImporter::ThrowException("failed to determine primary site element");
}
}
// ------------------------------------------------------------------------------------------------
void MakeTreeRelative(aiNode* start, const aiMatrix4x4& combined)
{
void MakeTreeRelative(aiNode *start, const aiMatrix4x4 &combined) {
// combined is the parent's absolute transformation matrix
const aiMatrix4x4 old = start->mTransformation;
@ -976,13 +929,10 @@ void MakeTreeRelative(aiNode* start, const aiMatrix4x4& combined)
}
// ------------------------------------------------------------------------------------------------
void MakeTreeRelative(ConversionData& conv)
{
void MakeTreeRelative(ConversionData &conv) {
MakeTreeRelative(conv.out->mRootNode, IfcMatrix4());
}
} // !anon
} // namespace
#endif

View File

@ -362,8 +362,9 @@ void TempMesh::FixupFaceOrientation()
{
std::reverse(mVerts.begin() + nbvsi, mVerts.begin() + nbvsi + nbvc);
std::reverse(neighbour.begin() + nbvsi, neighbour.begin() + nbvsi + nbvc);
for( size_t a = 0; a < nbvc - 1; ++a )
std::swap(neighbour[nbvsi + a], neighbour[nbvsi + a + 1]);
for (size_t aa = 0; aa < nbvc - 1; ++aa) {
std::swap(neighbour[nbvsi + aa], neighbour[nbvsi + aa + 1]);
}
}
// either way we're done with the neighbour. Mark it as done and continue checking from there recursively

View File

@ -50,12 +50,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/TinyFormatter.h>
#include <assimp/fast_atof.h>
#include <memory>
#include <functional>
using namespace Assimp;
namespace EXPRESS = STEP::EXPRESS;
#include <functional>
namespace EXPRESS = STEP::EXPRESS;
// ------------------------------------------------------------------------------------------------
std::string AddLineNumber(const std::string& s,uint64_t line /*= LINE_NOT_SPECIFIED*/, const std::string& prefix = "")
@ -127,8 +126,8 @@ STEP::DB* STEP::ReadFileHeader(std::shared_ptr<IOStream> stream) {
if (list->GetSize() > 1) {
ASSIMP_LOG_WARN(AddLineNumber("multiple schemas currently not supported",line));
}
const EXPRESS::STRING* string( nullptr );
if (!list->GetSize() || !(string=dynamic_cast<const EXPRESS::STRING*>( (*list)[0].get() ))) {
const EXPRESS::STRING *string = dynamic_cast<const EXPRESS::STRING *>((*list)[0].get());
if (!list->GetSize() || nullptr == string ) {
throw STEP::SyntaxError("expected FILE_SCHEMA to contain a single string literal",line);
}
head.fileSchema = *string;
@ -539,7 +538,7 @@ void STEP::LazyObject::LazyInit() const {
}
const char* acopy = args;
std::shared_ptr<const EXPRESS::LIST> conv_args = EXPRESS::LIST::Parse(acopy,STEP::SyntaxError::LINE_NOT_SPECIFIED,&db.GetSchema());
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;

View File

@ -45,24 +45,23 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* @brief Implementation of the LWO importer class
*/
#ifndef ASSIMP_BUILD_NO_LWO_IMPORTER
// internal headers
#include "LWO/LWOLoader.h"
#include "PostProcessing/ProcessHelper.h"
#include "PostProcessing/ConvertToLHProcess.h"
#include "PostProcessing/ProcessHelper.h"
#include <assimp/StringComparison.h>
#include <assimp/SGSpatialSort.h>
#include <assimp/ByteSwapper.h>
#include <assimp/IOSystem.hpp>
#include <assimp/SGSpatialSort.h>
#include <assimp/StringComparison.h>
#include <assimp/importerdesc.h>
#include <assimp/IOSystem.hpp>
#include <memory>
#include <sstream>
#include <iomanip>
#include <map>
#include <memory>
#include <sstream>
using namespace Assimp;
@ -81,8 +80,8 @@ static const aiImporterDesc desc = {
// ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer
LWOImporter::LWOImporter()
: mIsLWO2(),
LWOImporter::LWOImporter() :
mIsLWO2(),
mIsLXOB(),
mLayers(),
mCurLayer(),
@ -91,22 +90,23 @@ LWOImporter::LWOImporter()
mSurfaces(),
mFileBuffer(),
fileSize(),
pScene(),
mScene(nullptr),
configSpeedFlag(),
configLayerIndex(),
hasNamedLayer()
{}
hasNamedLayer() {
// empty
}
// ------------------------------------------------------------------------------------------------
// Destructor, private as well
LWOImporter::~LWOImporter()
{}
LWOImporter::~LWOImporter() {
// empty
}
// ------------------------------------------------------------------------------------------------
// Returns whether the class can handle the format of the given file.
bool LWOImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
{
const std::string extension = GetExtension(pFile);
bool LWOImporter::CanRead(const std::string &file, IOSystem *pIOHandler, bool checkSig) const {
const std::string extension = GetExtension(file);
if (extension == "lwo" || extension == "lxo") {
return true;
}
@ -117,15 +117,14 @@ bool LWOImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool
tokens[0] = AI_LWO_FOURCC_LWOB;
tokens[1] = AI_LWO_FOURCC_LWO2;
tokens[2] = AI_LWO_FOURCC_LXOB;
return CheckMagicToken(pIOHandler,pFile,tokens,3,8);
return CheckMagicToken(pIOHandler, file, tokens, 3, 8);
}
return false;
}
// ------------------------------------------------------------------------------------------------
// Setup configuration properties
void LWOImporter::SetupProperties(const Importer* pImp)
{
void LWOImporter::SetupProperties(const Importer *pImp) {
configSpeedFlag = (0 != pImp->GetPropertyInteger(AI_CONFIG_FAVOUR_SPEED, 0) ? true : false);
configLayerIndex = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_LWO_ONE_LAYER_ONLY, UINT_MAX);
configLayerName = pImp->GetPropertyString(AI_CONFIG_IMPORT_LWO_ONE_LAYER_ONLY, "");
@ -133,8 +132,7 @@ void LWOImporter::SetupProperties(const Importer* pImp)
// ------------------------------------------------------------------------------------------------
// Get list of file extensions
const aiImporterDesc* LWOImporter::GetInfo () const
{
const aiImporterDesc *LWOImporter::GetInfo() const {
return &desc;
}
@ -142,21 +140,22 @@ const aiImporterDesc* LWOImporter::GetInfo () const
// Imports the given file into the given scene structure.
void LWOImporter::InternReadFile(const std::string &pFile,
aiScene *pScene,
IOSystem* pIOHandler)
{
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 LWO file " + pFile + ".");
}
if((this->fileSize = (unsigned int)file->FileSize()) < 12)
if ((this->fileSize = (unsigned int)file->FileSize()) < 12) {
throw DeadlyImportError("LWO: The file is too small to contain the IFF header");
}
// Allocate storage and copy the contents of the file to a memory buffer
std::vector<uint8_t> mBuffer(fileSize);
file->Read(&mBuffer[0], 1, fileSize);
this->pScene = pScene;
this->mScene = pScene;
// Determine the type of the file
uint32_t fileType;
@ -186,7 +185,7 @@ void LWOImporter::InternReadFile( const std::string& pFile,
mLayers->push_back(Layer());
mCurLayer = &mLayers->back();
mCurLayer->mName = "<LWODefault>";
mCurLayer->mIndex = -1;
mCurLayer->mIndex = (uint16_t) -1;
// old lightwave file format (prior to v6)
if (AI_LWO_FOURCC_LWOB == fileType) {
@ -207,8 +206,7 @@ void LWOImporter::InternReadFile( const std::string& pFile,
ASSIMP_LOG_INFO("LWO file format: LXOB (Modo)");
}
// we don't know this format
else
{
else {
char szBuff[5];
szBuff[0] = (char)(fileType >> 24u);
szBuff[1] = (char)(fileType >> 16u);
@ -235,8 +233,7 @@ void LWOImporter::InternReadFile( const std::string& pFile,
}
if (configLayerName.length() && !hasNamedLayer) {
throw DeadlyImportError("LWO2: Unable to find the requested layer: "
+ configLayerName);
throw DeadlyImportError("LWO2: Unable to find the requested layer: " + configLayerName);
}
}
@ -271,8 +268,7 @@ void LWOImporter::InternReadFile( const std::string& pFile,
}
unsigned int idx = (*it).surfaceIndex;
if (idx >= mTags->size())
{
if (idx >= mTags->size()) {
ASSIMP_LOG_WARN("LWO: Invalid face surface index");
idx = UINT_MAX;
}
@ -291,8 +287,8 @@ void LWOImporter::InternReadFile( const std::string& pFile,
if (UINT_MAX == iDefaultSurface) {
pSorted.erase(pSorted.end() - 1);
}
for (unsigned int p = 0,i = 0;i < mSurfaces->size();++i) {
SortedRep& sorted = pSorted[i];
for (unsigned int p = 0, j = 0; j < mSurfaces->size(); ++j) {
SortedRep &sorted = pSorted[j];
if (sorted.empty())
continue;
@ -307,9 +303,9 @@ void LWOImporter::InternReadFile( const std::string& pFile,
mesh->mNumVertices += layer.mFaces[*it].mNumIndices;
}
aiVector3D *nrm = NULL, * pv = mesh->mVertices = new aiVector3D[mesh->mNumVertices];
aiVector3D *nrm = nullptr, *pv = mesh->mVertices = new aiVector3D[mesh->mNumVertices];
aiFace *pf = mesh->mFaces = new aiFace[mesh->mNumFaces];
mesh->mMaterialIndex = i;
mesh->mMaterialIndex = j;
// find out which vertex color channels and which texture coordinate
// channels are really required by the material attached to this mesh
@ -325,8 +321,8 @@ void LWOImporter::InternReadFile( const std::string& pFile,
}
#endif
FindUVChannels(_mSurfaces[i],sorted,layer,vUVChannelIndices);
FindVCChannels(_mSurfaces[i],sorted,layer,vVColorIndices);
FindUVChannels(_mSurfaces[j], sorted, layer, vUVChannelIndices);
FindVCChannels(_mSurfaces[j], sorted, layer, vVColorIndices);
// allocate storage for UV and CV channels
aiVector3D *pvUV[AI_MAX_NUMBER_OF_TEXTURECOORDS];
@ -341,8 +337,9 @@ void LWOImporter::InternReadFile( const std::string& pFile,
mesh->mNumUVComponents[0] = 2;
}
if (layer.mNormals.name.length())
if (layer.mNormals.name.length()) {
nrm = mesh->mNormals = new aiVector3D[mesh->mNumVertices];
}
aiColor4D *pvVC[AI_MAX_NUMBER_OF_COLOR_SETS];
for (unsigned int mui = 0; mui < AI_MAX_NUMBER_OF_COLOR_SETS; ++mui) {
@ -415,7 +412,8 @@ void LWOImporter::InternReadFile( const std::string& pFile,
}
pf->mIndices = face.mIndices;
pf->mNumIndices = face.mNumIndices;
unsigned int** p = (unsigned int**)&face.mIndices;*p = NULL; // HACK: make sure it won't be deleted
unsigned int **facePtr = (unsigned int **)&face.mIndices;
*facePtr = nullptr; // HACK: make sure it won't be deleted
pf++;
}
@ -424,8 +422,7 @@ void LWOImporter::InternReadFile( const std::string& pFile,
// Step here since it wouldn't handle smoothing groups correctly for LWO.
// So we use a separate implementation.
ComputeNormals(mesh, smoothingGroups, _mSurfaces[i]);
}
else {
} else {
ASSIMP_LOG_DEBUG("LWO2: No need to compute normals, they're already there");
}
++p;
@ -470,8 +467,7 @@ void LWOImporter::InternReadFile( const std::string& pFile,
// ------------------------------------------------------------------------------------------------
void LWOImporter::ComputeNormals(aiMesh *mesh, const std::vector<unsigned int> &smoothingGroups,
const LWO::Surface& surface)
{
const LWO::Surface &surface) {
// Allocate output storage
mesh->mNormals = new aiVector3D[mesh->mNumVertices];
@ -510,11 +506,9 @@ void LWOImporter::ComputeNormals(aiMesh* mesh, const std::vector<unsigned int>&
// Now generate the spatial sort tree
SGSpatialSort sSort;
std::vector<unsigned int>::const_iterator it = smoothingGroups.begin();
for( begin = mesh->mFaces; begin != end; ++begin, ++it)
{
for (begin = mesh->mFaces; begin != end; ++begin, ++it) {
aiFace &face = *begin;
for (unsigned int i = 0; i < face.mNumIndices;++i)
{
for (unsigned int i = 0; i < face.mNumIndices; ++i) {
unsigned int tt = face.mIndices[i];
sSort.Add(mesh->mVertices[tt], tt, *it);
}
@ -532,14 +526,12 @@ void LWOImporter::ComputeNormals(aiMesh* mesh, const std::vector<unsigned int>&
for (begin = mesh->mFaces, it = smoothingGroups.begin(); begin != end; ++begin, ++it) {
const aiFace &face = *begin;
unsigned int *beginIdx = face.mIndices, *const endIdx = face.mIndices + face.mNumIndices;
for (; beginIdx != endIdx; ++beginIdx)
{
for (; beginIdx != endIdx; ++beginIdx) {
unsigned int idx = *beginIdx;
sSort.FindPositions(mesh->mVertices[idx], *it, posEpsilon, poResult, true);
std::vector<unsigned int>::const_iterator a, end = poResult.end();
aiVector3D vNormals;
for (a = poResult.begin();a != end;++a) {
for (std::vector<unsigned int>::const_iterator a = poResult.begin(); a != poResult.end(); ++a) {
const aiVector3D &v = faceNormals[*a];
if (v * faceNormals[idx] < fLimit)
continue;
@ -555,21 +547,19 @@ void LWOImporter::ComputeNormals(aiMesh* mesh, const std::vector<unsigned int>&
for (begin = mesh->mFaces, it = smoothingGroups.begin(); begin != end; ++begin, ++it) {
const aiFace &face = *begin;
unsigned int *beginIdx = face.mIndices, *const endIdx = face.mIndices + face.mNumIndices;
for (; beginIdx != endIdx; ++beginIdx)
{
for (; beginIdx != endIdx; ++beginIdx) {
unsigned int idx = *beginIdx;
if (vertexDone[idx])
continue;
sSort.FindPositions(mesh->mVertices[idx], *it, posEpsilon, poResult, true);
std::vector<unsigned int>::const_iterator a, end = poResult.end();
aiVector3D vNormals;
for (a = poResult.begin();a != end;++a) {
for (std::vector<unsigned int>::const_iterator a = poResult.begin(); a != poResult.end(); ++a) {
const aiVector3D &v = faceNormals[*a];
vNormals += v;
}
vNormals.Normalize();
for (a = poResult.begin();a != end;++a) {
for (std::vector<unsigned int>::const_iterator a = poResult.begin(); a != poResult.end(); ++a) {
mesh->mNormals[*a] = vNormals;
vertexDone[*a] = true;
}
@ -579,10 +569,9 @@ void LWOImporter::ComputeNormals(aiMesh* mesh, const std::vector<unsigned int>&
}
// ------------------------------------------------------------------------------------------------
void LWOImporter::GenerateNodeGraph(std::map<uint16_t,aiNode*>& apcNodes)
{
void LWOImporter::GenerateNodeGraph(std::map<uint16_t, aiNode *> &apcNodes) {
// now generate the final nodegraph - generate a root node and attach children
aiNode* root = pScene->mRootNode = new aiNode();
aiNode *root = mScene->mRootNode = new aiNode();
root->mName.Set("<LWORoot>");
//Set parent of all children, inserting pivots
@ -622,7 +611,7 @@ void LWOImporter::GenerateNodeGraph(std::map<uint16_t,aiNode*>& apcNodes)
}
//Set children of all parents
apcNodes[-1] = root;
apcNodes[(uint16_t)-1] = root;
for (auto itMapParentNodes = apcNodes.begin(); itMapParentNodes != apcNodes.end(); ++itMapParentNodes) {
for (auto itMapChildNodes = apcNodes.begin(); itMapChildNodes != apcNodes.end(); ++itMapChildNodes) {
if ((itMapParentNodes->first != itMapChildNodes->first) && (itMapParentNodes->second == itMapChildNodes->second->mParent)) {
@ -640,28 +629,27 @@ void LWOImporter::GenerateNodeGraph(std::map<uint16_t,aiNode*>& apcNodes)
}
}
if (!pScene->mRootNode->mNumChildren)
if (!mScene->mRootNode->mNumChildren)
throw DeadlyImportError("LWO: Unable to build a valid node graph");
// Remove a single root node with no meshes assigned to it ...
if (1 == pScene->mRootNode->mNumChildren) {
aiNode* pc = pScene->mRootNode->mChildren[0];
pc->mParent = pScene->mRootNode->mChildren[0] = NULL;
delete pScene->mRootNode;
pScene->mRootNode = pc;
if (1 == mScene->mRootNode->mNumChildren) {
aiNode *pc = mScene->mRootNode->mChildren[0];
pc->mParent = mScene->mRootNode->mChildren[0] = nullptr;
delete mScene->mRootNode;
mScene->mRootNode = pc;
}
// convert the whole stuff to RH with CCW winding
MakeLeftHandedProcess maker;
maker.Execute(pScene);
maker.Execute(mScene);
FlipWindingOrderProcess flipper;
flipper.Execute(pScene);
flipper.Execute(mScene);
}
// ------------------------------------------------------------------------------------------------
void LWOImporter::ResolveTags()
{
void LWOImporter::ResolveTags() {
// --- this function is used for both LWO2 and LWOB
mMapping->resize(mTags->size(), UINT_MAX);
for (unsigned int a = 0; a < mTags->size(); ++a) {
@ -680,8 +668,7 @@ void LWOImporter::ResolveTags()
}
// ------------------------------------------------------------------------------------------------
void LWOImporter::ResolveClips()
{
void LWOImporter::ResolveClips() {
for (unsigned int i = 0; i < mClips.size(); ++i) {
Clip &clip = mClips[i];
@ -707,8 +694,7 @@ void LWOImporter::ResolveClips()
}
// ------------------------------------------------------------------------------------------------
void LWOImporter::AdjustTexturePath(std::string& out)
{
void LWOImporter::AdjustTexturePath(std::string &out) {
// --- this function is used for both LWO2 and LWOB
if (!mIsLWO2 && ::strstr(out.c_str(), "(sequence)")) {
@ -725,16 +711,13 @@ void LWOImporter::AdjustTexturePath(std::string& out)
}
// ------------------------------------------------------------------------------------------------
void LWOImporter::LoadLWOTags(unsigned int size)
{
void LWOImporter::LoadLWOTags(unsigned int size) {
// --- this function is used for both LWO2 and LWOB
const char *szCur = (const char *)mFileBuffer, *szLast = szCur;
const char *const szEnd = szLast + size;
while (szCur < szEnd)
{
if (!(*szCur))
{
while (szCur < szEnd) {
if (!(*szCur)) {
const size_t len = (size_t)(szCur - szLast);
// FIX: skip empty-sized tags
if (len)
@ -747,27 +730,24 @@ void LWOImporter::LoadLWOTags(unsigned int size)
}
// ------------------------------------------------------------------------------------------------
void LWOImporter::LoadLWOPoints(unsigned int length)
{
void LWOImporter::LoadLWOPoints(unsigned int length) {
// --- this function is used for both LWO2 and LWOB but for
// LWO2 we need to allocate 25% more storage - it could be we'll
// need to duplicate some points later.
const size_t vertexLen = 12;
if ((length % vertexLen) != 0)
{
if ((length % vertexLen) != 0) {
throw DeadlyImportError("LWO2: Points chunk length is not multiple of vertexLen (12)");
}
unsigned int regularSize = (unsigned int)mCurLayer->mTempPoints.size() + length / 12;
if (mIsLWO2)
{
if (mIsLWO2) {
mCurLayer->mTempPoints.reserve(regularSize + (regularSize >> 2u));
mCurLayer->mTempPoints.resize(regularSize);
// initialize all point referrers with the default values
mCurLayer->mPointReferrers.reserve(regularSize + (regularSize >> 2u));
mCurLayer->mPointReferrers.resize(regularSize, UINT_MAX);
}
else mCurLayer->mTempPoints.resize( regularSize );
} else
mCurLayer->mTempPoints.resize(regularSize);
// perform endianness conversions
#ifndef AI_BUILD_BIG_ENDIAN
@ -778,20 +758,19 @@ void LWOImporter::LoadLWOPoints(unsigned int length)
}
// ------------------------------------------------------------------------------------------------
void LWOImporter::LoadLWO2Polygons(unsigned int length)
{
void LWOImporter::LoadLWO2Polygons(unsigned int length) {
LE_NCONST uint16_t *const end = (LE_NCONST uint16_t *)(mFileBuffer + length);
const uint32_t type = GetU4();
// Determine the type of the polygons
switch (type)
{
switch (type) {
// read unsupported stuff too (although we won't process it)
case AI_LWO_MBAL:
ASSIMP_LOG_WARN("LWO2: Encountered unsupported primitive chunk (METABALL)");
break;
case AI_LWO_CURV:
ASSIMP_LOG_WARN("LWO2: Encountered unsupported primitive chunk (SPLINE)");;
ASSIMP_LOG_WARN("LWO2: Encountered unsupported primitive chunk (SPLINE)");
;
break;
// These are ok with no restrictions
@ -814,8 +793,7 @@ void LWOImporter::LoadLWO2Polygons(unsigned int length)
CountVertsAndFacesLWO2(iNumVertices, iNumFaces, cursor, end);
// allocate the output array and copy face indices
if (iNumFaces)
{
if (iNumFaces) {
cursor = (uint16_t *)mFileBuffer;
mCurLayer->mFaces.resize(iNumFaces, LWO::Face(type));
@ -826,10 +804,8 @@ void LWOImporter::LoadLWO2Polygons(unsigned int length)
// ------------------------------------------------------------------------------------------------
void LWOImporter::CountVertsAndFacesLWO2(unsigned int &verts, unsigned int &faces,
uint16_t*& cursor, const uint16_t* const end, unsigned int max)
{
while (cursor < end && max--)
{
uint16_t *&cursor, const uint16_t *const end, unsigned int max) {
while (cursor < end && max--) {
uint16_t numIndices;
::memcpy(&numIndices, cursor++, 2);
AI_LSWAP2(numIndices);
@ -838,8 +814,7 @@ void LWOImporter::CountVertsAndFacesLWO2(unsigned int& verts, unsigned int& face
verts += numIndices;
++faces;
for(uint16_t i = 0; i < numIndices; i++)
{
for (uint16_t i = 0; i < numIndices; i++) {
ReadVSizedIntLWO2((uint8_t *&)cursor);
}
}
@ -848,10 +823,8 @@ void LWOImporter::CountVertsAndFacesLWO2(unsigned int& verts, unsigned int& face
// ------------------------------------------------------------------------------------------------
void LWOImporter::CopyFaceIndicesLWO2(FaceList::iterator &it,
uint16_t *&cursor,
const uint16_t* const end)
{
while (cursor < end)
{
const uint16_t *const end) {
while (cursor < end) {
LWO::Face &face = *it++;
uint16_t numIndices;
::memcpy(&numIndices, cursor++, 2);
@ -861,24 +834,20 @@ void LWOImporter::CopyFaceIndicesLWO2(FaceList::iterator& it,
if (face.mNumIndices) /* byte swapping has already been done */
{
face.mIndices = new unsigned int[face.mNumIndices];
for(unsigned int i = 0; i < face.mNumIndices; i++)
{
for (unsigned int i = 0; i < face.mNumIndices; i++) {
face.mIndices[i] = ReadVSizedIntLWO2((uint8_t *&)cursor) + mCurLayer->mPointIDXOfs;
if(face.mIndices[i] > mCurLayer->mTempPoints.size())
{
if (face.mIndices[i] > mCurLayer->mTempPoints.size()) {
ASSIMP_LOG_WARN("LWO2: Failure evaluating face record, index is out of range");
face.mIndices[i] = (unsigned int)mCurLayer->mTempPoints.size() - 1;
}
}
}
else throw DeadlyImportError("LWO2: Encountered invalid face record with zero indices");
} else
throw DeadlyImportError("LWO2: Encountered invalid face record with zero indices");
}
}
// ------------------------------------------------------------------------------------------------
void LWOImporter::LoadLWO2PolygonTags(unsigned int length)
{
void LWOImporter::LoadLWO2PolygonTags(unsigned int length) {
LE_NCONST uint8_t *const end = mFileBuffer + length;
AI_LWO_VALIDATE_CHUNK_LENGTH(length, PTAG, 4);
@ -887,8 +856,7 @@ void LWOImporter::LoadLWO2PolygonTags(unsigned int length)
if (type != AI_LWO_SURF && type != AI_LWO_SMGP)
return;
while (mFileBuffer < end)
{
while (mFileBuffer < end) {
unsigned int i = ReadVSizedIntLWO2(mFileBuffer) + mCurLayer->mFaceIDXOfs;
unsigned int j = GetU2();
@ -911,8 +879,7 @@ void LWOImporter::LoadLWO2PolygonTags(unsigned int length)
// ------------------------------------------------------------------------------------------------
template <class T>
VMapEntry* FindEntry(std::vector< T >& list,const std::string& name, bool perPoly)
{
VMapEntry *FindEntry(std::vector<T> &list, const std::string &name, bool perPoly) {
for (auto &elem : list) {
if (elem.name == name) {
if (!perPoly) {
@ -929,8 +896,7 @@ VMapEntry* FindEntry(std::vector< T >& list,const std::string& name, bool perPol
// ------------------------------------------------------------------------------------------------
template <class T>
inline void CreateNewEntry(T& chan, unsigned int srcIdx)
{
inline void CreateNewEntry(T &chan, unsigned int srcIdx) {
if (!chan.name.length())
return;
@ -943,8 +909,7 @@ inline void CreateNewEntry(T& chan, unsigned int srcIdx)
// ------------------------------------------------------------------------------------------------
template <class T>
inline void CreateNewEntry(std::vector< T >& list, unsigned int srcIdx)
{
inline void CreateNewEntry(std::vector<T> &list, unsigned int srcIdx) {
for (auto &elem : list) {
CreateNewEntry(elem, srcIdx);
}
@ -952,8 +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)
{
unsigned int idx, float *data) {
ai_assert(NULL != data);
LWO::ReferrerList &refList = mCurLayer->mPointReferrers;
unsigned int i;
@ -972,8 +936,7 @@ inline void LWOImporter::DoRecursiveVMAPAssignment(VMapEntry* base, unsigned int
}
// ------------------------------------------------------------------------------------------------
inline void AddToSingleLinkedList(ReferrerList& refList, unsigned int srcIdx, unsigned int destIdx)
{
inline void AddToSingleLinkedList(ReferrerList &refList, unsigned int srcIdx, unsigned int destIdx) {
if (UINT_MAX == refList[srcIdx]) {
refList[srcIdx] = destIdx;
return;
@ -983,8 +946,7 @@ inline void AddToSingleLinkedList(ReferrerList& refList, unsigned int srcIdx, un
// ------------------------------------------------------------------------------------------------
// Load LWO2 vertex map
void LWOImporter::LoadLWO2VertexMap(unsigned int length, bool perPoly)
{
void LWOImporter::LoadLWO2VertexMap(unsigned int length, bool perPoly) {
LE_NCONST uint8_t *const end = mFileBuffer + length;
AI_LWO_VALIDATE_CHUNK_LENGTH(length, VMAP, 6);
@ -997,12 +959,10 @@ void LWOImporter::LoadLWO2VertexMap(unsigned int length, bool perPoly)
std::string name;
GetS0(name, length);
switch (type)
{
switch (type) {
case AI_LWO_TXUV:
if (dims != 2) {
ASSIMP_LOG_WARN("LWO2: Skipping UV channel \'"
+ name + "\' with !2 components");
ASSIMP_LOG_WARN("LWO2: Skipping UV channel \'" + name + "\' with !2 components");
return;
}
base = FindEntry(mCurLayer->mUVChannels, name, perPoly);
@ -1010,18 +970,15 @@ void LWOImporter::LoadLWO2VertexMap(unsigned int length, bool perPoly)
case AI_LWO_WGHT:
case AI_LWO_MNVW:
if (dims != 1) {
ASSIMP_LOG_WARN("LWO2: Skipping Weight Channel \'"
+ name + "\' with !1 components");
ASSIMP_LOG_WARN("LWO2: Skipping Weight Channel \'" + name + "\' with !1 components");
return;
}
base = FindEntry((type == AI_LWO_WGHT ? mCurLayer->mWeightChannels
: mCurLayer->mSWeightChannels),name,perPoly);
base = FindEntry((type == AI_LWO_WGHT ? mCurLayer->mWeightChannels : mCurLayer->mSWeightChannels), name, perPoly);
break;
case AI_LWO_RGB:
case AI_LWO_RGBA:
if (dims != 3 && dims != 4) {
ASSIMP_LOG_WARN("LWO2: Skipping Color Map \'"
+ name + "\' with a dimension > 4 or < 3");
ASSIMP_LOG_WARN("LWO2: Skipping Color Map \'" + name + "\' with a dimension > 4 or < 3");
return;
}
base = FindEntry(mCurLayer->mVColorChannels, name, perPoly);
@ -1096,8 +1053,7 @@ void LWOImporter::LoadLWO2VertexMap(unsigned int length, bool perPoly)
do {
if (tmp == srcIdx)
break;
}
while ((tmp = refList[tmp]) != UINT_MAX);
} while ((tmp = refList[tmp]) != UINT_MAX);
if (tmp == UINT_MAX) {
continue;
}
@ -1138,8 +1094,7 @@ void LWOImporter::LoadLWO2VertexMap(unsigned int length, bool perPoly)
// ------------------------------------------------------------------------------------------------
// Load LWO2 clip
void LWOImporter::LoadLWO2Clip(unsigned int length)
{
void LWOImporter::LoadLWO2Clip(unsigned int length) {
AI_LWO_VALIDATE_CHUNK_LENGTH(length, CLIP, 10);
mClips.push_back(LWO::Clip());
@ -1149,8 +1104,7 @@ void LWOImporter::LoadLWO2Clip(unsigned int length)
clip.idx = GetU4();
IFF::SubChunkHeader head = IFF::LoadSubChunk(mFileBuffer);
switch (head.type)
{
switch (head.type) {
case AI_LWO_STIL:
AI_LWO_VALIDATE_CHUNK_LENGTH(head.length, STIL, 1);
@ -1163,9 +1117,12 @@ void LWOImporter::LoadLWO2Clip(unsigned int length)
AI_LWO_VALIDATE_CHUNK_LENGTH(head.length, ISEQ, 16);
// Image sequence. We'll later take the first.
{
uint8_t digits = GetU1(); mFileBuffer++;
int16_t offset = GetU2(); mFileBuffer+=4;
int16_t start = GetU2(); mFileBuffer+=4;
uint8_t digits = GetU1();
mFileBuffer++;
int16_t offset = GetU2();
mFileBuffer += 4;
int16_t start = GetU2();
mFileBuffer += 4;
std::string s;
std::ostringstream ss;
@ -1209,8 +1166,7 @@ void LWOImporter::LoadLWO2Clip(unsigned int length)
// ------------------------------------------------------------------------------------------------
// Load envelope description
void LWOImporter::LoadLWO2Envelope(unsigned int length)
{
void LWOImporter::LoadLWO2Envelope(unsigned int length) {
LE_NCONST uint8_t *const end = mFileBuffer + length;
AI_LWO_VALIDATE_CHUNK_LENGTH(length, ENVL, 4);
@ -1223,18 +1179,15 @@ void LWOImporter::LoadLWO2Envelope(unsigned int length)
// It looks like there might be an extra U4 right after the index,
// at least in modo (LXOB) files: we'll ignore it if it's zero,
// otherwise it represents the start of a subchunk, so we backtrack.
if (mIsLXOB)
{
if (mIsLXOB) {
uint32_t extra = GetU4();
if (extra)
{
if (extra) {
mFileBuffer -= 4;
}
}
// ... and read all subchunks
while (true)
{
while (true) {
if (mFileBuffer + 6 >= end) break;
LE_NCONST IFF::SubChunkHeader head = IFF::LoadSubChunk(mFileBuffer);
@ -1242,8 +1195,7 @@ void LWOImporter::LoadLWO2Envelope(unsigned int length)
throw DeadlyImportError("LWO2: Invalid envelope chunk length");
uint8_t *const next = mFileBuffer + head.length;
switch (head.type)
{
switch (head.type) {
// Type & representation of the envelope
case AI_LWO_TYPE:
AI_LWO_VALIDATE_CHUNK_LENGTH(head.length, TYPE, 2);
@ -1267,8 +1219,7 @@ void LWOImporter::LoadLWO2Envelope(unsigned int length)
break;
// keyframe
case AI_LWO_KEY:
{
case AI_LWO_KEY: {
AI_LWO_VALIDATE_CHUNK_LENGTH(head.length, KEY, 8);
envelope.keys.push_back(LWO::Key());
@ -1280,27 +1231,31 @@ void LWOImporter::LoadLWO2Envelope(unsigned int length)
}
// interval interpolation
case AI_LWO_SPAN:
{
case AI_LWO_SPAN: {
AI_LWO_VALIDATE_CHUNK_LENGTH(head.length, SPAN, 4);
if (envelope.keys.size() < 2)
ASSIMP_LOG_WARN("LWO2: Unexpected SPAN chunk");
else {
LWO::Key &key = envelope.keys.back();
switch (GetU4())
{
switch (GetU4()) {
case AI_LWO_STEP:
key.inter = LWO::IT_STEP;break;
key.inter = LWO::IT_STEP;
break;
case AI_LWO_LINE:
key.inter = LWO::IT_LINE;break;
key.inter = LWO::IT_LINE;
break;
case AI_LWO_TCB:
key.inter = LWO::IT_TCB;break;
key.inter = LWO::IT_TCB;
break;
case AI_LWO_HERM:
key.inter = LWO::IT_HERM;break;
key.inter = LWO::IT_HERM;
break;
case AI_LWO_BEZI:
key.inter = LWO::IT_BEZI;break;
key.inter = LWO::IT_BEZI;
break;
case AI_LWO_BEZ2:
key.inter = LWO::IT_BEZ2;break;
key.inter = LWO::IT_BEZ2;
break;
default:
ASSIMP_LOG_WARN("LWO2: Unknown interval interpolation mode");
};
@ -1321,19 +1276,16 @@ void LWOImporter::LoadLWO2Envelope(unsigned int length)
// ------------------------------------------------------------------------------------------------
// Load file - master function
void LWOImporter::LoadLWO2File()
{
void LWOImporter::LoadLWO2File() {
bool skip = false;
LE_NCONST uint8_t *const end = mFileBuffer + fileSize;
unsigned int iUnnamed = 0;
while (true)
{
while (true) {
if (mFileBuffer + sizeof(IFF::ChunkHeader) > end) break;
const IFF::ChunkHeader head = IFF::LoadChunk(mFileBuffer);
if (mFileBuffer + head.length > end)
{
if (mFileBuffer + head.length > end) {
throw DeadlyImportError("LWO2: Chunk length points behind the file");
break;
}
@ -1344,11 +1296,9 @@ void LWOImporter::LoadLWO2File()
continue;
}
switch (head.type)
{
switch (head.type) {
// new layer
case AI_LWO_LAYR:
{
case AI_LWO_LAYR: {
// add a new layer to the list ....
mLayers->push_back(LWO::Layer());
LWO::Layer &layer = mLayers->back();
@ -1362,8 +1312,8 @@ void LWOImporter::LoadLWO2File()
// Continue loading this layer or ignore it? Check the layer index property
if (UINT_MAX != configLayerIndex && (configLayerIndex - 1) != layer.mIndex) {
skip = true;
}
else skip = false;
} else
skip = false;
// pivot point
mFileBuffer += 2; /* unknown */
@ -1382,13 +1332,14 @@ void LWOImporter::LoadLWO2File()
// load this layer or ignore it? Check the layer name property
if (configLayerName.length() && configLayerName != layer.mName) {
skip = true;
}
else hasNamedLayer = true;
} else
hasNamedLayer = true;
// optional: parent of this layer
if (mFileBuffer + 2 <= next)
layer.mParent = GetU2();
else layer.mParent = -1;
else
layer.mParent = (uint16_t) -1;
// Set layer skip parameter
layer.skip = skip;
@ -1397,8 +1348,7 @@ void LWOImporter::LoadLWO2File()
}
// vertex list
case AI_LWO_PNTS:
{
case AI_LWO_PNTS: {
if (skip)
break;
@ -1409,25 +1359,23 @@ void LWOImporter::LoadLWO2File()
}
// vertex tags
case AI_LWO_VMAD:
if (mCurLayer->mFaces.empty())
{
if (mCurLayer->mFaces.empty()) {
ASSIMP_LOG_WARN("LWO2: Unexpected VMAD chunk");
break;
}
// --- intentionally no break here
case AI_LWO_VMAP:
{
case AI_LWO_VMAP: {
if (skip)
break;
if (mCurLayer->mTempPoints.empty())
ASSIMP_LOG_WARN("LWO2: Unexpected VMAP chunk");
else LoadLWO2VertexMap(head.length,head.type == AI_LWO_VMAD);
else
LoadLWO2VertexMap(head.length, head.type == AI_LWO_VMAD);
break;
}
// face list
case AI_LWO_POLS:
{
case AI_LWO_POLS: {
if (skip)
break;
@ -1437,8 +1385,7 @@ void LWOImporter::LoadLWO2File()
break;
}
// polygon tags
case AI_LWO_PTAG:
{
case AI_LWO_PTAG: {
if (skip)
break;
@ -1450,8 +1397,7 @@ void LWOImporter::LoadLWO2File()
break;
}
// list of tags
case AI_LWO_TAGS:
{
case AI_LWO_TAGS: {
if (!mTags->empty()) {
ASSIMP_LOG_WARN("LWO2: SRFS chunk encountered twice");
} else {
@ -1461,22 +1407,19 @@ void LWOImporter::LoadLWO2File()
}
// surface chunk
case AI_LWO_SURF:
{
case AI_LWO_SURF: {
LoadLWO2Surface(head.length);
break;
}
// clip chunk
case AI_LWO_CLIP:
{
case AI_LWO_CLIP: {
LoadLWO2Clip(head.length);
break;
}
// envelope chunk
case AI_LWO_ENVL:
{
case AI_LWO_ENVL: {
LoadLWO2Envelope(head.length);
break;
}

View File

@ -76,9 +76,6 @@ public:
LWOImporter();
~LWOImporter();
public:
// -------------------------------------------------------------------
/** Returns whether the class can handle the format of the given file.
* See BaseImporter::CanRead() for details.
@ -86,7 +83,6 @@ public:
bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
bool checkSig) const;
// -------------------------------------------------------------------
/** Called prior to ReadFile().
* The function is a request to the importer to update its configuration
@ -389,7 +385,7 @@ protected:
unsigned int fileSize;
/** Output scene */
aiScene* pScene;
aiScene* mScene;
/** Configuration option: speed flag set? */
bool configSpeedFlag;
@ -406,8 +402,8 @@ protected:
// ------------------------------------------------------------------------------------------------
inline float LWOImporter::GetF4()
{
inline
float LWOImporter::GetF4() {
float f;
::memcpy(&f, mFileBuffer, 4);
mFileBuffer += 4;

View File

@ -43,30 +43,24 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/** @file Implementation of the material oart of the LWO importer class */
#ifndef ASSIMP_BUILD_NO_LWO_IMPORTER
// internal headers
#include "LWOLoader.h"
#include <assimp/ByteSwapper.h>
using namespace Assimp;
// ------------------------------------------------------------------------------------------------
template <class T>
T lerp(const T& one, const T& two, float val)
{
T lerp(const T &one, const T &two, float val) {
return one + (two - one) * val;
}
// ------------------------------------------------------------------------------------------------
// Convert a lightwave mapping mode to our's
inline aiTextureMapMode GetMapMode(LWO::Texture::Wrap in)
{
switch (in)
{
inline aiTextureMapMode GetMapMode(LWO::Texture::Wrap in) {
switch (in) {
case LWO::Texture::REPEAT:
return aiTextureMapMode_Wrap;
@ -84,8 +78,7 @@ inline aiTextureMapMode GetMapMode(LWO::Texture::Wrap in)
}
// ------------------------------------------------------------------------------------------------
bool LWOImporter::HandleTextures(aiMaterial* pcMat, const TextureList& in, aiTextureType type)
{
bool LWOImporter::HandleTextures(aiMaterial *pcMat, const TextureList &in, aiTextureType type) {
ai_assert(NULL != pcMat);
unsigned int cur = 0, temp = 0;
@ -101,9 +94,8 @@ bool LWOImporter::HandleTextures(aiMaterial* pcMat, const TextureList& in, aiTex
// as they are, the GenUVcoords step will compute UV
// channels if they're not there.
aiTextureMapping mapping;
switch (texture.mapMode)
{
aiTextureMapping mapping = aiTextureMapping_OTHER;
switch (texture.mapMode) {
case LWO::Texture::Planar:
mapping = aiTextureMapping_PLANE;
break;
@ -120,8 +112,7 @@ bool LWOImporter::HandleTextures(aiMaterial* pcMat, const TextureList& in, aiTex
ASSIMP_LOG_ERROR("LWO2: Unsupported texture mapping: FrontProjection");
mapping = aiTextureMapping_OTHER;
break;
case LWO::Texture::UV:
{
case LWO::Texture::UV: {
if (UINT_MAX == texture.mRealUVIndex) {
// We have no UV index for this texture, so we can't display it
continue;
@ -132,8 +123,7 @@ bool LWOImporter::HandleTextures(aiMaterial* pcMat, const TextureList& in, aiTex
pcMat->AddProperty<int>((int *)&temp, 1, AI_MATKEY_UVWSRC(type, cur));
mapping = aiTextureMapping_UV;
}
break;
} break;
default:
ai_assert(false);
};
@ -178,7 +168,6 @@ bool LWOImporter::HandleTextures(aiMaterial* pcMat, const TextureList& in, aiTex
if ((*clip).idx == temp) {
candidate = clip;
}
}
if (candidate == end) {
ASSIMP_LOG_ERROR("LWO2: Clip index is out of bounds");
@ -191,8 +180,7 @@ bool LWOImporter::HandleTextures(aiMaterial* pcMat, const TextureList& in, aiTex
s.Set("$texture.png");
//continue;
}
else {
} else {
if (Clip::UNSUPPORTED == (*candidate).type) {
ASSIMP_LOG_ERROR("LWO2: Clip type is not supported");
continue;
@ -207,9 +195,7 @@ bool LWOImporter::HandleTextures(aiMaterial* pcMat, const TextureList& in, aiTex
}
pcMat->AddProperty(&flags, 1, AI_MATKEY_TEXFLAGS(type, cur));
}
}
else
{
} else {
std::string ss = texture.mFileName;
if (!ss.length()) {
ASSIMP_LOG_WARN("LWOB: Empty file name");
@ -224,8 +210,7 @@ bool LWOImporter::HandleTextures(aiMaterial* pcMat, const TextureList& in, aiTex
pcMat->AddProperty<float>(&texture.mStrength, 1, AI_MATKEY_TEXBLEND(type, cur));
// add the blend operation
switch (texture.blendType)
{
switch (texture.blendType) {
case LWO::Texture::Normal:
case LWO::Texture::Multiply:
temp = (unsigned int)aiTextureOp_Multiply;
@ -247,7 +232,6 @@ bool LWOImporter::HandleTextures(aiMaterial* pcMat, const TextureList& in, aiTex
default:
temp = (unsigned int)aiTextureOp_Multiply;
ASSIMP_LOG_WARN("LWO2: Unsupported texture blend mode: alpha or displacement");
}
// Setup texture operation
pcMat->AddProperty<int>((int *)&temp, 1, AI_MATKEY_TEXOP(type, cur));
@ -270,8 +254,7 @@ bool LWOImporter::HandleTextures(aiMaterial* pcMat, const TextureList& in, aiTex
}
// ------------------------------------------------------------------------------------------------
void LWOImporter::ConvertMaterial(const LWO::Surface& surf,aiMaterial* pcMat)
{
void LWOImporter::ConvertMaterial(const LWO::Surface &surf, aiMaterial *pcMat) {
// copy the name of the surface
aiString st;
st.Set(surf.mName);
@ -285,28 +268,26 @@ void LWOImporter::ConvertMaterial(const LWO::Surface& surf,aiMaterial* pcMat)
pcMat->AddProperty(&surf.mBumpIntensity, 1, AI_MATKEY_BUMPSCALING);
aiShadingMode m;
if (surf.mSpecularValue && surf.mGlossiness)
{
if (surf.mSpecularValue && surf.mGlossiness) {
float fGloss;
if (mIsLWO2) {
fGloss = std::pow(surf.mGlossiness * ai_real(10.0) + ai_real(2.0), ai_real(2.0));
}
else
{
} else {
if (16.0 >= surf.mGlossiness)
fGloss = 6.0;
else if (64.0 >= surf.mGlossiness)
fGloss = 20.0;
else if (256.0 >= surf.mGlossiness)
fGloss = 50.0;
else fGloss = 80.0;
else
fGloss = 80.0;
}
pcMat->AddProperty(&surf.mSpecularValue, 1, AI_MATKEY_SHININESS_STRENGTH);
pcMat->AddProperty(&fGloss, 1, AI_MATKEY_SHININESS);
m = aiShadingMode_Phong;
}
else m = aiShadingMode_Gouraud;
} else
m = aiShadingMode_Gouraud;
// specular color
aiColor3D clr = lerp(aiColor3D(1.0, 1.0, 1.0), surf.mColor, surf.mColorHighlights);
@ -330,7 +311,6 @@ void LWOImporter::ConvertMaterial(const LWO::Surface& surf,aiMaterial* pcMat)
pcMat->AddProperty(&def, 1, AI_MATKEY_BLEND_FUNC);
}
// ADD TEXTURES to the material
// TODO: find out how we can handle COLOR textures correctly...
bool b = HandleTextures(pcMat, surf.mColorTextures, aiTextureType_DIFFUSE);
@ -349,15 +329,12 @@ void LWOImporter::ConvertMaterial(const LWO::Surface& surf,aiMaterial* pcMat)
m = aiShadingMode_Toon;
break;
}
else if (shader.functionName == "LW_RealFresnel" || shader.functionName == "LW_FastFresnel") {
} else if (shader.functionName == "LW_RealFresnel" || shader.functionName == "LW_FastFresnel") {
ASSIMP_LOG_INFO("LWO2: Mapping LW_RealFresnel/LW_FastFresnel to aiShadingMode_Fresnel");
m = aiShadingMode_Fresnel;
break;
}
else
{
} else {
ASSIMP_LOG_WARN_F("LWO2: Unknown surface shader: ", shader.functionName);
}
}
@ -377,8 +354,7 @@ void LWOImporter::ConvertMaterial(const LWO::Surface& surf,aiMaterial* pcMat)
// ------------------------------------------------------------------------------------------------
char LWOImporter::FindUVChannels(LWO::TextureList &list,
LWO::Layer& /*layer*/,LWO::UVChannel& uv, unsigned int next)
{
LWO::Layer & /*layer*/, LWO::UVChannel &uv, unsigned int next) {
char ret = 0;
for (auto &texture : list) {
@ -391,11 +367,9 @@ char LWOImporter::FindUVChannels(LWO::TextureList& list,
ret = 1;
// got it.
if (texture.mRealUVIndex == UINT_MAX || texture.mRealUVIndex == next)
{
if (texture.mRealUVIndex == UINT_MAX || texture.mRealUVIndex == next) {
texture.mRealUVIndex = next;
}
else {
} else {
// channel mismatch. need to duplicate the material.
ASSIMP_LOG_WARN("LWO: Channel mismatch, would need to duplicate surface [design bug]");
@ -409,8 +383,7 @@ char LWOImporter::FindUVChannels(LWO::TextureList& list,
// ------------------------------------------------------------------------------------------------
void LWOImporter::FindUVChannels(LWO::Surface &surf,
LWO::SortedRep &sorted, LWO::Layer &layer,
unsigned int out[AI_MAX_NUMBER_OF_TEXTURECOORDS])
{
unsigned int out[AI_MAX_NUMBER_OF_TEXTURECOORDS]) {
unsigned int next = 0, extra = 0, num_extra = 0;
// Check whether we have an UV entry != 0 for one of the faces in 'sorted'
@ -429,10 +402,10 @@ void LWOImporter::FindUVChannels(LWO::Surface& surf,
if (extra >= AI_MAX_NUMBER_OF_TEXTURECOORDS) {
ASSIMP_LOG_ERROR("LWO: Maximum number of UV channels for "
"this mesh reached. Skipping channel \'" + uv.name + "\'");
"this mesh reached. Skipping channel \'" +
uv.name + "\'");
}
else {
} else {
// Search through all textures assigned to 'surf' and look for this UV channel
char had = 0;
had |= FindUVChannels(surf.mColorTextures, layer, uv, next);
@ -474,8 +447,7 @@ void LWOImporter::FindUVChannels(LWO::Surface& surf,
// ------------------------------------------------------------------------------------------------
void LWOImporter::FindVCChannels(const LWO::Surface &surf, LWO::SortedRep &sorted, const LWO::Layer &layer,
unsigned int out[AI_MAX_NUMBER_OF_COLOR_SETS])
{
unsigned int out[AI_MAX_NUMBER_OF_COLOR_SETS]) {
unsigned int next = 0;
// Check whether we have an vc entry != 0 for one of the faces in 'sorted'
@ -489,8 +461,7 @@ void LWOImporter::FindVCChannels(const LWO::Surface& surf, LWO::SortedRep& sorte
}
out[0] = i;
++next;
}
else {
} else {
for (LWO::SortedRep::iterator it = sorted.begin(); it != sorted.end(); ++it) {
const LWO::Face &face = layer.mFaces[*it];
@ -502,10 +473,10 @@ void LWOImporter::FindVCChannels(const LWO::Surface& surf, LWO::SortedRep& sorte
if (next >= AI_MAX_NUMBER_OF_COLOR_SETS) {
ASSIMP_LOG_ERROR("LWO: Maximum number of vertex color channels for "
"this mesh reached. Skipping channel \'" + vc.name + "\'");
"this mesh reached. Skipping channel \'" +
vc.name + "\'");
}
else {
} else {
out[next++] = i;
}
it = sorted.end() - 1;
@ -521,11 +492,9 @@ void LWOImporter::FindVCChannels(const LWO::Surface& surf, LWO::SortedRep& sorte
}
// ------------------------------------------------------------------------------------------------
void LWOImporter::LoadLWO2ImageMap(unsigned int size, LWO::Texture& tex )
{
void LWOImporter::LoadLWO2ImageMap(unsigned int size, LWO::Texture &tex) {
LE_NCONST uint8_t *const end = mFileBuffer + size;
while (true)
{
while (true) {
if (mFileBuffer + 6 >= end) break;
LE_NCONST IFF::SubChunkHeader head = IFF::LoadSubChunk(mFileBuffer);
@ -533,8 +502,7 @@ void LWOImporter::LoadLWO2ImageMap(unsigned int size, LWO::Texture& tex )
throw DeadlyImportError("LWO2: Invalid SURF.BLOCK chunk length");
uint8_t *const next = mFileBuffer + head.length;
switch (head.type)
{
switch (head.type) {
case AI_LWO_PROJ:
tex.mapMode = (Texture::MappingMode)GetU2();
break;
@ -563,37 +531,32 @@ void LWOImporter::LoadLWO2ImageMap(unsigned int size, LWO::Texture& tex )
}
// ------------------------------------------------------------------------------------------------
void LWOImporter::LoadLWO2Procedural(unsigned int /*size*/, LWO::Texture& tex )
{
void LWOImporter::LoadLWO2Procedural(unsigned int /*size*/, LWO::Texture &tex) {
// --- not supported at the moment
ASSIMP_LOG_ERROR("LWO2: Found procedural texture, this is not supported");
tex.bCanUse = false;
}
// ------------------------------------------------------------------------------------------------
void LWOImporter::LoadLWO2Gradient(unsigned int /*size*/, LWO::Texture& tex )
{
void LWOImporter::LoadLWO2Gradient(unsigned int /*size*/, LWO::Texture &tex) {
// --- not supported at the moment
ASSIMP_LOG_ERROR("LWO2: Found gradient texture, this is not supported");
tex.bCanUse = false;
}
// ------------------------------------------------------------------------------------------------
void LWOImporter::LoadLWO2TextureHeader(unsigned int size, LWO::Texture& tex )
{
void LWOImporter::LoadLWO2TextureHeader(unsigned int size, LWO::Texture &tex) {
LE_NCONST uint8_t *const end = mFileBuffer + size;
// get the ordinal string
GetS0(tex.ordinal, size);
// we could crash later if this is an empty string ...
if (!tex.ordinal.length())
{
if (!tex.ordinal.length()) {
ASSIMP_LOG_ERROR("LWO2: Ill-formed SURF.BLOK ordinal string");
tex.ordinal = "\x00";
}
while (true)
{
while (true) {
if (mFileBuffer + 6 >= end) break;
const IFF::SubChunkHeader head = IFF::LoadSubChunk(mFileBuffer);
@ -601,8 +564,7 @@ void LWOImporter::LoadLWO2TextureHeader(unsigned int size, LWO::Texture& tex )
throw DeadlyImportError("LWO2: Invalid texture header chunk length");
uint8_t *const next = mFileBuffer + head.length;
switch (head.type)
{
switch (head.type) {
case AI_LWO_CHAN:
tex.type = GetU4();
break;
@ -619,8 +581,7 @@ void LWOImporter::LoadLWO2TextureHeader(unsigned int size, LWO::Texture& tex )
}
// ------------------------------------------------------------------------------------------------
void LWOImporter::LoadLWO2TextureBlock(LE_NCONST IFF::SubChunkHeader* head, unsigned int size )
{
void LWOImporter::LoadLWO2TextureBlock(LE_NCONST IFF::SubChunkHeader *head, unsigned int size) {
ai_assert(!mSurfaces->empty());
LWO::Surface &surf = mSurfaces->back();
LWO::Texture tex;
@ -630,8 +591,7 @@ void LWOImporter::LoadLWO2TextureBlock(LE_NCONST IFF::SubChunkHeader* head, unsi
size -= head->length + 6;
// now get the exact type of the texture
switch (head->type)
{
switch (head->type) {
case AI_LWO_PROC:
LoadLWO2Procedural(size, tex);
break;
@ -644,22 +604,28 @@ void LWOImporter::LoadLWO2TextureBlock(LE_NCONST IFF::SubChunkHeader* head, unsi
// get the destination channel
TextureList *listRef = NULL;
switch (tex.type)
{
switch (tex.type) {
case AI_LWO_COLR:
listRef = &surf.mColorTextures;break;
listRef = &surf.mColorTextures;
break;
case AI_LWO_DIFF:
listRef = &surf.mDiffuseTextures;break;
listRef = &surf.mDiffuseTextures;
break;
case AI_LWO_SPEC:
listRef = &surf.mSpecularTextures;break;
listRef = &surf.mSpecularTextures;
break;
case AI_LWO_GLOS:
listRef = &surf.mGlossinessTextures;break;
listRef = &surf.mGlossinessTextures;
break;
case AI_LWO_BUMP:
listRef = &surf.mBumpTextures;break;
listRef = &surf.mBumpTextures;
break;
case AI_LWO_TRAN:
listRef = &surf.mOpacityTextures;break;
listRef = &surf.mOpacityTextures;
break;
case AI_LWO_REFL:
listRef = &surf.mReflectionTextures;break;
listRef = &surf.mReflectionTextures;
break;
default:
ASSIMP_LOG_WARN("LWO2: Encountered unknown texture type");
return;
@ -676,8 +642,7 @@ void LWOImporter::LoadLWO2TextureBlock(LE_NCONST IFF::SubChunkHeader* head, unsi
}
// ------------------------------------------------------------------------------------------------
void LWOImporter::LoadLWO2ShaderBlock(LE_NCONST IFF::SubChunkHeader* /*head*/, unsigned int size )
{
void LWOImporter::LoadLWO2ShaderBlock(LE_NCONST IFF::SubChunkHeader * /*head*/, unsigned int size) {
LE_NCONST uint8_t *const end = mFileBuffer + size;
ai_assert(!mSurfaces->empty());
@ -688,15 +653,13 @@ void LWOImporter::LoadLWO2ShaderBlock(LE_NCONST IFF::SubChunkHeader* /*head*/, u
GetS0(shader.ordinal, size);
// we could crash later if this is an empty string ...
if (!shader.ordinal.length())
{
if (!shader.ordinal.length()) {
ASSIMP_LOG_ERROR("LWO2: Ill-formed SURF.BLOK ordinal string");
shader.ordinal = "\x00";
}
// read the header
while (true)
{
while (true) {
if (mFileBuffer + 6 >= end) break;
const IFF::SubChunkHeader head = IFF::LoadSubChunk(mFileBuffer);
@ -704,8 +667,7 @@ void LWOImporter::LoadLWO2ShaderBlock(LE_NCONST IFF::SubChunkHeader* /*head*/, u
throw DeadlyImportError("LWO2: Invalid shader header chunk length");
uint8_t *const next = mFileBuffer + head.length;
switch (head.type)
{
switch (head.type) {
case AI_LWO_ENAB:
shader.enabled = GetU2() ? true : false;
break;
@ -727,8 +689,7 @@ void LWOImporter::LoadLWO2ShaderBlock(LE_NCONST IFF::SubChunkHeader* /*head*/, u
}
// ------------------------------------------------------------------------------------------------
void LWOImporter::LoadLWO2Surface(unsigned int size)
{
void LWOImporter::LoadLWO2Surface(unsigned int size) {
LE_NCONST uint8_t *const end = mFileBuffer + size;
mSurfaces->push_back(LWO::Surface());
@ -741,19 +702,20 @@ void LWOImporter::LoadLWO2Surface(unsigned int size)
GetS0(derived, (unsigned int)(end - mFileBuffer));
if (derived.length()) {
// yes, find this surface
for (SurfaceList::iterator it = mSurfaces->begin(), end = mSurfaces->end()-1; it != end; ++it) {
for (SurfaceList::iterator it = mSurfaces->begin(), itEnd = mSurfaces->end() - 1; it != itEnd; ++it) {
if ((*it).mName == derived) {
// we have it ...
surf = *it;
derived.clear();break;
derived.clear();
break;
}
}
if (derived.size())
if (derived.size()) {
ASSIMP_LOG_WARN("LWO2: Unable to find source surface: " + derived);
}
}
while (true)
{
while (true) {
if (mFileBuffer + 6 >= end)
break;
const IFF::SubChunkHeader head = IFF::LoadSubChunk(mFileBuffer);
@ -762,11 +724,9 @@ void LWOImporter::LoadLWO2Surface(unsigned int size)
throw DeadlyImportError("LWO2: Invalid surface chunk length");
uint8_t *const next = mFileBuffer + head.length;
switch (head.type)
{
switch (head.type) {
// diffuse color
case AI_LWO_COLR:
{
case AI_LWO_COLR: {
AI_LWO_VALIDATE_CHUNK_LENGTH(head.length, COLR, 12);
surf.mColor.r = GetF4();
surf.mColor.g = GetF4();
@ -774,22 +734,19 @@ void LWOImporter::LoadLWO2Surface(unsigned int size)
break;
}
// diffuse strength ... hopefully
case AI_LWO_DIFF:
{
case AI_LWO_DIFF: {
AI_LWO_VALIDATE_CHUNK_LENGTH(head.length, DIFF, 4);
surf.mDiffuseValue = GetF4();
break;
}
// specular strength ... hopefully
case AI_LWO_SPEC:
{
case AI_LWO_SPEC: {
AI_LWO_VALIDATE_CHUNK_LENGTH(head.length, SPEC, 4);
surf.mSpecularValue = GetF4();
break;
}
// transparency
case AI_LWO_TRAN:
{
case AI_LWO_TRAN: {
// transparency explicitly disabled?
if (surf.mTransparency == 10e10f)
break;
@ -799,65 +756,56 @@ void LWOImporter::LoadLWO2Surface(unsigned int size)
break;
}
// additive transparency
case AI_LWO_ADTR:
{
case AI_LWO_ADTR: {
AI_LWO_VALIDATE_CHUNK_LENGTH(head.length, ADTR, 4);
surf.mAdditiveTransparency = GetF4();
break;
}
// wireframe mode
case AI_LWO_LINE:
{
case AI_LWO_LINE: {
AI_LWO_VALIDATE_CHUNK_LENGTH(head.length, LINE, 2);
if (GetU2() & 0x1)
surf.mWireframe = true;
break;
}
// glossiness
case AI_LWO_GLOS:
{
case AI_LWO_GLOS: {
AI_LWO_VALIDATE_CHUNK_LENGTH(head.length, GLOS, 4);
surf.mGlossiness = GetF4();
break;
}
// bump intensity
case AI_LWO_BUMP:
{
case AI_LWO_BUMP: {
AI_LWO_VALIDATE_CHUNK_LENGTH(head.length, BUMP, 4);
surf.mBumpIntensity = GetF4();
break;
}
// color highlights
case AI_LWO_CLRH:
{
case AI_LWO_CLRH: {
AI_LWO_VALIDATE_CHUNK_LENGTH(head.length, CLRH, 4);
surf.mColorHighlights = GetF4();
break;
}
// index of refraction
case AI_LWO_RIND:
{
case AI_LWO_RIND: {
AI_LWO_VALIDATE_CHUNK_LENGTH(head.length, RIND, 4);
surf.mIOR = GetF4();
break;
}
// polygon sidedness
case AI_LWO_SIDE:
{
case AI_LWO_SIDE: {
AI_LWO_VALIDATE_CHUNK_LENGTH(head.length, SIDE, 2);
surf.bDoubleSided = (3 == GetU2());
break;
}
// maximum smoothing angle
case AI_LWO_SMAN:
{
case AI_LWO_SMAN: {
AI_LWO_VALIDATE_CHUNK_LENGTH(head.length, SMAN, 4);
surf.mMaximumSmoothAngle = std::fabs(GetF4());
break;
}
// vertex color channel to be applied to the surface
case AI_LWO_VCOL:
{
case AI_LWO_VCOL: {
AI_LWO_VALIDATE_CHUNK_LENGTH(head.length, VCOL, 12);
surf.mDiffuseValue *= GetF4(); // strength
ReadVSizedIntLWO2(mFileBuffer); // skip envelope
@ -868,13 +816,11 @@ void LWOImporter::LoadLWO2Surface(unsigned int size)
break;
}
// surface bock entry
case AI_LWO_BLOK:
{
case AI_LWO_BLOK: {
AI_LWO_VALIDATE_CHUNK_LENGTH(head.length, BLOK, 4);
IFF::SubChunkHeader head2 = IFF::LoadSubChunk(mFileBuffer);
switch (head2.type)
{
switch (head2.type) {
case AI_LWO_PROC:
case AI_LWO_GRAD:
case AI_LWO_IMAP:

View File

@ -45,22 +45,21 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* @brief Implementation of the LWS importer class
*/
#ifndef ASSIMP_BUILD_NO_LWS_IMPORTER
#include "LWS/LWSLoader.h"
#include "PostProcessing/ConvertToLHProcess.h"
#include "Common/Importer.h"
#include "PostProcessing/ConvertToLHProcess.h"
#include <assimp/ParsingUtils.h>
#include <assimp/fast_atof.h>
#include <assimp/SceneCombiner.h>
#include <assimp/GenericProperty.h>
#include <assimp/ParsingUtils.h>
#include <assimp/SceneCombiner.h>
#include <assimp/SkeletonMeshBuilder.h>
#include <assimp/DefaultLogger.hpp>
#include <assimp/scene.h>
#include <assimp/IOSystem.hpp>
#include <assimp/fast_atof.h>
#include <assimp/importerdesc.h>
#include <assimp/scene.h>
#include <assimp/DefaultLogger.hpp>
#include <assimp/IOSystem.hpp>
#include <memory>
@ -81,8 +80,7 @@ static const aiImporterDesc desc = {
// ------------------------------------------------------------------------------------------------
// Recursive parsing of LWS files
void LWS::Element::Parse (const char*& buffer)
{
void LWS::Element::Parse(const char *&buffer) {
for (; SkipSpacesAndLineEnd(&buffer); SkipLine(&buffer)) {
// begin of a new element with children
@ -91,8 +89,7 @@ void LWS::Element::Parse (const char*& buffer)
++buffer;
SkipSpaces(&buffer);
sub = true;
}
else if (*buffer == '}')
} else if (*buffer == '}')
return;
children.push_back(Element());
@ -100,12 +97,12 @@ void LWS::Element::Parse (const char*& buffer)
// copy data line - read token per token
const char *cur = buffer;
while (!IsSpaceOrNewLine(*buffer)) ++buffer;
while (!IsSpaceOrNewLine(*buffer))
++buffer;
children.back().tokens[0] = std::string(cur, (size_t)(buffer - cur));
SkipSpaces(&buffer);
if (children.back().tokens[0] == "Plugin")
{
if (children.back().tokens[0] == "Plugin") {
ASSIMP_LOG_DEBUG("LWS: Skipping over plugin-specific data");
// strange stuff inside Plugin/Endplugin blocks. Needn't
@ -120,7 +117,8 @@ void LWS::Element::Parse (const char*& buffer)
}
cur = buffer;
while (!IsLineEnd(*buffer)) ++buffer;
while (!IsLineEnd(*buffer))
++buffer;
children.back().tokens[1] = std::string(cur, (size_t)(buffer - cur));
// parse more elements recursively
@ -131,28 +129,25 @@ void LWS::Element::Parse (const char*& buffer)
// ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer
LWSImporter::LWSImporter()
: configSpeedFlag(),
LWSImporter::LWSImporter() :
configSpeedFlag(),
io(),
first(),
last(),
fps(),
noSkeletonMesh()
{
noSkeletonMesh() {
// nothing to do here
}
// ------------------------------------------------------------------------------------------------
// Destructor, private as well
LWSImporter::~LWSImporter()
{
LWSImporter::~LWSImporter() {
// nothing to do here
}
// ------------------------------------------------------------------------------------------------
// Returns whether the class can handle the format of the given file.
bool LWSImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler,bool checkSig) const
{
bool LWSImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool checkSig) const {
const std::string extension = GetExtension(pFile);
if (extension == "lws" || extension == "mot")
return true;
@ -169,15 +164,13 @@ bool LWSImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler,bool c
// ------------------------------------------------------------------------------------------------
// Get list of file extensions
const aiImporterDesc* LWSImporter::GetInfo () const
{
const aiImporterDesc *LWSImporter::GetInfo() const {
return &desc;
}
// ------------------------------------------------------------------------------------------------
// Setup configuration properties
void LWSImporter::SetupProperties(const Importer* pImp)
{
void LWSImporter::SetupProperties(const Importer *pImp) {
// AI_CONFIG_FAVOUR_SPEED
configSpeedFlag = (0 != pImp->GetPropertyInteger(AI_CONFIG_FAVOUR_SPEED, 0));
@ -198,15 +191,15 @@ void LWSImporter::SetupProperties(const Importer* pImp)
// ------------------------------------------------------------------------------------------------
// Read an envelope description
void LWSImporter::ReadEnvelope(const LWS::Element& dad, LWO::Envelope& fill )
{
void LWSImporter::ReadEnvelope(const LWS::Element &dad, LWO::Envelope &fill) {
if (dad.children.empty()) {
ASSIMP_LOG_ERROR("LWS: Envelope descriptions must not be empty");
return;
}
// reserve enough storage
std::list< LWS::Element >::const_iterator it = dad.children.begin();;
std::list<LWS::Element>::const_iterator it = dad.children.begin();
;
fill.keys.reserve(strtoul10(it->tokens[1].c_str()));
for (++it; it != dad.children.end(); ++it) {
@ -255,8 +248,7 @@ void LWSImporter::ReadEnvelope(const LWS::Element& dad, LWO::Envelope& fill )
SkipSpaces(&c);
c = fast_atoreal_move<float>(c, key.params[i]);
}
}
else if ((*it).tokens[0] == "Behaviors") {
} else if ((*it).tokens[0] == "Behaviors") {
SkipSpaces(&c);
fill.pre = (LWO::PrePostBehaviour)strtoul10(c, &c);
SkipSpaces(&c);
@ -271,8 +263,7 @@ void LWSImporter::ReadEnvelope_Old(
std::list<LWS::Element>::const_iterator &it,
const std::list<LWS::Element>::const_iterator &end,
LWS::NodeDesc &nodes,
unsigned int /*version*/)
{
unsigned int /*version*/) {
unsigned int num, sub_num;
if (++it == end) goto unexpected_end;
@ -311,8 +302,7 @@ unexpected_end:
// ------------------------------------------------------------------------------------------------
// Setup a nice name for a node
void LWSImporter::SetupNodeName(aiNode* nd, LWS::NodeDesc& src)
{
void LWSImporter::SetupNodeName(aiNode *nd, LWS::NodeDesc &src) {
const unsigned int combined = src.number | ((unsigned int)src.type) << 28u;
// the name depends on the type. We break LWS's strange naming convention
@ -323,7 +313,8 @@ void LWSImporter::SetupNodeName(aiNode* nd, LWS::NodeDesc& src)
std::string::size_type s = src.path.find_last_of("\\/");
if (s == std::string::npos)
s = 0;
else ++s;
else
++s;
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);
@ -339,8 +330,7 @@ void LWSImporter::BuildGraph(aiNode* nd, LWS::NodeDesc& src, std::vector<Attachm
BatchLoader &batch,
aiCamera **&camOut,
aiLight **&lightOut,
std::vector<aiNodeAnim*>& animOut)
{
std::vector<aiNodeAnim *> &animOut) {
// Setup a very cryptic name for the node, we want the user to be happy
SetupNodeName(nd, src);
aiNode *ndAnim = nd;
@ -354,8 +344,7 @@ void LWSImporter::BuildGraph(aiNode* nd, LWS::NodeDesc& src, std::vector<Attachm
obj = batch.GetImport(src.id);
if (!obj) {
ASSIMP_LOG_ERROR("LWS: Failed to read external file " + src.path);
}
else {
} else {
if (obj->mRootNode->mNumChildren == 1) {
//If the pivot is not set for this layer, get it from the external object
@ -418,11 +407,10 @@ void LWSImporter::BuildGraph(aiNode* nd, LWS::NodeDesc& src, std::vector<Attachm
lit->mAngleInnerCone = (float)AI_DEG_TO_RAD(src.lightConeAngle);
lit->mAngleOuterCone = lit->mAngleInnerCone + (float)AI_DEG_TO_RAD(src.lightEdgeAngle);
}
else if (src.lightType == 1) { /* directional light source */
} else if (src.lightType == 1) { /* directional light source */
lit->mType = aiLightSource_DIRECTIONAL;
}
else lit->mType = aiLightSource_POINT;
} else
lit->mType = aiLightSource_POINT;
// fixme: no proper handling of light falloffs yet
if (src.lightFalloffType == 1)
@ -471,15 +459,13 @@ void LWSImporter::BuildGraph(aiNode* nd, LWS::NodeDesc& src, std::vector<Attachm
// ------------------------------------------------------------------------------------------------
// Determine the exact location of a LWO file
std::string LWSImporter::FindLWOFile(const std::string& in)
{
std::string LWSImporter::FindLWOFile(const std::string &in) {
// insert missing directory separator if necessary
std::string tmp;
if (in.length() > 3 && in[1] == ':'&& in[2] != '\\' && in[2] != '/')
{
if (in.length() > 3 && in[1] == ':' && in[2] != '\\' && in[2] != '/') {
tmp = in[0] + (std::string(":\\") + in.substr(2));
}
else tmp = in;
} else
tmp = in;
if (io->Exists(tmp)) {
return in;
@ -503,7 +489,6 @@ std::string LWSImporter::FindLWOFile(const std::string& in)
return test;
}
// return original path, maybe the IOsystem knows better
return tmp;
}
@ -511,8 +496,7 @@ std::string LWSImporter::FindLWOFile(const std::string& in)
// ------------------------------------------------------------------------------------------------
// Read file into given scene data structure
void LWSImporter::InternReadFile(const std::string &pFile, aiScene *pScene,
IOSystem* pIOHandler)
{
IOSystem *pIOHandler) {
io = pIOHandler;
std::unique_ptr<IOStream> file(pIOHandler->Open(pFile, "rb"));
@ -526,7 +510,8 @@ void LWSImporter::InternReadFile( const std::string& pFile, aiScene* pScene,
TextFileToBuffer(file.get(), mBuffer);
// Parse the file structure
LWS::Element root; const char* dummy = &mBuffer[0];
LWS::Element root;
const char *dummy = &mBuffer[0];
root.Parse(dummy);
// Construct a Batchimporter to read more files recursively
@ -594,8 +579,8 @@ void LWSImporter::InternReadFile( const std::string& pFile, aiScene* pScene,
if (version >= 4) { // handle LWSC 4 explicit ID
SkipSpaces(&c);
d.number = strtoul16(c, &c) & AI_LWS_MASK;
}
else d.number = cur_object++;
} else
d.number = cur_object++;
// and add the file to the import list
SkipSpaces(&c);
@ -616,8 +601,8 @@ void LWSImporter::InternReadFile( const std::string& pFile, aiScene* pScene,
if (version >= 4) { // handle LWSC 4 explicit ID
d.number = strtoul16(c, &c) & AI_LWS_MASK;
SkipSpaces(&c);
}
else d.number = cur_object++;
} else
d.number = cur_object++;
std::string path = FindLWOFile(c);
d.id = batch.AddLoadRequest(path, 0, NULL);
@ -634,8 +619,8 @@ void LWSImporter::InternReadFile( const std::string& pFile, aiScene* pScene,
if (version >= 4) { // handle LWSC 4 explicit ID
d.number = strtoul16(c, &c) & AI_LWS_MASK;
SkipSpaces(&c);
}
else d.number = cur_object++;
} else
d.number = cur_object++;
d.name = c;
nodes.push_back(d);
@ -695,11 +680,13 @@ void LWSImporter::InternReadFile( const std::string& pFile, aiScene* pScene,
if (nodes.empty())
ASSIMP_LOG_ERROR("LWS: Unexpected keyword: \'Pre/PostBehavior'");
else {
for (std::list<LWO::Envelope>::iterator it = nodes.back().channels.begin(); it != nodes.back().channels.end(); ++it) {
for (std::list<LWO::Envelope>::iterator envelopeIt = nodes.back().channels.begin(); envelopeIt != nodes.back().channels.end(); ++envelopeIt) {
// two ints per envelope
LWO::Envelope& env = *it;
env.pre = (LWO::PrePostBehaviour) strtoul10(c,&c); SkipSpaces(&c);
env.post = (LWO::PrePostBehaviour) strtoul10(c,&c); SkipSpaces(&c);
LWO::Envelope &env = *envelopeIt;
env.pre = (LWO::PrePostBehaviour)strtoul10(c, &c);
SkipSpaces(&c);
env.post = (LWO::PrePostBehaviour)strtoul10(c, &c);
SkipSpaces(&c);
}
}
}
@ -708,7 +695,8 @@ void LWSImporter::InternReadFile( const std::string& pFile, aiScene* pScene,
if (nodes.empty())
ASSIMP_LOG_ERROR("LWS: Unexpected keyword: \'ParentItem\'");
else nodes.back().parent = strtoul16(c,&c);
else
nodes.back().parent = strtoul16(c, &c);
}
// 'ParentObject': deprecated one for older formats
else if (version < 3 && (*it).tokens[0] == "ParentObject") {
@ -728,8 +716,8 @@ void LWSImporter::InternReadFile( const std::string& pFile, aiScene* pScene,
if (version >= 4) { // handle LWSC 4 explicit ID
d.number = strtoul16(c, &c) & AI_LWS_MASK;
}
else d.number = cur_camera++;
} else
d.number = cur_camera++;
nodes.push_back(d);
num_camera++;
@ -739,7 +727,8 @@ void LWSImporter::InternReadFile( const std::string& pFile, aiScene* pScene,
if (nodes.empty() || nodes.back().type != LWS::NodeDesc::CAMERA)
ASSIMP_LOG_ERROR("LWS: Unexpected keyword: \'CameraName\'");
else nodes.back().name = c;
else
nodes.back().name = c;
}
// 'AddLight': add a light to the scenegraph
else if ((*it).tokens[0] == "AddLight") {
@ -750,8 +739,8 @@ void LWSImporter::InternReadFile( const std::string& pFile, aiScene* pScene,
if (version >= 4) { // handle LWSC 4 explicit ID
d.number = strtoul16(c, &c) & AI_LWS_MASK;
}
else d.number = cur_light++;
} else
d.number = cur_light++;
nodes.push_back(d);
num_light++;
@ -761,14 +750,16 @@ void LWSImporter::InternReadFile( const std::string& pFile, aiScene* pScene,
if (nodes.empty() || nodes.back().type != LWS::NodeDesc::LIGHT)
ASSIMP_LOG_ERROR("LWS: Unexpected keyword: \'LightName\'");
else nodes.back().name = c;
else
nodes.back().name = c;
}
// 'LightIntensity': set intensity of currently active light
else if ((*it).tokens[0] == "LightIntensity" || (*it).tokens[0] == "LgtIntensity") {
if (nodes.empty() || nodes.back().type != LWS::NodeDesc::LIGHT)
ASSIMP_LOG_ERROR("LWS: Unexpected keyword: \'LightIntensity\'");
else fast_atoreal_move<float>(c, nodes.back().lightIntensity );
else
fast_atoreal_move<float>(c, nodes.back().lightIntensity);
}
// 'LightType': set type of currently active light
@ -776,7 +767,8 @@ void LWSImporter::InternReadFile( const std::string& pFile, aiScene* pScene,
if (nodes.empty() || nodes.back().type != LWS::NodeDesc::LIGHT)
ASSIMP_LOG_ERROR("LWS: Unexpected keyword: \'LightType\'");
else nodes.back().lightType = strtoul10(c);
else
nodes.back().lightType = strtoul10(c);
}
// 'LightFalloffType': set falloff type of currently active light
@ -784,7 +776,8 @@ void LWSImporter::InternReadFile( const std::string& pFile, aiScene* pScene,
if (nodes.empty() || nodes.back().type != LWS::NodeDesc::LIGHT)
ASSIMP_LOG_ERROR("LWS: Unexpected keyword: \'LightFalloffType\'");
else nodes.back().lightFalloffType = strtoul10(c);
else
nodes.back().lightFalloffType = strtoul10(c);
}
// 'LightConeAngle': set cone angle of currently active light
@ -792,7 +785,8 @@ void LWSImporter::InternReadFile( const std::string& pFile, aiScene* pScene,
if (nodes.empty() || nodes.back().type != LWS::NodeDesc::LIGHT)
ASSIMP_LOG_ERROR("LWS: Unexpected keyword: \'LightConeAngle\'");
else nodes.back().lightConeAngle = fast_atof(c);
else
nodes.back().lightConeAngle = fast_atof(c);
}
// 'LightEdgeAngle': set area where we're smoothing from min to max intensity
@ -800,7 +794,8 @@ void LWSImporter::InternReadFile( const std::string& pFile, aiScene* pScene,
if (nodes.empty() || nodes.back().type != LWS::NodeDesc::LIGHT)
ASSIMP_LOG_ERROR("LWS: Unexpected keyword: \'LightEdgeAngle\'");
else nodes.back().lightEdgeAngle = fast_atof(c);
else
nodes.back().lightEdgeAngle = fast_atof(c);
}
// 'LightColor': set color of currently active light
@ -834,32 +829,33 @@ void LWSImporter::InternReadFile( const std::string& pFile, aiScene* pScene,
}
// resolve parenting
for (std::list<LWS::NodeDesc>::iterator it = nodes.begin(); it != nodes.end(); ++it) {
for (std::list<LWS::NodeDesc>::iterator ndIt = nodes.begin(); ndIt != nodes.end(); ++ndIt) {
// check whether there is another node which calls us a parent
for (std::list<LWS::NodeDesc>::iterator dit = nodes.begin(); dit != nodes.end(); ++dit) {
if (dit != it && *it == (*dit).parent) {
if (dit != ndIt && *ndIt == (*dit).parent) {
if ((*dit).parent_resolved) {
// fixme: it's still possible to produce an overflow due to cross references ..
ASSIMP_LOG_ERROR("LWS: Found cross reference in scene-graph");
continue;
}
(*it).children.push_back(&*dit);
(*dit).parent_resolved = &*it;
ndIt->children.push_back(&*dit);
(*dit).parent_resolved = &*ndIt;
}
}
}
// find out how many nodes have no parent yet
unsigned int no_parent = 0;
for (std::list<LWS::NodeDesc>::iterator it = nodes.begin(); it != nodes.end(); ++it) {
if (!(*it).parent_resolved)
for (std::list<LWS::NodeDesc>::iterator ndIt = nodes.begin(); ndIt != nodes.end(); ++ndIt) {
if (!ndIt->parent_resolved) {
++no_parent;
}
if (!no_parent)
}
if (!no_parent) {
throw DeadlyImportError("LWS: Unable to find scene root node");
}
// Load all subsequent files
batch.LoadAll();
@ -884,14 +880,14 @@ void LWSImporter::InternReadFile( const std::string& pFile, aiScene* pScene,
nd->mName.Set("<LWSRoot>");
nd->mChildren = new aiNode *[no_parent];
for (std::list<LWS::NodeDesc>::iterator it = nodes.begin(); it != nodes.end(); ++it) {
if (!(*it).parent_resolved) {
for (std::list<LWS::NodeDesc>::iterator ndIt = nodes.begin(); ndIt != nodes.end(); ++ndIt) {
if (!ndIt->parent_resolved) {
aiNode *ro = nd->mChildren[nd->mNumChildren++] = new aiNode();
ro->mParent = nd;
// ... and build the scene graph. If we encounter object nodes,
// add then to our attachment table.
BuildGraph(ro,*it, attach, batch, cams, lights, anims);
BuildGraph(ro, *ndIt, attach, batch, cams, lights, anims);
}
}
@ -920,7 +916,8 @@ void LWSImporter::InternReadFile( const std::string& pFile, aiScene* pScene,
// OK ... finally build the output graph
SceneCombiner::MergeScenes(&pScene, master, attach,
AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES | (!configSpeedFlag ? (
AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES_IF_NECESSARY | AI_INT_MERGE_SCENE_GEN_UNIQUE_MATNAMES) : 0));
AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES_IF_NECESSARY | AI_INT_MERGE_SCENE_GEN_UNIQUE_MATNAMES) :
0));
// Check flags
if (!pScene->mNumMeshes || !pScene->mNumMaterials) {
@ -931,7 +928,6 @@ void LWSImporter::InternReadFile( const std::string& pFile, aiScene* pScene,
SkeletonMeshBuilder builder(pScene);
}
}
}
#endif // !! ASSIMP_BUILD_NO_LWS_IMPORTER

View File

@ -56,9 +56,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/Importer.hpp>
#include <memory>
#include "M3DWrapper.h"
#include "M3DImporter.h"
#include "M3DMaterials.h"
#include "M3DWrapper.h"
// RESOURCES:
// https://gitlab.com/bztsrc/model3d/blob/master/docs/m3d_format.md
@ -256,9 +256,9 @@ void M3DImporter::importMaterials(const M3DWrapper &m3d) {
for (i = 0; i < m3d->nummaterial; i++) {
m = &m3d->material[i];
aiMaterial *mat = new aiMaterial;
aiMaterial *newMat = new aiMaterial;
name.Set(std::string(m->name));
mat->AddProperty(&name, AI_MATKEY_NAME);
newMat->AddProperty(&name, AI_MATKEY_NAME);
for (j = 0; j < m->numprop; j++) {
// look up property type
// 0 - 127 scalar values,
@ -271,29 +271,36 @@ void M3DImporter::importMaterials(const M3DWrapper &m3d) {
break;
}
// should never happen, but be safe than sorry
if (k == 256) continue;
if (k == 256)
continue;
// scalar properties
if (m->prop[j].type < 128 && aiProps[k].pKey) {
switch (m3d_propertytypes[k].format) {
case m3dpf_color:
c = mkColor(m->prop[j].value.color);
mat->AddProperty(&c, 1, aiProps[k].pKey, aiProps[k].type, aiProps[k].index);
newMat->AddProperty(&c, 1, aiProps[k].pKey, aiProps[k].type, aiProps[k].index);
break;
case m3dpf_float:
f = m->prop[j].value.fnum;
mat->AddProperty(&f, 1, aiProps[k].pKey, aiProps[k].type, aiProps[k].index);
newMat->AddProperty(&f, 1, aiProps[k].pKey, aiProps[k].type, aiProps[k].index);
break;
default:
n = m->prop[j].value.num;
if (m->prop[j].type == m3dp_il) {
switch (n) {
case 0: n = aiShadingMode_NoShading; break;
case 2: n = aiShadingMode_Phong; break;
default: n = aiShadingMode_Gouraud; break;
case 0:
n = aiShadingMode_NoShading;
break;
case 2:
n = aiShadingMode_Phong;
break;
default:
n = aiShadingMode_Gouraud;
break;
}
}
mat->AddProperty(&n, 1, aiProps[k].pKey, aiProps[k].type, aiProps[k].index);
newMat->AddProperty(&n, 1, aiProps[k].pKey, aiProps[k].type, aiProps[k].index);
break;
}
}
@ -403,7 +410,6 @@ void M3DImporter::importMeshes(const M3DWrapper &m3d) {
ai_assert(m3d);
ai_assert(mScene->mRootNode != nullptr);
for (i = 0; i < m3d->numface; i++) {
// we must switch mesh if material changes
if (lastMat != m3d->face[i].materialid) {

View File

@ -100,6 +100,10 @@ M3DWrapper::M3DWrapper() {
}
M3DWrapper::M3DWrapper(IOSystem *pIOHandler, const std::vector<unsigned char> &buffer) {
if (nullptr == pIOHandler) {
ai_assert(nullptr != pIOHandler);
}
#ifdef ASSIMP_USE_M3D_READFILECB
// pass this IOHandler to the C callback in a thread-local pointer
m3dimporter_pIOHandler = pIOHandler;

View File

@ -99,6 +99,10 @@ typedef uint16_t M3D_INDEX;
#define _register
#endif
#pragma warning(push)
#pragma warning(disable : 4127 )
#pragma warning(disable : 4505 )
/*** File format structures ***/
/**
@ -2162,8 +2166,8 @@ M3D_INDEX _m3d_gettx(m3d_t *model, m3dread_t readfilecb, m3dfree_t freecb, char
w = h = len = 0;
ri.bits_per_channel = 8;
model->texture[i].d = (uint8_t*)stbi__png_load(&s, (int*)&w, (int*)&h, (int*)&len, 0, &ri);
model->texture[i].w = w;
model->texture[i].h = h;
model->texture[i].w = (uint16_t) w;
model->texture[i].h = (uint16_t) h;
model->texture[i].f = (uint8_t)len;
#endif
} else {
@ -5605,6 +5609,9 @@ namespace M3D {
#endif /* impl */
}
#pragma warning(pop<)
#endif
#endif /* __cplusplus */

View File

@ -45,21 +45,20 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* @brief Implementation of the MD5 importer class
*/
#ifndef ASSIMP_BUILD_NO_MD5_IMPORTER
// internal headers
#include <assimp/RemoveComments.h>
#include "MD5Loader.h"
#include <assimp/MathFunctions.h>
#include <assimp/RemoveComments.h>
#include <assimp/SkeletonMeshBuilder.h>
#include <assimp/StringComparison.h>
#include <assimp/fast_atof.h>
#include <assimp/MathFunctions.h>
#include <assimp/SkeletonMeshBuilder.h>
#include <assimp/Importer.hpp>
#include <assimp/scene.h>
#include <assimp/IOSystem.hpp>
#include <assimp/DefaultLogger.hpp>
#include <assimp/importerdesc.h>
#include <assimp/scene.h>
#include <assimp/DefaultLogger.hpp>
#include <assimp/IOSystem.hpp>
#include <assimp/Importer.hpp>
#include <memory>
using namespace Assimp;
@ -67,7 +66,6 @@ using namespace Assimp;
// Minimum weight value. Weights inside [-n ... n] are ignored
#define AI_MD5_WEIGHT_EPSILON Math::getEpsilon<float>()
static const aiImporterDesc desc = {
"Doom 3 / MD5 Mesh Importer",
"",
@ -83,28 +81,20 @@ static const aiImporterDesc desc = {
// ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer
MD5Importer::MD5Importer()
: mIOHandler()
, mBuffer()
, fileSize()
, iLineNumber()
, pScene()
, pIOHandler()
, bHadMD5Mesh()
, bHadMD5Anim()
, bHadMD5Camera()
, configNoAutoLoad (false)
{}
MD5Importer::MD5Importer() :
mIOHandler(nullptr), mBuffer(), fileSize(), iLineNumber(), pScene(), bHadMD5Mesh(), bHadMD5Anim(), bHadMD5Camera(), configNoAutoLoad(false) {
// empty
}
// ------------------------------------------------------------------------------------------------
// Destructor, private as well
MD5Importer::~MD5Importer()
{}
MD5Importer::~MD5Importer() {
// empty
}
// ------------------------------------------------------------------------------------------------
// Returns whether the class can handle the format of the given file.
bool MD5Importer::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
{
bool MD5Importer::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool checkSig) const {
const std::string extension = GetExtension(pFile);
if (extension == "md5anim" || extension == "md5mesh" || extension == "md5camera")
@ -121,15 +111,13 @@ bool MD5Importer::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool
// ------------------------------------------------------------------------------------------------
// Get list of all supported extensions
const aiImporterDesc* MD5Importer::GetInfo () const
{
const aiImporterDesc *MD5Importer::GetInfo() const {
return &desc;
}
// ------------------------------------------------------------------------------------------------
// Setup import properties
void MD5Importer::SetupProperties(const Importer* pImp)
{
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));
}
@ -137,9 +125,8 @@ void MD5Importer::SetupProperties(const Importer* pImp)
// ------------------------------------------------------------------------------------------------
// Imports the given file into the given scene structure.
void MD5Importer::InternReadFile(const std::string &pFile,
aiScene* _pScene, IOSystem* _pIOHandler)
{
pIOHandler = _pIOHandler;
aiScene *_pScene, IOSystem *pIOHandler) {
mIOHandler = pIOHandler;
pScene = _pScene;
bHadMD5Mesh = bHadMD5Anim = bHadMD5Camera = false;
@ -151,25 +138,21 @@ void MD5Importer::InternReadFile( const std::string& pFile,
try {
if (extension == "md5camera") {
LoadMD5CameraFile();
}
else if (configNoAutoLoad || extension == "md5anim") {
} else if (configNoAutoLoad || 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");
}
if (extension == "md5anim") {
LoadMD5AnimFile();
}
else if (extension == "md5mesh") {
} else if (extension == "md5mesh") {
LoadMD5MeshFile();
}
}
else {
} else {
LoadMD5MeshFile();
LoadMD5AnimFile();
}
}
catch ( ... ) { // std::exception, Assimp::DeadlyImportError
} catch (...) { // std::exception, Assimp::DeadlyImportError
UnloadFileFromMemory();
throw;
}
@ -194,8 +177,7 @@ void MD5Importer::InternReadFile( const std::string& pFile,
// ------------------------------------------------------------------------------------------------
// Load a file into a memory buffer
void MD5Importer::LoadFileIntoMemory (IOStream* file)
{
void MD5Importer::LoadFileIntoMemory(IOStream *file) {
// unload the previous buffer, if any
UnloadFileFromMemory();
@ -217,8 +199,7 @@ void MD5Importer::LoadFileIntoMemory (IOStream* file)
// ------------------------------------------------------------------------------------------------
// Unload the current memory buffer
void MD5Importer::UnloadFileFromMemory ()
{
void MD5Importer::UnloadFileFromMemory() {
// delete the file buffer
delete[] mBuffer;
mBuffer = NULL;
@ -227,8 +208,7 @@ void MD5Importer::UnloadFileFromMemory ()
// ------------------------------------------------------------------------------------------------
// Build unique vertices
void MD5Importer::MakeDataUnique (MD5::MeshDesc& meshSrc)
{
void MD5Importer::MakeDataUnique(MD5::MeshDesc &meshSrc) {
std::vector<bool> abHad(meshSrc.mVertices.size(), false);
// allocate enough storage to keep the output structures
@ -252,8 +232,8 @@ void MD5Importer::MakeDataUnique (MD5::MeshDesc& meshSrc)
// generate a new vertex
meshSrc.mVertices[iNewIndex] = meshSrc.mVertices[face.mIndices[i]];
face.mIndices[i] = iNewIndex++;
}
else abHad[face.mIndices[i]] = true;
} else
abHad[face.mIndices[i]] = true;
}
// swap face order
std::swap(face.mIndices[0], face.mIndices[2]);
@ -262,8 +242,7 @@ void MD5Importer::MakeDataUnique (MD5::MeshDesc& meshSrc)
// ------------------------------------------------------------------------------------------------
// Recursive node graph construction from a MD5MESH
void MD5Importer::AttachChilds_Mesh(int iParentID,aiNode* piParent, BoneList& bones)
{
void MD5Importer::AttachChilds_Mesh(int iParentID, aiNode *piParent, BoneList &bones) {
ai_assert(NULL != piParent && !piParent->mNumChildren);
// First find out how many children we'll have
@ -313,8 +292,7 @@ void MD5Importer::AttachChilds_Mesh(int iParentID,aiNode* piParent, BoneList& bo
// ------------------------------------------------------------------------------------------------
// Recursive node graph construction from a MD5ANIM
void MD5Importer::AttachChilds_Anim(int iParentID,aiNode* piParent, AnimBoneList& bones,const aiNodeAnim** node_anims)
{
void MD5Importer::AttachChilds_Anim(int iParentID, aiNode *piParent, AnimBoneList &bones, const aiNodeAnim **node_anims) {
ai_assert(NULL != piParent && !piParent->mNumChildren);
// First find out how many children we'll have
@ -327,8 +305,7 @@ void MD5Importer::AttachChilds_Anim(int iParentID,aiNode* piParent, AnimBoneList
piParent->mChildren = new aiNode *[piParent->mNumChildren];
for (int i = 0; i < (int)bones.size(); ++i) {
// (avoid infinite recursion)
if (iParentID != i && bones[i].mParentIndex == iParentID)
{
if (iParentID != i && bones[i].mParentIndex == iParentID) {
aiNode *pc;
// setup a new node
*piParent->mChildren++ = pc = new aiNode();
@ -337,7 +314,8 @@ void MD5Importer::AttachChilds_Anim(int iParentID,aiNode* piParent, AnimBoneList
// get the corresponding animation channel and its first frame
const aiNodeAnim **cur = node_anims;
while ((**cur).mNodeName != pc->mName)++cur;
while ((**cur).mNodeName != pc->mName)
++cur;
aiMatrix4x4::Translation((**cur).mPositionKeys[0].mValue, pc->mTransformation);
pc->mTransformation = pc->mTransformation * aiMatrix4x4((**cur).mRotationKeys[0].mValue.GetMatrix());
@ -353,13 +331,12 @@ void MD5Importer::AttachChilds_Anim(int iParentID,aiNode* piParent, AnimBoneList
// ------------------------------------------------------------------------------------------------
// Load a MD5MESH file
void MD5Importer::LoadMD5MeshFile ()
{
void MD5Importer::LoadMD5MeshFile() {
std::string pFile = mFile + "md5mesh";
std::unique_ptr<IOStream> file( pIOHandler->Open( pFile, "rb"));
std::unique_ptr<IOStream> file(mIOHandler->Open(pFile, "rb"));
// Check whether we can read from the file
if( file.get() == NULL || !file->FileSize()) {
if (file.get() == nullptr || !file->FileSize()) {
ASSIMP_LOG_WARN("Failed to access MD5MESH file: " + pFile);
return;
}
@ -442,8 +419,7 @@ void MD5Importer::LoadMD5MeshFile ()
::memset(piCount, 0, sizeof(unsigned int) * meshParser.mJoints.size());
for (MD5::VertexList::const_iterator iter = meshSrc.mVertices.begin(); iter != meshSrc.mVertices.end(); ++iter, ++pv) {
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) {
MD5::WeightDesc &weightDesc = meshSrc.mWeights[w];
/* FIX for some invalid exporters */
if (!(weightDesc.mWeight < AI_MD5_WEIGHT_EPSILON && weightDesc.mWeight >= -AI_MD5_WEIGHT_EPSILON))
@ -458,8 +434,7 @@ void MD5Importer::LoadMD5MeshFile ()
if (mesh->mNumBones) // just for safety
{
mesh->mBones = new aiBone *[mesh->mNumBones];
for (unsigned int q = 0,h = 0; q < meshParser.mJoints.size();++q)
{
for (unsigned int q = 0, h = 0; q < meshParser.mJoints.size(); ++q) {
if (!piCount[q]) continue;
aiBone *p = mesh->mBones[h] = new aiBone();
p->mNumWeights = piCount[q];
@ -561,8 +536,7 @@ void MD5Importer::LoadMD5MeshFile ()
// set this also as material name
mat->AddProperty(&meshSrc.mShader, AI_MATKEY_NAME);
}
else {
} else {
mat->AddProperty(&meshSrc.mShader, AI_MATKEY_TEXTURE_DIFFUSE(0));
}
mesh->mMaterialIndex = n++;
@ -572,10 +546,9 @@ void MD5Importer::LoadMD5MeshFile ()
// ------------------------------------------------------------------------------------------------
// Load an MD5ANIM file
void MD5Importer::LoadMD5AnimFile ()
{
void MD5Importer::LoadMD5AnimFile() {
std::string pFile = mFile + "md5anim";
std::unique_ptr<IOStream> file( pIOHandler->Open( pFile, "rb"));
std::unique_ptr<IOStream> file(mIOHandler->Open(pFile, "rb"));
// Check whether we can read from the file
if (!file.get() || !file->FileSize()) {
@ -594,8 +567,7 @@ void MD5Importer::LoadMD5AnimFile ()
if (animParser.mAnimatedBones.empty() || animParser.mFrames.empty() ||
animParser.mBaseFrames.size() != animParser.mAnimatedBones.size()) {
ASSIMP_LOG_ERROR("MD5ANIM: No frames or animated bones loaded");
}
else {
} else {
bHadMD5Anim = true;
pScene->mAnimations = new aiAnimation *[pScene->mNumAnimations = 1];
@ -622,14 +594,12 @@ void MD5Importer::LoadMD5AnimFile ()
// now process all values in there ... read all joints
MD5::BaseFrameDesc *pcBaseFrame = &animParser.mBaseFrames[0];
for (AnimBoneList::const_iterator iter2 = animParser.mAnimatedBones.begin(); iter2 != animParser.mAnimatedBones.end(); ++iter2,
++pcAnimNode,++pcBaseFrame)
{
++pcAnimNode, ++pcBaseFrame) {
if ((*iter2).iFirstKeyIndex >= (*iter).mValues.size()) {
// Allow for empty frames
if ((*iter2).iFlags != 0) {
throw DeadlyImportError("MD5: Keyframe index is out of range");
}
continue;
}
@ -644,16 +614,16 @@ void MD5Importer::LoadMD5AnimFile ()
for (unsigned int i = 0; i < 3; ++i) {
if ((*iter2).iFlags & (1u << i)) {
vKey->mValue[i] = *fpCur++;
}
else vKey->mValue[i] = pcBaseFrame->vPositionXYZ[i];
} else
vKey->mValue[i] = pcBaseFrame->vPositionXYZ[i];
}
// orientation component
for (unsigned int i = 0; i < 3; ++i) {
if ((*iter2).iFlags & (8u << i)) {
vTemp[i] = *fpCur++;
}
else vTemp[i] = pcBaseFrame->vRotationQuat[i];
} else
vTemp[i] = pcBaseFrame->vRotationQuat[i];
}
MD5::ConvertQuaternion(vTemp, qKey->mValue);
@ -683,10 +653,9 @@ void MD5Importer::LoadMD5AnimFile ()
// ------------------------------------------------------------------------------------------------
// Load an MD5CAMERA file
void MD5Importer::LoadMD5CameraFile ()
{
void MD5Importer::LoadMD5CameraFile() {
std::string pFile = mFile + "md5camera";
std::unique_ptr<IOStream> file( pIOHandler->Open( pFile, "rb"));
std::unique_ptr<IOStream> file(mIOHandler->Open(pFile, "rb"));
// Check whether we can read from the file
if (!file.get() || !file->FileSize()) {
@ -727,8 +696,7 @@ void MD5Importer::LoadMD5CameraFile ()
if (!cuts.size()) {
cuts.push_back(0);
cuts.push_back(static_cast<unsigned int>(frames.size() - 1));
}
else {
} else {
cuts.insert(cuts.begin(), 0);
if (cuts.back() < frames.size() - 1)

View File

@ -40,7 +40,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------
*/
/** @file MD5Loader.h
* @brief Definition of the .MD5 importer class.
* http://www.modwiki.net/wiki/MD5_(file_format)
@ -48,8 +47,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_MD5LOADER_H_INCLUDED
#define AI_MD5LOADER_H_INCLUDED
#include <assimp/BaseImporter.h>
#include "MD5Parser.h"
#include <assimp/BaseImporter.h>
#include <assimp/types.h>
@ -64,15 +63,11 @@ using namespace Assimp::MD5;
// ---------------------------------------------------------------------------
/** Importer class for the MD5 file format
*/
class MD5Importer : public BaseImporter
{
class MD5Importer : public BaseImporter {
public:
MD5Importer();
~MD5Importer();
public:
// -------------------------------------------------------------------
/** Returns whether the class can handle the format of the given file.
* See BaseImporter::CanRead() for details.
@ -81,7 +76,6 @@ public:
bool checkSig) const;
protected:
// -------------------------------------------------------------------
/** Return importer meta information.
* See #BaseImporter::GetInfo for the details
@ -102,9 +96,6 @@ protected:
void InternReadFile(const std::string &pFile, aiScene *pScene,
IOSystem *pIOHandler);
protected:
// -------------------------------------------------------------------
/** Load a *.MD5MESH file.
*/
@ -154,7 +145,6 @@ protected:
void LoadFileIntoMemory(IOStream *pFile);
void UnloadFileFromMemory();
/** IOSystem to be used to access files */
IOSystem *mIOHandler;
@ -174,9 +164,6 @@ protected:
/** Scene to be filled */
aiScene *pScene;
/** (Custom) I/O handler implementation */
IOSystem* pIOHandler;
/** true if a MD5MESH file has already been parsed */
bool bHadMD5Mesh;

View File

@ -817,20 +817,20 @@ void HL1MDLLoader::read_meshes() {
mesh_faces.reserve(num_faces);
if (is_triangle_fan) {
for (int i = 0; i < num_faces; ++i) {
for (int faceIdx = 0; faceIdx < num_faces; ++faceIdx) {
mesh_faces.push_back(HL1MeshFace{
tricmds[0],
tricmds[i + 1],
tricmds[i + 2] });
tricmds[faceIdx + 1],
tricmds[faceIdx + 2] });
}
} else {
for (int i = 0; i < num_faces; ++i) {
for (int faceIdx = 0; faceIdx < num_faces; ++faceIdx) {
if (i & 1) {
// Preserve winding order.
mesh_faces.push_back(HL1MeshFace{
tricmds[i + 1],
tricmds[i],
tricmds[i + 2] });
tricmds[faceIdx + 1],
tricmds[faceIdx],
tricmds[faceIdx + 2] });
} else {
mesh_faces.push_back(HL1MeshFace{
tricmds[i],
@ -1122,10 +1122,10 @@ void HL1MDLLoader::read_sequence_infos() {
aiNode *blend_controller_node = blend_controllers_node->mChildren[j] = new aiNode();
blend_controller_node->mParent = blend_controllers_node;
aiMetadata *md = blend_controller_node->mMetaData = aiMetadata::Alloc(3);
md->Set(0, "Start", pseqdesc->blendstart[j]);
md->Set(1, "End", pseqdesc->blendend[j]);
md->Set(2, "MotionFlags", pseqdesc->blendtype[j]);
aiMetadata *metaData = blend_controller_node->mMetaData = aiMetadata::Alloc(3);
metaData->Set(0, "Start", pseqdesc->blendstart[j]);
metaData->Set(1, "End", pseqdesc->blendend[j]);
metaData->Set(2, "MotionFlags", pseqdesc->blendtype[j]);
}
}
}
@ -1151,10 +1151,10 @@ void HL1MDLLoader::read_sequence_infos() {
aiNode *pEvent = pEventsNode->mChildren[j] = new aiNode();
pEvent->mParent = pEventsNode;
aiMetadata *md = pEvent->mMetaData = aiMetadata::Alloc(3);
md->Set(0, "Frame", pevent->frame);
md->Set(1, "ScriptEvent", pevent->event);
md->Set(2, "Options", aiString(pevent->options));
aiMetadata *metaData = pEvent->mMetaData = aiMetadata::Alloc(3);
metaData->Set(0, "Frame", pevent->frame);
metaData->Set(1, "ScriptEvent", pevent->event);
metaData->Set(2, "Options", aiString(pevent->options));
}
}

View File

@ -68,7 +68,7 @@ struct HL1MeshTrivert {
normindex(normindex),
s(s),
t(t),
localindex() {
localindex(localindex) {
}
HL1MeshTrivert(const Trivert &a) :

View File

@ -68,7 +68,7 @@ static aiTexel* const bad_texel = reinterpret_cast<aiTexel*>(SIZE_MAX);
void MDLImporter::SearchPalette(const unsigned char** pszColorMap)
{
// now try to find the color map in the current directory
IOStream* pcStream = pIOHandler->Open(configPalette,"rb");
IOStream* pcStream = mIOHandler->Open(configPalette,"rb");
const unsigned char* szColorMap = (const unsigned char*)::g_aclrDefaultColorMap;
if(pcStream)
@ -702,14 +702,13 @@ void MDLImporter::ParseSkinLump_3DGS_MDL7(
// data structures in the aiScene instance
if (pcNew && pScene->mNumTextures <= 999)
{
// place this as diffuse texture
char szCurrent[5];
ai_snprintf(szCurrent,5,"*%i",this->pScene->mNumTextures);
char current[5];
ai_snprintf(current, 5, "*%i", this->pScene->mNumTextures);
aiString szFile;
const size_t iLen = strlen((const char*)szCurrent);
::memcpy(szFile.data,(const char*)szCurrent,iLen+1);
const size_t iLen = strlen((const char *)current);
::memcpy(szFile.data, (const char *)current, iLen + 1);
szFile.length = (ai_uint32)iLen;
pcMatOut->AddProperty(&szFile,AI_MATKEY_TEXTURE_DIFFUSE(0));

View File

@ -261,19 +261,19 @@ void MS3DImporter::InternReadFile( const std::string& pFile,
TempTriangle& t = triangles[i];
stream.IncPtr(2);
for (unsigned int i = 0; i < 3; ++i) {
t.indices[i] = stream.GetI2();
for (unsigned int j = 0; j < 3; ++j) {
t.indices[j] = stream.GetI2();
}
for (unsigned int i = 0; i < 3; ++i) {
ReadVector(stream,t.normals[i]);
for (unsigned int j = 0; j < 3; ++j) {
ReadVector(stream,t.normals[j]);
}
for (unsigned int i = 0; i < 3; ++i) {
stream >> (float&)(t.uv[i].x); // see note in ReadColor()
for (unsigned int j = 0; j < 3; ++j) {
stream >> (float&)(t.uv[j].x); // see note in ReadColor()
}
for (unsigned int i = 0; i < 3; ++i) {
stream >> (float&)(t.uv[i].y);
for (unsigned int j = 0; j < 3; ++j) {
stream >> (float&)(t.uv[j].y);
}
t.sg = stream.GetI1();
@ -296,8 +296,8 @@ void MS3DImporter::InternReadFile( const std::string& pFile,
stream >> num;
t.triangles.resize(num);
for (unsigned int i = 0; i < num; ++i) {
t.triangles[i] = stream.GetI2();
for (unsigned int j = 0; j < num; ++j) {
t.triangles[j] = stream.GetI2();
}
t.mat = stream.GetI1();
if (t.mat == UINT_MAX) {
@ -309,8 +309,8 @@ void MS3DImporter::InternReadFile( const std::string& pFile,
stream >> mat;
std::vector<TempMaterial> materials(mat);
for (unsigned int i = 0;i < mat; ++i) {
TempMaterial& t = materials[i];
for (unsigned int j = 0;j < mat; ++j) {
TempMaterial& t = materials[j];
stream.CopyAndAdvance(t.name,32);
t.name[32] = '\0';
@ -338,8 +338,8 @@ void MS3DImporter::InternReadFile( const std::string& pFile,
stream >> joint;
std::vector<TempJoint> joints(joint);
for(unsigned int i = 0; i < joint; ++i) {
TempJoint& j = joints[i];
for(unsigned int ii = 0; ii < joint; ++ii) {
TempJoint& j = joints[ii];
stream.IncPtr(1);
stream.CopyAndAdvance(j.name,32);
@ -494,17 +494,17 @@ void MS3DImporter::InternReadFile( const std::string& pFile,
typedef std::map<unsigned int,unsigned int> BoneSet;
BoneSet mybones;
for (unsigned int i = 0,n = 0; i < m->mNumFaces; ++i) {
aiFace& f = m->mFaces[i];
if (g.triangles[i]>triangles.size()) {
for (unsigned int j = 0,n = 0; j < m->mNumFaces; ++j) {
aiFace& f = m->mFaces[j];
if (g.triangles[j]>triangles.size()) {
throw DeadlyImportError("MS3D: Encountered invalid triangle index, file is malformed");
}
TempTriangle& t = triangles[g.triangles[i]];
f.mIndices = new unsigned int[f.mNumIndices=3];
for (unsigned int i = 0; i < 3; ++i,++n) {
if (t.indices[i]>vertices.size()) {
for (unsigned int k = 0; k < 3; ++k,++n) {
if (t.indices[k]>vertices.size()) {
throw DeadlyImportError("MS3D: Encountered invalid vertex index, file is malformed");
}
@ -545,11 +545,11 @@ void MS3DImporter::InternReadFile( const std::string& pFile,
}
// .. and collect bone weights
for (unsigned int i = 0,n = 0; i < m->mNumFaces; ++i) {
TempTriangle& t = triangles[g.triangles[i]];
for (unsigned int j = 0,n = 0; j < m->mNumFaces; ++j) {
TempTriangle& t = triangles[g.triangles[j]];
for (unsigned int i = 0; i < 3; ++i,++n) {
const TempVertex& v = vertices[t.indices[i]];
for (unsigned int k = 0; k < 3; ++k,++n) {
const TempVertex& v = vertices[t.indices[k]];
for(unsigned int a = 0; a < 4; ++a) {
const unsigned int bone = v.bone_id[a];
if(bone==UINT_MAX){

File diff suppressed because it is too large Load Diff

View File

@ -185,8 +185,8 @@ private:
// for spheres, cones and cylinders: center point of the object
aiVector3D center, radius, dir;
char name[128];
static const size_t MaxNameLen = 128;
char name[MaxNameLen];
std::vector<aiVector3D> vertices, normals, uvs;
std::vector<unsigned int> faces;

View File

@ -80,7 +80,7 @@ ObjFileParser::ObjFileParser( IOStreamBuffer<char> &streamBuffer, const std::str
m_progress(progress),
m_originalObjFileName(originalObjFileName)
{
std::fill_n(m_buffer,Buffersize,0);
std::fill_n(m_buffer,Buffersize,'\0');
// Create the model instance to store all the data
m_pModel.reset(new ObjFile::Model());

View File

@ -668,8 +668,8 @@ void OgreBinarySerializer::ReadEdgeList(Mesh * /*mesh*/)
for (size_t i=0; i<numEdgeGroups; ++i)
{
uint16_t id = ReadHeader();
if (id != M_EDGE_GROUP)
uint16_t curId = ReadHeader();
if (curId != M_EDGE_GROUP)
throw DeadlyImportError("M_EDGE_GROUP not found in M_EDGE_LIST_LOD");
m_reader->IncPtr(sizeof(uint32_t) * 3);

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,

View File

@ -206,8 +206,8 @@ aiMaterial* OgreImporter::ReadMaterial(const std::string &pFile, Assimp::IOSyste
aiMaterial *material = new aiMaterial();
m_textures.clear();
aiString ts(materialName);
material->AddProperty(&ts, AI_MATKEY_NAME);
aiString matName(materialName);
material->AddProperty(&matName, AI_MATKEY_NAME);
// The stringstream will push words from a line until newline.
// It will also trim whitespace from line start and between words.
@ -279,14 +279,14 @@ aiMaterial* OgreImporter::ReadMaterial(const std::string &pFile, Assimp::IOSyste
else if (linePart=="$colormap")
{
ss >> linePart;
aiString ts(linePart);
material->AddProperty(&ts, AI_MATKEY_TEXTURE(aiTextureType_DIFFUSE, 0));
aiString cm(linePart);
material->AddProperty(&cm, AI_MATKEY_TEXTURE(aiTextureType_DIFFUSE, 0));
}
else if (linePart=="$normalmap")
{
ss >> linePart;
aiString ts(linePart);
material->AddProperty(&ts, AI_MATKEY_TEXTURE(aiTextureType_NORMALS, 0));
aiString nm(linePart);
material->AddProperty(&nm, AI_MATKEY_TEXTURE(aiTextureType_NORMALS, 0));
}
else if (linePart=="$shininess_strength")
{

View File

@ -46,26 +46,25 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef ASSIMP_BUILD_NO_OGRE_IMPORTER
#include <assimp/ParsingUtils.h>
#include <functional>
#include <algorithm>
#include <stdint.h>
#include <sstream>
#include <algorithm>
#include <cctype>
#include <functional>
#include <sstream>
namespace Assimp {
namespace Ogre {
/// Returns a lower cased copy of @s.
static AI_FORCE_INLINE
std::string ToLower(std::string s)
{
std::transform(s.begin(), s.end(), s.begin(), ::tolower);
return s;
static AI_FORCE_INLINE std::string ToLower(const std::string &s) {
std::string lower(s);
std::transform(lower.begin(), lower.end(), lower.begin(), Assimp::ToLower<char>);
return lower;
}
/// Returns if @c s ends with @c suffix. If @c caseSensitive is false, both strings will be lower cased before matching.
static AI_FORCE_INLINE
bool EndsWith(const std::string &s, const std::string &suffix, bool caseSensitive = true) {
static AI_FORCE_INLINE bool EndsWith( const std::string &s, const std::string &suffix, bool caseSensitive = true) {
if (s.empty() || suffix.empty()) {
return false;
} else if (s.length() < suffix.length()) {
@ -86,7 +85,8 @@ bool EndsWith(const std::string &s, const std::string &suffix, bool caseSensitiv
/// Trim from start
static AI_FORCE_INLINE
std::string &TrimLeft(std::string &s, bool newlines = true) {
std::string &
TrimLeft(std::string &s, bool newlines = true) {
if (!newlines) {
s.erase(s.begin(), std::find_if(s.begin(), s.end(), [](char c) { return !Assimp::IsSpace<char>(c); }));
} else {
@ -97,7 +97,8 @@ std::string &TrimLeft(std::string &s, bool newlines = true) {
/// Trim from end
static AI_FORCE_INLINE
std::string &TrimRight(std::string &s, bool newlines = true) {
std::string &
TrimRight(std::string &s, bool newlines = true) {
if (!newlines) {
s.erase(std::find_if(s.rbegin(), s.rend(), [](char c) { return !Assimp::IsSpace<char>(c); }).base(), s.end());
} else {
@ -108,13 +109,15 @@ std::string &TrimRight(std::string &s, bool newlines = true) {
/// Trim from both ends
static AI_FORCE_INLINE
std::string &Trim(std::string &s, bool newlines = true) {
std::string &
Trim(std::string &s, bool newlines = true) {
return TrimLeft(TrimRight(s, newlines), newlines);
}
/// Skips a line from current @ss position until a newline. Returns the skipped part.
static AI_FORCE_INLINE
std::string SkipLine(std::stringstream &ss) {
std::string
SkipLine(std::stringstream &ss) {
std::string skipped;
getline(ss, skipped);
return skipped;
@ -123,14 +126,15 @@ std::string SkipLine(std::stringstream &ss) {
/// Skips a line and reads next element from @c ss to @c nextElement.
/** @return Skipped line content until newline. */
static AI_FORCE_INLINE
std::string NextAfterNewLine(std::stringstream &ss, std::string &nextElement) {
std::string
NextAfterNewLine(std::stringstream &ss, std::string &nextElement) {
std::string skipped = SkipLine(ss);
ss >> nextElement;
return skipped;
}
} // Ogre
} // Assimp
} // namespace Ogre
} // namespace Assimp
#endif // ASSIMP_BUILD_NO_OGRE_IMPORTER
#endif // AI_OGREPARSINGUTILS_H_INC

View File

@ -53,140 +53,94 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Define as 1 to get verbose logging.
#define OGRE_XML_SERIALIZER_DEBUG 0
namespace Assimp
{
namespace Ogre
{
namespace Assimp {
namespace Ogre {
AI_WONT_RETURN void ThrowAttibuteError(const XmlReader *reader, const std::string &name, const std::string &error = "") AI_WONT_RETURN_SUFFIX;
AI_WONT_RETURN void ThrowAttibuteError(const XmlReader* reader, const std::string &name, const std::string &error)
{
if (!error.empty())
{
AI_WONT_RETURN void ThrowAttibuteError(const XmlReader *reader, const std::string &name, const std::string &error) {
if (!error.empty()) {
throw DeadlyImportError(error + " in node '" + std::string(reader->getNodeName()) + "' and attribute '" + name + "'");
}
else
{
} else {
throw DeadlyImportError("Attribute '" + name + "' does not exist in node '" + std::string(reader->getNodeName()) + "'");
}
}
template <>
int32_t OgreXmlSerializer::ReadAttribute<int32_t>(const char *name) const
{
if (HasAttribute(name))
{
int32_t OgreXmlSerializer::ReadAttribute<int32_t>(const char *name) const {
if (!HasAttribute(name)) {
ThrowAttibuteError(m_reader, name);
}
return static_cast<int32_t>(m_reader->getAttributeValueAsInt(name));
}
else
{
ThrowAttibuteError(m_reader, name);
return 0;
}
}
template <>
uint32_t OgreXmlSerializer::ReadAttribute<uint32_t>(const char *name) const
{
if (HasAttribute(name))
{
/** @note This is hackish. But we are never expecting unsigned values that go outside the
int32_t range. Just monitor for negative numbers and kill the import. */
int32_t temp = ReadAttribute<int32_t>(name);
if (temp >= 0)
{
return static_cast<uint32_t>(temp);
uint32_t OgreXmlSerializer::ReadAttribute<uint32_t>(const char *name) const {
if (!HasAttribute(name)) {
ThrowAttibuteError(m_reader, name);
}
else
{
// @note This is hackish. But we are never expecting unsigned values that go outside the
// int32_t range. Just monitor for negative numbers and kill the import.
int32_t temp = ReadAttribute<int32_t>(name);
if (temp < 0) {
ThrowAttibuteError(m_reader, name, "Found a negative number value where expecting a uint32_t value");
}
}
else
{
ThrowAttibuteError(m_reader, name);
}
return 0;
return static_cast<uint32_t>(temp);
}
template <>
uint16_t OgreXmlSerializer::ReadAttribute<uint16_t>(const char *name) const
{
if (HasAttribute(name))
{
uint16_t OgreXmlSerializer::ReadAttribute<uint16_t>(const char *name) const {
if (!HasAttribute(name)) {
ThrowAttibuteError(m_reader, name);
}
return static_cast<uint16_t>(ReadAttribute<uint32_t>(name));
}
else
{
ThrowAttibuteError(m_reader, name);
}
return 0;
}
template <>
float OgreXmlSerializer::ReadAttribute<float>(const char *name) const
{
if (HasAttribute(name))
{
float OgreXmlSerializer::ReadAttribute<float>(const char *name) const {
if (!HasAttribute(name)) {
ThrowAttibuteError(m_reader, name);
}
return m_reader->getAttributeValueAsFloat(name);
}
else
{
ThrowAttibuteError(m_reader, name);
return 0;
}
}
template <>
std::string OgreXmlSerializer::ReadAttribute<std::string>(const char *name) const
{
std::string OgreXmlSerializer::ReadAttribute<std::string>(const char *name) const {
const char *value = m_reader->getAttributeValue(name);
if (value)
{
if (nullptr == value) {
ThrowAttibuteError(m_reader, name);
}
return std::string(value);
}
else
{
ThrowAttibuteError(m_reader, name);
return "";
}
}
template <>
bool OgreXmlSerializer::ReadAttribute<bool>(const char *name) const
{
bool OgreXmlSerializer::ReadAttribute<bool>(const char *name) const {
std::string value = Ogre::ToLower(ReadAttribute<std::string>(name));
if (ASSIMP_stricmp(value, "true") == 0)
{
if (ASSIMP_stricmp(value, "true") == 0) {
return true;
}
else if (ASSIMP_stricmp(value, "false") == 0)
{
} else if (ASSIMP_stricmp(value, "false") == 0) {
return false;
}
else
{
} else {
ThrowAttibuteError(m_reader, name, "Boolean value is expected to be 'true' or 'false', encountered '" + value + "'");
return false;
}
}
bool OgreXmlSerializer::HasAttribute(const char *name) const
{
bool OgreXmlSerializer::HasAttribute(const char *name) const {
return (m_reader->getAttributeValue(name) != 0);
}
std::string &OgreXmlSerializer::NextNode()
{
do
{
if (!m_reader->read())
{
std::string &OgreXmlSerializer::NextNode() {
do {
if (!m_reader->read()) {
m_currentNodeName = "";
return m_currentNodeName;
}
}
while(m_reader->getNodeType() != irr::io::EXN_ELEMENT);
} while (m_reader->getNodeType() != irr::io::EXN_ELEMENT);
CurrentNodeName(true);
#if (OGRE_XML_SERIALIZER_DEBUG == 1)
@ -195,20 +149,17 @@ std::string &OgreXmlSerializer::NextNode()
return m_currentNodeName;
}
bool OgreXmlSerializer::CurrentNodeNameEquals(const std::string &name) const
{
bool OgreXmlSerializer::CurrentNodeNameEquals(const std::string &name) const {
return (ASSIMP_stricmp(m_currentNodeName, name) == 0);
}
std::string OgreXmlSerializer::CurrentNodeName(bool forceRead)
{
std::string OgreXmlSerializer::CurrentNodeName(bool forceRead) {
if (forceRead)
m_currentNodeName = std::string(m_reader->getNodeName());
return m_currentNodeName;
}
std::string &OgreXmlSerializer::SkipCurrentNode()
{
std::string &OgreXmlSerializer::SkipCurrentNode() {
#if (OGRE_XML_SERIALIZER_DEBUG == 1)
ASSIMP_LOG_DEBUG("Skipping node <" + m_currentNodeName + ">");
#endif
@ -330,26 +281,18 @@ void OgreXmlSerializer::ReadMesh(MeshXml *mesh) {
m_currentNodeName == nnSubMeshNames ||
m_currentNodeName == nnExtremes ||
m_currentNodeName == nnPoses ||
m_currentNodeName == nnAnimations)
{
if (m_currentNodeName == nnSharedGeometry)
{
m_currentNodeName == nnAnimations) {
if (m_currentNodeName == nnSharedGeometry) {
mesh->sharedVertexData = new VertexDataXml();
ReadGeometry(mesh->sharedVertexData);
}
else if (m_currentNodeName == nnSubMeshes)
{
} else if (m_currentNodeName == nnSubMeshes) {
NextNode();
while (m_currentNodeName == nnSubMesh) {
ReadSubMesh(mesh);
}
}
else if (m_currentNodeName == nnBoneAssignments)
{
} else if (m_currentNodeName == nnBoneAssignments) {
ReadBoneAssignments(mesh->sharedVertexData);
}
else if (m_currentNodeName == nnSkeletonLink)
{
} else if (m_currentNodeName == nnSkeletonLink) {
mesh->skeletonRef = ReadAttribute<std::string>("name");
ASSIMP_LOG_DEBUG_F("Read skeleton link ", mesh->skeletonRef);
NextNode();
@ -360,8 +303,7 @@ void OgreXmlSerializer::ReadMesh(MeshXml *mesh) {
}
}
void OgreXmlSerializer::ReadGeometry(VertexDataXml *dest)
{
void OgreXmlSerializer::ReadGeometry(VertexDataXml *dest) {
dest->count = ReadAttribute<uint32_t>("vertexcount");
ASSIMP_LOG_DEBUG_F(" - Reading geometry of ", dest->count, " vertices");
@ -371,8 +313,7 @@ void OgreXmlSerializer::ReadGeometry(VertexDataXml *dest)
}
}
void OgreXmlSerializer::ReadGeometryVertexBuffer(VertexDataXml *dest)
{
void OgreXmlSerializer::ReadGeometryVertexBuffer(VertexDataXml *dest) {
bool positions = (HasAttribute("positions") && ReadAttribute<bool>("positions"));
bool normals = (HasAttribute("normals") && ReadAttribute<bool>("normals"));
bool tangents = (HasAttribute("tangents") && ReadAttribute<bool>("tangents"));
@ -383,23 +324,19 @@ void OgreXmlSerializer::ReadGeometryVertexBuffer(VertexDataXml *dest)
throw DeadlyImportError("Vertex buffer does not contain positions!");
}
if (positions)
{
if (positions) {
ASSIMP_LOG_DEBUG(" - Contains positions");
dest->positions.reserve(dest->count);
}
if (normals)
{
if (normals) {
ASSIMP_LOG_DEBUG(" - Contains normals");
dest->normals.reserve(dest->count);
}
if (tangents)
{
if (tangents) {
ASSIMP_LOG_DEBUG(" - Contains tangents");
dest->tangents.reserve(dest->count);
}
if (uvs > 0)
{
if (uvs > 0) {
ASSIMP_LOG_DEBUG_F(" - Contains ", uvs, " texture coords");
dest->uvs.resize(uvs);
for (size_t i = 0, len = dest->uvs.size(); i < len; ++i) {
@ -420,42 +357,33 @@ void OgreXmlSerializer::ReadGeometryVertexBuffer(VertexDataXml *dest)
m_currentNodeName == nnBinormal ||
m_currentNodeName == nnTexCoord ||
m_currentNodeName == nnColorDiffuse ||
m_currentNodeName == nnColorSpecular)
{
m_currentNodeName == nnColorSpecular) {
if (m_currentNodeName == nnVertex) {
NextNode();
}
/// @todo Implement nnBinormal, nnColorDiffuse and nnColorSpecular
if (positions && m_currentNodeName == nnPosition)
{
if (positions && m_currentNodeName == nnPosition) {
aiVector3D pos;
pos.x = ReadAttribute<float>(anX);
pos.y = ReadAttribute<float>(anY);
pos.z = ReadAttribute<float>(anZ);
dest->positions.push_back(pos);
}
else if (normals && m_currentNodeName == nnNormal)
{
} else if (normals && m_currentNodeName == nnNormal) {
aiVector3D normal;
normal.x = ReadAttribute<float>(anX);
normal.y = ReadAttribute<float>(anY);
normal.z = ReadAttribute<float>(anZ);
dest->normals.push_back(normal);
}
else if (tangents && m_currentNodeName == nnTangent)
{
} else if (tangents && m_currentNodeName == nnTangent) {
aiVector3D tangent;
tangent.x = ReadAttribute<float>(anX);
tangent.y = ReadAttribute<float>(anY);
tangent.z = ReadAttribute<float>(anZ);
dest->tangents.push_back(tangent);
}
else if (uvs > 0 && m_currentNodeName == nnTexCoord)
{
for(auto &uvs : dest->uvs)
{
} else if (uvs > 0 && m_currentNodeName == nnTexCoord) {
for (auto &curUvs : dest->uvs) {
if (m_currentNodeName != nnTexCoord) {
throw DeadlyImportError("Vertex buffer declared more UVs than can be found in a vertex");
}
@ -463,47 +391,31 @@ void OgreXmlSerializer::ReadGeometryVertexBuffer(VertexDataXml *dest)
aiVector3D uv;
uv.x = ReadAttribute<float>("u");
uv.y = (ReadAttribute<float>("v") * -1) + 1; // Flip UV from Ogre to Assimp form
uvs.push_back(uv);
curUvs.push_back(uv);
NextNode();
}
// Continue main loop as above already read next node
continue;
}
else
{
} else {
/// @todo Remove this stuff once implemented. We only want to log warnings once per element.
bool warn = true;
if (m_currentNodeName == nnBinormal)
{
if (warnBinormal)
{
if (m_currentNodeName == nnBinormal) {
if (warnBinormal) {
warnBinormal = false;
}
else
{
} else {
warn = false;
}
}
else if (m_currentNodeName == nnColorDiffuse)
{
if (warnColorDiffuse)
{
} else if (m_currentNodeName == nnColorDiffuse) {
if (warnColorDiffuse) {
warnColorDiffuse = false;
}
else
{
} else {
warn = false;
}
}
else if (m_currentNodeName == nnColorSpecular)
{
if (warnColorSpecular)
{
} else if (m_currentNodeName == nnColorSpecular) {
if (warnColorSpecular) {
warnColorSpecular = false;
}
else
{
} else {
warn = false;
}
}
@ -526,8 +438,7 @@ void OgreXmlSerializer::ReadGeometryVertexBuffer(VertexDataXml *dest)
if (tangents && dest->tangents.size() != dest->count) {
throw DeadlyImportError(Formatter::format() << "Read only " << dest->tangents.size() << " tangents when should have read " << dest->count);
}
for(unsigned int i=0; i<dest->uvs.size(); ++i)
{
for (unsigned int i = 0; i < dest->uvs.size(); ++i) {
if (dest->uvs[i].size() != dest->count) {
throw DeadlyImportError(Formatter::format() << "Read only " << dest->uvs[i].size()
<< " uvs for uv index " << i << " when should have read " << dest->count);
@ -535,8 +446,7 @@ void OgreXmlSerializer::ReadGeometryVertexBuffer(VertexDataXml *dest)
}
}
void OgreXmlSerializer::ReadSubMesh(MeshXml *mesh)
{
void OgreXmlSerializer::ReadSubMesh(MeshXml *mesh) {
static const char *anMaterial = "material";
static const char *anUseSharedVertices = "usesharedvertices";
static const char *anCount = "count";
@ -568,16 +478,13 @@ void OgreXmlSerializer::ReadSubMesh(MeshXml *mesh)
while (m_currentNodeName == nnFaces ||
m_currentNodeName == nnGeometry ||
m_currentNodeName == nnTextures ||
m_currentNodeName == nnBoneAssignments)
{
if (m_currentNodeName == nnFaces)
{
m_currentNodeName == nnBoneAssignments) {
if (m_currentNodeName == nnFaces) {
submesh->indexData->faceCount = ReadAttribute<uint32_t>(anCount);
submesh->indexData->faces.reserve(submesh->indexData->faceCount);
NextNode();
while(m_currentNodeName == nnFace)
{
while (m_currentNodeName == nnFace) {
aiFace face;
face.mNumIndices = 3;
face.mIndices = new unsigned int[3];
@ -622,8 +529,7 @@ void OgreXmlSerializer::ReadSubMesh(MeshXml *mesh)
mesh->subMeshes.push_back(submesh);
}
void OgreXmlSerializer::ReadBoneAssignments(VertexDataXml *dest)
{
void OgreXmlSerializer::ReadBoneAssignments(VertexDataXml *dest) {
if (!dest) {
throw DeadlyImportError("Cannot read bone assignments, vertex data is null.");
}
@ -635,8 +541,7 @@ void OgreXmlSerializer::ReadBoneAssignments(VertexDataXml *dest)
std::set<uint32_t> influencedVertices;
NextNode();
while(m_currentNodeName == nnVertexBoneAssignment)
{
while (m_currentNodeName == nnVertexBoneAssignment) {
VertexBoneAssignment ba;
ba.vertexIndex = ReadAttribute<uint32_t>(anVertexIndex);
ba.boneIndex = ReadAttribute<uint16_t>(anBoneIndex);
@ -652,18 +557,14 @@ void OgreXmlSerializer::ReadBoneAssignments(VertexDataXml *dest)
Some exporters won't care if the sum of all bone weights
for a single vertex equals 1 or not, so validate here. */
const float epsilon = 0.05f;
for (const uint32_t vertexIndex : influencedVertices)
{
for (const uint32_t vertexIndex : influencedVertices) {
float sum = 0.0f;
for (VertexBoneAssignmentList::const_iterator baIter=dest->boneAssignments.begin(), baEnd=dest->boneAssignments.end(); baIter != baEnd; ++baIter)
{
for (VertexBoneAssignmentList::const_iterator baIter = dest->boneAssignments.begin(), baEnd = dest->boneAssignments.end(); baIter != baEnd; ++baIter) {
if (baIter->vertexIndex == vertexIndex)
sum += baIter->weight;
}
if ((sum < (1.0f - epsilon)) || (sum > (1.0f + epsilon)))
{
for (auto &boneAssign : dest->boneAssignments)
{
if ((sum < (1.0f - epsilon)) || (sum > (1.0f + epsilon))) {
for (auto &boneAssign : dest->boneAssignments) {
if (boneAssign.vertexIndex == vertexIndex)
boneAssign.weight /= sum;
}
@ -675,15 +576,13 @@ void OgreXmlSerializer::ReadBoneAssignments(VertexDataXml *dest)
// Skeleton
bool OgreXmlSerializer::ImportSkeleton(Assimp::IOSystem *pIOHandler, MeshXml *mesh)
{
bool OgreXmlSerializer::ImportSkeleton(Assimp::IOSystem *pIOHandler, MeshXml *mesh) {
if (!mesh || mesh->skeletonRef.empty())
return false;
// Highly unusual to see in read world cases but support
// XML mesh referencing a binary skeleton file.
if (EndsWith(mesh->skeletonRef, ".skeleton", false))
{
if (EndsWith(mesh->skeletonRef, ".skeleton", false)) {
if (OgreBinarySerializer::ImportSkeleton(pIOHandler, mesh))
return true;
@ -705,8 +604,7 @@ bool OgreXmlSerializer::ImportSkeleton(Assimp::IOSystem *pIOHandler, MeshXml *me
return true;
}
bool OgreXmlSerializer::ImportSkeleton(Assimp::IOSystem *pIOHandler, Mesh *mesh)
{
bool OgreXmlSerializer::ImportSkeleton(Assimp::IOSystem *pIOHandler, Mesh *mesh) {
if (!mesh || mesh->skeletonRef.empty())
return false;
@ -721,16 +619,13 @@ bool OgreXmlSerializer::ImportSkeleton(Assimp::IOSystem *pIOHandler, Mesh *mesh)
return true;
}
XmlReaderPtr OgreXmlSerializer::OpenReader(Assimp::IOSystem *pIOHandler, const std::string &filename)
{
if (!EndsWith(filename, ".skeleton.xml", false))
{
XmlReaderPtr OgreXmlSerializer::OpenReader(Assimp::IOSystem *pIOHandler, const std::string &filename) {
if (!EndsWith(filename, ".skeleton.xml", false)) {
ASSIMP_LOG_ERROR_F("Imported Mesh is referencing to unsupported '", filename, "' skeleton file.");
return XmlReaderPtr();
}
if (!pIOHandler->Exists(filename))
{
if (!pIOHandler->Exists(filename)) {
ASSIMP_LOG_ERROR_F("Failed to find skeleton file '", filename, "' that is referenced by imported Mesh.");
return XmlReaderPtr();
}
@ -748,8 +643,7 @@ XmlReaderPtr OgreXmlSerializer::OpenReader(Assimp::IOSystem *pIOHandler, const s
return reader;
}
void OgreXmlSerializer::ReadSkeleton(Skeleton *skeleton)
{
void OgreXmlSerializer::ReadSkeleton(Skeleton *skeleton) {
if (NextNode() != nnSkeleton) {
throw DeadlyImportError("Root node is <" + m_currentNodeName + "> expecting <skeleton>");
}
@ -758,8 +652,7 @@ void OgreXmlSerializer::ReadSkeleton(Skeleton *skeleton)
// Optional blend mode from root node
if (HasAttribute("blendmode")) {
skeleton->blendMode = (ToLower(ReadAttribute<std::string>("blendmode")) == "cumulative"
? Skeleton::ANIMBLEND_CUMULATIVE : Skeleton::ANIMBLEND_AVERAGE);
skeleton->blendMode = (ToLower(ReadAttribute<std::string>("blendmode")) == "cumulative" ? Skeleton::ANIMBLEND_CUMULATIVE : Skeleton::ANIMBLEND_AVERAGE);
}
NextNode();
@ -768,8 +661,7 @@ void OgreXmlSerializer::ReadSkeleton(Skeleton *skeleton)
while (m_currentNodeName == nnBones ||
m_currentNodeName == nnBoneHierarchy ||
m_currentNodeName == nnAnimations ||
m_currentNodeName == nnAnimationLinks)
{
m_currentNodeName == nnAnimationLinks) {
if (m_currentNodeName == nnBones)
ReadBones(skeleton);
else if (m_currentNodeName == nnBoneHierarchy)
@ -781,8 +673,7 @@ void OgreXmlSerializer::ReadSkeleton(Skeleton *skeleton)
}
}
void OgreXmlSerializer::ReadAnimations(Skeleton *skeleton)
{
void OgreXmlSerializer::ReadAnimations(Skeleton *skeleton) {
if (skeleton->bones.empty()) {
throw DeadlyImportError("Cannot read <animations> for a Skeleton without bones");
}
@ -790,8 +681,7 @@ void OgreXmlSerializer::ReadAnimations(Skeleton *skeleton)
ASSIMP_LOG_DEBUG(" - Animations");
NextNode();
while(m_currentNodeName == nnAnimation)
{
while (m_currentNodeName == nnAnimation) {
Animation *anim = new Animation(skeleton);
anim->name = ReadAttribute<std::string>("name");
anim->length = ReadAttribute<float>("length");
@ -807,11 +697,9 @@ void OgreXmlSerializer::ReadAnimations(Skeleton *skeleton)
}
}
void OgreXmlSerializer::ReadAnimationTracks(Animation *dest)
{
void OgreXmlSerializer::ReadAnimationTracks(Animation *dest) {
NextNode();
while(m_currentNodeName == nnTrack)
{
while (m_currentNodeName == nnTrack) {
VertexAnimationTrack track;
track.type = VertexAnimationTrack::VAT_TRANSFORM;
track.boneName = ReadAttribute<std::string>("bone");
@ -826,27 +714,21 @@ void OgreXmlSerializer::ReadAnimationTracks(Animation *dest)
}
}
void OgreXmlSerializer::ReadAnimationKeyFrames(Animation *anim, VertexAnimationTrack *dest)
{
void OgreXmlSerializer::ReadAnimationKeyFrames(Animation *anim, VertexAnimationTrack *dest) {
const aiVector3D zeroVec(0.f, 0.f, 0.f);
NextNode();
while(m_currentNodeName == nnKeyFrame)
{
while (m_currentNodeName == nnKeyFrame) {
TransformKeyFrame keyframe;
keyframe.timePos = ReadAttribute<float>("time");
NextNode();
while(m_currentNodeName == nnTranslate || m_currentNodeName == nnRotate || m_currentNodeName == nnScale)
{
if (m_currentNodeName == nnTranslate)
{
while (m_currentNodeName == nnTranslate || m_currentNodeName == nnRotate || m_currentNodeName == nnScale) {
if (m_currentNodeName == nnTranslate) {
keyframe.position.x = ReadAttribute<float>(anX);
keyframe.position.y = ReadAttribute<float>(anY);
keyframe.position.z = ReadAttribute<float>(anZ);
}
else if (m_currentNodeName == nnRotate)
{
} else if (m_currentNodeName == nnRotate) {
float angle = ReadAttribute<float>("angle");
if (NextNode() != nnAxis) {
@ -857,17 +739,14 @@ void OgreXmlSerializer::ReadAnimationKeyFrames(Animation *anim, VertexAnimationT
axis.x = ReadAttribute<float>(anX);
axis.y = ReadAttribute<float>(anY);
axis.z = ReadAttribute<float>(anZ);
if (axis.Equal(zeroVec))
{
if (axis.Equal(zeroVec)) {
axis.x = 1.0f;
if (angle != 0) {
ASSIMP_LOG_WARN_F("Found invalid a key frame with a zero rotation axis in animation: ", anim->name);
}
}
keyframe.rotation = aiQuaternion(axis, angle);
}
else if (m_currentNodeName == nnScale)
{
} else if (m_currentNodeName == nnScale) {
keyframe.scale.x = ReadAttribute<float>(anX);
keyframe.scale.y = ReadAttribute<float>(anY);
keyframe.scale.z = ReadAttribute<float>(anZ);
@ -880,14 +759,12 @@ void OgreXmlSerializer::ReadAnimationKeyFrames(Animation *anim, VertexAnimationT
}
}
void OgreXmlSerializer::ReadBoneHierarchy(Skeleton *skeleton)
{
void OgreXmlSerializer::ReadBoneHierarchy(Skeleton *skeleton) {
if (skeleton->bones.empty()) {
throw DeadlyImportError("Cannot read <bonehierarchy> for a Skeleton without bones");
}
while(NextNode() == nnBoneParent)
{
while (NextNode() == nnBoneParent) {
const std::string name = ReadAttribute<std::string>("bone");
const std::string parentName = ReadAttribute<std::string>("parent");
@ -901,29 +778,25 @@ void OgreXmlSerializer::ReadBoneHierarchy(Skeleton *skeleton)
}
// Calculate bone matrices for root bones. Recursively calculates their children.
for (size_t i=0, len=skeleton->bones.size(); i<len; ++i)
{
for (size_t i = 0, len = skeleton->bones.size(); i < len; ++i) {
Bone *bone = skeleton->bones[i];
if (!bone->IsParented())
bone->CalculateWorldMatrixAndDefaultPose(skeleton);
}
}
static bool BoneCompare(Bone *a, Bone *b)
{
static bool BoneCompare(Bone *a, Bone *b) {
ai_assert(nullptr != a);
ai_assert(nullptr != b);
return (a->id < b->id);
}
void OgreXmlSerializer::ReadBones(Skeleton *skeleton)
{
void OgreXmlSerializer::ReadBones(Skeleton *skeleton) {
ASSIMP_LOG_DEBUG(" - Bones");
NextNode();
while(m_currentNodeName == nnBone)
{
while (m_currentNodeName == nnBone) {
Bone *bone = new Bone();
bone->id = ReadAttribute<uint16_t>("id");
bone->name = ReadAttribute<std::string>("name");
@ -931,16 +804,12 @@ void OgreXmlSerializer::ReadBones(Skeleton *skeleton)
NextNode();
while (m_currentNodeName == nnPosition ||
m_currentNodeName == nnRotation ||
m_currentNodeName == nnScale)
{
if (m_currentNodeName == nnPosition)
{
m_currentNodeName == nnScale) {
if (m_currentNodeName == nnPosition) {
bone->position.x = ReadAttribute<float>(anX);
bone->position.y = ReadAttribute<float>(anY);
bone->position.z = ReadAttribute<float>(anZ);
}
else if (m_currentNodeName == nnRotation)
{
} else if (m_currentNodeName == nnRotation) {
float angle = ReadAttribute<float>("angle");
if (NextNode() != nnAxis) {
@ -953,17 +822,12 @@ void OgreXmlSerializer::ReadBones(Skeleton *skeleton)
axis.z = ReadAttribute<float>(anZ);
bone->rotation = aiQuaternion(axis, angle);
}
else if (m_currentNodeName == nnScale)
{
} else if (m_currentNodeName == nnScale) {
/// @todo Implement taking scale into account in matrix/pose calculations!
if (HasAttribute("factor"))
{
if (HasAttribute("factor")) {
float factor = ReadAttribute<float>("factor");
bone->scale.Set(factor, factor, factor);
}
else
{
} else {
if (HasAttribute(anX))
bone->scale.x = ReadAttribute<float>(anX);
if (HasAttribute(anY))
@ -985,8 +849,7 @@ void OgreXmlSerializer::ReadBones(Skeleton *skeleton)
// Validate that bone indexes are not skipped.
/** @note Left this from original authors code, but not sure if this is strictly necessary
as per the Ogre skeleton spec. It might be more that other (later) code in this imported does not break. */
for (size_t i=0, len=skeleton->bones.size(); i<len; ++i)
{
for (size_t i = 0, len = skeleton->bones.size(); i < len; ++i) {
Bone *b = skeleton->bones[i];
ASSIMP_LOG_DEBUG_F(" ", b->id, " ", b->name);
@ -996,7 +859,7 @@ void OgreXmlSerializer::ReadBones(Skeleton *skeleton)
}
}
} // Ogre
} // Assimp
} // namespace Ogre
} // namespace Assimp
#endif // ASSIMP_BUILD_NO_OGRE_IMPORTER

View File

@ -1212,8 +1212,8 @@ void OpenGEXImporter::resolveReferences() {
if( RefInfo::MeshRef == currentRefInfo->m_type ) {
for( size_t i = 0; i < currentRefInfo->m_Names.size(); ++i ) {
const std::string &name( currentRefInfo->m_Names[ i ] );
ReferenceMap::const_iterator it( m_mesh2refMap.find( name ) );
if( m_mesh2refMap.end() != it ) {
ReferenceMap::const_iterator curIt( m_mesh2refMap.find( name ) );
if (m_mesh2refMap.end() != curIt) {
unsigned int meshIdx = static_cast<unsigned int>(m_mesh2refMap[ name ]);
node->mMeshes[ i ] = meshIdx;
}
@ -1221,8 +1221,8 @@ void OpenGEXImporter::resolveReferences() {
} else if( RefInfo::MaterialRef == currentRefInfo->m_type ) {
for ( size_t i = 0; i < currentRefInfo->m_Names.size(); ++i ) {
const std::string name( currentRefInfo->m_Names[ i ] );
ReferenceMap::const_iterator it( m_material2refMap.find( name ) );
if ( m_material2refMap.end() != it ) {
ReferenceMap::const_iterator curIt(m_material2refMap.find(name));
if (m_material2refMap.end() != curIt) {
if ( nullptr != m_currentMesh ) {
unsigned int matIdx = static_cast< unsigned int >( m_material2refMap[ name ] );
if ( m_currentMesh->mMaterialIndex != 0 ) {

View File

@ -49,10 +49,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// internal headers
#include "PlyLoader.h"
#include <assimp/IOStreamBuffer.h>
#include <memory>
#include <assimp/IOSystem.hpp>
#include <assimp/scene.h>
#include <assimp/importerdesc.h>
#include <assimp/scene.h>
#include <assimp/IOSystem.hpp>
#include <memory>
using namespace ::Assimp;
@ -69,29 +69,25 @@ static const aiImporterDesc desc = {
"ply"
};
// ------------------------------------------------------------------------------------------------
// Internal stuff
namespace {
// ------------------------------------------------------------------------------------------------
// Checks that property index is within range
template <class T>
inline
const T &GetProperty(const std::vector<T> &props, int idx) {
inline const T &GetProperty(const std::vector<T> &props, int idx) {
if (static_cast<size_t>(idx) >= props.size()) {
throw DeadlyImportError("Invalid .ply file: Property index is out of range.");
}
return props[idx];
}
}
} // namespace
// ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer
PLYImporter::PLYImporter()
: mBuffer(nullptr)
, pcDOM(nullptr)
, mGeneratedMesh(nullptr) {
PLYImporter::PLYImporter() :
mBuffer(nullptr), pcDOM(nullptr), mGeneratedMesh(nullptr) {
// empty
}
@ -397,19 +393,25 @@ void PLYImporter::LoadVertex(const PLY::Element* pcElement, const PLY::ElementIn
bool haveColor = false;
if (0xFFFFFFFF != aiColors[0]) {
cOut.r = NormalizeColorValue(GetProperty(instElement->alProperties,
aiColors[0]).avList.front(), aiColorsTypes[0]);
aiColors[0])
.avList.front(),
aiColorsTypes[0]);
haveColor = true;
}
if (0xFFFFFFFF != aiColors[1]) {
cOut.g = NormalizeColorValue(GetProperty(instElement->alProperties,
aiColors[1]).avList.front(), aiColorsTypes[1]);
aiColors[1])
.avList.front(),
aiColorsTypes[1]);
haveColor = true;
}
if (0xFFFFFFFF != aiColors[2]) {
cOut.b = NormalizeColorValue(GetProperty(instElement->alProperties,
aiColors[2]).avList.front(), aiColorsTypes[2]);
aiColors[2])
.avList.front(),
aiColorsTypes[2]);
haveColor = true;
}
@ -418,7 +420,9 @@ void PLYImporter::LoadVertex(const PLY::Element* pcElement, const PLY::ElementIn
cOut.a = 1.0;
} else {
cOut.a = NormalizeColorValue(GetProperty(instElement->alProperties,
aiColors[3]).avList.front(), aiColorsTypes[3]);
aiColors[3])
.avList.front(),
aiColorsTypes[3]);
haveColor = true;
}
@ -474,7 +478,6 @@ void PLYImporter::LoadVertex(const PLY::Element* pcElement, const PLY::ElementIn
}
}
// ------------------------------------------------------------------------------------------------
// Convert a color component to [0...1]
ai_real PLYImporter::NormalizeColorValue(PLY::PropertyInstance::ValueUnion val, PLY::EDataType eType) {
@ -684,44 +687,50 @@ void PLYImporter::LoadFace(const PLY::Element* pcElement, const PLY::ElementInst
void PLYImporter::GetMaterialColor(const std::vector<PLY::PropertyInstance> &avList,
unsigned int aiPositions[4],
PLY::EDataType aiTypes[4],
aiColor4D* clrOut)
{
aiColor4D *clrOut) {
ai_assert(NULL != clrOut);
if (0xFFFFFFFF == aiPositions[0])clrOut->r = 0.0f;
else
{
if (0xFFFFFFFF == aiPositions[0])
clrOut->r = 0.0f;
else {
clrOut->r = NormalizeColorValue(GetProperty(avList,
aiPositions[0]).avList.front(), aiTypes[0]);
aiPositions[0])
.avList.front(),
aiTypes[0]);
}
if (0xFFFFFFFF == aiPositions[1])clrOut->g = 0.0f;
else
{
if (0xFFFFFFFF == aiPositions[1])
clrOut->g = 0.0f;
else {
clrOut->g = NormalizeColorValue(GetProperty(avList,
aiPositions[1]).avList.front(), aiTypes[1]);
aiPositions[1])
.avList.front(),
aiTypes[1]);
}
if (0xFFFFFFFF == aiPositions[2])clrOut->b = 0.0f;
else
{
if (0xFFFFFFFF == aiPositions[2])
clrOut->b = 0.0f;
else {
clrOut->b = NormalizeColorValue(GetProperty(avList,
aiPositions[2]).avList.front(), aiTypes[2]);
aiPositions[2])
.avList.front(),
aiTypes[2]);
}
// assume 1.0 for the alpha channel ifit is not set
if (0xFFFFFFFF == aiPositions[3])clrOut->a = 1.0f;
else
{
if (0xFFFFFFFF == aiPositions[3])
clrOut->a = 1.0f;
else {
clrOut->a = NormalizeColorValue(GetProperty(avList,
aiPositions[3]).avList.front(), aiTypes[3]);
aiPositions[3])
.avList.front(),
aiTypes[3]);
}
}
// ------------------------------------------------------------------------------------------------
// Extract a material from the PLY DOM
void PLYImporter::LoadMaterial(std::vector<aiMaterial*>* pvOut, std::string &defaultTexture, const bool pointsOnly)
{
void PLYImporter::LoadMaterial(std::vector<aiMaterial *> *pvOut, std::string &defaultTexture, const bool pointsOnly) {
ai_assert(NULL != pvOut);
// diffuse[4], specular[4], ambient[4]
@ -749,102 +758,74 @@ void PLYImporter::LoadMaterial(std::vector<aiMaterial*>* pvOut, std::string &def
// search in the DOM for a vertex entry
unsigned int _i = 0;
for (std::vector<PLY::Element>::const_iterator i = this->pcDOM->alElements.begin();
i != this->pcDOM->alElements.end(); ++i, ++_i)
{
if (PLY::EEST_Material == (*i).eSemantic)
{
i != this->pcDOM->alElements.end(); ++i, ++_i) {
if (PLY::EEST_Material == (*i).eSemantic) {
pcList = &this->pcDOM->alElementData[_i];
// now check whether which coordinate sets are available
unsigned int _a = 0;
for (std::vector<PLY::Property>::const_iterator
a = (*i).alProperties.begin();
a != (*i).alProperties.end(); ++a, ++_a)
{
a != (*i).alProperties.end(); ++a, ++_a) {
if ((*a).bIsList) continue;
// pohng specularity -----------------------------------
if (PLY::EST_PhongPower == (*a).Semantic)
{
if (PLY::EST_PhongPower == (*a).Semantic) {
iPhong = _a;
ePhong = (*a).eType;
}
// general opacity -----------------------------------
if (PLY::EST_Opacity == (*a).Semantic)
{
if (PLY::EST_Opacity == (*a).Semantic) {
iOpacity = _a;
eOpacity = (*a).eType;
}
// diffuse color channels -----------------------------------
if (PLY::EST_DiffuseRed == (*a).Semantic)
{
if (PLY::EST_DiffuseRed == (*a).Semantic) {
aaiPositions[0][0] = _a;
aaiTypes[0][0] = (*a).eType;
}
else if (PLY::EST_DiffuseGreen == (*a).Semantic)
{
} else if (PLY::EST_DiffuseGreen == (*a).Semantic) {
aaiPositions[0][1] = _a;
aaiTypes[0][1] = (*a).eType;
}
else if (PLY::EST_DiffuseBlue == (*a).Semantic)
{
} else if (PLY::EST_DiffuseBlue == (*a).Semantic) {
aaiPositions[0][2] = _a;
aaiTypes[0][2] = (*a).eType;
}
else if (PLY::EST_DiffuseAlpha == (*a).Semantic)
{
} else if (PLY::EST_DiffuseAlpha == (*a).Semantic) {
aaiPositions[0][3] = _a;
aaiTypes[0][3] = (*a).eType;
}
// specular color channels -----------------------------------
else if (PLY::EST_SpecularRed == (*a).Semantic)
{
else if (PLY::EST_SpecularRed == (*a).Semantic) {
aaiPositions[1][0] = _a;
aaiTypes[1][0] = (*a).eType;
}
else if (PLY::EST_SpecularGreen == (*a).Semantic)
{
} else if (PLY::EST_SpecularGreen == (*a).Semantic) {
aaiPositions[1][1] = _a;
aaiTypes[1][1] = (*a).eType;
}
else if (PLY::EST_SpecularBlue == (*a).Semantic)
{
} else if (PLY::EST_SpecularBlue == (*a).Semantic) {
aaiPositions[1][2] = _a;
aaiTypes[1][2] = (*a).eType;
}
else if (PLY::EST_SpecularAlpha == (*a).Semantic)
{
} else if (PLY::EST_SpecularAlpha == (*a).Semantic) {
aaiPositions[1][3] = _a;
aaiTypes[1][3] = (*a).eType;
}
// ambient color channels -----------------------------------
else if (PLY::EST_AmbientRed == (*a).Semantic)
{
else if (PLY::EST_AmbientRed == (*a).Semantic) {
aaiPositions[2][0] = _a;
aaiTypes[2][0] = (*a).eType;
}
else if (PLY::EST_AmbientGreen == (*a).Semantic)
{
} else if (PLY::EST_AmbientGreen == (*a).Semantic) {
aaiPositions[2][1] = _a;
aaiTypes[2][1] = (*a).eType;
}
else if (PLY::EST_AmbientBlue == (*a).Semantic)
{
} else if (PLY::EST_AmbientBlue == (*a).Semantic) {
aaiPositions[2][2] = _a;
aaiTypes[2][2] = (*a).eType;
}
else if (PLY::EST_AmbientAlpha == (*a).Semantic)
{
} else if (PLY::EST_AmbientAlpha == (*a).Semantic) {
aaiPositions[2][3] = _a;
aaiTypes[2][3] = (*a).eType;
}
}
break;
}
else if (PLY::EEST_TextureFile == (*i).eSemantic)
{
} else if (PLY::EEST_TextureFile == (*i).eSemantic) {
defaultTexture = (*i).szName;
}
}
@ -895,21 +876,17 @@ void PLYImporter::LoadMaterial(std::vector<aiMaterial*>* pvOut, std::string &def
pcHelper->AddProperty(&two_sided, 1, AI_MATKEY_TWOSIDED);
//default texture
if (!defaultTexture.empty())
{
if (!defaultTexture.empty()) {
const aiString name(defaultTexture.c_str());
pcHelper->AddProperty(&name, _AI_MATKEY_TEXTURE_BASE, aiTextureType_DIFFUSE, 0);
}
if (!pointsOnly)
{
const int two_sided = 1;
if (!pointsOnly) {
pcHelper->AddProperty(&two_sided, 1, AI_MATKEY_TWOSIDED);
}
//set to wireframe, so when using this material info we can switch to points rendering
if (pointsOnly)
{
if (pointsOnly) {
const int wireframe = 1;
pcHelper->AddProperty(&wireframe, 1, AI_MATKEY_ENABLE_WIREFRAME);
}
@ -917,9 +894,7 @@ void PLYImporter::LoadMaterial(std::vector<aiMaterial*>* pvOut, std::string &def
// add the newly created material instance to the list
pvOut->push_back(pcHelper);
}
}
else
{
} else {
// generate a default material
aiMaterial *pcHelper = new aiMaterial();
@ -938,22 +913,19 @@ void PLYImporter::LoadMaterial(std::vector<aiMaterial*>* pvOut, std::string &def
// The face order is absolutely undefined for PLY, so we have to
// use two-sided rendering to be sure it's ok.
if (!pointsOnly)
{
if (!pointsOnly) {
const int two_sided = 1;
pcHelper->AddProperty(&two_sided, 1, AI_MATKEY_TWOSIDED);
}
//default texture
if (!defaultTexture.empty())
{
if (!defaultTexture.empty()) {
const aiString name(defaultTexture.c_str());
pcHelper->AddProperty(&name, _AI_MATKEY_TEXTURE_BASE, aiTextureType_DIFFUSE, 0);
}
//set to wireframe, so when using this material info we can switch to points rendering
if (pointsOnly)
{
if (pointsOnly) {
const int wireframe = 1;
pcHelper->AddProperty(&wireframe, 1, AI_MATKEY_ENABLE_WIREFRAME);
}

View File

@ -137,7 +137,7 @@ bool EmbedTexturesProcess::addTexture(aiScene* pScene, std::string path) const {
pTexture->pcData = imageContent;
auto extension = path.substr(path.find_last_of('.') + 1u);
std::transform(extension.begin(), extension.end(), extension.begin(), ::tolower);
std::transform(extension.begin(), extension.end(), extension.begin(), ToLower<char> );
if (extension == "jpeg") {
extension = "jpg";
}

View File

@ -105,7 +105,8 @@ void TextureTransformStep::PreProcessUVTransform(STransformVecInfo& info)
if (info.mRotation)
{
float out = info.mRotation;
if ((rounded = static_cast<int>((info.mRotation / static_cast<float>(AI_MATH_TWO_PI)))))
rounded = static_cast<int>((info.mRotation / static_cast<float>(AI_MATH_TWO_PI)));
if (rounded)
{
out -= rounded * static_cast<float>(AI_MATH_PI);
ASSIMP_LOG_INFO_F("Texture coordinate rotation ", info.mRotation, " can be simplified to ", out);

View File

@ -517,8 +517,8 @@ outer:
for (FaceIdxArray::const_iterator it = fidx[i].begin(),end = fidx[i].end();
it != end; ++it, ++faces)
{
Mesh& m = meshes[(*it).first];
Face& face = m.faces[(*it).second];
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];
@ -528,29 +528,30 @@ outer:
for (unsigned int n = 0; n < faces->mNumIndices;++n, ++cnt, ++norms, ++verts)
{
if (face.indices[n] >= m.verts.size())
if (face.indices[n] >= curMesh.verts.size())
{
ASSIMP_LOG_WARN("Quick3D: Vertex index overflow");
face.indices[n] = 0;
}
// copy vertices
*verts = m.verts[ face.indices[n] ];
*verts = curMesh.verts[face.indices[n]];
if (face.indices[n] >= m.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)
{
const aiVector3D& pV1 = m.verts[ face.indices[0] ];
const aiVector3D& pV2 = m.verts[ face.indices[1] ];
const aiVector3D& pV3 = m.verts[ face.indices.size() - 1 ];
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];
faceNormal = (pV2 - pV1) ^ (pV3 - pV1).Normalize();
fnOK = true;
}
*norms = faceNormal;
} else {
*norms = curMesh.normals[face.indices[n]];
}
else *norms = m.normals[ face.indices[n] ];
// copy texture coordinates
if (uv && m.uv.size())

View File

@ -44,16 +44,19 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define INCLUDED_AI_STEPFILE_H
#include <bitset>
#include <map>
#include <memory>
#include <set>
#include <typeinfo>
#include <vector>
#include <map>
#include <set>
#include "FBX/FBXDocument.h" //ObjectMap::value_type
#include <assimp/DefaultLogger.hpp>
#pragma warning( push )
#pragma warning( disable : 4456 )
#pragma warning(disable : 4245)
//
#if _MSC_VER > 1500 || (defined __GNUC___)
#define ASSIMP_STEP_USE_UNORDERED_MULTIMAP
@ -86,7 +89,6 @@ namespace Assimp {
// ********************************************************************************
// before things get complicated, this is the basic outline:
namespace STEP {
namespace EXPRESS {
@ -107,16 +109,15 @@ namespace STEP {
// is a list of pointers to conversion functions to build up the
// object tree from an input file.
class ConversionSchema;
}
} // namespace EXPRESS
struct HeaderInfo;
class Object;
class LazyObject;
class DB;
typedef Object *(*ConvertObjectProc)(const DB &db, const EXPRESS::LIST &params);
}
} // namespace STEP
// ********************************************************************************
@ -134,7 +135,6 @@ namespace STEP {
SyntaxError(const std::string &s, uint64_t line = LINE_NOT_SPECIFIED);
};
// -------------------------------------------------------------------------------
/** 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.
@ -149,31 +149,26 @@ namespace STEP {
TypeError(const std::string &s, uint64_t entity = ENTITY_NOT_SPECIFIED, uint64_t line = SyntaxError::LINE_NOT_SPECIFIED);
};
// hack to make a given member template-dependent
template <typename T, typename T2>
T2 &Couple(T2 &in) {
return in;
}
namespace EXPRESS {
// -------------------------------------------------------------------------------
//** Base class for all STEP data types */
// -------------------------------------------------------------------------------
class DataType
{
class DataType {
public:
typedef std::shared_ptr<const DataType> Out;
public:
virtual ~DataType() {
}
public:
template <typename T>
const T &To() const {
return dynamic_cast<const T &>(*this);
@ -184,7 +179,6 @@ namespace STEP {
return dynamic_cast<T &>(*this);
}
template <typename T>
const T *ToPtr() const {
return dynamic_cast<const T *>(this);
@ -209,7 +203,6 @@ namespace STEP {
}
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.
@ -229,8 +222,7 @@ namespace STEP {
// -------------------------------------------------------------------------------
/** Sentinel class to represent explicitly unset (optional) fields ($) */
// -------------------------------------------------------------------------------
class UNSET : public DataType
{
class UNSET : public DataType {
public:
private:
};
@ -238,8 +230,7 @@ namespace STEP {
// -------------------------------------------------------------------------------
/** Sentinel class to represent explicitly derived fields (*) */
// -------------------------------------------------------------------------------
class ISDERIVED : public DataType
{
class ISDERIVED : public DataType {
public:
private:
};
@ -248,28 +239,20 @@ namespace STEP {
/** Shared implementation for some of the primitive data type, i.e. int, float */
// -------------------------------------------------------------------------------
template <typename T>
class PrimitiveDataType : public DataType
{
class PrimitiveDataType : public DataType {
public:
// This is the type that will cd ultimatively be used to
// expose this data type to the user.
typedef T Out;
public:
PrimitiveDataType() {}
PrimitiveDataType(const T& val)
: val(val)
{}
PrimitiveDataType(const T &val) :
val(val) {}
PrimitiveDataType(const PrimitiveDataType &o) {
(*this) = o;
}
public:
operator const T &() const {
return val;
}
@ -281,7 +264,6 @@ namespace STEP {
protected:
T val;
};
typedef PrimitiveDataType<int64_t> INTEGER;
@ -289,18 +271,13 @@ namespace STEP {
typedef PrimitiveDataType<double> NUMBER;
typedef PrimitiveDataType<std::string> STRING;
// -------------------------------------------------------------------------------
/** Generic base class for all enumerated types */
// -------------------------------------------------------------------------------
class ENUMERATION : public STRING
{
class ENUMERATION : public STRING {
public:
ENUMERATION (const std::string& val)
: STRING(val)
{}
ENUMERATION(const std::string &val) :
STRING(val) {}
private:
};
@ -310,19 +287,16 @@ namespace STEP {
// -------------------------------------------------------------------------------
/** This is just a reference to an entity/object somewhere else */
// -------------------------------------------------------------------------------
class ENTITY : public PrimitiveDataType<uint64_t>
{
class ENTITY : public PrimitiveDataType<uint64_t> {
public:
ENTITY(uint64_t val)
: PrimitiveDataType<uint64_t>(val)
{
ENTITY(uint64_t val) :
PrimitiveDataType<uint64_t>(val) {
ai_assert(val != 0);
}
ENTITY()
: PrimitiveDataType<uint64_t>(TypeError::ENTITY_NOT_SPECIFIED)
{
ENTITY() :
PrimitiveDataType<uint64_t>(TypeError::ENTITY_NOT_SPECIFIED) {
// empty
}
private:
@ -331,10 +305,8 @@ namespace STEP {
// -------------------------------------------------------------------------------
/** Wrap any STEP aggregate: LIST, SET, ... */
// -------------------------------------------------------------------------------
class LIST : public DataType
{
class LIST : public DataType {
public:
// access a particular list index, throw std::range_error for wrong indices
std::shared_ptr<const DataType> operator[](size_t index) const {
return members[index];
@ -345,13 +317,11 @@ namespace STEP {
}
public:
/** @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);
private:
typedef std::vector<std::shared_ptr<const DataType>> MemberList;
MemberList members;
@ -359,13 +329,13 @@ namespace STEP {
class BINARY : public PrimitiveDataType<uint32_t> {
public:
BINARY(uint32_t val)
: PrimitiveDataType<uint32_t>(val) {
BINARY(uint32_t val) :
PrimitiveDataType<uint32_t>(val) {
// empty
}
BINARY()
: PrimitiveDataType<uint32_t>(TypeError::ENTITY_NOT_SPECIFIED_32) {
BINARY() :
PrimitiveDataType<uint32_t>(TypeError::ENTITY_NOT_SPECIFIED_32) {
// empty
}
};
@ -378,9 +348,8 @@ namespace STEP {
class ConversionSchema {
public:
struct SchemaEntry {
SchemaEntry( const char *name, ConvertObjectProc func )
: mName( name )
, mFunc(func) {
SchemaEntry(const char *name, ConvertObjectProc func) :
mName(name), mFunc(func) {
// empty
}
@ -396,7 +365,6 @@ namespace STEP {
}
ConversionSchema() {
}
ConvertObjectProc GetConverterProc(const std::string &name) const {
@ -413,7 +381,6 @@ namespace STEP {
return it == converters.end() ? nullptr : (*it).first.c_str();
}
template <size_t N>
const ConversionSchema &operator=(const SchemaEntry (&schemas)[N]) {
for (size_t i = 0; i < N; ++i) {
@ -426,31 +393,26 @@ namespace STEP {
private:
ConverterMap converters;
};
}
} // namespace EXPRESS
// ------------------------------------------------------------------------------
/** 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.*/
// ------------------------------------------------------------------------------
struct HeaderInfo
{
struct HeaderInfo {
std::string timestamp;
std::string app;
std::string fileSchema;
};
// ------------------------------------------------------------------------------
/** Base class for all concrete object instances */
// ------------------------------------------------------------------------------
class Object {
public:
Object(const char* classname = "unknown")
: id( 0 )
, classname(classname) {
Object(const char *classname = "unknown") :
id(0), classname(classname) {
// empty
}
@ -500,14 +462,13 @@ namespace STEP {
size_t GenericFill(const STEP::DB &db, const EXPRESS::LIST &params, T *in);
// (intentionally undefined)
// ------------------------------------------------------------------------------
/** CRTP shared base class for use by concrete entity implementation classes */
// ------------------------------------------------------------------------------
template <typename TDerived, size_t arg_count>
struct ObjectHelper : virtual Object {
ObjectHelper()
: aux_is_derived(0) {
ObjectHelper() :
aux_is_derived(0) {
// empty
}
@ -539,18 +500,16 @@ namespace STEP {
// ------------------------------------------------------------------------------
template <typename T>
struct Maybe {
Maybe()
: have() {
Maybe() :
have() {
// empty
}
explicit Maybe(const T& ptr)
: ptr(ptr)
, have(true) {
explicit Maybe(const T &ptr) :
ptr(ptr), have(true) {
// empty
}
void flag_invalid() {
have = false;
}
@ -559,7 +518,6 @@ namespace STEP {
have = true;
}
bool operator!() const {
return !have;
}
@ -584,7 +542,8 @@ namespace STEP {
}
private:
template <typename T2> friend struct InternGenericConvert;
template <typename T2>
friend struct InternGenericConvert;
operator T &() {
return ptr;
@ -673,14 +632,12 @@ namespace STEP {
};
template <typename T>
inline
bool operator==( std::shared_ptr<LazyObject> lo, T whatever ) {
inline bool operator==(std::shared_ptr<LazyObject> lo, T whatever) {
return *lo == whatever; // XXX use std::forward if we have 0x
}
template <typename T>
inline
bool operator==( const std::pair<uint64_t, std::shared_ptr<LazyObject> >& lo, T whatever ) {
inline bool operator==(const std::pair<uint64_t, std::shared_ptr<LazyObject>> &lo, T whatever) {
return *(lo.second) == whatever; // XXX use std::forward if we have 0x
}
@ -690,8 +647,8 @@ namespace STEP {
template <typename T>
struct Lazy {
typedef Lazy Out;
Lazy(const LazyObject* obj = nullptr)
: obj(obj) {
Lazy(const LazyObject *obj = nullptr) :
obj(obj) {
// empty
}
@ -780,8 +737,7 @@ namespace STEP {
// XXX is this really how the EXPRESS notation ([?:3],[1:3]) is intended?
if (max_cnt && inp->GetSize() > max_cnt) {
ASSIMP_LOG_WARN("too many aggregate elements");
}
else if (inp->GetSize() < min_cnt) {
} else if (inp->GetSize() < min_cnt) {
ASSIMP_LOG_WARN("too few aggregate elements");
}
@ -791,8 +747,7 @@ namespace STEP {
out.push_back(typename ListOf<T, min_cnt, max_cnt>::OutScalar());
try {
GenericConvert(out.back(), (*inp)[i], db);
}
catch(const TypeError& t) {
} catch (const TypeError &t) {
throw TypeError(t.what() + std::string(" of aggregate"));
}
}
@ -825,13 +780,11 @@ namespace STEP {
* STEP file. DB's are exclusively maintained by the functions in
* STEPFileReader.h*/
// -------------------------------------------------------------------------------
class DB
{
class DB {
friend DB *ReadFileHeader(std::shared_ptr<IOStream> stream);
friend void ReadFile(DB &db, const EXPRESS::ConversionSchema &scheme,
const char *const *types_to_track, size_t len,
const char* const* inverse_indices_to_track, size_t len2
);
const char *const *inverse_indices_to_track, size_t len2);
friend class LazyObject;
@ -855,13 +808,8 @@ namespace STEP {
typedef std::pair<RefMap::const_iterator, RefMap::const_iterator> RefMapRange;
private:
DB(std::shared_ptr<StreamReaderLE> reader)
: reader(reader)
, splitter(*reader,true,true)
, evaluated_count()
, schema( nullptr )
{}
DB(std::shared_ptr<StreamReaderLE> reader) :
reader(reader), splitter(*reader, true, true), evaluated_count(), schema(nullptr) {}
public:
~DB() {
@ -902,7 +850,6 @@ namespace STEP {
return inv_whitelist.find(type) != inv_whitelist.end();
}
// get the yet unevaluated object record with a given id
const LazyObject *GetObject(uint64_t id) const {
const ObjectMap::const_iterator it = objects.find(id);
@ -912,7 +859,6 @@ namespace STEP {
return nullptr;
}
// get an arbitrary object out of the soup with the only restriction being its type.
const LazyObject *GetObject(const std::string &type) const {
const ObjectMapByType::const_iterator it = objects_bytype.find(type);
@ -939,7 +885,6 @@ namespace STEP {
return *o;
}
#ifdef ASSIMP_IFC_TEST
// evaluate *all* entities in the file. this is a power test for the loader
@ -953,7 +898,6 @@ namespace STEP {
#endif
private:
// full access only offered to close friends - they should
// use the provided getters rather than messing around with
// the members directly.
@ -974,7 +918,6 @@ namespace STEP {
schema = &_schema;
}
void SetTypesToTrack(const char *const *types, size_t N) {
for (size_t i = 0; i < N; ++i) {
objects_bytype[types[i]] = ObjectSet();
@ -1009,8 +952,10 @@ namespace STEP {
const EXPRESS::ConversionSchema *schema;
};
}
#pragma warning( pop )
} // end Assimp
} // namespace STEP
} // namespace Assimp
#endif // INCLUDED_AI_STEPFILE_H

View File

@ -297,8 +297,7 @@ std::string XGLImporter::GetElementName()
std::string ret;
ret.resize(len);
std::transform(s,s+len,ret.begin(),::tolower);
std::transform(s, s + len, ret.begin(), ::ToLower<char>);
return ret;
}
@ -618,26 +617,22 @@ bool XGLImporter::ReadMesh(TempScope& scope)
bool has[3] = {0};
while (ReadElementUpToClosing(s.c_str())) {
const std::string& s = GetElementName();
if (s == "fv1" || s == "lv1" || s == "pv1") {
const std::string& elemName = GetElementName();
if (elemName == "fv1" || elemName == "lv1" || elemName == "pv1") {
ReadFaceVertex(t,tf[0]);
has[0] = true;
}
else if (s == "fv2" || s == "lv2") {
} else if (elemName == "fv2" || elemName == "lv2") {
ReadFaceVertex(t, tf[1]);
has[1] = true;
}
else if (s == "fv3") {
} else if (elemName == "fv3") {
ReadFaceVertex(t, tf[2]);
has[2] = true;
}
else if (s == "mat") {
} else if (elemName == "mat") {
if (mid != ~0u) {
LogWarn("only one material tag allowed per <f>");
}
mid = ResolveMaterialRef(scope);
}
else if (s == "matref") {
} else if (elemName == "matref") {
if (mid != ~0u) {
LogWarn("only one material tag allowed per <f>");
}

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,