diff --git a/code/FBXDocument.cpp b/code/FBXDocument.cpp new file mode 100644 index 000000000..062c30170 --- /dev/null +++ b/code/FBXDocument.cpp @@ -0,0 +1,173 @@ +/* +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 FBXDocument.cpp + * @brief Implementation of the FBX DOM classes + */ +#include "AssimpPCH.h" + +#ifndef ASSIMP_BUILD_NO_FBX_IMPORTER + +#include "FBXParser.h" +#include "FBXDocument.h" +#include "FBXUtil.h" + +namespace { + + using namespace Assimp; + using namespace Assimp::FBX; + + // ------------------------------------------------------------------------------------------------ + // signal DOM construction error, this is always unrecoverable. Throws DeadlyImportError. + void DOMError(const std::string& message, Element* element = NULL) + { + throw DeadlyImportError(element ? Util::AddTokenText("FBX-DOM",message,element->KeyToken()) : ("FBX-DOM " + message)); + } +} + +namespace Assimp { +namespace FBX { + +// ------------------------------------------------------------------------------------------------ +LazyObject::LazyObject(const Element& element) +: element(element) +{ + +} + +// ------------------------------------------------------------------------------------------------ +LazyObject::~LazyObject() +{ + +} + +// ------------------------------------------------------------------------------------------------ +const Object* LazyObject::Get() +{ + if (object.get()) { + return object.get(); + } + + // XXX + return NULL; +} + +// ------------------------------------------------------------------------------------------------ +Object::Object(const Element& element) +: element(element) +{ + +} + +// ------------------------------------------------------------------------------------------------ +Object::~Object() +{ + +} + +// ------------------------------------------------------------------------------------------------ +Geometry::Geometry(const Element& element) +: Object(element) +{ + +} + +// ------------------------------------------------------------------------------------------------ +Geometry::~Geometry() +{ + +} + +// ------------------------------------------------------------------------------------------------ +MeshGeometry::MeshGeometry(const Element& element) +: Geometry(element) +{ + +} + +// ------------------------------------------------------------------------------------------------ +MeshGeometry::~MeshGeometry() +{ + +} + +// ------------------------------------------------------------------------------------------------ +Document::Document(const Parser& parser) +: parser(parser) +{ + + const Scope& sc = parser.GetRootScope(); + const Element* const eobjects = sc["Objects"]; + if(!eobjects || !eobjects->Compound()) { + DOMError("no Objects dictionary found"); + } + + const Scope* const sobjects = eobjects->Compound(); + BOOST_FOREACH(const ElementMap::value_type& el, sobjects->Elements()) { + + // extract ID + const TokenList& tok = el.second->Tokens(); + + if (tok.empty()) { + DOMError("expected ID after object key",el.second); + } + + const char* err; + + const uint64_t id = ParseTokenAsID(*tok[0], err); + if(err) { + DOMError(err,el.second); + } + + objects[id] = new LazyObject(*el.second); + } +} + +// ------------------------------------------------------------------------------------------------ +Document::~Document() +{ + +} + +} // !FBX +} // !Assimp + +#endif + diff --git a/code/FBXDocument.h b/code/FBXDocument.h new file mode 100644 index 000000000..cb5d0fdfd --- /dev/null +++ b/code/FBXDocument.h @@ -0,0 +1,211 @@ +/* +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 FBXDocument.h + * @brief FBX DOM + */ +#ifndef INCLUDED_AI_FBX_DOCUMENT_H +#define INCLUDED_AI_FBX_DOCUMENT_H + +#include +#include +#include + +namespace Assimp { +namespace FBX { + + class Parser; + class Object; + + +/** Represents a delay-parsed FBX objects. Many objects in the scene + * are not needed by assimp, so it makes no sense to parse them + * upfront. */ +class LazyObject +{ +public: + + LazyObject(const Element& element); + ~LazyObject(); + +public: + + const Object* Get(); + + template + T* Get() { + const Object* const ob = Get(); + return ob ? dynamic_cast(ob) : NULL; + } + +private: + + const Element& element; + boost::scoped_ptr object; +}; + + + +/** Base class for in-memory (DOM) representations of FBX objects */ +class Object +{ +public: + + Object(const Element& element); + ~Object(); + +public: + +protected: + const Element& element; +}; + + +/** DOM base class for all kinds of FBX geometry */ +class Geometry : public Object +{ +public: + + Geometry(const Element& element); + ~Geometry(); +}; + + +/** DOM class for FBX geometry of type "Mesh"*/ +class MeshGeometry : public Geometry +{ + +public: + + MeshGeometry(const Element& element); + ~MeshGeometry(); + +public: + + /** Get a list of all vertex points, non-unique*/ + const std::vector& GetVertices() const { + return vertices; + } + + /** Get a list of all vertex normals or an empty array if + * no normals are specified. */ + const std::vector& GetNormals() const { + return normals; + } + + /** Get a list of all vertex tangents or an empty array + * if no tangents are specified */ + const std::vector& GetTangents() const { + return tangents; + } + + /** Return list of faces - each entry denotes a face and specifies + * how many vertices it has. Vertices are taken from the + * vertex data arrays in sequential order. */ + const std::vector& GetFaceIndexCounts() const { + return faces; + } + + /** Get a UV coordinate slot, returns an empty array if + * the requested slot does not exist. */ + const std::vector& GetTextureCoords(unsigned int index) const { + static const std::vector empty; + return index >= AI_MAX_NUMBER_OF_TEXTURECOORDS ? empty : uvs[index]; + } + + /** Get a vertex color coordinate slot, returns an empty array if + * the requested slot does not exist. */ + const std::vector& GetVertexColors(unsigned int index) const { + static const std::vector empty; + return index >= AI_MAX_NUMBER_OF_COLOR_SETS ? empty : colors[index]; + } + + + /** Get per-face-vertex material assignments */ + const std::vector& GetMaterialIndices() const { + return materials; + } + +public: + +private: + + // cached data arrays + std::vector materials; + std::vector vertices; + std::vector faces; + std::vector tangents; + std::vector normals; + std::vector uvs[AI_MAX_NUMBER_OF_TEXTURECOORDS]; + std::vector colors[AI_MAX_NUMBER_OF_COLOR_SETS]; +}; + + // XXX again, unique_ptr would be useful. shared_ptr is too + // bloated since the objects have a well-defined single owner + // during their entire lifetime (Document). FBX files have + // up to many thousands of objects (most of which we never use), + // so the memory overhead for them should be kept at a minimum. + typedef std::map ObjectMap; + + +/** DOM root for a FBX file */ +class Document +{ +public: + + Document(const Parser& parser); + ~Document(); + +public: + + const ObjectMap& Objects() const { + return objects; + } + +private: + + ObjectMap objects; + const Parser& parser; +}; + +} +} + +#endif diff --git a/code/FBXImporter.cpp b/code/FBXImporter.cpp index c917b6d72..3a8193509 100644 --- a/code/FBXImporter.cpp +++ b/code/FBXImporter.cpp @@ -54,6 +54,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "FBXTokenizer.h" #include "FBXParser.h" #include "FBXUtil.h" +#include "FBXDocument.h" #include "StreamReader.h" #include "MemoryIOWrapper.h" @@ -155,6 +156,9 @@ void FBXImporter::InternReadFile( const std::string& pFile, // use this information to construct a very rudimentary // parse-tree representing the FBX scope structure Parser parser(tokens); + + // take the raw parse-tree and convert it to a FBX DOM + Document doc(parser); } catch(...) { std::for_each(tokens.begin(),tokens.end(),Util::delete_fun()); diff --git a/code/FBXParser.cpp b/code/FBXParser.cpp index dcd415b11..a10d70adc 100644 --- a/code/FBXParser.cpp +++ b/code/FBXParser.cpp @@ -49,6 +49,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "FBXParser.h" #include "FBXUtil.h" +#include "ParsingUtils.h" +#include "fast_atof.h" + using namespace Assimp; using namespace Assimp::FBX; @@ -63,8 +66,12 @@ void ParseError(const std::string& message, TokenPtr token) } +namespace Assimp { +namespace FBX { + // ------------------------------------------------------------------------------------------------ -Element::Element(Parser& parser) +Element::Element(TokenPtr key_token, Parser& parser) +: key_token(key_token) { TokenPtr n = NULL; do { @@ -108,7 +115,7 @@ Element::Element(Parser& parser) // ------------------------------------------------------------------------------------------------ Element::~Element() { - std::for_each(tokens.begin(),tokens.end(),Util::delete_fun()); + // no need to delete tokens, they are owned by the parser } // ------------------------------------------------------------------------------------------------ @@ -133,7 +140,7 @@ Scope::Scope(Parser& parser,bool topLevel) } const std::string& str = n->StringContents(); - elements.insert(ElementMap::value_type(str,new_Element(parser))); + elements.insert(ElementMap::value_type(str,new_Element(n,parser))); // Element() should stop at the next Key token (or right after a Close token) n = parser.CurrentToken(); @@ -200,5 +207,138 @@ TokenPtr Parser::LastToken() const } +// ------------------------------------------------------------------------------------------------ +uint64_t ParseTokenAsID(const Token& t, const char*& err_out) +{ + err_out = NULL; + + if (t.Type() != TokenType_DATA) { + err_out = "expected TOK_DATA token"; + return 0L; + } + + // XXX: should use size_t here + unsigned int length = static_cast(t.end() - t.begin()); + ai_assert(length > 0); + + const char* out; + const uint64_t id = strtoul10_64(t.begin(),&out,&length); + if (out != t.end()) { + err_out = "failed to parse ID"; + return 0L; + } + + return id; +} + + +// ------------------------------------------------------------------------------------------------ +uint64_t ParseTokenAsDim(const Token& t, const char*& err_out) +{ + // same as ID parsing, except there is a trailing asterisk + err_out = NULL; + + if (t.Type() != TokenType_DATA) { + err_out = "expected TOK_DATA token"; + return 0L; + } + + if(*t.begin() != '*') { + err_out = "expected asterisk before array dimension"; + return 0L; + } + + // XXX: should use size_t here + unsigned int length = static_cast(t.end() - t.begin()); + if(length == 0) { + err_out = "expected valid integer number after asterisk"; + return 0L; + } + + const char* out; + const uint64_t id = strtoul10_64(t.begin() + 1,&out,&length); + if (out != t.end()) { + err_out = "failed to parse ID"; + return 0L; + } + + return id; +} + + +// ------------------------------------------------------------------------------------------------ +float ParseTokenAsFloat(const Token& t, const char*& err_out) +{ + err_out = NULL; + + if (t.Type() != TokenType_DATA) { + err_out = "expected TOK_DATA token"; + return 0.0f; + } + + const char* inout = t.begin(); + + float f; + fast_atof(&inout); + if (inout != t.end()) { + err_out = "failed to parse floating point number"; + return 0.0f; + } + + return f; +} + + +// ------------------------------------------------------------------------------------------------ +int ParseTokenAsInt(const Token& t, const char*& err_out) +{ + err_out = NULL; + + if (t.Type() != TokenType_DATA) { + err_out = "expected TOK_DATA token"; + return 0; + } + + ai_assert(static_cast(t.end() - t.begin()) > 0); + + const char* out; + const int intval = strtol10(t.begin(),&out); + if (out != t.end()) { + err_out = "failed to parse ID"; + return 0; + } + + return intval; +} + + +// ------------------------------------------------------------------------------------------------ +std::string ParseTokenAsString(const Token& t, const char*& err_out) +{ + err_out = NULL; + + if (t.Type() != TokenType_DATA) { + err_out = "expected TOK_DATA token"; + return ""; + } + + const size_t length = static_cast(t.end() - t.begin()); + if(length < 2) { + err_out = "token is too short to hold a string"; + return ""; + } + + const char* s = t.begin(), *e = t.end() - 1; + if (*s != '\"' || *e != '\*') { + err_out = "expected double quoted string"; + return ""; + } + + return std::string(s+1,length-2); +} + +} // !FBX +} // !Assimp + #endif diff --git a/code/FBXParser.h b/code/FBXParser.h index 086608b28..94a0560bd 100644 --- a/code/FBXParser.h +++ b/code/FBXParser.h @@ -85,17 +85,26 @@ class Element { public: - Element(Parser& parser); + Element(TokenPtr key_token, Parser& parser); ~Element(); public: + const Scope* Compound() const { + return compound.get(); + } + + TokenPtr KeyToken() const { + return key_token; + } + const TokenList& Tokens() const { return tokens; } private: + TokenPtr key_token; TokenList tokens; boost::scoped_ptr compound; }; @@ -123,6 +132,11 @@ public: public: + const Element* operator[] (const std::string& index) const { + ElementMap::const_iterator it = elements.find(index); + return it == elements.end() ? NULL : (*it).second; + } + const ElementMap& Elements() const { return elements; } @@ -139,6 +153,8 @@ class Parser { public: + /** Parse given a token list. Does not take ownership of the tokens - + * the objects must persist during the entire parser lifetime */ Parser (const TokenList& tokens); ~Parser(); @@ -168,6 +184,14 @@ private: }; +/* token parsing - this happens when building the DOM out of the parse-tree*/ +uint64_t ParseTokenAsID(const Token& t, const char*& err_out); +uint64_t ParseTokenAsDim(const Token& t, const char*& err_out); + +float ParseTokenAsFloat(const Token& t, const char*& err_out); +int ParseTokenAsInt(const Token& t, const char*& err_out); +std::string ParseTokenAsString(const Token& t, const char*& err_out); + } // ! FBX } // ! Assimp diff --git a/code/FBXTokenizer.cpp b/code/FBXTokenizer.cpp index bbe0403e6..7aa81543a 100644 --- a/code/FBXTokenizer.cpp +++ b/code/FBXTokenizer.cpp @@ -69,6 +69,9 @@ Token::Token(const char* sbegin, const char* send, TokenType type, unsigned int { ai_assert(sbegin); ai_assert(send); + + // tokens must be of non-zero length + ai_assert(static_cast(send-sbegin) > 0); } diff --git a/workspaces/vc9/assimp.vcproj b/workspaces/vc9/assimp.vcproj index 431f4efc6..5d9f46437 100644 --- a/workspaces/vc9/assimp.vcproj +++ b/workspaces/vc9/assimp.vcproj @@ -1,7 +1,7 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -2227,6 +2235,14 @@ UsePrecompiledHeader="0" /> + + + @@ -2251,6 +2267,14 @@ UsePrecompiledHeader="0" /> + + + @@ -2275,22 +2299,6 @@ UsePrecompiledHeader="0" /> - - - - - - @@ -2425,6 +2433,14 @@ PrecompiledHeaderThrough="AssimpPCH.h" /> + + + @@ -2452,6 +2468,14 @@ PrecompiledHeaderThrough="AssimpPCH.h" /> + + + @@ -2479,22 +2503,6 @@ PrecompiledHeaderThrough="AssimpPCH.h" /> - - - - - - @@ -2802,62 +2810,6 @@ UsePrecompiledHeader="0" /> - - - - - - - - - - - - - - - - - - - - - @@ -2866,6 +2818,14 @@ UsePrecompiledHeader="0" /> + + + @@ -2874,6 +2834,14 @@ UsePrecompiledHeader="0" /> + + + @@ -2882,6 +2850,14 @@ UsePrecompiledHeader="0" /> + + + @@ -2890,6 +2866,14 @@ UsePrecompiledHeader="0" /> + + + @@ -2898,6 +2882,14 @@ UsePrecompiledHeader="0" /> + + + @@ -2906,6 +2898,14 @@ UsePrecompiledHeader="0" /> + + + @@ -2914,6 +2914,14 @@ UsePrecompiledHeader="0" /> + + + @@ -2946,62 +2954,6 @@ UsePrecompiledHeader="0" /> - - - - - - - - - - - - - - - - - - - - - @@ -3010,6 +2962,14 @@ UsePrecompiledHeader="0" /> + + + @@ -3018,6 +2978,14 @@ UsePrecompiledHeader="0" /> + + + @@ -3026,6 +2994,14 @@ UsePrecompiledHeader="0" /> + + + @@ -3034,6 +3010,14 @@ UsePrecompiledHeader="0" /> + + + @@ -3042,6 +3026,14 @@ UsePrecompiledHeader="0" /> + + + @@ -3050,6 +3042,14 @@ UsePrecompiledHeader="0" /> + + + @@ -3058,6 +3058,14 @@ UsePrecompiledHeader="0" /> + + + @@ -3078,62 +3086,6 @@ UsePrecompiledHeader="0" /> - - - - - - - - - - - - - - - - - - - - - @@ -3142,6 +3094,14 @@ UsePrecompiledHeader="0" /> + + + @@ -3150,6 +3110,14 @@ UsePrecompiledHeader="0" /> + + + @@ -3158,6 +3126,14 @@ UsePrecompiledHeader="0" /> + + + @@ -3166,6 +3142,14 @@ UsePrecompiledHeader="0" /> + + + @@ -3174,6 +3158,14 @@ UsePrecompiledHeader="0" /> + + + @@ -3182,6 +3174,14 @@ UsePrecompiledHeader="0" /> + + + @@ -3190,6 +3190,14 @@ UsePrecompiledHeader="0" /> + + + @@ -3218,62 +3226,6 @@ UsePrecompiledHeader="0" /> - - - - - - - - - - - - - - - - - - - - - @@ -3282,6 +3234,14 @@ UsePrecompiledHeader="0" /> + + + @@ -3290,6 +3250,14 @@ UsePrecompiledHeader="0" /> + + + @@ -3298,6 +3266,14 @@ UsePrecompiledHeader="0" /> + + + @@ -3306,6 +3282,14 @@ UsePrecompiledHeader="0" /> + + + @@ -3314,6 +3298,14 @@ UsePrecompiledHeader="0" /> + + + @@ -3322,6 +3314,14 @@ UsePrecompiledHeader="0" /> + + + @@ -3330,6 +3330,14 @@ UsePrecompiledHeader="0" /> + + + @@ -3358,62 +3366,6 @@ UsePrecompiledHeader="0" /> - - - - - - - - - - - - - - - - - - - - - @@ -3422,6 +3374,14 @@ UsePrecompiledHeader="0" /> + + + @@ -3430,6 +3390,14 @@ UsePrecompiledHeader="0" /> + + + @@ -3438,6 +3406,14 @@ UsePrecompiledHeader="0" /> + + + @@ -3446,6 +3422,14 @@ UsePrecompiledHeader="0" /> + + + @@ -3454,6 +3438,14 @@ UsePrecompiledHeader="0" /> + + + @@ -3462,6 +3454,14 @@ UsePrecompiledHeader="0" /> + + + @@ -3470,6 +3470,14 @@ UsePrecompiledHeader="0" /> + + + @@ -3494,62 +3502,6 @@ UsePrecompiledHeader="0" /> - - - - - - - - - - - - - - - - - - - - - @@ -3558,6 +3510,14 @@ UsePrecompiledHeader="0" /> + + + @@ -3566,6 +3526,14 @@ UsePrecompiledHeader="0" /> + + + @@ -3574,6 +3542,14 @@ UsePrecompiledHeader="0" /> + + + @@ -3582,6 +3558,14 @@ UsePrecompiledHeader="0" /> + + + @@ -3590,6 +3574,14 @@ UsePrecompiledHeader="0" /> + + + @@ -3598,6 +3590,14 @@ UsePrecompiledHeader="0" /> + + + @@ -3606,6 +3606,14 @@ UsePrecompiledHeader="0" /> + + + @@ -3630,62 +3638,6 @@ UsePrecompiledHeader="0" /> - - - - - - - - - - - - - - - - - - - - - @@ -3694,6 +3646,14 @@ UsePrecompiledHeader="0" /> + + + @@ -3702,6 +3662,14 @@ UsePrecompiledHeader="0" /> + + + @@ -3710,6 +3678,14 @@ UsePrecompiledHeader="0" /> + + + @@ -3718,6 +3694,14 @@ UsePrecompiledHeader="0" /> + + + @@ -3726,6 +3710,14 @@ UsePrecompiledHeader="0" /> + + + @@ -3734,6 +3726,14 @@ UsePrecompiledHeader="0" /> + + + @@ -3742,6 +3742,14 @@ UsePrecompiledHeader="0" /> + + + @@ -3766,62 +3774,6 @@ UsePrecompiledHeader="0" /> - - - - - - - - - - - - - - - - - - - - - @@ -3830,6 +3782,14 @@ UsePrecompiledHeader="0" /> + + + @@ -3838,6 +3798,14 @@ UsePrecompiledHeader="0" /> + + + @@ -3846,6 +3814,14 @@ UsePrecompiledHeader="0" /> + + + @@ -3854,6 +3830,14 @@ UsePrecompiledHeader="0" /> + + + @@ -3862,6 +3846,14 @@ UsePrecompiledHeader="0" /> + + + @@ -3870,6 +3862,14 @@ UsePrecompiledHeader="0" /> + + + @@ -3878,6 +3878,14 @@ UsePrecompiledHeader="0" /> + + + @@ -3914,62 +3922,6 @@ UsePrecompiledHeader="0" /> - - - - - - - - - - - - - - - - - - - - - @@ -3978,6 +3930,14 @@ UsePrecompiledHeader="0" /> + + + @@ -3986,6 +3946,14 @@ UsePrecompiledHeader="0" /> + + + @@ -3994,6 +3962,14 @@ UsePrecompiledHeader="0" /> + + + @@ -4002,6 +3978,14 @@ UsePrecompiledHeader="0" /> + + + @@ -4010,6 +3994,14 @@ UsePrecompiledHeader="0" /> + + + @@ -4018,6 +4010,14 @@ UsePrecompiledHeader="0" /> + + + @@ -4026,6 +4026,14 @@ UsePrecompiledHeader="0" /> + + + @@ -4054,62 +4062,6 @@ UsePrecompiledHeader="0" /> - - - - - - - - - - - - - - - - - - - - - @@ -4118,6 +4070,14 @@ UsePrecompiledHeader="0" /> + + + @@ -4126,6 +4086,14 @@ UsePrecompiledHeader="0" /> + + + @@ -4134,6 +4102,14 @@ UsePrecompiledHeader="0" /> + + + @@ -4142,6 +4118,14 @@ UsePrecompiledHeader="0" /> + + + @@ -4150,6 +4134,14 @@ UsePrecompiledHeader="0" /> + + + @@ -4158,6 +4150,14 @@ UsePrecompiledHeader="0" /> + + + @@ -4166,6 +4166,14 @@ UsePrecompiledHeader="0" /> + + + @@ -4194,62 +4202,6 @@ UsePrecompiledHeader="0" /> - - - - - - - - - - - - - - - - - - - - - @@ -4258,6 +4210,14 @@ UsePrecompiledHeader="0" /> + + + @@ -4266,6 +4226,14 @@ UsePrecompiledHeader="0" /> + + + @@ -4274,6 +4242,14 @@ UsePrecompiledHeader="0" /> + + + @@ -4282,6 +4258,14 @@ UsePrecompiledHeader="0" /> + + + @@ -4290,6 +4274,14 @@ UsePrecompiledHeader="0" /> + + + @@ -4298,6 +4290,14 @@ UsePrecompiledHeader="0" /> + + + @@ -4306,6 +4306,14 @@ UsePrecompiledHeader="0" /> + + + @@ -4330,62 +4338,6 @@ UsePrecompiledHeader="0" /> - - - - - - - - - - - - - - - - - - - - - @@ -4394,6 +4346,14 @@ UsePrecompiledHeader="0" /> + + + @@ -4402,6 +4362,14 @@ UsePrecompiledHeader="0" /> + + + @@ -4410,6 +4378,14 @@ UsePrecompiledHeader="0" /> + + + @@ -4418,6 +4394,14 @@ UsePrecompiledHeader="0" /> + + + @@ -4426,6 +4410,14 @@ UsePrecompiledHeader="0" /> + + + @@ -4434,6 +4426,14 @@ UsePrecompiledHeader="0" /> + + + @@ -4442,6 +4442,14 @@ UsePrecompiledHeader="0" /> + + + @@ -4470,62 +4478,6 @@ UsePrecompiledHeader="0" /> - - - - - - - - - - - - - - - - - - - - - @@ -4534,6 +4486,14 @@ UsePrecompiledHeader="0" /> + + + @@ -4542,6 +4502,14 @@ UsePrecompiledHeader="0" /> + + + @@ -4550,6 +4518,14 @@ UsePrecompiledHeader="0" /> + + + @@ -4558,6 +4534,14 @@ UsePrecompiledHeader="0" /> + + + @@ -4566,6 +4550,14 @@ UsePrecompiledHeader="0" /> + + + @@ -4574,6 +4566,14 @@ UsePrecompiledHeader="0" /> + + + @@ -4582,6 +4582,14 @@ UsePrecompiledHeader="0" /> + + + @@ -4606,62 +4614,6 @@ UsePrecompiledHeader="0" /> - - - - - - - - - - - - - - - - - - - - - @@ -4670,6 +4622,14 @@ UsePrecompiledHeader="0" /> + + + @@ -4678,6 +4638,14 @@ UsePrecompiledHeader="0" /> + + + @@ -4686,6 +4654,14 @@ UsePrecompiledHeader="0" /> + + + @@ -4694,6 +4670,14 @@ UsePrecompiledHeader="0" /> + + + @@ -4702,6 +4686,14 @@ UsePrecompiledHeader="0" /> + + + @@ -4710,6 +4702,14 @@ UsePrecompiledHeader="0" /> + + + @@ -4718,6 +4718,14 @@ UsePrecompiledHeader="0" /> + + + @@ -4742,62 +4750,6 @@ UsePrecompiledHeader="0" /> - - - - - - - - - - - - - - - - - - - - - @@ -4806,6 +4758,14 @@ UsePrecompiledHeader="0" /> + + + @@ -4814,6 +4774,14 @@ UsePrecompiledHeader="0" /> + + + @@ -4822,6 +4790,14 @@ UsePrecompiledHeader="0" /> + + + @@ -4830,6 +4806,14 @@ UsePrecompiledHeader="0" /> + + + @@ -4838,6 +4822,14 @@ UsePrecompiledHeader="0" /> + + + @@ -4846,6 +4838,14 @@ UsePrecompiledHeader="0" /> + + + @@ -4854,6 +4854,14 @@ UsePrecompiledHeader="0" /> + + + @@ -4886,62 +4894,6 @@ UsePrecompiledHeader="0" /> - - - - - - - - - - - - - - - - - - - - - @@ -4950,6 +4902,14 @@ UsePrecompiledHeader="0" /> + + + @@ -4958,6 +4918,14 @@ UsePrecompiledHeader="0" /> + + + @@ -4966,6 +4934,14 @@ UsePrecompiledHeader="0" /> + + + @@ -4974,6 +4950,14 @@ UsePrecompiledHeader="0" /> + + + @@ -4982,6 +4966,14 @@ UsePrecompiledHeader="0" /> + + + @@ -4990,6 +4982,14 @@ UsePrecompiledHeader="0" /> + + + @@ -4998,6 +4998,14 @@ UsePrecompiledHeader="0" /> + + +