diff --git a/code/BlenderDNA.inl b/code/BlenderDNA.inl index 8b669180c..c65ea81bc 100644 --- a/code/BlenderDNA.inl +++ b/code/BlenderDNA.inl @@ -585,7 +585,7 @@ template <> inline void Structure :: Convert (int& dest,const FileDataba } // ------------------------------------------------------------------------------------------------ -template <> inline void Structure :: Convert (short& dest,const FileDatabase& db) const +template<> inline void Structure :: Convert (short& dest,const FileDatabase& db) const { // automatic rescaling from short to float and vice versa (seems to be used by normals) if (name == "float") { diff --git a/code/BlenderModifier.cpp b/code/BlenderModifier.cpp index a1ccba5f4..348df1f48 100644 --- a/code/BlenderModifier.cpp +++ b/code/BlenderModifier.cpp @@ -310,7 +310,9 @@ void BlenderModifier_Subdivision :: DoIt(aiNode& out, ConversionData& conv_data std::unique_ptr subd(Subdivider::Create(algo)); ai_assert(subd); - + if ( conv_data.meshes->empty() ) { + return; + } aiMesh** const meshes = &conv_data.meshes[conv_data.meshes->size() - out.mNumMeshes]; std::unique_ptr tempmeshes(new aiMesh*[out.mNumMeshes]()); diff --git a/code/CMakeLists.txt b/code/CMakeLists.txt index e87dad550..4890a3c9e 100644 --- a/code/CMakeLists.txt +++ b/code/CMakeLists.txt @@ -156,6 +156,8 @@ SET( Common_SRCS SkeletonMeshBuilder.h SplitByBoneCountProcess.cpp SplitByBoneCountProcess.h + ScaleProcess.cpp + ScaleProcess.h SmoothingGroups.h StandardShapes.cpp StandardShapes.h diff --git a/code/DeboneProcess.h b/code/DeboneProcess.h index 75f158c03..8d4607bb9 100644 --- a/code/DeboneProcess.h +++ b/code/DeboneProcess.h @@ -1,4 +1,4 @@ - /* +/* Open Asset Import Library (assimp) ---------------------------------------------------------------------- diff --git a/code/FindInvalidDataProcess.cpp b/code/FindInvalidDataProcess.cpp index 77915bc4e..a6cb037b2 100644 --- a/code/FindInvalidDataProcess.cpp +++ b/code/FindInvalidDataProcess.cpp @@ -339,32 +339,37 @@ void FindInvalidDataProcess::ProcessAnimationChannel (aiNodeAnim* anim) int FindInvalidDataProcess::ProcessMesh (aiMesh* pMesh) { bool ret = false; - std::vector dirtyMask(pMesh->mNumVertices,(pMesh->mNumFaces ? true : false)); + std::vector dirtyMask(pMesh->mNumVertices, pMesh->mNumFaces); // Ignore elements that are not referenced by vertices. // (they are, for example, caused by the FindDegenerates step) - for (unsigned int m = 0; m < pMesh->mNumFaces;++m) { + for (unsigned int m = 0; m < pMesh->mNumFaces; ++m) { const aiFace& f = pMesh->mFaces[m]; - for (unsigned int i = 0; i < f.mNumIndices;++i) { + for (unsigned int i = 0; i < f.mNumIndices; ++i) { dirtyMask[f.mIndices[i]] = false; } } // Process vertex positions - if(pMesh->mVertices && ProcessArray(pMesh->mVertices,pMesh->mNumVertices,"positions",dirtyMask)) { + if (pMesh->mVertices && ProcessArray(pMesh->mVertices, pMesh->mNumVertices, "positions", dirtyMask)) { DefaultLogger::get()->error("Deleting mesh: Unable to continue without vertex positions"); + return 2; } // process texture coordinates - for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS && pMesh->mTextureCoords[i];++i) { - if (ProcessArray(pMesh->mTextureCoords[i],pMesh->mNumVertices,"uvcoords",dirtyMask)) { + for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS && pMesh->mTextureCoords[i]; ++i) { + if (ProcessArray(pMesh->mTextureCoords[i], pMesh->mNumVertices, "uvcoords", dirtyMask)) { + pMesh->mNumUVComponents[i] = 0; // delete all subsequent texture coordinate sets. - for (unsigned int a = i+1; a < AI_MAX_NUMBER_OF_TEXTURECOORDS;++a) { - delete[] pMesh->mTextureCoords[a]; pMesh->mTextureCoords[a] = NULL; + for (unsigned int a = i + 1; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++a) { + delete[] pMesh->mTextureCoords[a]; + pMesh->mTextureCoords[a] = NULL; + pMesh->mNumUVComponents[a] = 0; } + ret = true; } } diff --git a/code/FixNormalsStep.h b/code/FixNormalsStep.h index b47155ccd..71309c7e5 100644 --- a/code/FixNormalsStep.h +++ b/code/FixNormalsStep.h @@ -56,14 +56,11 @@ namespace Assimp * vectors of an object are facing inwards. In this case they will be * flipped. */ -class FixInfacingNormalsProcess : public BaseProcess -{ +class FixInfacingNormalsProcess : public BaseProcess { public: - FixInfacingNormalsProcess(); ~FixInfacingNormalsProcess(); -public: // ------------------------------------------------------------------- /** Returns whether the processing step is present in the given flag field. * @param pFlags The processing flags the importer was called with. A bitwise diff --git a/code/IFCCurve.cpp b/code/IFCCurve.cpp index 176fe3c13..4a8026551 100644 --- a/code/IFCCurve.cpp +++ b/code/IFCCurve.cpp @@ -43,28 +43,22 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * @brief Read profile and curves entities from IFC files */ - - #ifndef ASSIMP_BUILD_NO_IFC_IMPORTER #include "IFCUtil.h" namespace Assimp { - namespace IFC { - namespace { +namespace IFC { +namespace { // -------------------------------------------------------------------------------- // Conic is the base class for Circle and Ellipse // -------------------------------------------------------------------------------- -class Conic : public Curve -{ - +class Conic : public Curve { public: - // -------------------------------------------------- Conic(const IfcConic& entity, ConversionData& conv) - : Curve(entity,conv) - { + : Curve(entity,conv) { IfcMatrix4 trafo; ConvertAxisPlacement(trafo,*entity.Position,conv); @@ -75,8 +69,6 @@ public: p[2] = IfcVector3(trafo.a3,trafo.b3,trafo.c3); } -public: - // -------------------------------------------------- bool IsClosed() const { return true; @@ -84,7 +76,8 @@ public: // -------------------------------------------------- size_t EstimateSampleCount(IfcFloat a, IfcFloat b) const { - ai_assert(InRange(a) && InRange(b)); + ai_assert( InRange( a ) ); + ai_assert( InRange( b ) ); a *= conv.angle_scale; b *= conv.angle_scale; @@ -104,15 +97,11 @@ protected: IfcVector3 location, p[3]; }; - // -------------------------------------------------------------------------------- // Circle // -------------------------------------------------------------------------------- -class Circle : public Conic -{ - +class Circle : public Conic { public: - // -------------------------------------------------- Circle(const IfcCircle& entity, ConversionData& conv) : Conic(entity,conv) @@ -120,8 +109,6 @@ public: { } -public: - // -------------------------------------------------- IfcVector3 Eval(IfcFloat u) const { u = -conv.angle_scale * u; @@ -137,20 +124,15 @@ private: // -------------------------------------------------------------------------------- // Ellipse // -------------------------------------------------------------------------------- -class Ellipse : public Conic -{ - +class Ellipse : public Conic { public: - // -------------------------------------------------- Ellipse(const IfcEllipse& entity, ConversionData& conv) - : Conic(entity,conv) - , entity(entity) - { + : Conic(entity,conv) + , entity(entity) { + // empty } -public: - // -------------------------------------------------- IfcVector3 Eval(IfcFloat u) const { u = -conv.angle_scale * u; @@ -162,25 +144,18 @@ private: const IfcEllipse& entity; }; - // -------------------------------------------------------------------------------- // Line // -------------------------------------------------------------------------------- -class Line : public Curve -{ - +class Line : public Curve { public: - // -------------------------------------------------- Line(const IfcLine& entity, ConversionData& conv) - : Curve(entity,conv) - { + : Curve(entity,conv) { ConvertCartesianPoint(p,entity.Pnt); ConvertVector(v,entity.Dir); } -public: - // -------------------------------------------------- bool IsClosed() const { return false; @@ -193,16 +168,17 @@ public: // -------------------------------------------------- size_t EstimateSampleCount(IfcFloat a, IfcFloat b) const { - ai_assert(InRange(a) && InRange(b)); + ai_assert( InRange( a ) ); + ai_assert( InRange( b ) ); // two points are always sufficient for a line segment return a==b ? 1 : 2; } // -------------------------------------------------- - void SampleDiscrete(TempMesh& out,IfcFloat a, IfcFloat b) const - { - ai_assert(InRange(a) && InRange(b)); + void SampleDiscrete(TempMesh& out,IfcFloat a, IfcFloat b) const { + ai_assert( InRange( a ) ); + ai_assert( InRange( b ) ); if (a == b) { out.verts.push_back(Eval(a)); @@ -227,18 +203,14 @@ private: // -------------------------------------------------------------------------------- // CompositeCurve joins multiple smaller, bounded curves // -------------------------------------------------------------------------------- -class CompositeCurve : public BoundedCurve -{ - +class CompositeCurve : public BoundedCurve { typedef std::pair< std::shared_ptr< BoundedCurve >, bool > CurveEntry; public: - // -------------------------------------------------- CompositeCurve(const IfcCompositeCurve& entity, ConversionData& conv) - : BoundedCurve(entity,conv) - , total() - { + : BoundedCurve(entity,conv) + , total() { curves.reserve(entity.Segments.size()); for(const IfcCompositeCurveSegment& curveSegment :entity.Segments) { // according to the specification, this must be a bounded curve @@ -263,8 +235,6 @@ public: } } -public: - // -------------------------------------------------- IfcVector3 Eval(IfcFloat u) const { if (curves.empty()) { @@ -287,7 +257,8 @@ public: // -------------------------------------------------- size_t EstimateSampleCount(IfcFloat a, IfcFloat b) const { - ai_assert(InRange(a) && InRange(b)); + ai_assert( InRange( a ) ); + ai_assert( InRange( b ) ); size_t cnt = 0; IfcFloat acc = 0; @@ -306,9 +277,9 @@ public: } // -------------------------------------------------- - void SampleDiscrete(TempMesh& out,IfcFloat a, IfcFloat b) const - { - ai_assert(InRange(a) && InRange(b)); + void SampleDiscrete(TempMesh& out,IfcFloat a, IfcFloat b) const { + ai_assert( InRange( a ) ); + ai_assert( InRange( b ) ); const size_t cnt = EstimateSampleCount(a,b); out.verts.reserve(out.verts.size() + cnt); @@ -330,19 +301,14 @@ public: private: std::vector< CurveEntry > curves; - IfcFloat total; }; - // -------------------------------------------------------------------------------- // TrimmedCurve can be used to trim an unbounded curve to a bounded range // -------------------------------------------------------------------------------- -class TrimmedCurve : public BoundedCurve -{ - +class TrimmedCurve : public BoundedCurve { public: - // -------------------------------------------------- TrimmedCurve(const IfcTrimmedCurve& entity, ConversionData& conv) : BoundedCurve(entity,conv) @@ -409,8 +375,6 @@ public: ai_assert(maxval >= 0); } -public: - // -------------------------------------------------- IfcVector3 Eval(IfcFloat p) const { ai_assert(InRange(p)); @@ -419,7 +383,8 @@ public: // -------------------------------------------------- size_t EstimateSampleCount(IfcFloat a, IfcFloat b) const { - ai_assert(InRange(a) && InRange(b)); + ai_assert( InRange( a ) ); + ai_assert( InRange( b ) ); return base->EstimateSampleCount(TrimParam(a),TrimParam(b)); } @@ -435,13 +400,11 @@ public: } private: - // -------------------------------------------------- IfcFloat TrimParam(IfcFloat f) const { return agree_sense ? f + range.first : range.second - f; } - private: ParamRange range; IfcFloat maxval; @@ -454,11 +417,8 @@ private: // -------------------------------------------------------------------------------- // PolyLine is a 'curve' defined by linear interpolation over a set of discrete points // -------------------------------------------------------------------------------- -class PolyLine : public BoundedCurve -{ - +class PolyLine : public BoundedCurve { public: - // -------------------------------------------------- PolyLine(const IfcPolyline& entity, ConversionData& conv) : BoundedCurve(entity,conv) @@ -472,8 +432,6 @@ public: } } -public: - // -------------------------------------------------- IfcVector3 Eval(IfcFloat p) const { ai_assert(InRange(p)); @@ -502,13 +460,10 @@ private: std::vector points; }; - } // anon - // ------------------------------------------------------------------------------------------------ -Curve* Curve :: Convert(const IFC::IfcCurve& curve,ConversionData& conv) -{ +Curve* Curve::Convert(const IFC::IfcCurve& curve,ConversionData& conv) { if(curve.ToPtr()) { if(const IfcPolyline* c = curve.ToPtr()) { return new PolyLine(*c,conv); @@ -519,9 +474,6 @@ Curve* Curve :: Convert(const IFC::IfcCurve& curve,ConversionData& conv) if(const IfcCompositeCurve* c = curve.ToPtr()) { return new CompositeCurve(*c,conv); } - //if(const IfcBSplineCurve* c = curve.ToPtr()) { - // return new BSplineCurve(*c,conv); - //} } if(curve.ToPtr()) { @@ -543,8 +495,7 @@ Curve* Curve :: Convert(const IFC::IfcCurve& curve,ConversionData& conv) #ifdef ASSIMP_BUILD_DEBUG // ------------------------------------------------------------------------------------------------ -bool Curve :: InRange(IfcFloat u) const -{ +bool Curve::InRange(IfcFloat u) const { const ParamRange range = GetParametricRange(); if (IsClosed()) { return true; @@ -555,24 +506,23 @@ bool Curve :: InRange(IfcFloat u) const #endif // ------------------------------------------------------------------------------------------------ -IfcFloat Curve :: GetParametricRangeDelta() const -{ +IfcFloat Curve::GetParametricRangeDelta() const { const ParamRange& range = GetParametricRange(); return std::abs(range.second - range.first); } // ------------------------------------------------------------------------------------------------ -size_t Curve :: EstimateSampleCount(IfcFloat a, IfcFloat b) const -{ - ai_assert(InRange(a) && InRange(b)); +size_t Curve::EstimateSampleCount(IfcFloat a, IfcFloat b) const { + ai_assert( InRange( a ) ); + ai_assert( InRange( b ) ); // arbitrary default value, deriving classes should supply better suited values return 16; } // ------------------------------------------------------------------------------------------------ -IfcFloat RecursiveSearch(const Curve* cv, const IfcVector3& val, IfcFloat a, IfcFloat b, unsigned int samples, IfcFloat threshold, unsigned int recurse = 0, unsigned int max_recurse = 15) -{ +IfcFloat RecursiveSearch(const Curve* cv, const IfcVector3& val, IfcFloat a, IfcFloat b, + unsigned int samples, IfcFloat threshold, unsigned int recurse = 0, unsigned int max_recurse = 15) { ai_assert(samples>1); const IfcFloat delta = (b-a)/samples, inf = std::numeric_limits::infinity(); @@ -594,7 +544,8 @@ IfcFloat RecursiveSearch(const Curve* cv, const IfcVector3& val, IfcFloat a, Ifc } } - ai_assert(min_diff[0] != inf && min_diff[1] != inf); + ai_assert( min_diff[ 0 ] != inf ); + ai_assert( min_diff[ 1 ] != inf ); if ( std::fabs(a-min_point[0]) < threshold || recurse >= max_recurse) { return min_point[0]; } @@ -615,15 +566,15 @@ IfcFloat RecursiveSearch(const Curve* cv, const IfcVector3& val, IfcFloat a, Ifc } // ------------------------------------------------------------------------------------------------ -bool Curve :: ReverseEval(const IfcVector3& val, IfcFloat& paramOut) const +bool Curve::ReverseEval(const IfcVector3& val, IfcFloat& paramOut) const { // note: the following algorithm is not guaranteed to find the 'right' parameter value // in all possible cases, but it will always return at least some value so this function // will never fail in the default implementation. // XXX derive threshold from curve topology - const IfcFloat threshold = 1e-4f; - const unsigned int samples = 16; + static const IfcFloat threshold = 1e-4f; + static const unsigned int samples = 16; const ParamRange& range = GetParametricRange(); paramOut = RecursiveSearch(this,val,range.first,range.second,samples,threshold); @@ -632,9 +583,9 @@ bool Curve :: ReverseEval(const IfcVector3& val, IfcFloat& paramOut) const } // ------------------------------------------------------------------------------------------------ -void Curve :: SampleDiscrete(TempMesh& out,IfcFloat a, IfcFloat b) const -{ - ai_assert(InRange(a) && InRange(b)); +void Curve::SampleDiscrete(TempMesh& out,IfcFloat a, IfcFloat b) const { + ai_assert( InRange( a ) ); + ai_assert( InRange( b ) ); const size_t cnt = std::max(static_cast(0),EstimateSampleCount(a,b)); out.verts.reserve( out.verts.size() + cnt + 1); @@ -646,16 +597,15 @@ void Curve :: SampleDiscrete(TempMesh& out,IfcFloat a, IfcFloat b) const } // ------------------------------------------------------------------------------------------------ -bool BoundedCurve :: IsClosed() const -{ +bool BoundedCurve::IsClosed() const { return false; } // ------------------------------------------------------------------------------------------------ -void BoundedCurve :: SampleDiscrete(TempMesh& out) const -{ +void BoundedCurve::SampleDiscrete(TempMesh& out) const { const ParamRange& range = GetParametricRange(); - ai_assert(range.first != std::numeric_limits::infinity() && range.second != std::numeric_limits::infinity()); + ai_assert( range.first != std::numeric_limits::infinity() ); + ai_assert( range.second != std::numeric_limits::infinity() ); return SampleDiscrete(out,range.first,range.second); } diff --git a/code/LineSplitter.h b/code/LineSplitter.h index 10ca1d35a..003b42d52 100644 --- a/code/LineSplitter.h +++ b/code/LineSplitter.h @@ -69,27 +69,23 @@ for(LineSplitter splitter(stream);splitter;++splitter) { std::cout << "Current line is: " << splitter.get_index() << std::endl; } -@endcode */ +@endcode +*/ // ------------------------------------------------------------------------------------------------ -class LineSplitter -{ +class LineSplitter { public: - typedef size_t line_idx; -public: - // ----------------------------------------- /** construct from existing stream reader note: trim is *always* assumed true if skyp_empty_lines==true */ LineSplitter(StreamReaderLE& stream, bool skip_empty_lines = true, bool trim = true) - : idx( 0 ) - , stream(stream) - , swallow() - , skip_empty_lines(skip_empty_lines) - , trim(trim) - { + : idx( 0 ) + , stream(stream) + , swallow() + , skip_empty_lines(skip_empty_lines) + , trim(trim) { cur.reserve(1024); operator++(); diff --git a/code/RemoveVCProcess.h b/code/RemoveVCProcess.h index 5735bf419..d7d45e73e 100644 --- a/code/RemoveVCProcess.h +++ b/code/RemoveVCProcess.h @@ -54,8 +54,7 @@ namespace Assimp { /** RemoveVCProcess: Class to exclude specific parts of the data structure * from further processing by removing them, */ -class ASSIMP_API RemoveVCProcess : public BaseProcess -{ +class ASSIMP_API RemoveVCProcess : public BaseProcess { public: /// The default class constructor. RemoveVCProcess(); @@ -63,7 +62,6 @@ public: /// The class destructor. ~RemoveVCProcess(); -public: // ------------------------------------------------------------------- /** Returns whether the processing step is present in the given flag field. * @param pFlags The processing flags the importer was called with. A bitwise diff --git a/code/STEPFile.h b/code/STEPFile.h index 529d4edbd..8a30beb3f 100644 --- a/code/STEPFile.h +++ b/code/STEPFile.h @@ -55,7 +55,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // #if _MSC_VER > 1500 || (defined __GNUC___) # define ASSIMP_STEP_USE_UNORDERED_MULTIMAP -# else +#else # define step_unordered_map map # define step_unordered_multimap multimap #endif diff --git a/code/ScaleProcess.cpp b/code/ScaleProcess.cpp new file mode 100644 index 000000000..ada978e82 --- /dev/null +++ b/code/ScaleProcess.cpp @@ -0,0 +1,105 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2017, 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. + +---------------------------------------------------------------------- +*/ +#include "ScaleProcess.h" + +#include +#include + +namespace Assimp { + +ScaleProcess::ScaleProcess() +: BaseProcess() +, mScale( AI_CONFIG_GLOBAL_SCALE_FACTOR_DEFAULT ) { + // empty +} + +ScaleProcess::~ScaleProcess() { + // empty +} + +void ScaleProcess::setScale( ai_real scale ) { + mScale = scale; +} + +ai_real ScaleProcess::getScale() const { + return mScale; +} + +bool ScaleProcess::IsActive( unsigned int pFlags ) const { + return ( pFlags & aiProcess_GlobalScale ) != 0; +} + +void ScaleProcess::SetupProperties( const Importer* pImp ) { + mScale = pImp->GetPropertyFloat( AI_CONFIG_GLOBAL_SCALE_FACTOR_KEY, 0 ); +} + +void ScaleProcess::Execute( aiScene* pScene ) { + if ( nullptr == pScene ) { + return; + } + + if ( nullptr == pScene->mRootNode ) { + return; + } + + traverseNodes( pScene->mRootNode ); +} + +void ScaleProcess::traverseNodes( aiNode *node ) { + applyScaling( node ); + + /*for ( unsigned int i = 0; i < node->mNumChildren; ++i ) { + aiNode *currentNode = currentNode->mChildren[ i ]; + if ( nullptr != currentNode ) { + traverseNodes( currentNode ); + } + }*/ +} + +void ScaleProcess::applyScaling( aiNode *currentNode ) { + if ( nullptr != currentNode ) { + currentNode->mTransformation.a1 = currentNode->mTransformation.a1 * mScale; + currentNode->mTransformation.b2 = currentNode->mTransformation.b2 * mScale; + currentNode->mTransformation.c3 = currentNode->mTransformation.c3 * mScale; + } +} + +} // Namespace Assimp diff --git a/code/ScaleProcess.h b/code/ScaleProcess.h new file mode 100644 index 000000000..7eb91fd5c --- /dev/null +++ b/code/ScaleProcess.h @@ -0,0 +1,87 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2017, 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. + +---------------------------------------------------------------------- +*/ +#pragma once + +#include "BaseProcess.h" + +struct aiNode; + +#if (!defined AI_CONFIG_GLOBAL_SCALE_FACTOR_DEFAULT) +# define AI_CONFIG_GLOBAL_SCALE_FACTOR_DEFAULT 1.0f +#endif // !! AI_DEBONE_THRESHOLD + +namespace Assimp { + +// --------------------------------------------------------------------------- +/** ScaleProcess: Class to rescale the whole model. +*/ +class ASSIMP_API ScaleProcess : public BaseProcess { +public: + /// The default class constructor. + ScaleProcess(); + + /// The class destructor. + virtual ~ScaleProcess(); + + /// Will set the scale manually. + void setScale( ai_real scale ); + + /// Returns the current scaling value. + ai_real getScale() const; + + /// Overwritten, @see BaseProcess + virtual bool IsActive( unsigned int pFlags ) const; + + /// Overwritten, @see BaseProcess + virtual void SetupProperties( const Importer* pImp ); + + /// Overwritten, @see BaseProcess + virtual void Execute( aiScene* pScene ); + +private: + void traverseNodes( aiNode *currentNode ); + void applyScaling( aiNode *currentNode ); + +private: + ai_real mScale; +}; + +} // Namespace Assimp diff --git a/include/assimp/config.h.in b/include/assimp/config.h.in index 00fe7b593..29b9d5870 100644 --- a/include/assimp/config.h.in +++ b/include/assimp/config.h.in @@ -933,6 +933,14 @@ enum aiComponent #define AI_CONFIG_EXPORT_XFILE_64BIT "EXPORT_XFILE_64BIT" +/** + * @brief Specifies a gobal key factor for scale, float value + */ +#define AI_CONFIG_GLOBAL_SCALE_FACTOR_KEY "GLOBAL_SCALE_FACTOR" + +#if (!defined AI_CONFIG_GLOBAL_SCALE_FACTOR_DEFAULT) +# define AI_CONFIG_GLOBAL_SCALE_FACTOR_DEFAULT 1.0f +#endif // !! AI_DEBONE_THRESHOLD // ---------- All the Build/Compile-time defines ------------ diff --git a/include/assimp/postprocess.h b/include/assimp/postprocess.h index b35bc34f5..970df8e8a 100644 --- a/include/assimp/postprocess.h +++ b/include/assimp/postprocess.h @@ -525,7 +525,17 @@ enum aiPostProcessSteps * Use #AI_CONFIG_PP_DB_ALL_OR_NONE if you want bones removed if and * only if all bones within the scene qualify for removal. */ - aiProcess_Debone = 0x4000000 + aiProcess_Debone = 0x4000000, + + // ------------------------------------------------------------------------- + /**
This step will perform a global scale of the model. + * + * Some importers are providing a mechanism to define a scaling unit for the + * model. This post processing step can be used to do so. + * + * Use #AI_CONFIG_GLOBAL_SCALE_FACTOR_KEY to control this. + */ + aiProcess_GlobalScale = 0x8000000 // aiProcess_GenEntityMeshes = 0x100000, // aiProcess_OptimizeAnimations = 0x200000 diff --git a/port/PyAssimp/pyassimp/helper.py b/port/PyAssimp/pyassimp/helper.py index 4fa01d51d..85bb53add 100644 --- a/port/PyAssimp/pyassimp/helper.py +++ b/port/PyAssimp/pyassimp/helper.py @@ -30,6 +30,9 @@ if os.name=='posix': additional_dirs.append('/usr/lib/x86_64-linux-gnu') additional_dirs.append('/usr/local/lib/') + if 'LD_LIBRARY_PATH' in os.environ: + additional_dirs.extend([item for item in os.environ['LD_LIBRARY_PATH'].split(':') if item]) + # check if running from anaconda. if "conda" or "continuum" in sys.version.lower(): cur_path = get_python_lib() diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 3520f9782..62270b935 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -114,8 +114,6 @@ SET( TEST_SRCS unit/utPMXImporter.cpp unit/utRemoveComments.cpp unit/utRemoveComponent.cpp - unit/utRemoveRedundantMaterials.cpp - unit/utRemoveVCProcess.cpp unit/utScenePreprocessor.cpp unit/utSceneCombiner.cpp unit/utSharedPPData.cpp @@ -135,8 +133,15 @@ SET( TEST_SRCS unit/utQ3DImportExport.cpp unit/utProfiler.cpp ) +SET( POST_PROCESSES + unit/utRemoveRedundantMaterials.cpp + unit/utRemoveVCProcess.cpp + unit/utScaleProcess.cpp + unit/utJoinVertices.cpp +) -SOURCE_GROUP( tests FILES ${TEST_SRCS} ) +SOURCE_GROUP( tests FILES ${TEST_SRCS} ) +SOURCE_GROUP( tests/PostProcess FILES ${POST_PROCESSES}) add_executable( unit ../contrib/gtest/src/gtest-all.cc @@ -144,6 +149,7 @@ add_executable( unit unit/Main.cpp ../code/Version.cpp ${TEST_SRCS} + ${POST_PROCESSES} ) add_definitions(-DASSIMP_TEST_MODELS_DIR="${CMAKE_CURRENT_LIST_DIR}/models") diff --git a/test/unit/TestModelFactory.h b/test/unit/TestModelFactory.h index ca070890d..950374112 100644 --- a/test/unit/TestModelFactory.h +++ b/test/unit/TestModelFactory.h @@ -43,6 +43,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "UnitTestPCH.h" #include +#include #include namespace Assimp { @@ -57,7 +58,7 @@ public: // empty } - static aiScene *createDefaultTestModel( float &opacity ) { + static aiScene *createDefaultTestModel( float &opacity ) { aiScene *scene( new aiScene ); scene->mNumMaterials = 1; scene->mMaterials = new aiMaterial*[scene->mNumMaterials]; @@ -93,6 +94,11 @@ public: return scene; } + + static void releaseDefaultTestModel( aiScene **scene ) { + delete *scene; + *scene = nullptr; + } }; } diff --git a/test/unit/utScaleProcess.cpp b/test/unit/utScaleProcess.cpp new file mode 100644 index 000000000..7ab44dd15 --- /dev/null +++ b/test/unit/utScaleProcess.cpp @@ -0,0 +1,85 @@ +/* +--------------------------------------------------------------------------- +Open Asset Import Library (assimp) +--------------------------------------------------------------------------- + +Copyright (c) 2006-2017, 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. +--------------------------------------------------------------------------- +*/ +#include "UnitTestPCH.h" +#include "ScaleProcess.h" +#include "TestModelFactory.h" + +namespace Assimp { +namespace UnitTest { + +class utScaleProcess : public ::testing::Test { + // empty +}; + +TEST_F( utScaleProcess, createTest ) { + bool ok = true; + try { + ScaleProcess process; + } catch ( ... ) { + ok = false; + } + EXPECT_TRUE( ok ); +} + +TEST_F( utScaleProcess, accessScaleTest ) { + ScaleProcess process; + EXPECT_FLOAT_EQ( AI_CONFIG_GLOBAL_SCALE_FACTOR_DEFAULT, process.getScale() ); + + process.setScale( 2.0f ); + EXPECT_FLOAT_EQ( 2.0f, process.getScale() ); +} + +TEST_F( utScaleProcess, rescaleModelTest ) { + float opacity; + aiScene *testScene = TestModelFacttory::createDefaultTestModel( opacity ); + ai_real v1 = testScene->mRootNode->mTransformation.a1; + ScaleProcess process; + process.setScale( 10.0f ); + process.Execute( testScene ); + ai_real v2 = testScene->mRootNode->mTransformation.a1; + const ai_real scale = v2 / v1; + EXPECT_FLOAT_EQ( scale, 10.0f ); + TestModelFacttory::releaseDefaultTestModel( &testScene ); +} + +} // Namespace UnitTest +} // Namespace Assimp