From 00f249b8dd76ce1efa9a8ee84b5970d3c3be6604 Mon Sep 17 00:00:00 2001 From: acgessler Date: Mon, 2 Jul 2012 15:57:51 +0200 Subject: [PATCH] - fbx: add property system --- code/FBXDocument.cpp | 22 +++++ code/FBXDocumentUtil.h | 5 + code/FBXMaterial.cpp | 64 +++++++++++++ code/FBXMeshGeometry.cpp | 2 +- code/FBXProperties.cpp | 180 +++++++++++++++++++++++++++++++++++ code/FBXProperties.h | 161 +++++++++++++++++++++++++++++++ workspaces/vc9/assimp.vcproj | 12 +++ 7 files changed, 445 insertions(+), 1 deletion(-) create mode 100644 code/FBXMaterial.cpp create mode 100644 code/FBXProperties.cpp create mode 100644 code/FBXProperties.h diff --git a/code/FBXDocument.cpp b/code/FBXDocument.cpp index 56ac480cb..bf5f2e0c0 100644 --- a/code/FBXDocument.cpp +++ b/code/FBXDocument.cpp @@ -73,6 +73,28 @@ void DOMError(const std::string& message, const Element* element /*= NULL*/) } +// ------------------------------------------------------------------------------------------------ +// print warning, do return +void DOMWarning(const std::string& message, const Token& token) +{ + if(DefaultLogger::get()) { + DefaultLogger::get()->warn(Util::AddTokenText("FBX-DOM",message,&token)); + } +} + +// ------------------------------------------------------------------------------------------------ +void DOMWarning(const std::string& message, const Element* element /*= NULL*/) +{ + if(element) { + DOMWarning(message,element->KeyToken()); + return; + } + if(DefaultLogger::get()) { + DefaultLogger::get()->warn("FBX-DOM: " + message); + } +} + + // ------------------------------------------------------------------------------------------------ // extract required compound scope const Scope& GetRequiredScope(const Element& el) diff --git a/code/FBXDocumentUtil.h b/code/FBXDocumentUtil.h index 631560c3d..8363138b6 100644 --- a/code/FBXDocumentUtil.h +++ b/code/FBXDocumentUtil.h @@ -48,9 +48,14 @@ namespace Assimp { namespace FBX { namespace Util { +// does not return void DOMError(const std::string& message, const Token& token); void DOMError(const std::string& message, const Element* element = NULL); +// does return +void DOMWarning(const std::string& message, const Token& token); +void DOMWarning(const std::string& message, const Element* element = NULL); + // extract required compound scope const Scope& GetRequiredScope(const Element& el); // get token at a particular index diff --git a/code/FBXMaterial.cpp b/code/FBXMaterial.cpp new file mode 100644 index 000000000..1585b9c98 --- /dev/null +++ b/code/FBXMaterial.cpp @@ -0,0 +1,64 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2012, assimp team +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ + +/** @file FBXMaterial.cpp + * @brief Assimp::FBX::Material implementation + */ +#include "AssimpPCH.h" + +#ifndef ASSIMP_BUILD_NO_FBX_IMPORTER + +#include "FBXParser.h" +#include "FBXDocument.h" +#include "FBXImporter.h" +#include "FBXImportSettings.h" +#include "FBXDocumentUtil.h" + +namespace Assimp { +namespace FBX { + + using namespace Util; + + + +} //!FBX +} //!Assimp + +#endif diff --git a/code/FBXMeshGeometry.cpp b/code/FBXMeshGeometry.cpp index 479f40338..2dc04294b 100644 --- a/code/FBXMeshGeometry.cpp +++ b/code/FBXMeshGeometry.cpp @@ -39,7 +39,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** @file FBXMeshGeometry.cpp - * @brief FBX::MeshGeometry implementation + * @brief Assimp::FBX::MeshGeometry implementation */ #include "AssimpPCH.h" diff --git a/code/FBXProperties.cpp b/code/FBXProperties.cpp new file mode 100644 index 000000000..9e042ca5a --- /dev/null +++ b/code/FBXProperties.cpp @@ -0,0 +1,180 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2012, assimp team +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ + +/** @file FBXProperties.cpp + * @brief Implementation of the FBX dynamic properties system + */ +#include "AssimpPCH.h" + +#ifndef ASSIMP_BUILD_NO_FBX_IMPORTER + +#include "FBXTokenizer.h" +#include "FBXParser.h" +#include "FBXDocument.h" +#include "FBXDocumentUtil.h" +#include "FBXProperties.h" + +namespace Assimp { +namespace FBX { + + using namespace Util; + +// ------------------------------------------------------------------------------------------------ +Property::Property() +{ +} + +// ------------------------------------------------------------------------------------------------ +Property::~Property() +{ +} + +namespace { + +// ------------------------------------------------------------------------------------------------ +// read a typed property out of a FBX element. The return value is NULL if the property cannot be read. +Property* ReadTypedProperty(const Element& element) +{ + ai_assert(element.KeyToken().StringContents() == "P"); + + const TokenList& tok = element.Tokens(); + ai_assert(tok.size() >= 5); + + const std::string& s = ParseTokenAsString(*tok[1]); + const char* const cs = s.c_str(); + if (!strcmp(cs,"KString")) { + return new TypedProperty(ParseTokenAsString(*tok[4])); + } + else if (!strcmp(cs,"bool")) { + return new TypedProperty(ParseTokenAsInt(*tok[4]) != 0); + } + else if (!strcmp(cs,"int")) { + return new TypedProperty(ParseTokenAsInt(*tok[4])); + } + else if (!strcmp(cs,"Vector3D")) { + return new TypedProperty(aiVector3D( + ParseTokenAsFloat(*tok[4]), + ParseTokenAsFloat(*tok[5]), + ParseTokenAsFloat(*tok[6])) + ); + } + return NULL; +} + +// ------------------------------------------------------------------------------------------------ +// peek into an element and check if it contains a FBX property, if so return its name. +std::string PeekPropertyName(const Element& element) +{ + ai_assert(element.KeyToken().StringContents() == "P"); + const TokenList& tok = element.Tokens(); + if(tok.size() < 5) { + return ""; + } + + return ParseTokenAsString(*tok[0]); +} + +} //! anon + +// ------------------------------------------------------------------------------------------------ +PropertyTable::PropertyTable(const Element& element, PropertyTable* templateProps) +: element(element) +, templateProps(templateProps) +{ + const Scope& scope = GetRequiredScope(element); + BOOST_FOREACH(const ElementMap::value_type& v, scope.Elements()) { + if(v.first != "P") { + DOMWarning("expected only P elements in property table",v.second); + continue; + } + + const std::string& name = PeekPropertyName(*v.second); + if(!name.length()) { + DOMWarning("could not read property name",v.second); + continue; + } + + LazyPropertyMap::const_iterator it = lazyProps.find(name); + if (it != lazyProps.end()) { + DOMWarning("duplicate property name, will hide previous value: " + name,v.second); + continue; + } + + lazyProps[name] = v.second; + } +} + +// ------------------------------------------------------------------------------------------------ +PropertyTable::~PropertyTable() +{ +} + +// ------------------------------------------------------------------------------------------------ +const Property* PropertyTable::Get(const std::string& name) +{ + PropertyMap::const_iterator it = props.find(name); + if (it == props.end()) { + // hasn't been parsed yet? + LazyPropertyMap::const_iterator lit = lazyProps.find(name); + if(lit != lazyProps.end()) { + props[name] = ReadTypedProperty(*(*lit).second); + it = props.find(name); + + ai_assert(it != props.end()); + } + + if (it == props.end()) { + // check property template + if(templateProps) { + return templateProps->Get(name); + } + + return NULL; + } + } + + ai_assert((*it).second); + return (*it).second; +} + +} //! FBX +} //! Assimp + +#endif diff --git a/code/FBXProperties.h b/code/FBXProperties.h new file mode 100644 index 000000000..af74c0acd --- /dev/null +++ b/code/FBXProperties.h @@ -0,0 +1,161 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2012, assimp team +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ + +/** @file FBXProperties.h + * @brief FBX dynamic properties + */ +#ifndef INCLUDED_AI_FBX_PROPERTIES_H +#define INCLUDED_AI_FBX_PROPERTIES_H + +#include +#include + +namespace Assimp { +namespace FBX { + + class Element; + + +/** Represents a dynamic property. Type info added by deriving classes, + * see #TypedProperty. + Example: + @verbatim + P: "ShininessExponent", "double", "Number", "",0.5 + @endvebatim + +*/ +class Property +{ +protected: + + Property(); + +public: + + virtual ~Property(); + +public: + + template + const T* As() const { + return dynamic_cast(t); + } +}; + + +template +class TypedProperty : public Property +{ +public: + + TypedProperty(const T& value) + : value(value) + { + } + +public: + + const T& Value() const { + return value; + } + +private: + T value; +}; + + +typedef std::fbx_unordered_map PropertyMap; +typedef std::fbx_unordered_map LazyPropertyMap; + +/** Represents a property table as can be found in the newer FBX files (Properties60, Properties70)*/ +class PropertyTable +{ +public: + + PropertyTable(const Element& element, PropertyTable* templateProps); + ~PropertyTable(); + +public: + + const Property* Get(const std::string& name); + + const Element& GetElement() const { + return element; + } + + const PropertyTable* TemplateProps() const { + return templateProps; + } + +private: + + LazyPropertyMap lazyProps; + PropertyMap props; + PropertyTable* const templateProps; + const Element& element; +}; + + +// ------------------------------------------------------------------------------------------------ +template +inline T PropertyGet(const PropertyTable& in, const std::string& name, + const T& defaultValue, + bool ignoreTemplate /*= false*/) +{ + const Property* const prop = PropertyGet(in,name); + if(!prop) { + return defaultValue; + } + + // strong typing, no need to be lenient + const TypedProperty* const tprop = prop->As< TypedProperty >(); + if(!tprop) { + // XXX print type name + DOMError("unexpected data type: property " + name,in.GetElement()); + } + + return tprop->Value(); +} + + +} //! FBX +} //! Assimp + +#endif // diff --git a/workspaces/vc9/assimp.vcproj b/workspaces/vc9/assimp.vcproj index 817304dcb..352957caf 100644 --- a/workspaces/vc9/assimp.vcproj +++ b/workspaces/vc9/assimp.vcproj @@ -2091,6 +2091,10 @@ RelativePath="..\..\code\FBXImportSettings.h" > + + @@ -2103,6 +2107,14 @@ RelativePath="..\..\code\FBXParser.h" > + + + +