Compare commits

..
Author SHA1 Message Date
Kim Kulling 30b20e07e7 Fix possible overflow 2025-09-23 21:28:54 +02:00
Kim Kulling fa18d3dde6 Fix possible overflow 2025-09-23 21:24:58 +02:00
198 changed files with 3877 additions and 6856 deletions
+5 -5
View File
@@ -48,7 +48,7 @@ jobs:
- name: ccache
uses: hendrikmuhs/ccache-action@v1.2
- uses: actions/checkout@v6
- uses: actions/checkout@v5
with:
submodules: true
@@ -65,7 +65,7 @@ jobs:
- name: Cache DX SDK
id: dxcache
if: contains(matrix.name, 'windows')
uses: actions/cache@v5
uses: actions/cache@v4
with:
path: '${{ github.workspace }}/DX_SDK'
key: ${{ runner.os }}-DX_SDK
@@ -109,7 +109,7 @@ jobs:
run: cd build/bin && ./unit ${{ steps.hunter_extra_test_args.outputs.args }}
shell: bash
- uses: actions/upload-artifact@v6
- uses: actions/upload-artifact@v4
if: matrix.name == 'windows-msvc'
with:
name: 'assimp-bins-${{ matrix.name }}'
@@ -141,7 +141,7 @@ jobs:
prerelease: true
- run: |
echo '${{steps.create-release.outputs.upload_url}}' > release_upload_url.txt
- uses: actions/upload-artifact@v6
- uses: actions/upload-artifact@v4
with:
name: create-release
path: release_upload_url.txt
@@ -188,7 +188,7 @@ jobs:
- id: upload-url
run: |
echo "url=$(cat create-release/release_upload_url.txt)" >> $GITHUB_OUTPUT
- uses: actions/download-artifact@v7
- uses: actions/download-artifact@v5
with:
name: 'assimp-bins-${{ matrix.name }}-${{ github.sha }}'
- uses: actions/upload-release-asset@v1
+1 -1
View File
@@ -27,7 +27,7 @@ jobs:
os: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v5
- uses: lukka/get-cmake@latest
+1 -1
View File
@@ -19,7 +19,7 @@ jobs:
dry-run: false
language: c++
- name: Upload Crash
uses: actions/upload-artifact@v6
uses: actions/upload-artifact@v4
if: failure() && steps.build.outcome == 'success'
with:
name: artifacts
+3 -3
View File
@@ -14,7 +14,7 @@ jobs:
name: adress-sanitizer
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v5
- uses: lukka/get-cmake@latest
- uses: lukka/set-shell-env@v1
with:
@@ -38,7 +38,7 @@ jobs:
name: undefined-behavior-sanitizer
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v5
- uses: lukka/get-cmake@latest
- uses: lukka/set-shell-env@v1
with:
@@ -62,7 +62,7 @@ jobs:
name: printf-sanitizer
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v5
- name: run scan_printf script
run: ./scripts/scan_printf.sh
+1 -1
View File
@@ -30,7 +30,7 @@ cmake --build .
Note that by default this builds a shared library into the `bin` directory. If you want to build it as a static library see the build options at the bottom of this file.
### Build instructions for Windows with Visual-Studio
First, you have to install Visual-Studio on your windows-system. You can get the Community-Version for free [here](https://visualstudio.microsoft.com/downloads/)
First, you have to install Visual-Studio on your windows-system. You can get the Community-Version for free here: https://visualstudio.microsoft.com/de/downloads/
To generate the build environment for your IDE open a command prompt, navigate to your repo and type:
```bash
cmake CMakeLists.txt
+607
View File
@@ -0,0 +1,607 @@
----------------------------------------------------------------------
CHANGELOG
----------------------------------------------------------------------
4.1.0 (2017-12):
- FEATURES:
- Export 3MF ( experimental )
- Import / Export glTF 2
- Introduce new zib-lib to eb able to export zip-archives
- FIXES/HOUSEKEEPING:
- Added missing include to stdlib.h and remove load library call
- Fix install for builds with MSVC compiler and NMake.
- Update list of supported file formats.
- Add TriLib to the official list of supported ports.
- Re-enabling PACK_STRUCT for MDL files.
- Use std.::unique_ptr
- Update D3MFExporter.h
- Update MD3Loader.cpp, using index
- Fix all warnings on MSVC14
- Copy assimp dll to unit folder on windows
- Update jvm port supported formats
- Add support for building Mac OS X Framework bundles
- Check for nullptr dereferencing before copying scene data
- Update ValidateDataStructure.h, typo
- Enable data structure validation in cases where it doesn't cause failures
- Remove some dead assignments
- fast_atof: Silence some uninitialized variable warnings
- Check for area test if the face is a triangle.
- Set mNumUVComponents to 0 when deleting texture coordinate sets
- Only scale the root node because this will rescale all children nodes as well.
- Issue 1514: Fix frame pointer arithmetic
- Prevent failing stringstream to crash the export process
- powf -> pow
- add Defines.h to include folder for install.
- Android:
- Fix android build
- Fix assimp for cross compile for android
- Use define for D_FILE_OFFSET_BITS only for not-android systems.
- FBX:
- Fix handling with embedded textures
- FBX 7500 Binary reading
- Remove dead assignment
- Fix export of deleted meshes; Add LazyDict::Remove method
- Log an error instead of letting the fbx-importer crash. ( issue 213 )
- Replace bad pointer casting with memcpy
- Remove useless const qualifier from return value
- Add explicit instantiation of log_prefix so other FBX source files can see it
- add missing inversion of postrotation matrix for fbx.
- FIReader: Silence uninitialized variable warning
- Update version check in FBX reader to check for version >= 7500
- Use actual min/max of anim keys when start/stop time is missing
- GLTF1:
- Fix output of glTF 1 version string
- Fix delete / delete[] mismatch in glTFAsset
- Don’t ignore rgba(1,1,1,1) color properties
- glTF2 primitives fixes
- Don’t ignore rgba(1,1,1,1) color properties
- Fix delete / delete[] mismatch in glTFAsset
- Remove KHR_binary_glTF code
- glTF nodes can only hold one mesh. this simply assigns to and check’s a Node’s Mesh
- version in glb header is stored as uint32_t
- GLTF2:
- node name conflict fix
- Fix transform matrices multiplication order
- Preserve node names when importing
- Add support for tangents in import
- Fix typo on gltf2 camera parameters
- Moved byteStride from accessor to bufferView
- Implemented reading binary glTF2 (glb) files
- Fix signed/unsigned warning
- Add postprocess step for scaling
- Fix shininess to roughness conversion
- Prefer “BLEND” over “MASK” as an alphaMode default
- Approximate specularity / glossiness in metallicRoughness materials
- Diffuse color and diffuse texture import and export improvements
- Addressed some mismatched news/deletes caused by the new glTF2 sources.
- Fix delete / delete[] mismatches in glTF2 importer
- use correct name of exporter to gltf2
- Fix possible infinite loop when exporting to gltf2
- Fix glTF2::Asset::FindUniqueID() when the input string is >= 256 chars
- Fix glTF2 alphaMode storage and reading
- Fix glTF 2.0 multi-primitive support
- Load gltf .bin files from correct directory
- Add support for importing both glTF and glTF2 files
- ampler improvements; Add new LazyDict method
- Changes to GLTF2 materials
- Remove Light, Technique references
- Start removing materials common, and adding pbrSpecularGlossiness
- Use !ObjectEmpty() vs. MemberCount() > 0
- Working read, import, export, and write of gltf2 (pbr) material
- Check in gltf2 models to test directory
- Remove un-needed test models
- Start managing and importing gltf2 pbr materials
- Update glTF2 Asset to use indexes
- Duplicate gltfImporter as gltf2Importer; Include glTF2 importer in CMake List
- glTF2: Fix animation export
- use opacity for diffuse alpha + alphaMode
- STL:
- Restore import of multi mesh binary STLs
- Blender:
- Silence warning about uninitialized member
- MDLImporter:
- Don't take address of packed struct member
- assimp_cmd:
- Fix strict-aliasing warnings
- Open3DGC:
- Fix strict-aliasing warnings
- Add assertions to silence static analyzer warnings
- Remove redundant const qualifiers from return types
- Fix some uninitialized variable warnings
- Remove OPEN3DGC and compression references
- unzip:
- Remove dead assignment
- Bail on bad compression method
- Fix possibly uninitialized variables
- clipper:
- Add assertion to silence a static analyzer warning
- OpenDDLExport:
- Reduce scope of a variable
- Remove dead variable
- Remove dead assignment
- Fix another potential memory leak
- X3DImporter:
- Add assertions to silence static analyzer warnings
- Add missing unittest
- Workaround for buggy Android NDK (issue #1361)
- TerragenLoader:
- Remove unused variable
- SIBImporter:
- Add assertions to silence static analyzer warnings
- IFC:
- Remove dead code
- Add explicit instantiation of log_prefix so IFCMaterial.cpp can see it
- PLY:
- Remove dead assignment and reduce scope of a variable
- fix vertex attribute lookup.
- OpenGEX:
- Add assertion to silence a static analyzer warning
- Fix for TextureFile with number in file name
- Return early when element is TextureFile
- NFF:
- Add assertions to silence static analyzer warnings
- Split up some complicated assignments
- Raw: Fix misleading indentation warning
- Reduce scope of a variable
- LWO
- Reduce scope of a variable
- IRRLoader:
- Fix confusing boolean casting
- AssbinExporter:
- Add assertion to silence a static analyzer warning
- ASE:
- Add assertion to silence a static analyzer warning
- AMFImporter:
- Add assertion to silence a static analyzer warning
- Add a block
- OptimizeGraph:
- Fix possible null pointer dereference
- RemoveRedundantMaterials:
- Add assertion to silence a static analyzer warning
- ImproveCacheLocality:
- Add assertion to silence a static analyzer warning
- RemoveRedundantMaterials:
- Set pointer to nullptr after deleting it
- Travis:
- Disable unit tests in scan-build config
- Move slower builds earlier to improve parallelization
- Add static analysis to build
- Remove unused branch rule for travis.
- Add Clang UBSan build configuration
- Treat warnings as errors, without typos this time
- Unittests:
- Add VS-based source groups for the unittests.
- Collada:
- export <library_animations> tag
- Update ColladaExporter.cpp
- Silence uninitialized variable warning
- Add support for line strip primitives
- Obj Wavefront:
- check in exporting against out-of-bounds-access .
- Issue 1351: use correct name for obj-meshname export for groups.
- fix mem-lead: face will be not released in case of an error.
- Anatoscope obj exporter nomtl
- Raise exception when obj file contains invalid face indices
- Added alternative displacement texture token in OBJ MTL material.
- Obj: rename attribute from exporter.
- Fix OBJ discarding all material names if the material library is missing
- Step:
- use correct lookup for utf32
- MD2:
- Fix MD2 frames containing garbage
- STL
- add missing const.
- Fix memory-alignment bug.
- Fix issue 104: deal with more solids in one STL file.
- CMake
- Fix issue 213: use correct include folder for assimp
- Doxygen
- Fix issue 1513: put irrXML onto exclucde list for doxygen run
- PyAssimp:
- Search for libassimp.so in LD_LIBRARY_PATH if available.
- Fix operator precedence issue in header check
- Split setup.py into multiple lines
- Detect if Anaconda and fixed 3d_viewer for Python 3
- created a python3 version of the 3dviewer and fixed the / = float in py3
- Blender:
- Fix invalid access to mesh array when the array is empty.
- Fix short overflow.
- Silence warning about inline function which is declared but not defined
- JAssimp
- Changed license header for IHMC contributions from Apache 2.0 to BSD
- Add Node metadata to the Jassmip Java API
- Added supported for custom IO Systems in Java. Implemented ClassLoader IO System
- Added a link to pure jvm assimp port
- Clang sanitizer:
- Undefined Behavior sanitizer
- Fixed a divide by zero error in IFCBoolean that was latent, but nevertheless a bug
- B3DImporter:
- Replace bad pointer casting with memcpy
- AppVeyor:
- Cleanup and Addition of VS 2017 and running Tests
- Fixed File Size reported as 0 in tests that use temporary files
- x86 isn't a valid VS platform. Win32 it is, then.
- Replaced the worker image name, which doesn't work as generator name, with a manually created generator name.
- Cleaned up appveyor setup, added VS 2017 to the build matrix and attempted to add running of tests.
- Treat warnings as errors on Appveyor
- Disable warning 4351 on MSVC 2013
- OpenGEXImporter:
- Copy materials to scene
- Store RefInfo in unique_ptr so they get automatically cleaned up
- Fix IOStream leak
- Store ChildInfo in unique_ptr so they get automatically cleaned up
- improve logging to be able to detect error-prone situations.
- AMFImporter:
- Fix memory leak
- UnrealLoader:
- Fix IOStream leak
- Upgrade RapidJSON to get rid of a clang warning
- zlib:
- Update zlib contribution
- Removed unnecessary files from zlib contribution
- Replaced unsigned long for the crc table to z_crc_t, to match what is returned by get-crc_table
- MakeVerboseFormat:
- Fix delete / delete[] mismatches in MakeVerboseFormat
- MaterialSystem:
- Fix out-of-bounds read in MaterialSystem unit test
- SIB:
- Added support for SIB models from Silo 2.5
- AssbinExporter:
- Fix strict aliasing violation
- Add Write specialization for aiColor3D
- DefaultLogger:
- Whitespace cleanup to fix GCC misleading indentation warning
- MDP:
- Fix encoding issues.
- PreTransformVertices:
- fix name lost in mesh and nodes when load with flag
- C4D:
- Fixes for C4D importer
- Unzip:
- Latest greatest.
4.0.1 (2017-07-28)
- FIXES/HOUSEKEEPING:
- fix version test.
- Not compiling when using ASSIMP_DOUBLE_PRECISION
- Added support for python3
- Check if cmake is installed with brew
- Low performance in OptimizeMeshesProcess::ProcessNode with huge numbers of meshes
- Elapsed seconds not shown correctly
- StreamReader: fix out-of-range exception
- PPdPmdParser: fix compilation for clang
4.0.0 (2017-07-18)
FEATURES:
- Double precision support provided ( available via cmake option )
- QT-Widget based assimp-viewer ( works for windows, linux, osx )
- Open3DGC codec supported by glFT-importer
- glTF: Read and write transparency values
- Add Triangulate post-processing step to glTF exporters
- Update rapidjson to v1.0.2
- Added method to append new metadata to structure
- Unittests: intoduce a prototype model differ
- X3D support
- AMF support
- Lugdunum3D support
- Obj-Importer: obj-homogeneous_coords support
- Obj-Importer: new streaming handling
- Added support for 64 bit version header introduced in FbxSdk2016
- Travis: enable coverall support.
- PyAssimp: New version of the pyASSIMP 3D viewer, with much improved 3D controls
- Morph animation support for collada
- Added support for parameters Ni and Tf in OBJ/MTL file format
- aiScene: add method to add children
- Added new option to IFC importer to control tessellation angle + removed unused IFC option
- aiMetaData: introduce aiMetaData::Dealloc
- Samples: add a DX11 example
- travis ci: test on OXS ( XCode 6.3 ) as well
- travis ci: enable sudo support.
- openddlparser: integrate release v0.4.0
- aiMetaData: Added support for metadata in assbin format
FIXES/HOUSEKEEPING:
- Introduce usage of #pragma statement
- Put cmake-scripts into their own folder
- Fix install pathes ( issue 938 )
- Fix object_compare in blender importer( issue 946 )
- Fix OSX compilation error
- Fix unzip path when no other version was found ( issue 967 )
- Set _FILE_OFFSET_BITS=64 for 32-bit linux ( issue 975 )
- Fix constructor for radjson on OSX
- Use Assimp namespace to fix build for big-endian architectures
- Add -fPIC to C Flags for 64bit linux Shared Object builds
- MDLLoader: fix resource leak.
- MakeVerboseFormat: fix invalid delete statement
- IFC: fix possible use after free access bug
- ComputeUVMappingprocess: add missing initialization for scalar value
- Fix invalid release of mat + mesh
- IrrImporter: Fix release functions
- Split mesh before exporting gltf ( issue 995 )
- 3MFImporter: add source group for visual studio
- IFC: Switch generated file to 2 files to fix issue related to <mingw4.9 ( Thanks Qt! )
- ObjImporter: fix test for vertices import
- export scene combiner ( issues177 )
- FBX: make lookup test less strict ( issues 994 )
- OpenGEX-Importer: add import of vertex colors ( issue 954 )
- fix bug when exporting mRotationKeys data
- fix mingw build (mingw supports stat64 nowadays)
- cfileio: fix leaks by not closing files in the destructor
- Fix OBJ parser mtllib statement parsing bug.
- Q3BSP-Importer: remove dead code
- Fix BlenderDNA for clang cross compiler.
- ScenePreprocessor: fix invalid index counter.
- Fix compiler warnings ( issue 957 )
- Fix obj .mtl file loading
- Fixed a compile error on MSVC14 x64 caused by the /bigobj flag failing to be set for the 1 and 2-suffixed versions introduced in commit 0a25b076b8968b7ea2aa96d7d1b4381be2d72ce6
- Fixed build warnings on MSVC14 x64
- Remove scaling of specular exponent in OBJFileImporter.cpp
- use ai_assert instead of assert ( issue 1076 )
- Added a preprocessor definition for MSVC to silence safety warnings regarding C library functions. This addresses all warnings for MSVC x86 and x64 when building zlib, tools and viewer as a static lib
- fix parsing of texture name ( issue 899 )
- add warning when detecting invalid mat definition ( issue 1111 )
- copy aiTexture type declaration instead of using decltype for declaration to fix iOS build( issue 1101 )
- FBX: Add additional material properties
- FBX: Correct camera position and clip planes
- FBX: Add correct light locations and falloff values
- fix typo ( issue 1141 )
- Fix collada export. Don't duplicate TEXCOORD/NORMALS/COLORS in <vertices> and <polylist> ( issue 1084 )
- OBJParser: set material index when changing current material
- OBJ: check for null mesh before updating material index
- add vertex color export support ( issue 809 )
- Fix memory leak in Collada importer ( issue 1169 )
- add stp to the list of supported extensions for step-files ( issue 1183 )
- fix clang build ( Issue-1169 )
- fix for FreeBSD
- Import FindPkgMacros to main CMake Configuration
- Extended support for tessellation parameter to more IFC shapes
- defensice handling of utf-8 decode issues ( issue 1211 )
- Fixed compiler error on clang 4.0 running on OSX
- use test extension for exported test files ( issue 1228 )
- Set UVW index material properties for OBJ files
- Fixed no member named 'atop' in global namespace issue for Android NDK compilation
- Apply mechanism to decide use for IrrXML external or internal
- Fix static init ordering bug in OpenGEX importer
- GLTF exporter: ensure animation accessors have same count
- GLTF exporter: convert animation time from ticks to seconds
- Add support for reading texture coordinates from PLY meshes with properties named 'texture_u' and 'texture_v'
- Added TokensForSearch in BlenderLoader to allow CanRead return true for in-memory files.
- fix wrong delete ( issue 1266 )
- OpenGEX: fix invalid handling with color4 token ( issue 1262 )
- LWOLoader: fix link in loader description
- Fix error when custom CMAKE_C_FLAGS is specified
- Fast-atof: log overflow errors
- Obj-Importer: do not break when detecting an overflow ( issue 1244 )
- Obj-Importer: fix parsing of multible line data definitions
- Fixed bug where IFC models with multiple IFCSite only loaded 1 site instead of the complete model
- PLYImporter: - optimize memory and speed on ply importer / change parser to use a file stream - manage texture path in ply
import - manage texture coords on faces in ply import - correction on point cloud faces generation
- Utf8: integrate new lib ( issue 1158 )
- fixed CMAKE_MODULE_PATH overwriting previous values
- OpenGEX: Fixed bug in material color processing ( issue 1271 )
- SceneCombiner: move header for scenecombiner to public folder.
- GLTF exporter: ensure buffer view byte offsets are correctly aligned
- X3D importer: Added EXPORT and IMPORT to the list of ignored XML tags
- X3D Exporter: fixed missing attributes
- X3D importer: Fixed import of normals for the single index / normal per vertex case
- X3D importer: Fixed handling of inlined files
- X3D importer: fixed whitespace handling (issue 1202)
- X3D importer: Fixed iterator on MSVC 2015
- X3D importer: Fixed problems with auto, override and regex on older compilers
- X3D importer: Fixed missing header file
- X3D importer: Fixed path handling
- X3D importer: Implemented support for binary X3D files
- fix build without 3DS ( issue 1319 )
- pyassimp: Fixed indices for IndexedTriangleFanSet, IndexedTriangleSet and IndexedTriangleStripSet
- Fixes parameters to pyassimp.load
- Obj-Importe: Fixed texture bug due simultaneously using 'usemtl' and 'usemap' attributes
- check if all exporters are disabled ( issue 1320 )
- Remove std functions deprecated by C++11.
- X-Importer: make it deal with lines
- use correct path for compilers ( issue 1335 )
- Collada: add workaround to deal with polygon with holes
- update python readme
- Use unique node names when loading Collada files
- Fixed many FBX bugs
API COMPATIBILITY:
- Changed ABI-compatibility to v3.3.1, please rebuild your precompiled libraries ( see issue 1182 )
- VS2010 outdated
3.3.1 (2016-07-08)
FIXES/HOUSEKEEPING:
- Setup of default precision for 17 exporters
- Fix xcode project files
- Fix BlenderTesselator: offsetof operator
- Invalid version in cmake file
- Update pstdint.h to latest greatest
3.3.0 (2016-07-05)
FEATURES:
- C++11 support enabled
- New regression-test-UI
- Experimental glTF-importer support
- OpenGEX: add support for cameras and lights
- C4D: update to latest Melange-SDK
- Add a gitter channel
- Coverity check enabled
- Switch to <...> include brackets for public headers
- Enable export by pyAssimp
- CI: check windows build
- Add functionality to perform a singlepost-processing step
- many more, just check the history
FIXES/HOUSEKEEPING:
- Fix of many resource leaks in unittests and main lib
- Fix iOS-buildfor X64
- Choosing zlib manually for cmake
- many more, just check the history
3.2.1 (2016-010-10)
FEATURES:
- Updated glTF exporter to meet 1.0 specification.
FIXES/HOUSEKEEPING:
- Fixed glTF Validator errors for exported glTF format.
ISSUES:
- Hard coded sampler setting for
- magFilter
- minFilter
- void* in ExportData for accessor max and min.
3.2.0 (2015-11-03)
FEATURES:
- OpenDDL-Parser is part of contrib-source.
- Experimental OpenGEX-support
- CI-check for linux and windows
- Coverity check added
- New regression testsuite.
FIXES/HOUSEKEEPING:
- Hundreds of bugfixes in all parts of the library
- Unified line endings
API COMPATIBILITY:
- Removed precompiled header to increase build speed for linux
3.1.1 (2014-06-15)
FEATURES:
- Support for FBX 2013 and newer, binary and ASCII (this is partly
work from Google Summer of Code 2012)
- Support for OGRE binary mesh and skeleton format
- Updated BLEND support for newer Blender versions
- Support for arbitrary meta data, used to hold FBX and DAE metadata
- OBJ Export now produces smaller files
- Meshes can now have names, this is supported by the major importers
- Improved IFC geometry generation
- M3 support has been removed
FIXES/HOUSEKEEPING:
- Hundreds of bugfixes in all parts of the library
- CMake is now the primary build system
API COMPATIBILITY:
- 3.1.1 is not binary compatible to 3.0 due to aiNode::mMetaData
and aiMesh::mName
- Export interface has been cleaned up and unified
- Other than that no relevant changes
3.0 (2012-07-07)
FEATURES:
- new export interface similar to the import API.
- Supported export formats: Collada, OBJ, PLY and STL
- added new import formats: XGL/ZGL, M3 (experimental)
- new postprocessing steps: Debone
- vastly improved IFC (Industry Foundation Classes) support
- introduced API to query importer meta information (such as supported
format versions, full name, maintainer info).
- reworked Ogre XML import
- C-API now supports per-import properties
FIXES/HOUSEKEEPING:
- hundreds of bugfixes in all parts of the library
- unified naming and cleanup of public headers
- improved CMake build system
- templatized math library
- reduce dependency on boost.thread, only remaining spot
is synchronization for the C logging API
API COMPATIBILITY:
- renamed headers, export interface, C API properties and meta data
prevent compatibility with code written for 2.0, but in
most cases these can be easily resolved
- Note: 3.0 is not binary compatible with 2.0
2.0 (2010-11-21)
FEATURES:
- Add support for static Blender (*.blend) scenes
- Add support for Q3BSP scenes
- Add a windows-based OpenGL sample featuring texturing & basic materials
- Add an experimental progress feedback interface.
- Vastly improved performance (up to 500%, depending on mesh size and
spatial structure) in some expensive postprocessing steps
- AssimpView now uses a reworked layout which leaves more space
to the scene hierarchy window
- Add C# bindings ('Assimp.NET')
- Keep BSD-licensed and otherwise free test files in separate
folders (./test/models and ./test/models-nonbsd).
FIXES:
- Many Collada bugfixes, improve fault tolerance
- Fix possible crashes in the Obj loader
- Improve the Ogre XML loader
- OpenGL-sample now works with MinGW
- Fix Importer::FindLoader failing on uppercase file extensions
- Fix flawed path handling when locating external files
- Limit the maximum number of vertices, faces, face indices and
weights that Assimp is able to handle. This is to avoid
crashes due to overflowing counters.
- Updated XCode project files
- Further CMAKE build improvements
API CHANGES:
- Add data structures for vertex-based animations (These are not
currently used, however ...)
- Some Assimp::Importer methods are const now.
1.1 (2010-04-17)
This is the list of relevant changes from the 1.0 (r412) release to 1.1 (r700).
FEATURES:
- Vastly improved Collada support
- Add MS3D (Milkshape 3D) support
- Add support for Ogre XML static meshes
- Add experimental COB (TrueSpace) support
- Automatic test suite to quickly locate regressions
- D bindings (`dAssimp`)
- Python 2.n bindings (`PyAssimp`)
- Add basic support for Unicode input files (utf8, utf16 and utf32)
- Add further utilities to the `assimp` tool (xml/binary dumps, quick file stats)
- Switch to a CMAKE-based build system including an install target for unix'es
- Automatic evaluation of subdivision surfaces for some formats.
- Add `Importer::ReadFileFromMemory` and the corresponding C-API `aiReadFileFromMemory`
- Expose further math utilities via the C-API (i.e. `aiMultiplyMatrix4`)
- Move noboost files away from the public include directory
- Many, many bugfixes and improvements in existing loaders and postprocessing steps
- Documentation improved and clarified in many places.
- Add a sample on using Assimp in conjunction with OpenGL
- Distribution/packaging: comfortable SDK installer for Windows
- Distribution/packaging: improved release packages for other architectures
CRITICAL FIXES:
- Resolve problems with clashing heap managers, STL ABIs and runtime libraries (win32)
- Fix automatic detection of file type if no file extension is given
- Improved exception safety and robustness, prevent leaking of exceptions through the C interface
- Fix possible heap corruption due to material properties pulled in incorrectly
- Avoid leaking in certain error scenarios
- Fix 64 bit compatibility problems in some loaders (i.e. MDL)
BREAKING API CHANGES:
- None -
MINOR API BEHAVIOUR CHANGES:
- Change quaternion orientation to suit to the more common convention (-w).
- aiString is utf8 now. Not yet consistent, however.
-3961
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -362,7 +362,7 @@ ELSEIF(MSVC)
elseif((GENERATOR_IS_MULTI_CONFIG) OR (CMAKE_BUILD_TYPE MATCHES Release))
message("-- MSVC PDB generation disabled. Release binary will not be debuggable.")
endif()
if(NOT CMAKE_CXX_FLAGS MATCHES "/utf-8")
if(NOT /utf-8 IN_LIST CMAKE_CXX_FLAGS)
# Source code is encoded in UTF-8
ADD_COMPILE_OPTIONS(/source-charset:utf-8)
endif()
+14 -50
View File
@@ -1,53 +1,17 @@
{
"version": 3,
"cmakeMinimumRequired": {
"major": 3,
"minor": 20,
"patch": 0
},
"configurePresets": [
{
"name": "assimp",
"binaryDir": "${sourceDir}",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Release",
"ASSIMP_BUILD_ASSIMP_TOOLS": "OFF"
}
"version": 3,
"cmakeMinimumRequired": {
"major": 3,
"minor": 20,
"patch": 0
},
{
"name": "assimp_static",
"binaryDir": "${sourceDir}",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Release",
"BUILD_SHARED_LIBS": "OFF",
"ASSIMP_BUILD_ASSIMP_TOOLS": "OFF",
"ASSIMP_DOUBLE_PRECISION": "ON"
}
},
{
"name": "assimp_double_precision",
"binaryDir": "${sourceDir}",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Release",
"ASSIMP_BUILD_ASSIMP_TOOLS": "OFF",
"ASSIMP_DOUBLE_PRECISION": "ON"
}
},
{
"name": "assimp_with_tools",
"binaryDir": "${sourceDir}",
"cacheVariables": {
"ASSIMP_BUILD_ASSIMP_TOOLS": "ON"
}
},
{
"name": "assimp_all",
"binaryDir": "${sourceDir}",
"cacheVariables": {
"ASSIMP_BUILD_ASSIMP_TOOLS": "ON",
"ASSIMP_BUILD_SAMPLES": "ON",
"ASSIMP_BUILD_DOCS": "ON"
}
}
]
"configurePresets": [
{
"name": "assimp_with_tools",
"binaryDir": "${sourceDir}",
"cacheVariables": {
"ASSIMP_BUILD_ASSIMP_TOOLS" : "ON"
}
}
]
}
+31 -35
View File
@@ -3,7 +3,7 @@ Open Asset Import Library (assimp)
Open Asset Import Library is a library that loads various 3D file formats into a shared, in-memory format. It supports more than __40 file formats__ for import and a growing selection of file formats for export.
### Current project status
### Current project status ###
![C/C++ CI](https://github.com/assimp/assimp/workflows/C/C++%20CI/badge.svg)
[![Codacy Badge](https://app.codacy.com/project/badge/Grade/9973693b7bdd4543b07084d5d9cf4745)](https://www.codacy.com/gh/assimp/assimp/dashboard?utm_source=github.com&amp;utm_medium=referral&amp;utm_content=assimp/assimp&amp;utm_campaign=Badge_Grade)
[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=assimp_assimp&metric=alert_status)](https://sonarcloud.io/summary/new_code?id=assimp_assimp)
@@ -16,32 +16,32 @@ Open Asset Import Library is a library that loads various 3D file formats into a
APIs are provided for C and C++. Various bindings exist to other languages (C#, Java, Python, Delphi, D). Assimp also runs on Android and iOS.
Additionally, assimp features various __mesh post-processing tools__: normals and tangent space generation, triangulation, vertex cache locality optimization, removal of degenerate primitives and duplicate vertices, sorting by primitive type, merging of redundant materials and many more.
## Project activity
## Project activity ##
![Alt](https://repobeats.axiom.co/api/embed/997f84e5f9fcf772da1e687f3a4f3a8afdbf4cf0.svg "Repobeats analytics image")
### Documentation
### Documentation ###
Read [our latest documentation](https://the-asset-importer-lib-documentation.readthedocs.io/en/latest/).
### Pre-built binaries
### Pre-built binaries ###
Download binaries from [our Itch Projectspace](https://kimkulling.itch.io/the-asset-importer-lib).
### Test data
### Test data ###
Clone [our model database for testing purposes](https://github.com/assimp/assimp-mdb).
### Communities
### Communities ###
- Ask questions at [the Assimp Discussion Board](https://github.com/assimp/assimp/discussions).
- Find us on [discord](https://discord.gg/kKazXMXDy2)
- Ask [the Assimp community on Reddit](https://www.reddit.com/r/Assimp/).
- Ask on [StackOverflow with the assimp-tag](http://stackoverflow.com/questions/tagged/assimp?sort=newest).
- Nothing has worked? File a question or an issue report at [The Assimp-Issue Tracker](https://github.com/assimp/assimp/issues)
#### Supported file formats
#### Supported file formats ####
See [the complete list of supported formats](https://github.com/assimp/assimp/blob/master/doc/Fileformats.md).
### Building
### Building ###
Start by reading [our build instructions](https://github.com/assimp/assimp/blob/master/Build.md). We are available in vcpkg, and our build system is CMake; if you used CMake before there is a good chance you know what to do.
### Ports
### Ports ###
* [Android](port/AndroidJNI/README.md)
* [Python](port/PyAssimp/README.md)
* [.NET](https://github.com/Saalvage/AssimpNetter)
@@ -54,39 +54,35 @@ Start by reading [our build instructions](https://github.com/assimp/assimp/blob/
* [HAXE-Port](https://github.com/longde123/assimp-haxe) The Assimp-HAXE-port.
* [Rust](https://github.com/jkvargas/russimp)
### Other tools
### Other tools ###
[Qt5-ModelViewer](https://github.com/sharjith/ModelViewer-Qt5) is a powerful viewer based on Qt5 and Assimp's import and export abilities.<br>
[Assimp-Viewer](https://github.com/assimp/assimp_view) is an experimental implementation for an Asset-Viewer based on ImGUI and Assimp (experimental).
#### Repository structure ####
Open Asset Import Library is implemented in C++. The directory structure looks like this:
```txt
code Source code
├── AssetLib/ The asset-importer and exporter lib
├── CApi/ C-API files
├── Common/ Common code used from all modules
├── Geometry/ Geometry utilities
├── Material/ Common materials
├── Pbrt/ Physical based materials
├── PostProcessing/ Post-processing steps
├── res Resouce files
contrib Third-party libraries
doc Documentation (Doxygen source and pre-compiled docs)
fuzz Contains the test code for the Google Fuzzer project
include Public header C and C++ header files
scripts Scripts are used to generate the loading code for some formats
port Ports to other languages and scripts to maintain those.
test Unit- and regression tests, test suite of models
├── headercheck Implements headerchecks
├── models-nonbsd Non-BSP licensed headers
├── models BSP-licensed models
├── unit Unit tests
tools Tools (old assimp viewer, command line `assimp`)
samples Small number of samples to illustrate possible use cases for Assimp
```
### Contributing
/code Source code
/contrib Third-party libraries
/doc Documentation (Doxygen source and pre-compiled docs)
/fuzz Contains the test code for the Google Fuzzer project
/include Public header C and C++ header files
/scripts Scripts are used to generate the loading code for some formats
/port Ports to other languages and scripts to maintain those.
/test Unit- and regression tests, test suite of models
/tools Tools (old assimp viewer, command line `assimp`)
/samples A small number of samples to illustrate possible use cases for Assimp
The source code is organized in the following way:
code/Common The base implementation for importers and the infrastructure
code/CApi Special implementations which are only used for the C-API
code/Geometry A collection of geometry tools
code/Material The material system
code/PBR An exporter for physical-based models
code/PostProcessing The post-processing steps
code/AssetLib/<FormatName> Implementation for import and export of the format
### Contributing ###
We would greatly appreciate for you to contribute to assimp. The easiest way to get involved is to submit
a pull request with your changes against the main repository's `master` branch.
+1 -1
View File
@@ -11,5 +11,5 @@ The current version of Assimp that's being supported with security updates:
## Reporting a Vulnerability
If you have found any security vulnerability you can contact us via
kim.kulling@assimp.org
kim.kulling@googlemail.com
+72
View File
@@ -0,0 +1,72 @@
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.
#.rst:
# FindDevIL
# ---------
#
#
#
# This module locates the developer's image library.
# http://openil.sourceforge.net/
#
# This module sets:
#
# ::
#
# IL_LIBRARIES - the name of the IL library. These include the full path to
# the core DevIL library. This one has to be linked into the
# application.
# ILU_LIBRARIES - the name of the ILU library. Again, the full path. This
# library is for filters and effects, not actual loading. It
# doesn't have to be linked if the functionality it provides
# is not used.
# ILUT_LIBRARIES - the name of the ILUT library. Full path. This part of the
# library interfaces with OpenGL. It is not strictly needed
# in applications.
# IL_INCLUDE_DIR - where to find the il.h, ilu.h and ilut.h files.
# IL_FOUND - this is set to TRUE if all the above variables were set.
# This will be set to false if ILU or ILUT are not found,
# even if they are not needed. In most systems, if one
# library is found all the others are as well. That's the
# way the DevIL developers release it.
# TODO: Add version support.
# Tested under Linux and Windows (MSVC)
#include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
include(FindPackageHandleStandardArgs)
find_path(IL_INCLUDE_DIR il.h
PATH_SUFFIXES include IL
DOC "The path to the directory that contains il.h"
)
#message("IL_INCLUDE_DIR is ${IL_INCLUDE_DIR}")
find_library(IL_LIBRARIES
NAMES IL DEVIL
PATH_SUFFIXES lib64 lib lib32
DOC "The file that corresponds to the base il library."
)
#message("IL_LIBRARIES is ${IL_LIBRARIES}")
find_library(ILUT_LIBRARIES
NAMES ILUT
PATH_SUFFIXES lib64 lib lib32
DOC "The file that corresponds to the il (system?) utility library."
)
#message("ILUT_LIBRARIES is ${ILUT_LIBRARIES}")
find_library(ILU_LIBRARIES
NAMES ILU
PATH_SUFFIXES lib64 lib lib32
DOC "The file that corresponds to the il utility library."
)
#message("ILU_LIBRARIES is ${ILU_LIBRARIES}")
FIND_PACKAGE_HANDLE_STANDARD_ARGS(IL DEFAULT_MSG
IL_LIBRARIES IL_INCLUDE_DIR)
+34 -39
View File
@@ -56,27 +56,23 @@ namespace Assimp {
static constexpr unsigned int NotSet = 0xcdcdcdcd;
using namespace D3DS;
// ------------------------------------------------------------------------------------------------
// Setup final material indices, generate a default material if necessary
// Setup final material indices, generae a default material if necessary
void Discreet3DSImporter::ReplaceDefaultMaterial() {
// Try to find an existing material that matches the
// typical default material setting:
// - no textures
// - diffuse color (in grey!)
// NOTE: This is here to work-around the fact that some
// NOTE: This is here to workaround the fact that some
// exporters are writing a default material, too.
unsigned int idx(NotSet);
for (unsigned int i = 0; i < mScene->mMaterials.size(); ++i) {
auto s = mScene->mMaterials[i].mName;
std::string s = mScene->mMaterials[i].mName;
for (char &it : s) {
it = static_cast<char>(::tolower(static_cast<unsigned char>(it)));
}
if (std::string::npos == s.find("default")) {
continue;
}
if (std::string::npos == s.find("default")) continue;
if (mScene->mMaterials[i].mDiffuse.r !=
mScene->mMaterials[i].mDiffuse.g ||
@@ -89,22 +85,22 @@ void Discreet3DSImporter::ReplaceDefaultMaterial() {
idx = i;
}
if (NotSet == idx) {
idx = static_cast<unsigned int>(mScene->mMaterials.size());
idx = (unsigned int)mScene->mMaterials.size();
}
// now iterate through all meshes and through all faces and
// find all faces that are using the default material
unsigned int cnt = 0;
for (auto i = mScene->mMeshes.begin(); i != mScene->mMeshes.end(); ++i) {
for (auto a = i->mFaceMaterials.begin(); a != i->mFaceMaterials.end(); ++a) {
for (auto a = (*i).mFaceMaterials.begin(); a != (*i).mFaceMaterials.end(); ++a) {
// NOTE: The additional check seems to be necessary,
// some exporters seem to generate invalid data here
if (NotSet == *a) {
*a = idx;
if (NotSet == (*a)) {
(*a) = idx;
++cnt;
} else if ((*a) >= mScene->mMaterials.size()) {
*a = idx;
(*a) = idx;
ASSIMP_LOG_WARN("Material index overflow in 3DS file. Using default material");
++cnt;
}
@@ -178,7 +174,7 @@ void CopyTexture(aiMaterial &mat, Texture &texture, aiTextureType type) {
mat.AddProperty<ai_real>(&texture.mTextureBlend, 1, AI_MATKEY_TEXBLEND(type, 0));
// Setup the texture mapping mode
auto mapMode = static_cast<int>(texture.mMapMode);
int mapMode = static_cast<int>(texture.mMapMode);
mat.AddProperty<int>(&mapMode, 1, AI_MATKEY_MAPPINGMODE_U(type, 0));
mat.AddProperty<int>(&mapMode, 1, AI_MATKEY_MAPPINGMODE_V(type, 0));
@@ -323,18 +319,17 @@ void Discreet3DSImporter::ConvertMaterial(Material &oldMat, aiMaterial &mat) {
// ------------------------------------------------------------------------------------------------
// Split meshes by their materials and generate output aiMesh'es
void Discreet3DSImporter::ConvertMeshes(aiScene *pcOut) {
std::vector<aiMesh *> avOutMeshes;
MeshArray avOutMeshes;
avOutMeshes.reserve(mScene->mMeshes.size() * 2);
unsigned int iFaceCnt = 0, num = 0;
aiString name;
// we need to split all meshes by their materials
for (auto i = mScene->mMeshes.begin(); i != mScene->mMeshes.end(); ++i) {
for (std::vector<D3DS::Mesh>::iterator i = mScene->mMeshes.begin(); i != mScene->mMeshes.end(); ++i) {
std::unique_ptr<std::vector<unsigned int>[]> aiSplit(new std::vector<unsigned int>[mScene->mMaterials.size()]);
name.length = ASSIMP_itoa10(name.data, num);
++num;
name.length = ASSIMP_itoa10(name.data, num++);
unsigned int iNum = 0;
for (std::vector<unsigned int>::const_iterator a = (*i).mFaceMaterials.begin();
@@ -346,7 +341,7 @@ void Discreet3DSImporter::ConvertMeshes(aiScene *pcOut) {
if (aiSplit[p].empty()) {
continue;
}
auto *meshOut = new aiMesh();
aiMesh *meshOut = new aiMesh();
meshOut->mName = name;
meshOut->mPrimitiveTypes = aiPrimitiveType_TRIANGLE;
@@ -358,7 +353,7 @@ void Discreet3DSImporter::ConvertMeshes(aiScene *pcOut) {
avOutMeshes.push_back(meshOut);
// convert vertices
meshOut->mNumFaces = static_cast<unsigned int>(aiSplit[p].size());
meshOut->mNumFaces = (unsigned int)aiSplit[p].size();
meshOut->mNumVertices = meshOut->mNumFaces * 3;
// allocate enough storage for faces
@@ -406,7 +401,8 @@ void Discreet3DSImporter::ConvertMeshes(aiScene *pcOut) {
// ------------------------------------------------------------------------------------------------
// Add a node to the scenegraph and setup its final transformation
void Discreet3DSImporter::AddNodeToGraph(aiScene *pcSOut, aiNode *pcOut, D3DS::Node *pcIn, aiMatrix4x4 & /*absTrafo*/) {
void Discreet3DSImporter::AddNodeToGraph(aiScene *pcSOut, aiNode *pcOut,
D3DS::Node *pcIn, aiMatrix4x4 & /*absTrafo*/) {
std::vector<unsigned int> iArray;
iArray.reserve(3);
@@ -414,7 +410,7 @@ void Discreet3DSImporter::AddNodeToGraph(aiScene *pcSOut, aiNode *pcOut, D3DS::N
// Find all meshes with the same name as the node
for (unsigned int a = 0; a < pcSOut->mNumMeshes; ++a) {
const auto *pcMesh = (const D3DS::Mesh *)pcSOut->mMeshes[a]->mColors[0];
const D3DS::Mesh *pcMesh = (const D3DS::Mesh *)pcSOut->mMeshes[a]->mColors[0];
ai_assert(nullptr != pcMesh);
if (pcIn->mName == pcMesh->mName)
@@ -423,7 +419,7 @@ void Discreet3DSImporter::AddNodeToGraph(aiScene *pcSOut, aiNode *pcOut, D3DS::N
if (!iArray.empty()) {
// The matrix should be identical for all meshes with the
// same name. It HAS to be identical for all meshes .....
auto *imesh = ((D3DS::Mesh *)pcSOut->mMeshes[iArray[0]]->mColors[0]);
D3DS::Mesh *imesh = ((D3DS::Mesh *)pcSOut->mMeshes[iArray[0]]->mColors[0]);
// Compute the inverse of the transformation matrix to move the
// vertices back to their relative and local space
@@ -432,7 +428,7 @@ void Discreet3DSImporter::AddNodeToGraph(aiScene *pcSOut, aiNode *pcOut, D3DS::N
mInvTransposed.Transpose();
aiVector3D pivot = pcIn->vPivot;
pcOut->mNumMeshes = static_cast<unsigned int>(iArray.size());
pcOut->mNumMeshes = (unsigned int)iArray.size();
pcOut->mMeshes = new unsigned int[iArray.size()];
for (unsigned int i = 0; i < iArray.size(); ++i) {
const unsigned int iIndex = iArray[i];
@@ -451,7 +447,7 @@ void Discreet3DSImporter::AddNodeToGraph(aiScene *pcSOut, aiNode *pcOut, D3DS::N
// Handle negative transformation matrix determinant -> invert vertex x
if (imesh->mMat.Determinant() < 0.0f) {
// we *must* have normals
/* we *must* have normals */
for (pvCurrent = mesh->mVertices, t2 = mesh->mNormals; pvCurrent != pvEnd; ++pvCurrent, ++t2) {
pvCurrent->x *= -1.f;
t2->x *= -1.f;
@@ -478,7 +474,7 @@ void Discreet3DSImporter::AddNodeToGraph(aiScene *pcSOut, aiNode *pcOut, D3DS::N
// Setup the name of the node
// First instance keeps its name otherwise something might break, all others will be postfixed with their instance number
if (pcIn->mInstanceNumber > 1) {
char tmp[12] = {'\0'};
char tmp[12];
ASSIMP_itoa10(tmp, pcIn->mInstanceNumber);
std::string tempStr = pcIn->mName + "_inst_";
tempStr += tmp;
@@ -491,7 +487,7 @@ void Discreet3DSImporter::AddNodeToGraph(aiScene *pcSOut, aiNode *pcOut, D3DS::N
if (pcIn->aRotationKeys.size()) {
// FIX to get to Assimp's quaternion conventions
for (auto it = pcIn->aRotationKeys.begin(); it != pcIn->aRotationKeys.end(); ++it) {
for (std::vector<aiQuatKey>::iterator it = pcIn->aRotationKeys.begin(); it != pcIn->aRotationKeys.end(); ++it) {
(*it).mValue.w *= -1.f;
}
@@ -603,11 +599,11 @@ void Discreet3DSImporter::AddNodeToGraph(aiScene *pcSOut, aiNode *pcOut, D3DS::N
}
// Allocate a new node anim and setup its name
auto *nda = anim->mChannels[anim->mNumChannels++] = new aiNodeAnim();
aiNodeAnim *nda = anim->mChannels[anim->mNumChannels++] = new aiNodeAnim();
nda->mNodeName.Set(pcIn->mName);
// POSITION keys
if (!pcIn->aPositionKeys.empty()) {
if (pcIn->aPositionKeys.size() > 0) {
nda->mNumPositionKeys = (unsigned int)pcIn->aPositionKeys.size();
nda->mPositionKeys = new aiVectorKey[nda->mNumPositionKeys];
::memcpy(nda->mPositionKeys, &pcIn->aPositionKeys[0],
@@ -615,7 +611,7 @@ void Discreet3DSImporter::AddNodeToGraph(aiScene *pcSOut, aiNode *pcOut, D3DS::N
}
// ROTATION keys
if (!pcIn->aRotationKeys.empty()) {
if (pcIn->aRotationKeys.size() > 0) {
nda->mNumRotationKeys = (unsigned int)pcIn->aRotationKeys.size();
nda->mRotationKeys = new aiQuatKey[nda->mNumRotationKeys];
@@ -631,7 +627,7 @@ void Discreet3DSImporter::AddNodeToGraph(aiScene *pcSOut, aiNode *pcOut, D3DS::N
}
// SCALING keys
if (!pcIn->aScalingKeys.empty()) {
if (pcIn->aScalingKeys.size() > 0) {
nda->mNumScalingKeys = (unsigned int)pcIn->aScalingKeys.size();
nda->mScalingKeys = new aiVectorKey[nda->mNumScalingKeys];
::memcpy(nda->mScalingKeys, &pcIn->aScalingKeys[0],
@@ -640,7 +636,7 @@ void Discreet3DSImporter::AddNodeToGraph(aiScene *pcSOut, aiNode *pcOut, D3DS::N
}
// Allocate storage for children
const auto size = static_cast<unsigned int>(pcIn->mChildren.size());
const unsigned int size = static_cast<unsigned int>(pcIn->mChildren.size());
pcOut->mNumChildren = size;
if (size == 0) {
@@ -683,7 +679,7 @@ void CountTracks(D3DS::Node *node, unsigned int &cnt) {
// Generate the output node graph
void Discreet3DSImporter::GenerateNodeGraph(aiScene *pcOut) {
pcOut->mRootNode = new aiNode();
if (mRootNode->mChildren.empty()) {
if (0 == mRootNode->mChildren.size()) {
//////////////////////////////////////////////////////////////////////////////
// It seems the file is so messed up that it has not even a hierarchy.
// generate a flat hiearachy which looks like this:
@@ -705,8 +701,7 @@ void Discreet3DSImporter::GenerateNodeGraph(aiScene *pcOut) {
// Build dummy nodes for all meshes
unsigned int a = 0;
for (unsigned int i = 0; i < pcOut->mNumMeshes; ++i, ++a) {
pcOut->mRootNode->mChildren[a] = new aiNode();
auto *pcNode = pcOut->mRootNode->mChildren[a];
aiNode *pcNode = pcOut->mRootNode->mChildren[a] = new aiNode();
pcNode->mParent = pcOut->mRootNode;
pcNode->mMeshes = new unsigned int[1];
pcNode->mMeshes[0] = i;
@@ -718,7 +713,7 @@ void Discreet3DSImporter::GenerateNodeGraph(aiScene *pcOut) {
// Build dummy nodes for all cameras
for (unsigned int i = 0; i < (unsigned int)mScene->mCameras.size(); ++i, ++a) {
auto *pcNode = pcOut->mRootNode->mChildren[a] = new aiNode();
aiNode *pcNode = pcOut->mRootNode->mChildren[a] = new aiNode();
pcNode->mParent = pcOut->mRootNode;
// Build a name for the node
@@ -727,7 +722,7 @@ void Discreet3DSImporter::GenerateNodeGraph(aiScene *pcOut) {
// Build dummy nodes for all lights
for (unsigned int i = 0; i < (unsigned int)mScene->mLights.size(); ++i, ++a) {
auto *pcNode = pcOut->mRootNode->mChildren[a] = new aiNode();
aiNode *pcNode = pcOut->mRootNode->mChildren[a] = new aiNode();
pcNode->mParent = pcOut->mRootNode;
// Build a name for the node
@@ -743,7 +738,7 @@ void Discreet3DSImporter::GenerateNodeGraph(aiScene *pcOut) {
// Allocate a primary animation channel
pcOut->mNumAnimations = 1;
pcOut->mAnimations = new aiAnimation *[1];
auto *anim = pcOut->mAnimations[0] = new aiAnimation();
aiAnimation *anim = pcOut->mAnimations[0] = new aiAnimation();
anim->mName.Set("3DSMasterAnim");
@@ -786,7 +781,7 @@ void Discreet3DSImporter::ConvertScene(aiScene *pcOut) {
// ... and convert the 3DS materials to aiMaterial's
for (unsigned int i = 0; i < pcOut->mNumMaterials; ++i) {
auto *pcNew = new aiMaterial();
aiMaterial *pcNew = new aiMaterial();
ConvertMaterial(mScene->mMaterials[i], *pcNew);
pcOut->mMaterials[i] = pcNew;
}
+18 -15
View File
@@ -76,26 +76,26 @@ class ChunkWriter {
public:
ChunkWriter(StreamWriterLE &writer, uint16_t chunk_type) :
mWriter(writer) {
mChunkStartPos = writer.GetCurrentPos();
writer(writer) {
chunk_start_pos = writer.GetCurrentPos();
writer.PutU2(chunk_type);
writer.PutU4((uint32_t)CHUNK_SIZE_NOT_SET);
}
~ChunkWriter() {
std::size_t head_pos = mWriter.GetCurrentPos();
std::size_t head_pos = writer.GetCurrentPos();
ai_assert(head_pos > mChunkStartPos);
const std::size_t chunk_size = head_pos - mChunkStartPos;
ai_assert(head_pos > chunk_start_pos);
const std::size_t chunk_size = head_pos - chunk_start_pos;
mWriter.SetCurrentPos(mChunkStartPos + SIZE_OFFSET);
mWriter.PutU4(static_cast<uint32_t>(chunk_size));
mWriter.SetCurrentPos(head_pos);
writer.SetCurrentPos(chunk_start_pos + SIZE_OFFSET);
writer.PutU4(static_cast<uint32_t>(chunk_size));
writer.SetCurrentPos(head_pos);
}
private:
StreamWriterLE &mWriter;
std::size_t mChunkStartPos;
StreamWriterLE &writer;
std::size_t chunk_start_pos;
};
// Return an unique name for a given |mesh| attached to |node| that
@@ -122,7 +122,8 @@ std::string GetMaterialName(const aiMaterial &mat, unsigned int index) {
char postfix[10] = { 0 };
ASSIMP_itoa10(postfix, index);
if (aiString mat_name; AI_SUCCESS == mat.Get(AI_MATKEY_NAME, mat_name)) {
aiString mat_name;
if (AI_SUCCESS == mat.Get(AI_MATKEY_NAME, mat_name)) {
return mat_name.C_Str() + underscore + postfix;
}
@@ -302,7 +303,8 @@ void Discreet3DSExporter::WriteMaterials() {
WriteColor(color);
}
if (aiShadingMode shading_mode = aiShadingMode_Flat; mat.Get(AI_MATKEY_SHADING_MODEL, shading_mode) == AI_SUCCESS) {
aiShadingMode shading_mode = aiShadingMode_Flat;
if (mat.Get(AI_MATKEY_SHADING_MODEL, shading_mode) == AI_SUCCESS) {
ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAT_SHADING);
Discreet3DS::shadetype3ds shading_mode_out;
@@ -330,7 +332,7 @@ void Discreet3DSExporter::WriteMaterials() {
default:
shading_mode_out = Discreet3DS::Flat;
ai_assert(false);
}
};
writer.PutU2(static_cast<uint16_t>(shading_mode_out));
}
@@ -344,7 +346,8 @@ void Discreet3DSExporter::WriteMaterials() {
WritePercentChunk(f);
}
if (int twosided; mat.Get(AI_MATKEY_TWOSIDED, twosided) == AI_SUCCESS && twosided != 0) {
int twosided;
if (mat.Get(AI_MATKEY_TWOSIDED, twosided) == AI_SUCCESS && twosided != 0) {
ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAT_TWO_SIDE);
writer.PutI2(1);
}
@@ -538,7 +541,7 @@ void Discreet3DSExporter::WriteFaceMaterialChunk(const aiMesh &mesh) {
// ------------------------------------------------------------------------------------------------
void Discreet3DSExporter::WriteString(const std::string &s) {
for (auto it = s.begin(); it != s.end(); ++it) {
for (std::string::const_iterator it = s.begin(); it != s.end(); ++it) {
writer.PutI1(*it);
}
writer.PutI1('\0');
+4 -2
View File
@@ -54,7 +54,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/qnan.h>
#include <cstdio> //sprintf
namespace Assimp::D3DS {
namespace Assimp {
namespace D3DS {
#include <assimp/Compiler/pushpack1.h>
@@ -578,6 +579,7 @@ struct Scene {
// Node* pcRootNode;
};
} // end of namespace Assimp::D3DS
} // end of namespace D3DS
} // end of namespace Assimp
#endif // AI_XFILEHELPER_H_INC
+178 -177
View File
@@ -56,8 +56,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
namespace Assimp {
using namespace D3DS;
static constexpr aiImporterDesc desc = {
"Discreet 3DS Importer",
"",
@@ -77,7 +75,7 @@ static constexpr aiImporterDesc desc = {
// - computes its length
#define ASSIMP_3DS_BEGIN_CHUNK() \
while (true) { \
if (mStream->GetRemainingSizeToLimit() < sizeof(Discreet3DS::Chunk)) { \
if (stream->GetRemainingSizeToLimit() < sizeof(Discreet3DS::Chunk)) { \
return; \
} \
Discreet3DS::Chunk chunk; \
@@ -85,23 +83,23 @@ static constexpr aiImporterDesc desc = {
int chunkSize = chunk.Size - sizeof(Discreet3DS::Chunk); \
if (chunkSize <= 0) \
continue; \
const unsigned int oldReadLimit = mStream->SetReadLimit( \
mStream->GetCurrentPos() + chunkSize);
const unsigned int oldReadLimit = stream->SetReadLimit( \
stream->GetCurrentPos() + chunkSize);
// ------------------------------------------------------------------------------------------------
// End a parsing block
// Must follow at the end of each parsing block, reset chunk end marker to previous value
#define ASSIMP_3DS_END_CHUNK() \
mStream->SkipToReadLimit(); \
mStream->SetReadLimit(oldReadLimit); \
if (mStream->GetRemainingSizeToLimit() == 0) \
stream->SkipToReadLimit(); \
stream->SetReadLimit(oldReadLimit); \
if (stream->GetRemainingSizeToLimit() == 0) \
return; \
}
// ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer
Discreet3DSImporter::Discreet3DSImporter() :
mStream(nullptr), mLastNodeIndex(), mCurrentNode(), mRootNode(), mScene(), mMasterScale(), bHasBG(), bIsPrj() {
stream(), mLastNodeIndex(), mCurrentNode(), mRootNode(), mScene(), mMasterScale(), bHasBG(), bIsPrj() {
// empty
}
@@ -126,7 +124,9 @@ void Discreet3DSImporter::SetupProperties(const Importer * /*pImp*/) {
// ------------------------------------------------------------------------------------------------
// Imports the given file into the given scene structure.
void Discreet3DSImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler) {
void Discreet3DSImporter::InternReadFile(const std::string &pFile,
aiScene *pScene, IOSystem *pIOHandler) {
auto theFile = pIOHandler->Open(pFile, "rb");
if (!theFile) {
throw DeadlyImportError("3DS: Could not open ", pFile);
@@ -138,14 +138,14 @@ void Discreet3DSImporter::InternReadFile(const std::string &pFile, aiScene *pSce
if (theStream.GetRemainingSize() < 16) {
throw DeadlyImportError("3DS file is either empty or corrupt: ", pFile);
}
mStream = &theStream;
this->stream = &theStream;
// Allocate our temporary 3DS representation
Scene _scene;
D3DS::Scene _scene;
mScene = &_scene;
// Initialize members
Node _rootNode("UNNAMED");
D3DS::Node _rootNode("UNNAMED");
mLastNodeIndex = -1;
mCurrentNode = &_rootNode;
mRootNode = mCurrentNode;
@@ -166,12 +166,12 @@ void Discreet3DSImporter::InternReadFile(const std::string &pFile, aiScene *pSce
// vectors from the smoothing groups we read from the
// file.
for (auto &mesh : mScene->mMeshes) {
if (!mesh.mFaces.empty() && mesh.mPositions.empty()) {
if (mesh.mFaces.size() > 0 && mesh.mPositions.size() == 0) {
throw DeadlyImportError("3DS file contains faces but no vertices: ", pFile);
}
CheckIndices(mesh);
MakeUnique(mesh);
ComputeNormalsWithSmoothingsGroups<Face>(mesh);
ComputeNormalsWithSmoothingsGroups<D3DS::Face>(mesh);
}
// Replace all occurrences of the default material with a
@@ -196,12 +196,12 @@ void Discreet3DSImporter::InternReadFile(const std::string &pFile, aiScene *pSce
AI_DEBUG_INVALIDATE_PTR(mRootNode);
AI_DEBUG_INVALIDATE_PTR(mScene);
AI_DEBUG_INVALIDATE_PTR(mStream);
AI_DEBUG_INVALIDATE_PTR(this->stream);
}
// ------------------------------------------------------------------------------------------------
// Applies a master-scaling factor to the imported scene
void Discreet3DSImporter::ApplyMasterScale(const aiScene *pScene) {
void Discreet3DSImporter::ApplyMasterScale(aiScene *pScene) {
// There are some 3DS files with a zero scaling factor
if (!mMasterScale)
mMasterScale = 1.0f;
@@ -223,14 +223,14 @@ void Discreet3DSImporter::ApplyMasterScale(const aiScene *pScene) {
void Discreet3DSImporter::ReadChunk(Discreet3DS::Chunk *pcOut) {
ai_assert(pcOut != nullptr);
pcOut->Flag = mStream->GetI2();
pcOut->Size = mStream->GetI4();
pcOut->Flag = stream->GetI2();
pcOut->Size = stream->GetI4();
if (pcOut->Size - sizeof(Discreet3DS::Chunk) > mStream->GetRemainingSize()) {
if (pcOut->Size - sizeof(Discreet3DS::Chunk) > stream->GetRemainingSize()) {
throw DeadlyImportError("Chunk is too large");
}
if (pcOut->Size - sizeof(Discreet3DS::Chunk) > mStream->GetRemainingSizeToLimit()) {
if (pcOut->Size - sizeof(Discreet3DS::Chunk) > stream->GetRemainingSizeToLimit()) {
ASSIMP_LOG_ERROR("3DS: Chunk overflow");
}
}
@@ -241,7 +241,8 @@ void Discreet3DSImporter::SkipChunk() {
Discreet3DS::Chunk psChunk;
ReadChunk(&psChunk);
mStream->IncPtr(psChunk.Size - sizeof(Discreet3DS::Chunk));
stream->IncPtr(psChunk.Size - sizeof(Discreet3DS::Chunk));
return;
}
// ------------------------------------------------------------------------------------------------
@@ -258,7 +259,7 @@ void Discreet3DSImporter::ParseMainChunk() {
case Discreet3DS::CHUNK_MAIN:
ParseEditorChunk();
break;
}
};
ASSIMP_3DS_END_CHUNK();
#if defined(__clang__)
@@ -274,29 +275,30 @@ void Discreet3DSImporter::ParseMainChunk() {
// ------------------------------------------------------------------------------------------------
void Discreet3DSImporter::ParseEditorChunk() {
ASSIMP_3DS_BEGIN_CHUNK()
ASSIMP_3DS_BEGIN_CHUNK();
// get chunk type
switch (chunk.Flag) {
case Discreet3DS::CHUNK_OBJMESH:
ParseObjectChunk();
break;
case Discreet3DS::CHUNK_OBJMESH:
// NOTE: In several documentations in the internet this
// chunk appears at different locations
case Discreet3DS::CHUNK_KEYFRAMER:
ParseKeyframeChunk();
break;
case Discreet3DS::CHUNK_VERSION: {
// print the version number
char buff[10];
ASSIMP_itoa10(buff, mStream->GetI2());
ASSIMP_LOG_INFO("3DS file format version: ", buff);
}
ParseObjectChunk();
break;
// NOTE: In several documentations in the internet this
// chunk appears at different locations
case Discreet3DS::CHUNK_KEYFRAMER:
ParseKeyframeChunk();
break;
case Discreet3DS::CHUNK_VERSION: {
// print the version number
char buff[10];
ASSIMP_itoa10(buff, stream->GetI2());
ASSIMP_LOG_INFO("3DS file format version: ", buff);
} break;
};
ASSIMP_3DS_END_CHUNK()
ASSIMP_3DS_END_CHUNK();
}
// ------------------------------------------------------------------------------------------------
@@ -307,10 +309,10 @@ void Discreet3DSImporter::ParseObjectChunk() {
switch (chunk.Flag) {
case Discreet3DS::CHUNK_OBJBLOCK: {
unsigned int cnt = 0;
const auto *sz = (const char *)mStream->GetPtr();
const char *sz = (const char *)stream->GetPtr();
// Get the name of the geometry object
while (mStream->GetI1())
while (stream->GetI1())
++cnt;
ParseChunk(sz, cnt);
} break;
@@ -338,8 +340,8 @@ void Discreet3DSImporter::ParseObjectChunk() {
// Specifies the background image. The string should already be
// properly 0 terminated but we need to be sure
unsigned int cnt = 0;
auto *sz = (const char *)mStream->GetPtr();
while (mStream->GetI1())
const char *sz = (const char *)stream->GetPtr();
while (stream->GetI1())
++cnt;
mBackgroundImage = std::string(sz, cnt);
} break;
@@ -350,7 +352,7 @@ void Discreet3DSImporter::ParseObjectChunk() {
case Discreet3DS::CHUNK_MASTER_SCALE:
// Scene master scaling factor
mMasterScale = mStream->GetF4();
mMasterScale = stream->GetF4();
break;
};
ASSIMP_3DS_END_CHUNK();
@@ -377,15 +379,15 @@ void Discreet3DSImporter::ParseChunk(const char *name, unsigned int num) {
case Discreet3DS::CHUNK_LIGHT: {
// This starts a new light
auto *light = new aiLight();
aiLight *light = new aiLight();
mScene->mLights.push_back(light);
light->mName.Set(std::string(name, num));
// First read the position of the light
light->mPosition.x = mStream->GetF4();
light->mPosition.y = mStream->GetF4();
light->mPosition.z = mStream->GetF4();
light->mPosition.x = stream->GetF4();
light->mPosition.y = stream->GetF4();
light->mPosition.z = stream->GetF4();
light->mColorDiffuse = aiColor3D(1.f, 1.f, 1.f);
@@ -406,19 +408,19 @@ void Discreet3DSImporter::ParseChunk(const char *name, unsigned int num) {
case Discreet3DS::CHUNK_CAMERA: {
// This starts a new camera
auto *camera = new aiCamera();
aiCamera *camera = new aiCamera();
mScene->mCameras.push_back(camera);
camera->mName.Set(std::string(name, num));
// First read the position of the camera
camera->mPosition.x = mStream->GetF4();
camera->mPosition.y = mStream->GetF4();
camera->mPosition.z = mStream->GetF4();
camera->mPosition.x = stream->GetF4();
camera->mPosition.y = stream->GetF4();
camera->mPosition.z = stream->GetF4();
// Then the camera target
camera->mLookAt.x = mStream->GetF4() - camera->mPosition.x;
camera->mLookAt.y = mStream->GetF4() - camera->mPosition.y;
camera->mLookAt.z = mStream->GetF4() - camera->mPosition.z;
camera->mLookAt.x = stream->GetF4() - camera->mPosition.x;
camera->mLookAt.y = stream->GetF4() - camera->mPosition.y;
camera->mLookAt.z = stream->GetF4() - camera->mPosition.z;
ai_real len = camera->mLookAt.Length();
if (len < 1e-5) {
@@ -430,12 +432,12 @@ void Discreet3DSImporter::ParseChunk(const char *name, unsigned int num) {
camera->mLookAt /= len;
// And finally - the camera rotation angle, in counter clockwise direction
const ai_real angle = AI_DEG_TO_RAD(mStream->GetF4());
const ai_real angle = AI_DEG_TO_RAD(stream->GetF4());
aiQuaternion quat(camera->mLookAt, angle);
camera->mUp = quat.GetMatrix() * aiVector3D(0.0, 1.0, 0.0);
// Read the lense angle
camera->mHorizontalFOV = AI_DEG_TO_RAD(mStream->GetF4());
camera->mHorizontalFOV = AI_DEG_TO_RAD(stream->GetF4());
if (camera->mHorizontalFOV < 0.001f) {
camera->mHorizontalFOV = float(AI_DEG_TO_RAD(45.f));
}
@@ -461,34 +463,34 @@ void Discreet3DSImporter::ParseLightChunk() {
light->mType = aiLightSource_SPOT;
// We wouldn't need to normalize here, but we do it
light->mDirection.x = mStream->GetF4() - light->mPosition.x;
light->mDirection.y = mStream->GetF4() - light->mPosition.y;
light->mDirection.z = mStream->GetF4() - light->mPosition.z;
light->mDirection.x = stream->GetF4() - light->mPosition.x;
light->mDirection.y = stream->GetF4() - light->mPosition.y;
light->mDirection.z = stream->GetF4() - light->mPosition.z;
light->mDirection.Normalize();
// Now the hotspot and falloff angles - in degrees
light->mAngleInnerCone = AI_DEG_TO_RAD(mStream->GetF4());
light->mAngleInnerCone = AI_DEG_TO_RAD(stream->GetF4());
// FIX: the falloff angle is just an offset
light->mAngleOuterCone = light->mAngleInnerCone + AI_DEG_TO_RAD(mStream->GetF4());
light->mAngleOuterCone = light->mAngleInnerCone + AI_DEG_TO_RAD(stream->GetF4());
break;
// intensity multiplier
case Discreet3DS::CHUNK_DL_MULTIPLIER:
light->mColorDiffuse = light->mColorDiffuse * mStream->GetF4();
light->mColorDiffuse = light->mColorDiffuse * stream->GetF4();
break;
// light color
case Discreet3DS::CHUNK_RGBF:
case Discreet3DS::CHUNK_LINRGBF:
light->mColorDiffuse.r *= mStream->GetF4();
light->mColorDiffuse.g *= mStream->GetF4();
light->mColorDiffuse.b *= mStream->GetF4();
light->mColorDiffuse.r *= stream->GetF4();
light->mColorDiffuse.g *= stream->GetF4();
light->mColorDiffuse.b *= stream->GetF4();
break;
// light attenuation
case Discreet3DS::CHUNK_DL_ATTENUATE:
light->mAttenuationLinear = mStream->GetF4();
light->mAttenuationLinear = stream->GetF4();
break;
};
@@ -503,10 +505,10 @@ void Discreet3DSImporter::ParseCameraChunk() {
// get chunk type
switch (chunk.Flag) {
// near and far clip plane
case Discreet3DS::CHUNK_CAM_RANGES:
camera->mClipPlaneNear = mStream->GetF4();
camera->mClipPlaneFar = mStream->GetF4();
break;
case Discreet3DS::CHUNK_CAM_RANGES:
camera->mClipPlaneNear = stream->GetF4();
camera->mClipPlaneFar = stream->GetF4();
break;
}
ASSIMP_3DS_END_CHUNK();
@@ -553,13 +555,14 @@ void Discreet3DSImporter::InverseNodeSearch(D3DS::Node *pcNode, D3DS::Node *pcCu
// ------------------------------------------------------------------------------------------------
// Find a node with a specific name in the import hierarchy
Node *FindNode(Node *root, const std::string &name) {
D3DS::Node *FindNode(D3DS::Node *root, const std::string &name) {
if (root->mName == name) {
return root;
}
for (auto it = root->mChildren.begin(); it != root->mChildren.end(); ++it) {
if (auto *nd = FindNode(*it, name); nullptr != nd) {
for (std::vector<D3DS::Node *>::iterator it = root->mChildren.begin(); it != root->mChildren.end(); ++it) {
D3DS::Node *nd = FindNode(*it, name);
if (nullptr != nd) {
return nd;
}
}
@@ -577,7 +580,7 @@ bool KeyUniqueCompare(const T &first, const T &second) {
// ------------------------------------------------------------------------------------------------
// Skip some additional import data.
void Discreet3DSImporter::SkipTCBInfo() {
unsigned int flags = mStream->GetI2();
unsigned int flags = stream->GetI2();
if (!flags) {
// Currently we can't do anything with these values. They occur
@@ -588,19 +591,19 @@ void Discreet3DSImporter::SkipTCBInfo() {
}
if (flags & Discreet3DS::KEY_USE_TENS) {
mStream->IncPtr(4);
stream->IncPtr(4);
}
if (flags & Discreet3DS::KEY_USE_BIAS) {
mStream->IncPtr(4);
stream->IncPtr(4);
}
if (flags & Discreet3DS::KEY_USE_CONT) {
mStream->IncPtr(4);
stream->IncPtr(4);
}
if (flags & Discreet3DS::KEY_USE_EASE_FROM) {
mStream->IncPtr(4);
stream->IncPtr(4);
}
if (flags & Discreet3DS::KEY_USE_EASE_TO) {
mStream->IncPtr(4);
stream->IncPtr(4);
}
}
@@ -619,15 +622,15 @@ void Discreet3DSImporter::ParseHierarchyChunk(uint16_t parent) {
// First of all: get the name of the object
unsigned int cnt = 0;
auto *sz = (const char *)mStream->GetPtr();
const char *sz = (const char *)stream->GetPtr();
while (mStream->GetI1())
while (stream->GetI1())
++cnt;
std::string name = std::string(sz, cnt);
// Now find out whether we have this node already (target animation channels
// are stored with a separate object ID)
Node *pcNode = FindNode(mRootNode, name);
D3DS::Node *pcNode = FindNode(mRootNode, name);
int instanceNumber = 1;
if (pcNode) {
@@ -643,10 +646,10 @@ void Discreet3DSImporter::ParseHierarchyChunk(uint16_t parent) {
pcNode->mInstanceNumber = instanceNumber;
// There are two unknown values which we can safely ignore
mStream->IncPtr(4);
stream->IncPtr(4);
// Now read the hierarchy position of the object
uint16_t hierarchy = mStream->GetI2() + 1;
uint16_t hierarchy = stream->GetI2() + 1;
pcNode->mHierarchyPos = hierarchy;
pcNode->mHierarchyIndex = mLastNodeIndex;
@@ -675,8 +678,8 @@ void Discreet3DSImporter::ParseHierarchyChunk(uint16_t parent) {
// This is the "real" name of a $$$DUMMY object
{
const char *sz = (const char *)mStream->GetPtr();
while (mStream->GetI1())
const char *sz = (const char *)stream->GetPtr();
while (stream->GetI1())
;
// If object name is DUMMY, take this one instead
@@ -695,16 +698,16 @@ void Discreet3DSImporter::ParseHierarchyChunk(uint16_t parent) {
}
// Pivot = origin of rotation and scaling
mCurrentNode->vPivot.x = mStream->GetF4();
mCurrentNode->vPivot.y = mStream->GetF4();
mCurrentNode->vPivot.z = mStream->GetF4();
mCurrentNode->vPivot.x = stream->GetF4();
mCurrentNode->vPivot.y = stream->GetF4();
mCurrentNode->vPivot.z = stream->GetF4();
break;
// ////////////////////////////////////////////////////////////////////
// POSITION KEYFRAME
case Discreet3DS::CHUNK_TRACKPOS: {
mStream->IncPtr(10);
const unsigned int numFrames = mStream->GetI4();
stream->IncPtr(10);
const unsigned int numFrames = stream->GetI4();
bool sortKeys = false;
// This could also be meant as the target position for
@@ -717,16 +720,16 @@ void Discreet3DSImporter::ParseHierarchyChunk(uint16_t parent) {
l->reserve(numFrames);
for (unsigned int i = 0; i < numFrames; ++i) {
const unsigned int fidx = mStream->GetI4();
const unsigned int fidx = stream->GetI4();
// Setup a new position key
aiVectorKey v;
v.mTime = (double)fidx;
SkipTCBInfo();
v.mValue.x = mStream->GetF4();
v.mValue.y = mStream->GetF4();
v.mValue.z = mStream->GetF4();
v.mValue.x = stream->GetF4();
v.mValue.y = stream->GetF4();
v.mValue.z = stream->GetF4();
// check whether we'll need to sort the keys
if (!l->empty() && v.mTime <= l->back().mTime)
@@ -756,11 +759,11 @@ void Discreet3DSImporter::ParseHierarchyChunk(uint16_t parent) {
bool sortKeys = false;
std::vector<aiFloatKey> *l = &mCurrentNode->aCameraRollKeys;
mStream->IncPtr(10);
const unsigned int numFrames = mStream->GetI4();
stream->IncPtr(10);
const unsigned int numFrames = stream->GetI4();
l->reserve(numFrames);
for (unsigned int i = 0; i < numFrames; ++i) {
const unsigned int fidx = mStream->GetI4();
const unsigned int fidx = stream->GetI4();
// Setup a new position key
aiFloatKey v;
@@ -768,7 +771,7 @@ void Discreet3DSImporter::ParseHierarchyChunk(uint16_t parent) {
// This is just a single float
SkipTCBInfo();
v.mValue = mStream->GetF4();
v.mValue = stream->GetF4();
// Check whether we'll need to sort the keys
if (!l->empty() && v.mTime <= l->back().mTime)
@@ -795,26 +798,26 @@ void Discreet3DSImporter::ParseHierarchyChunk(uint16_t parent) {
// ////////////////////////////////////////////////////////////////////
// ROTATION KEYFRAME
case Discreet3DS::CHUNK_TRACKROTATE: {
mStream->IncPtr(10);
const unsigned int numFrames = mStream->GetI4();
stream->IncPtr(10);
const unsigned int numFrames = stream->GetI4();
bool sortKeys = false;
std::vector<aiQuatKey> *l = &mCurrentNode->aRotationKeys;
l->reserve(numFrames);
for (unsigned int i = 0; i < numFrames; ++i) {
const unsigned int fidx = mStream->GetI4();
const unsigned int fidx = stream->GetI4();
SkipTCBInfo();
aiQuatKey v;
v.mTime = (double)fidx;
// The rotation keyframe is given as an axis-angle pair
const float rad = mStream->GetF4();
const float rad = stream->GetF4();
aiVector3D axis;
axis.x = mStream->GetF4();
axis.y = mStream->GetF4();
axis.z = mStream->GetF4();
axis.x = stream->GetF4();
axis.y = stream->GetF4();
axis.z = stream->GetF4();
if (!axis.x && !axis.y && !axis.z)
axis.y = 1.f;
@@ -839,16 +842,16 @@ void Discreet3DSImporter::ParseHierarchyChunk(uint16_t parent) {
// ////////////////////////////////////////////////////////////////////
// SCALING KEYFRAME
case Discreet3DS::CHUNK_TRACKSCALE: {
mStream->IncPtr(10);
const unsigned int numFrames = mStream->GetI2();
mStream->IncPtr(2);
stream->IncPtr(10);
const unsigned int numFrames = stream->GetI2();
stream->IncPtr(2);
bool sortKeys = false;
std::vector<aiVectorKey> *l = &mCurrentNode->aScalingKeys;
l->reserve(numFrames);
for (unsigned int i = 0; i < numFrames; ++i) {
const unsigned int fidx = mStream->GetI4();
const unsigned int fidx = stream->GetI4();
SkipTCBInfo();
// Setup a new key
@@ -856,9 +859,9 @@ void Discreet3DSImporter::ParseHierarchyChunk(uint16_t parent) {
v.mTime = (double)fidx;
// ... and read its value
v.mValue.x = mStream->GetF4();
v.mValue.y = mStream->GetF4();
v.mValue.z = mStream->GetF4();
v.mValue.x = stream->GetF4();
v.mValue.y = stream->GetF4();
v.mValue.z = stream->GetF4();
// check whether we'll need to sort the keys
if (!l->empty() && v.mTime <= l->back().mTime)
@@ -899,23 +902,23 @@ void Discreet3DSImporter::ParseFaceChunk() {
if (num > mMesh.mFaces.size()) {
throw DeadlyImportError("3DS: More smoothing groups than faces");
}
for (auto i = mMesh.mFaces.begin(); m != num; ++i, ++m) {
for (std::vector<D3DS::Face>::iterator i = mMesh.mFaces.begin(); m != num; ++i, ++m) {
// nth bit is set for nth smoothing group
i->iSmoothGroup = mStream->GetI4();
(*i).iSmoothGroup = stream->GetI4();
}
} break;
case Discreet3DS::CHUNK_FACEMAT: {
// at fist an asciiz with the material name
const char *sz = (const char *)mStream->GetPtr();
while (mStream->GetI1())
const char *sz = (const char *)stream->GetPtr();
while (stream->GetI1())
;
// find the index of the material
unsigned int idx = 0xcdcdcdcd, cnt = 0;
for (auto i = mScene->mMaterials.begin(); i != mScene->mMaterials.end(); ++i, ++cnt) {
for (std::vector<D3DS::Material>::const_iterator i = mScene->mMaterials.begin(); i != mScene->mMaterials.end(); ++i, ++cnt) {
// use case independent comparisons. hopefully it will work.
if (i->mName.length() && !ASSIMP_stricmp(sz, i->mName.c_str())) {
if ((*i).mName.length() && !ASSIMP_stricmp(sz, (*i).mName.c_str())) {
idx = cnt;
break;
}
@@ -925,9 +928,9 @@ void Discreet3DSImporter::ParseFaceChunk() {
}
// Now continue and read all material indices
cnt = (uint16_t)mStream->GetI2();
cnt = (uint16_t)stream->GetI2();
for (unsigned int i = 0; i < cnt; ++i) {
unsigned int fidx = (uint16_t)mStream->GetI2();
unsigned int fidx = (uint16_t)stream->GetI2();
// check range
if (fidx >= mMesh.mFaceMaterials.size()) {
@@ -952,59 +955,59 @@ void Discreet3DSImporter::ParseMeshChunk() {
switch (chunk.Flag) {
case Discreet3DS::CHUNK_VERTLIST: {
// This is the list of all vertices in the current mesh
int num = (int)(uint16_t)mStream->GetI2();
int num = (int)(uint16_t)stream->GetI2();
mMesh.mPositions.reserve(num);
while (num-- > 0) {
aiVector3D v;
v.x = mStream->GetF4();
v.y = mStream->GetF4();
v.z = mStream->GetF4();
v.x = stream->GetF4();
v.y = stream->GetF4();
v.z = stream->GetF4();
mMesh.mPositions.push_back(v);
}
} break;
case Discreet3DS::CHUNK_TRMATRIX: {
// This is the RLEATIVE transformation matrix of the current mesh. Vertices are
// pretransformed by this matrix wonder.
mMesh.mMat.a1 = mStream->GetF4();
mMesh.mMat.b1 = mStream->GetF4();
mMesh.mMat.c1 = mStream->GetF4();
mMesh.mMat.a2 = mStream->GetF4();
mMesh.mMat.b2 = mStream->GetF4();
mMesh.mMat.c2 = mStream->GetF4();
mMesh.mMat.a3 = mStream->GetF4();
mMesh.mMat.b3 = mStream->GetF4();
mMesh.mMat.c3 = mStream->GetF4();
mMesh.mMat.a4 = mStream->GetF4();
mMesh.mMat.b4 = mStream->GetF4();
mMesh.mMat.c4 = mStream->GetF4();
mMesh.mMat.a1 = stream->GetF4();
mMesh.mMat.b1 = stream->GetF4();
mMesh.mMat.c1 = stream->GetF4();
mMesh.mMat.a2 = stream->GetF4();
mMesh.mMat.b2 = stream->GetF4();
mMesh.mMat.c2 = stream->GetF4();
mMesh.mMat.a3 = stream->GetF4();
mMesh.mMat.b3 = stream->GetF4();
mMesh.mMat.c3 = stream->GetF4();
mMesh.mMat.a4 = stream->GetF4();
mMesh.mMat.b4 = stream->GetF4();
mMesh.mMat.c4 = stream->GetF4();
} break;
case Discreet3DS::CHUNK_MAPLIST: {
// This is the list of all UV coords in the current mesh
int num = (int)(uint16_t)mStream->GetI2();
int num = (int)(uint16_t)stream->GetI2();
mMesh.mTexCoords.reserve(num);
while (num-- > 0) {
aiVector3D v;
v.x = mStream->GetF4();
v.y = mStream->GetF4();
v.x = stream->GetF4();
v.y = stream->GetF4();
mMesh.mTexCoords.push_back(v);
}
} break;
case Discreet3DS::CHUNK_FACELIST: {
// This is the list of all faces in the current mesh
int num = (int)(uint16_t)mStream->GetI2();
int num = (int)(uint16_t)stream->GetI2();
mMesh.mFaces.reserve(num);
while (num-- > 0) {
// 3DS faces are ALWAYS triangles
mMesh.mFaces.emplace_back();
Face &sFace = mMesh.mFaces.back();
D3DS::Face &sFace = mMesh.mFaces.back();
sFace.mIndices[0] = (uint16_t)mStream->GetI2();
sFace.mIndices[1] = (uint16_t)mStream->GetI2();
sFace.mIndices[2] = (uint16_t)mStream->GetI2();
sFace.mIndices[0] = (uint16_t)stream->GetI2();
sFace.mIndices[1] = (uint16_t)stream->GetI2();
sFace.mIndices[2] = (uint16_t)stream->GetI2();
mStream->IncPtr(2); // skip edge visibility flag
stream->IncPtr(2); // skip edge visibility flag
}
// Resize the material array (0xcdcdcdcd marks the default material; so if a face is
@@ -1012,7 +1015,7 @@ void Discreet3DSImporter::ParseMeshChunk() {
mMesh.mFaceMaterials.resize(mMesh.mFaces.size(), 0xcdcdcdcd);
// Larger 3DS files could have multiple FACE chunks here
chunkSize = (int)mStream->GetRemainingSizeToLimit();
chunkSize = (int)stream->GetRemainingSizeToLimit();
if (chunkSize > (int)sizeof(Discreet3DS::Chunk))
ParseFaceChunk();
} break;
@@ -1029,9 +1032,9 @@ void Discreet3DSImporter::ParseMaterialChunk() {
{
// The material name string is already zero-terminated, but we need to be sure ...
const char *sz = (const char *)mStream->GetPtr();
const char *sz = (const char *)stream->GetPtr();
unsigned int cnt = 0;
while (mStream->GetI1())
while (stream->GetI1())
++cnt;
if (!cnt) {
@@ -1099,7 +1102,7 @@ void Discreet3DSImporter::ParseMaterialChunk() {
case Discreet3DS::CHUNK_MAT_SHADING:
// This is the material shading mode
mScene->mMaterials.back().mShading = (Discreet3DS::shadetype3ds)mStream->GetI2();
mScene->mMaterials.back().mShading = (D3DS::Discreet3DS::shadetype3ds)stream->GetI2();
break;
case Discreet3DS::CHUNK_MAT_TWO_SIDE:
@@ -1175,31 +1178,31 @@ void Discreet3DSImporter::ParseTextureChunk(D3DS::Texture *pcOut) {
switch (chunk.Flag) {
case Discreet3DS::CHUNK_MAPFILE: {
// The material name string is already zero-terminated, but we need to be sure ...
const char *sz = (const char *)mStream->GetPtr();
const char *sz = (const char *)stream->GetPtr();
unsigned int cnt = 0;
while (mStream->GetI1())
while (stream->GetI1())
++cnt;
pcOut->mMapName = std::string(sz, cnt);
} break;
case Discreet3DS::CHUNK_PERCENTD:
// Manually parse the blend factor
pcOut->mTextureBlend = ai_real(mStream->GetF8());
pcOut->mTextureBlend = ai_real(stream->GetF8());
break;
case Discreet3DS::CHUNK_PERCENTF:
// Manually parse the blend factor
pcOut->mTextureBlend = mStream->GetF4();
pcOut->mTextureBlend = stream->GetF4();
break;
case Discreet3DS::CHUNK_PERCENTW:
// Manually parse the blend factor
pcOut->mTextureBlend = (ai_real)((uint16_t) mStream->GetI2()) / ai_real(100.0);
pcOut->mTextureBlend = (ai_real)((uint16_t)stream->GetI2()) / ai_real(100.0);
break;
case Discreet3DS::CHUNK_MAT_MAP_USCALE:
// Texture coordinate scaling in the U direction
pcOut->mScaleU = mStream->GetF4();
pcOut->mScaleU = stream->GetF4();
if (0.0f == pcOut->mScaleU) {
ASSIMP_LOG_WARN("Texture coordinate scaling in the x direction is zero. Assuming 1.");
pcOut->mScaleU = 1.0f;
@@ -1207,7 +1210,7 @@ void Discreet3DSImporter::ParseTextureChunk(D3DS::Texture *pcOut) {
break;
case Discreet3DS::CHUNK_MAT_MAP_VSCALE:
// Texture coordinate scaling in the V direction
pcOut->mScaleV = mStream->GetF4();
pcOut->mScaleV = stream->GetF4();
if (0.0f == pcOut->mScaleV) {
ASSIMP_LOG_WARN("Texture coordinate scaling in the y direction is zero. Assuming 1.");
pcOut->mScaleV = 1.0f;
@@ -1216,21 +1219,21 @@ void Discreet3DSImporter::ParseTextureChunk(D3DS::Texture *pcOut) {
case Discreet3DS::CHUNK_MAT_MAP_UOFFSET:
// Texture coordinate offset in the U direction
pcOut->mOffsetU = -mStream->GetF4();
pcOut->mOffsetU = -stream->GetF4();
break;
case Discreet3DS::CHUNK_MAT_MAP_VOFFSET:
// Texture coordinate offset in the V direction
pcOut->mOffsetV = mStream->GetF4();
pcOut->mOffsetV = stream->GetF4();
break;
case Discreet3DS::CHUNK_MAT_MAP_ANG:
// Texture coordinate rotation, CCW in DEGREES
pcOut->mRotation = -AI_DEG_TO_RAD(mStream->GetF4());
pcOut->mRotation = -AI_DEG_TO_RAD(stream->GetF4());
break;
case Discreet3DS::CHUNK_MAT_MAP_TILING: {
const uint16_t iFlags = mStream->GetI2();
const uint16_t iFlags = stream->GetI2();
// Get the mapping mode (for both axes)
if (iFlags & 0x2u)
@@ -1255,11 +1258,9 @@ ai_real Discreet3DSImporter::ParsePercentageChunk() {
ReadChunk(&chunk);
if (Discreet3DS::CHUNK_PERCENTF == chunk.Flag) {
return mStream->GetF4() * ai_real(100) / ai_real(0xFFFF);
}
if (Discreet3DS::CHUNK_PERCENTW == chunk.Flag) {
return (ai_real)((uint16_t)mStream->GetI2()) / (ai_real)0xFFFF;
return stream->GetF4() * ai_real(100) / ai_real(0xFFFF);
} else if (Discreet3DS::CHUNK_PERCENTW == chunk.Flag) {
return (ai_real)((uint16_t)stream->GetI2()) / (ai_real)0xFFFF;
}
return get_qnan();
@@ -1290,9 +1291,9 @@ void Discreet3DSImporter::ParseColorChunk(aiColor3D *out, bool acceptPercent) {
*out = clrError;
return;
}
out->r = mStream->GetF4();
out->g = mStream->GetF4();
out->b = mStream->GetF4();
out->r = stream->GetF4();
out->g = stream->GetF4();
out->b = stream->GetF4();
break;
case Discreet3DS::CHUNK_LINRGBB:
@@ -1304,15 +1305,15 @@ void Discreet3DSImporter::ParseColorChunk(aiColor3D *out, bool acceptPercent) {
return;
}
const ai_real invVal = ai_real(1.0) / ai_real(255.0);
out->r = (ai_real)(uint8_t)mStream->GetI1() * invVal;
out->g = (ai_real)(uint8_t)mStream->GetI1() * invVal;
out->b = (ai_real)(uint8_t)mStream->GetI1() * invVal;
out->r = (ai_real)(uint8_t)stream->GetI1() * invVal;
out->g = (ai_real)(uint8_t)stream->GetI1() * invVal;
out->b = (ai_real)(uint8_t)stream->GetI1() * invVal;
} break;
// Percentage chunks are accepted, too.
case Discreet3DS::CHUNK_PERCENTF:
if (acceptPercent && 4 <= diff) {
out->g = out->b = out->r = mStream->GetF4();
out->g = out->b = out->r = stream->GetF4();
break;
}
*out = clrError;
@@ -1320,14 +1321,14 @@ void Discreet3DSImporter::ParseColorChunk(aiColor3D *out, bool acceptPercent) {
case Discreet3DS::CHUNK_PERCENTW:
if (acceptPercent && 1 <= diff) {
out->g = out->b = out->r = (ai_real)(uint8_t)mStream->GetI1() / ai_real(255.0);
out->g = out->b = out->r = (ai_real)(uint8_t)stream->GetI1() / ai_real(255.0);
break;
}
*out = clrError;
return;
default:
mStream->IncPtr(diff);
stream->IncPtr(diff);
// Skip unknown chunks, hope this won't cause any problems.
return ParseColorChunk(out, acceptPercent);
};
+35 -24
View File
@@ -49,6 +49,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/BaseImporter.h>
#include <assimp/types.h>
#include "3DSHelper.h"
#include <assimp/StreamReader.h>
@@ -56,6 +57,8 @@ struct aiNode;
namespace Assimp {
using namespace D3DS;
// ---------------------------------------------------------------------------------
/** Importer class for 3D Studio r3 and r4 3DS files
*/
@@ -96,14 +99,15 @@ protected:
// -------------------------------------------------------------------
/** Converts a temporary material to the outer representation
*/
void ConvertMaterial(D3DS::Material& p_cMat, aiMaterial& p_pcOut);
void ConvertMaterial(D3DS::Material& p_cMat,
aiMaterial& p_pcOut);
// -------------------------------------------------------------------
/** Read a chunk
*
* @param pcOut Receives the current chunk
*/
void ReadChunk(D3DS::Discreet3DS::Chunk* pcOut);
void ReadChunk(Discreet3DS::Chunk* pcOut);
// -------------------------------------------------------------------
/** Parse a percentage chunk. mCurrent will point to the next
@@ -113,10 +117,12 @@ protected:
ai_real ParsePercentageChunk();
// -------------------------------------------------------------------
/** Parse a color chunk. mCurrent will point to the next chunk behind
* afterward. If no color chunk is found QNAN is returned in all members.
*/
void ParseColorChunk(aiColor3D* p_pcOut, bool p_bAcceptPercent = true);
/** Parse a color chunk. mCurrent will point to the next
* chunk behind afterwards. If no color chunk is found
* QNAN is returned in all members.
*/
void ParseColorChunk(aiColor3D* p_pcOut,
bool p_bAcceptPercent = true);
// -------------------------------------------------------------------
/** Skip a chunk in the file
@@ -124,7 +130,7 @@ protected:
void SkipChunk();
// -------------------------------------------------------------------
/** Generate the node-graph
/** Generate the nodegraph
*/
void GenerateNodeGraph(aiScene* pcOut);
@@ -220,19 +226,19 @@ protected:
// -------------------------------------------------------------------
/** Add a node to the node graph
*/
void AddNodeToGraph(aiScene* pcSOut,aiNode* pcOut, D3DS::Node* pcIn,
void AddNodeToGraph(aiScene* pcSOut,aiNode* pcOut,D3DS::Node* pcIn,
aiMatrix4x4& absTrafo);
// -------------------------------------------------------------------
/** Search for a node in the graph.
* Called recursively
*/
void InverseNodeSearch(D3DS::Node* pcNode, D3DS::Node* pcCurrent);
void InverseNodeSearch(D3DS::Node* pcNode,D3DS::Node* pcCurrent);
// -------------------------------------------------------------------
/** Apply the master scaling factor to the mesh
*/
void ApplyMasterScale(const aiScene* pScene);
void ApplyMasterScale(aiScene* pScene);
// -------------------------------------------------------------------
/** Clamp all indices in the file to a valid range
@@ -244,26 +250,31 @@ protected:
*/
void SkipTCBInfo();
private:
/// Stream to read from
StreamReaderLE* mStream;
/// Last touched node index
protected:
/** Stream to read from */
StreamReaderLE* stream;
/** Last touched node index */
short mLastNodeIndex;
/// Current node
D3DS::Node* mCurrentNode;
/// Root node
D3DS::Node *mRootNode;
/// Scene under construction
/** Current node, root node */
D3DS::Node* mCurrentNode, *mRootNode;
/** Scene under construction */
D3DS::Scene* mScene;
/// Ambient base color of the scene
/** Ambient base color of the scene */
aiColor3D mClrAmbient;
/// Master scaling factor of the scene
/** Master scaling factor of the scene */
ai_real mMasterScale;
/// Path to the background image of the scene
/** Path to the background image of the scene */
std::string mBackgroundImage;
/// true for has a background
bool bHasBG;
/// true if PRJ file
/** true if PRJ file */
bool bIsPrj;
};
+27 -16
View File
@@ -49,7 +49,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
struct aiMaterial;
struct aiMesh;
namespace Assimp:: D3MF {
namespace Assimp {
namespace D3MF {
enum class ResourceType {
RT_Object,
@@ -64,7 +65,8 @@ class Resource {
public:
int mId;
explicit Resource(int id) : mId(id) {
Resource(int id) :
mId(id) {
// empty
}
@@ -75,7 +77,7 @@ public:
}
};
class EmbeddedTexture final : public Resource {
class EmbeddedTexture : public Resource {
public:
std::string mPath;
std::string mContentType;
@@ -83,7 +85,12 @@ public:
std::string mTilestyleV;
std::vector<char> mBuffer;
explicit EmbeddedTexture(int id) : Resource(id) {
EmbeddedTexture(int id) :
Resource(id),
mPath(),
mContentType(),
mTilestyleU(),
mTilestyleV() {
// empty
}
@@ -94,12 +101,13 @@ public:
}
};
class Texture2DGroup final : public Resource {
class Texture2DGroup : public Resource {
public:
std::vector<aiVector2D> mTex2dCoords;
int mTexId;
explicit Texture2DGroup(int id) : Resource(id), mTexId(-1) {
Texture2DGroup(int id) :
Resource(id),
mTexId(-1) {
// empty
}
@@ -110,11 +118,11 @@ public:
}
};
class ColorGroup final : public Resource {
class ColorGroup : public Resource {
public:
std::vector<aiColor4D> mColors;
explicit ColorGroup(int id) : Resource(id) {
ColorGroup(int id) :
Resource(id){
// empty
}
@@ -125,11 +133,13 @@ public:
}
};
class BaseMaterials final : public Resource {
class BaseMaterials : public Resource {
public:
std::vector<unsigned int> mMaterialIndex;
explicit BaseMaterials(int id) : Resource(id) {
BaseMaterials(int id) :
Resource(id),
mMaterialIndex() {
// empty
}
@@ -145,14 +155,14 @@ struct Component {
aiMatrix4x4 mTransformation;
};
class Object final : public Resource {
class Object : public Resource {
public:
std::vector<aiMesh *> mMeshes;
MeshArray mMeshes;
std::vector<unsigned int> mMeshIndex;
std::vector<Component> mComponents;
std::string mName;
explicit Object(int id) :
Object(int id) :
Resource(id),
mName(std::string("Object_") + ai_to_string(id)) {
// empty
@@ -165,4 +175,5 @@ public:
}
};
} // namespace Assimp::D3MF
} // namespace D3MF
} // namespace Assimp
+70 -65
View File
@@ -40,80 +40,85 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#pragma once
namespace Assimp::D3MF::XmlTag {
namespace Assimp {
namespace D3MF {
namespace XmlTag {
// Root tag
constexpr char RootTag[] = "3MF";
const char* const RootTag = "3MF";
// Meta-data
constexpr char meta[] = "metadata";
constexpr char meta_name[] = "name";
const char* const meta = "metadata";
const char* const meta_name = "name";
// Model-data specific tags
constexpr char model[] = "model";
constexpr char model_unit[] = "unit";
constexpr char metadata[] = "metadata";
constexpr char resources[] = "resources";
constexpr char object[] = "object";
constexpr char mesh[] = "mesh";
constexpr char components[] = "components";
constexpr char component[] = "component";
constexpr char vertices[] = "vertices";
constexpr char vertex[] = "vertex";
constexpr char triangles[] = "triangles";
constexpr char triangle[] = "triangle";
constexpr char x[] = "x";
constexpr char y[] = "y";
constexpr char z[] = "z";
constexpr char v1[] = "v1";
constexpr char v2[] = "v2";
constexpr char v3[] = "v3";
constexpr char id[] = "id";
constexpr char pid[] = "pid";
constexpr char pindex[] = "pindex";
constexpr char p1[] = "p1";
constexpr char p2[] = "p2";
constexpr char p3[] = "p3";
constexpr char name[] = "name";
constexpr char type[] = "type";
constexpr char build[] = "build";
constexpr char item[] = "item";
constexpr char objectid[] = "objectid";
constexpr char transform[] = "transform";
constexpr char path[] = "path";
const char* const model = "model";
const char* const model_unit = "unit";
const char* const metadata = "metadata";
const char* const resources = "resources";
const char* const object = "object";
const char* const mesh = "mesh";
const char* const components = "components";
const char* const component = "component";
const char* const vertices = "vertices";
const char* const vertex = "vertex";
const char* const triangles = "triangles";
const char* const triangle = "triangle";
const char* const x = "x";
const char* const y = "y";
const char* const z = "z";
const char* const v1 = "v1";
const char* const v2 = "v2";
const char* const v3 = "v3";
const char* const id = "id";
const char* const pid = "pid";
const char* const pindex = "pindex";
const char* const p1 = "p1";
const char *const p2 = "p2";
const char *const p3 = "p3";
const char* const name = "name";
const char* const type = "type";
const char* const build = "build";
const char* const item = "item";
const char* const objectid = "objectid";
const char* const transform = "transform";
const char *const path = "path";
// Material definitions
constexpr char basematerials[] = "basematerials";
constexpr char basematerials_base[] = "base";
constexpr char basematerials_name[] = "name";
constexpr char basematerials_displaycolor[] = "displaycolor";
constexpr char texture_2d[] = "m:texture2d";
constexpr char texture_group[] = "m:texture2dgroup";
constexpr char texture_content_type[] = "contenttype";
constexpr char texture_tilestyleu[] = "tilestyleu";
constexpr char texture_tilestylev[] = "tilestylev";
constexpr char texture_2d_coord[] = "m:tex2coord";
constexpr char texture_cuurd_u[] = "u";
constexpr char texture_cuurd_v[] = "v";
const char* const basematerials = "basematerials";
const char* const basematerials_base = "base";
const char* const basematerials_name = "name";
const char* const basematerials_displaycolor = "displaycolor";
const char* const texture_2d = "m:texture2d";
const char *const texture_group = "m:texture2dgroup";
const char *const texture_content_type = "contenttype";
const char *const texture_tilestyleu = "tilestyleu";
const char *const texture_tilestylev = "tilestylev";
const char *const texture_2d_coord = "m:tex2coord";
const char *const texture_cuurd_u = "u";
const char *const texture_cuurd_v = "v";
// vertex color definitions
constexpr char colorgroup[] = "m:colorgroup";
constexpr char color_item[] = "m:color";
constexpr char color_value[] = "color";
const char *const colorgroup = "m:colorgroup";
const char *const color_item = "m:color";
const char *const color_vaule = "color";
// Meta info tags
constexpr char CONTENT_TYPES_ARCHIVE[] = "[Content_Types].xml";
constexpr char ROOT_RELATIONSHIPS_ARCHIVE[] = "_rels/.rels";
constexpr char SCHEMA_CONTENTTYPES[] = "http://schemas.openxmlformats.org/package/2006/content-types";
constexpr char SCHEMA_RELATIONSHIPS[] = "http://schemas.openxmlformats.org/package/2006/relationships";
constexpr char RELS_RELATIONSHIP_CONTAINER[] = "Relationships";
constexpr char RELS_RELATIONSHIP_NODE[] = "Relationship";
constexpr char RELS_ATTRIB_TARGET[] = "Target";
constexpr char RELS_ATTRIB_TYPE[] = "Type";
constexpr char RELS_ATTRIB_ID[] = "Id";
constexpr char PACKAGE_START_PART_RELATIONSHIP_TYPE[] = "http://schemas.microsoft.com/3dmanufacturing/2013/01/3dmodel";
constexpr char PACKAGE_PRINT_TICKET_RELATIONSHIP_TYPE[] = "http://schemas.microsoft.com/3dmanufacturing/2013/01/printticket";
constexpr char PACKAGE_TEXTURE_RELATIONSHIP_TYPE[] = "http://schemas.microsoft.com/3dmanufacturing/2013/01/3dtexture";
constexpr char PACKAGE_CORE_PROPERTIES_RELATIONSHIP_TYPE[] = "http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties";
constexpr char PACKAGE_THUMBNAIL_RELATIONSHIP_TYPE[] = "http://schemas.openxmlformats.org/package/2006/relationships/metadata/thumbnail";
const char* const CONTENT_TYPES_ARCHIVE = "[Content_Types].xml";
const char* const ROOT_RELATIONSHIPS_ARCHIVE = "_rels/.rels";
const char* const SCHEMA_CONTENTTYPES = "http://schemas.openxmlformats.org/package/2006/content-types";
const char* const SCHEMA_RELATIONSHIPS = "http://schemas.openxmlformats.org/package/2006/relationships";
const char* const RELS_RELATIONSHIP_CONTAINER = "Relationships";
const char* const RELS_RELATIONSHIP_NODE = "Relationship";
const char* const RELS_ATTRIB_TARGET = "Target";
const char* const RELS_ATTRIB_TYPE = "Type";
const char* const RELS_ATTRIB_ID = "Id";
const char* const PACKAGE_START_PART_RELATIONSHIP_TYPE = "http://schemas.microsoft.com/3dmanufacturing/2013/01/3dmodel";
const char* const PACKAGE_PRINT_TICKET_RELATIONSHIP_TYPE = "http://schemas.microsoft.com/3dmanufacturing/2013/01/printticket";
const char* const PACKAGE_TEXTURE_RELATIONSHIP_TYPE = "http://schemas.microsoft.com/3dmanufacturing/2013/01/3dtexture";
const char* const PACKAGE_CORE_PROPERTIES_RELATIONSHIP_TYPE = "http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties";
const char* const PACKAGE_THUMBNAIL_RELATIONSHIP_TYPE = "http://schemas.openxmlformats.org/package/2006/relationships/metadata/thumbnail";
}
} // namespace Assimp::D3MF
} // Namespace D3MF
} // Namespace Assimp
+2 -1
View File
@@ -48,6 +48,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/scene.h>
#include <assimp/DefaultLogger.hpp>
#include <assimp/Exporter.hpp>
#include <assimp/IOStream.hpp>
#include <assimp/IOSystem.hpp>
#include "3MFXmlTags.h"
@@ -93,7 +94,7 @@ D3MFExporter::~D3MFExporter() {
mRelations.clear();
}
bool D3MFExporter::validate() const {
bool D3MFExporter::validate() {
if (mArchiveName.empty()) {
return false;
}
+1 -1
View File
@@ -68,7 +68,7 @@ class D3MFExporter {
public:
D3MFExporter( const char* pFile, const aiScene* pScene );
~D3MFExporter();
bool validate() const;
bool validate();
bool exportArchive( const char *file );
bool exportContentTypes();
bool exportRelations();
+1 -1
View File
@@ -53,7 +53,7 @@ namespace Assimp {
///
/// Implements the basic topology import and embedded textures.
// ---------------------------------------------------------------------------
class D3MFImporter final : public BaseImporter {
class D3MFImporter : public BaseImporter {
public:
/// @brief The default class constructor.
D3MFImporter() = default;
+11 -8
View File
@@ -58,16 +58,16 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <map>
#include <vector>
namespace Assimp {
namespace Assimp::D3MF {
namespace D3MF {
// ------------------------------------------------------------------------------------------------
using OpcPackageRelationshipPtr = std::shared_ptr<OpcPackageRelationship>;
class OpcPackageRelationshipReader final {
class OpcPackageRelationshipReader {
public:
explicit OpcPackageRelationshipReader(XmlParser &parser) : mRelations() {
OpcPackageRelationshipReader(XmlParser &parser) :
mRelations() {
XmlNode root = parser.getRootNode();
ParseRootNode(root);
}
@@ -131,9 +131,11 @@ static bool IsEmbeddedTexture( const std::string &filename ) {
// ------------------------------------------------------------------------------------------------
D3MFOpcPackage::D3MFOpcPackage(IOSystem *pIOHandler, const std::string &rFile) :
mRootStream(nullptr),
mZipArchive() {
mZipArchive(nullptr) {
mZipArchive = new ZipArchiveIOSystem(pIOHandler, rFile);
if (!mZipArchive->isOpen()) {
delete mZipArchive;
mZipArchive = nullptr;
throw DeadlyImportError("Failed to open file ", rFile, ".");
}
@@ -183,7 +185,9 @@ D3MFOpcPackage::D3MFOpcPackage(IOSystem *pIOHandler, const std::string &rFile) :
}
D3MFOpcPackage::~D3MFOpcPackage() {
mZipArchive->Close(mRootStream);
if (mRootStream && mZipArchive) {
mZipArchive->Close(mRootStream);
}
delete mZipArchive;
}
@@ -249,7 +253,6 @@ void D3MFOpcPackage::LoadEmbeddedTextures(IOStream *fileStream, const std::strin
mEmbeddedTextures.emplace_back(texture);
}
} // Namespace D3MF
} // Namespace Assimp
} // Namespace Assimp::D3MF
#endif //ASSIMP_BUILD_NO_3MF_IMPORTER
+8 -2
View File
@@ -495,13 +495,16 @@ void XmlSerializer::ImportTriangles(XmlNode &node, aiMesh *mesh) {
}
mesh->mTextureCoords[0] = new aiVector3D[mesh->mNumVertices];
for (unsigned int vertex_index = 0; vertex_index < mesh->mNumVertices; vertex_index++) {
mesh->mTextureCoords[0][vertex_index].z = IdNotSet;//mark not set
mesh->mTextureCoords[0][vertex_index].z = IdNotSet; //mark not set
}
}
auto update_texture = [&](int idx) {
if (pindex[idx] != IdNotSet) {
size_t vertex_index = face.mIndices[idx];
if (vertex_index >= mesh->mNumVertices) {
return;
}
mesh->mTextureCoords[0][vertex_index] =
aiVector3D(group->mTex2dCoords[pindex[idx]].x, group->mTex2dCoords[pindex[idx]].y, 0.0f);
}
@@ -521,6 +524,9 @@ void XmlSerializer::ImportTriangles(XmlNode &node, aiMesh *mesh) {
auto update_color = [&](int idx) {
if (pindex[idx] != IdNotSet) {
size_t vertex_index = face.mIndices[idx];
if (vertex_index >= mesh->mNumVertices) {
return;
}
mesh->mColors[0][vertex_index] = group->mColors[pindex[idx]];
}
};
@@ -680,7 +686,7 @@ void XmlSerializer::ReadColor(XmlNode &node, ColorGroup *colorGroup) {
for (XmlNode currentNode : node.children()) {
const std::string currentName = currentNode.name();
if (currentName == XmlTag::color_item) {
const char *color = currentNode.attribute(XmlTag::color_value).as_string();
const char *color = currentNode.attribute(XmlTag::color_vaule).as_string();
aiColor4D color_value;
if (parseColor(color, color_value)) {
colorGroup->mColors.push_back(color_value);
+1 -2
View File
@@ -59,10 +59,9 @@ class Texture2DGroup;
class EmbeddedTexture;
class ColorGroup;
/// @brief his class implements ther 3mf serialization.
class XmlSerializer final {
public:
explicit XmlSerializer(XmlParser &xmlParser);
XmlSerializer(XmlParser &xmlParser);
~XmlSerializer();
void ImportXml(aiScene *scene);
+3 -3
View File
@@ -418,7 +418,7 @@ void AC3DImporter::ConvertMaterial(const Object &object,
// ------------------------------------------------------------------------------------------------
// Converts the loaded data to the internal verbose representation
aiNode *AC3DImporter::ConvertObjectSection(Object &object,
std::vector<aiMesh *> &meshes,
MeshArray &meshes,
std::vector<aiMaterial *> &outMaterials,
const std::vector<Material> &materials,
aiNode *parent) {
@@ -710,7 +710,7 @@ aiNode *AC3DImporter::ConvertObjectSection(Object &object,
std::unique_ptr<Subdivider> div(Subdivider::Create(Subdivider::CATMULL_CLARKE));
ASSIMP_LOG_INFO("AC3D: Evaluating subdivision surface: ", object.name);
std::vector<aiMesh *> cpy(meshes.size() - oldm, nullptr);
MeshArray cpy(meshes.size() - oldm, nullptr);
div->Subdivide(&meshes[oldm], cpy.size(), &cpy.front(), object.subDiv, true);
std::copy(cpy.begin(), cpy.end(), meshes.begin() + oldm);
@@ -846,7 +846,7 @@ void AC3DImporter::InternReadFile(const std::string &pFile,
}
mNumMeshes += (mNumMeshes >> 2u) + 1;
std::vector<aiMesh *> meshes;
MeshArray meshes;
meshes.reserve(mNumMeshes);
std::vector<aiMaterial *> omaterials;
+2 -2
View File
@@ -60,7 +60,7 @@ namespace Assimp {
// ---------------------------------------------------------------------------
/** AC3D (*.ac) importer class
*/
class AC3DImporter final : public BaseImporter {
class AC3DImporter : public BaseImporter {
public:
AC3DImporter();
~AC3DImporter() override = default;
@@ -226,7 +226,7 @@ private:
* @param materials Material list
* @param Scenegraph node for the object */
aiNode *ConvertObjectSection(Object &object,
std::vector<aiMesh *> &meshes,
MeshArray &meshes,
std::vector<aiMaterial *> &outMaterials,
const std::vector<Material> &materials,
aiNode *parent = nullptr);
+2 -1
View File
@@ -327,7 +327,8 @@ void AMFImporter::ParseNode_Root() {
// Multi elements - Yes.
// Parent element - <amf>.
void AMFImporter::ParseNode_Constellation(XmlNode &node) {
std::string id = node.attribute("id").as_string();
std::string id;
id = node.attribute("id").as_string();
// create and if needed - define new grouping object.
AMFNodeElementBase *ne = new AMFConstellation(mNodeElement_Cur);
+1 -3
View File
@@ -97,10 +97,8 @@ namespace Assimp {
/// new - <texmap> and children <utex1>, <utex2>, <utex3>, <vtex1>, <vtex2>, <vtex3>
/// old - <map> and children <u1>, <u2>, <u3>, <v1>, <v2>, <v3>
///
class AMFImporter final : public BaseImporter {
class AMFImporter : public BaseImporter {
using AMFMetaDataArray = std::vector<AMFMetadata *>;
using MeshArray = std::vector<aiMesh *>;
using NodeArray = std::vector<aiNode *>;
public:
struct SPP_Material;
+31 -48
View File
@@ -107,16 +107,16 @@ protected:
}; // class IAMFImporter_NodeElement
/// A collection of objects or constellations with specific relative locations.
struct AMFConstellation final : public AMFNodeElementBase {
struct AMFConstellation : public AMFNodeElementBase {
/// Constructor.
/// \param [in] pParent - pointer to parent node.
explicit AMFConstellation(AMFNodeElementBase *pParent) :
AMFConstellation(AMFNodeElementBase *pParent) :
AMFNodeElementBase(ENET_Constellation, pParent) {}
}; // struct CAMFImporter_NodeElement_Constellation
/// Part of constellation.
struct AMFInstance final : public AMFNodeElementBase {
struct AMFInstance : public AMFNodeElementBase {
std::string ObjectID; ///< ID of object for instantiation.
/// \var Delta - The distance of translation in the x, y, or z direction, respectively, in the referenced object's coordinate system, to
@@ -129,7 +129,7 @@ struct AMFInstance final : public AMFNodeElementBase {
/// Constructor.
/// \param [in] pParent - pointer to parent node.
explicit AMFInstance(AMFNodeElementBase *pParent) :
AMFInstance(AMFNodeElementBase *pParent) :
AMFNodeElementBase(ENET_Instance, pParent) {}
};
@@ -141,10 +141,8 @@ struct AMFMetadata : public AMFNodeElementBase {
/// Constructor.
/// \param [in] pParent - pointer to parent node.
explicit AMFMetadata(AMFNodeElementBase *pParent) :
AMFNodeElementBase(ENET_Metadata, pParent) {
// empty
}
AMFMetadata(AMFNodeElementBase *pParent) :
AMFNodeElementBase(ENET_Metadata, pParent) {}
};
/// Structure that define root node.
@@ -155,10 +153,8 @@ struct AMFRoot : public AMFNodeElementBase {
/// Constructor.
/// \param [in] pParent - pointer to parent node.
explicit AMFRoot(AMFNodeElementBase *pParent) :
AMFNodeElementBase(ENET_Root, pParent) {
// empty
}
AMFRoot(AMFNodeElementBase *pParent) :
AMFNodeElementBase(ENET_Root, pParent) {}
};
/// Structure that define object node.
@@ -170,7 +166,7 @@ struct AMFColor : public AMFNodeElementBase {
/// @brief Constructor.
/// @param [in] pParent - pointer to parent node.
explicit AMFColor(AMFNodeElementBase *pParent) :
AMFColor(AMFNodeElementBase *pParent) :
AMFNodeElementBase(ENET_Color, pParent), Composed(false), Color() {
// empty
}
@@ -178,62 +174,53 @@ struct AMFColor : public AMFNodeElementBase {
/// Structure that define material node.
struct AMFMaterial : public AMFNodeElementBase {
/// Constructor.
/// \param [in] pParent - pointer to parent node.
explicit AMFMaterial(AMFNodeElementBase *pParent) :
AMFNodeElementBase(ENET_Material, pParent) {
// empty
}
AMFMaterial(AMFNodeElementBase *pParent) :
AMFNodeElementBase(ENET_Material, pParent) {}
};
/// Structure that define object node.
struct AMFObject : public AMFNodeElementBase {
/// Constructor.
/// \param [in] pParent - pointer to parent node.
explicit AMFObject(AMFNodeElementBase *pParent) :
AMFNodeElementBase(ENET_Object, pParent) {
// empty
}
AMFObject(AMFNodeElementBase *pParent) :
AMFNodeElementBase(ENET_Object, pParent) {}
};
/// \struct CAMFImporter_NodeElement_Mesh
/// Structure that define mesh node.
struct AMFMesh : public AMFNodeElementBase {
/// Constructor.
/// \param [in] pParent - pointer to parent node.
explicit AMFMesh(AMFNodeElementBase *pParent) :
AMFNodeElementBase(ENET_Mesh, pParent) {
// empty
}
AMFMesh(AMFNodeElementBase *pParent) :
AMFNodeElementBase(ENET_Mesh, pParent) {}
};
/// Structure that define vertex node.
struct AMFVertex : public AMFNodeElementBase {
/// Constructor.
/// \param [in] pParent - pointer to parent node.
explicit AMFVertex(AMFNodeElementBase *pParent) :
AMFNodeElementBase(ENET_Vertex, pParent) {
// empty
}
AMFVertex(AMFNodeElementBase *pParent) :
AMFNodeElementBase(ENET_Vertex, pParent) {}
};
/// Structure that define edge node.
struct AMFEdge : public AMFNodeElementBase {
/// Constructor.
/// \param [in] pParent - pointer to parent node.
explicit AMFEdge(AMFNodeElementBase *pParent) :
AMFNodeElementBase(ENET_Edge, pParent) {
// empty
}
AMFEdge(AMFNodeElementBase *pParent) :
AMFNodeElementBase(ENET_Edge, pParent) {}
};
/// Structure that define vertices node.
struct AMFVertices : public AMFNodeElementBase {
/// Constructor.
/// \param [in] pParent - pointer to parent node.
explicit AMFVertices(AMFNodeElementBase *pParent) :
AMFNodeElementBase(ENET_Vertices, pParent) {
// empty
}
AMFVertices(AMFNodeElementBase *pParent) :
AMFNodeElementBase(ENET_Vertices, pParent) {}
};
/// Structure that define volume node.
@@ -243,10 +230,8 @@ struct AMFVolume : public AMFNodeElementBase {
/// Constructor.
/// \param [in] pParent - pointer to parent node.
explicit AMFVolume(AMFNodeElementBase *pParent) :
AMFNodeElementBase(ENET_Volume, pParent) {
// empty
}
AMFVolume(AMFNodeElementBase *pParent) :
AMFNodeElementBase(ENET_Volume, pParent) {}
};
/// Structure that define coordinates node.
@@ -255,10 +240,8 @@ struct AMFCoordinates : public AMFNodeElementBase {
/// Constructor.
/// \param [in] pParent - pointer to parent node.
explicit AMFCoordinates(AMFNodeElementBase *pParent) :
AMFNodeElementBase(ENET_Coordinates, pParent) {
// empty
}
AMFCoordinates(AMFNodeElementBase *pParent) :
AMFNodeElementBase(ENET_Coordinates, pParent) {}
};
/// Structure that define texture coordinates node.
@@ -271,7 +254,7 @@ struct AMFTexMap : public AMFNodeElementBase {
/// Constructor.
/// \param [in] pParent - pointer to parent node.
explicit AMFTexMap(AMFNodeElementBase *pParent) :
AMFTexMap(AMFNodeElementBase *pParent) :
AMFNodeElementBase(ENET_TexMap, pParent), TextureCoordinate{} {
// empty
}
@@ -283,7 +266,7 @@ struct AMFTriangle : public AMFNodeElementBase {
/// Constructor.
/// \param [in] pParent - pointer to parent node.
explicit AMFTriangle(AMFNodeElementBase *pParent) :
AMFTriangle(AMFNodeElementBase *pParent) :
AMFNodeElementBase(ENET_Triangle, pParent) {
// empty
}
@@ -297,7 +280,7 @@ struct AMFTexture : public AMFNodeElementBase {
/// Constructor.
/// \param [in] pParent - pointer to parent node.
explicit AMFTexture(AMFNodeElementBase *pParent) :
AMFTexture(AMFNodeElementBase *pParent) :
AMFNodeElementBase(ENET_Texture, pParent), Width(0), Height(0), Depth(0), Data(), Tiled(false) {
// empty
}
@@ -57,6 +57,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
namespace Assimp {
aiColor4D AMFImporter::SPP_Material::GetColor(const float /*pX*/, const float /*pY*/, const float /*pZ*/) const {
aiColor4D tcol;
// Check if stored data are supported.
if (!Composition.empty()) {
throw DeadlyImportError("IME. GetColor for composition");
@@ -66,7 +68,7 @@ aiColor4D AMFImporter::SPP_Material::GetColor(const float /*pX*/, const float /*
throw DeadlyImportError("IME. GetColor, composed color");
}
aiColor4D tcol = Color->Color;
tcol = Color->Color;
// Check if default color must be used
if ((tcol.r == 0) && (tcol.g == 0) && (tcol.b == 0) && (tcol.a == 0)) {
@@ -530,9 +532,11 @@ void AMFImporter::Postprocess_BuildMeshSet(const AMFMesh &pNodeElement, const st
col_arr.reserve(VertexCount_Max * 2);
{ // fill arrays
size_t vert_idx_from, vert_idx_to;
// first iteration.
size_t vert_idx_to = 0;
size_t vert_idx_from = VertexIndex_GetMinimal(face_list_cur, nullptr);
vert_idx_to = 0;
vert_idx_from = VertexIndex_GetMinimal(face_list_cur, nullptr);
vert_arr.push_back(pVertexCoordinateArray.at(vert_idx_from));
col_arr.push_back(Vertex_CalculateColor(vert_idx_from));
if (vert_idx_from != vert_idx_to) VertexIndex_Replace(face_list_cur, vert_idx_from, vert_idx_to);
+5 -4
View File
@@ -162,7 +162,7 @@ void ASEImporter::InternReadFile(const std::string &pFile,
// process all meshes
bool tookNormals = false;
std::vector<aiMesh *> avOutMeshes;
MeshArray avOutMeshes;
avOutMeshes.reserve(mParser->m_vMeshes.size() * 2);
for (std::vector<ASE::Mesh>::iterator i = mParser->m_vMeshes.begin(); i != mParser->m_vMeshes.end(); ++i) {
if ((*i).bSkip) {
@@ -187,7 +187,7 @@ void ASEImporter::InternReadFile(const std::string &pFile,
// Now build the output mesh list. Remove dummies
pScene->mNumMeshes = (unsigned int)avOutMeshes.size();
aiMesh **pp = pScene->mMeshes = new aiMesh *[pScene->mNumMeshes];
for (std::vector<aiMesh *>::const_iterator i = avOutMeshes.begin(); i != avOutMeshes.end(); ++i) {
for (MeshArray::const_iterator i = avOutMeshes.begin(); i != avOutMeshes.end(); ++i) {
if (!(*i)->mNumFaces) {
continue;
}
@@ -902,7 +902,7 @@ void ASEImporter::ConvertMaterial(ASE::Material &mat) {
// ------------------------------------------------------------------------------------------------
// Build output meshes
void ASEImporter::ConvertMeshes(ASE::Mesh &mesh, std::vector<aiMesh *> &avOutMeshes) {
void ASEImporter::ConvertMeshes(ASE::Mesh &mesh, MeshArray &avOutMeshes) {
// validate the material index of the mesh
if (mesh.iMaterialIndex >= mParser->m_vMaterials.size()) {
mesh.iMaterialIndex = (unsigned int)mParser->m_vMaterials.size() - 1;
@@ -1270,4 +1270,5 @@ bool ASEImporter::GenerateNormals(ASE::Mesh &mesh) {
}
#endif // ASSIMP_BUILD_NO_3DS_IMPORTER
#endif // ASSIMP_BUILD_NO_ASE_IMPORTER
#endif // !! ASSIMP_BUILD_NO_BASE_IMPORTER
+1 -1
View File
@@ -59,7 +59,7 @@ namespace Assimp {
/** Importer class for the 3DS ASE ASCII format.
*
*/
class ASEImporter final : public BaseImporter {
class ASEImporter : public BaseImporter {
public:
ASEImporter();
~ASEImporter() override = default;
+8 -6
View File
@@ -57,13 +57,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// ASE is quite similar to 3ds. We can reuse some structures
#include "AssetLib/3DS/3DSLoader.h"
namespace Assimp::ASE {
namespace Assimp {
namespace ASE {
using namespace D3DS;
// ---------------------------------------------------------------------------
/** Helper structure representing an ASE material */
struct Material final : D3DS::Material {
struct Material : public D3DS::Material {
//! Default constructor has been deleted
Material() = delete;
@@ -114,7 +115,7 @@ struct Material final : D3DS::Material {
return *this;
}
~Material() override = default;
~Material() = default;
//! Contains all sub materials of this material
std::vector<Material> avSubMaterials;
@@ -372,8 +373,8 @@ struct Dummy : public BaseNode {
};
// Parameters to Parser::Parse()
static constexpr unsigned int AI_ASE_NEW_FILE_FORMAT = 200;
static constexpr unsigned int AI_ASE_OLD_FILE_FORMAT = 110;
#define AI_ASE_NEW_FILE_FORMAT 200
#define AI_ASE_OLD_FILE_FORMAT 110
// Internally we're a little bit more tolerant
#define AI_ASE_IS_NEW_FILE_FORMAT() (iFileFormat >= 200)
@@ -667,7 +668,8 @@ public:
unsigned int iFileFormat;
};
} // Namespace Assimp::ASE
} // Namespace ASE
} // namespace Assimp
#endif // ASSIMP_BUILD_NO_3DS_IMPORTER
+23 -23
View File
@@ -239,7 +239,29 @@ inline size_t WriteArray(IOStream *stream, const T *in, unsigned int size) {
* and the chunk contents to the container stream. This allows relatively easy chunk
* chunk construction, even recursively.
*/
class AssbinChunkWriter final : public IOStream {
class AssbinChunkWriter : public IOStream {
private:
uint8_t *buffer;
uint32_t magic;
IOStream *container;
size_t cur_size, cursor, initial;
private:
// -------------------------------------------------------------------
void Grow(size_t need = 0) {
size_t new_size = std::max(initial, std::max(need, cur_size + (cur_size >> 1)));
const uint8_t *const old = buffer;
buffer = new uint8_t[new_size];
if (old) {
memcpy(buffer, old, cur_size);
delete[] old;
}
cur_size = new_size;
}
public:
AssbinChunkWriter(IOStream *container, uint32_t magic, size_t initial = 4096) :
buffer(nullptr),
@@ -293,28 +315,6 @@ public:
return pCount;
}
private:
// -------------------------------------------------------------------
void Grow(size_t need = 0) {
size_t new_size = std::max(initial, std::max(need, cur_size + (cur_size >> 1)));
const uint8_t *const old = buffer;
buffer = new uint8_t[new_size];
if (old) {
memcpy(buffer, old, cur_size);
delete[] old;
}
cur_size = new_size;
}
private:
uint8_t *buffer;
uint32_t magic;
IOStream *container;
size_t cur_size, cursor, initial;
};
// ----------------------------------------------------------------------------------
+4 -7
View File
@@ -77,7 +77,8 @@ static int ioprintf(IOStream *io, const char *format, ...) {
}
static const int Size = 4096;
char sz[Size] = {};
char sz[Size];
::memset(sz, '\0', Size);
va_list va;
va_start(va, format);
const unsigned int nSize = vsnprintf(sz, Size - 1, format, va);
@@ -301,11 +302,7 @@ static void WriteDump(const char *pFile, const char *cmd, const aiScene *scene,
bool compressed = (tex->mHeight == 0);
// mesh header
std::string texName = "unknown";
if (tex->mFilename.length != 0u) {
texName = tex->mFilename.data;
}
ioprintf(io, "\t<Texture name=\"%s\" width=\"%u\" height=\"%u\" compressed=\"%s\"> \n", texName.c_str(),
ioprintf(io, "\t<Texture width=\"%u\" height=\"%u\" compressed=\"%s\"> \n",
(compressed ? -1 : tex->mWidth), (compressed ? -1 : tex->mHeight),
(compressed ? "true" : "false"));
@@ -353,7 +350,7 @@ static void WriteDump(const char *pFile, const char *cmd, const aiScene *scene,
for (unsigned int n = 0; n < mat->mNumProperties; ++n) {
const aiMaterialProperty *prop = mat->mProperties[n];
auto sz = "";
const char *sz = "";
if (prop->mType == aiPTI_Float) {
sz = "float";
} else if (prop->mType == aiPTI_Integer) {
+1 -1
View File
@@ -60,7 +60,7 @@ struct aiAnimation;
namespace Assimp{
class B3DImporter final : public BaseImporter{
class B3DImporter : public BaseImporter{
public:
B3DImporter() = default;
~B3DImporter() override;
+1 -1
View File
@@ -61,7 +61,7 @@ namespace Assimp {
* the hierarchy. It contains no actual mesh data, but we generate a dummy mesh
* inside the loader just to be able to see something.
*/
class BVHLoader final : public BaseImporter {
class BVHLoader : public BaseImporter {
/** Possible animation channels for which the motion data holds the values */
enum ChannelType {
+1 -3
View File
@@ -74,9 +74,7 @@ BlenderBMeshConverter::~BlenderBMeshConverter() {
// ------------------------------------------------------------------------------------------------
bool BlenderBMeshConverter::ContainsBMesh() const {
if (BMesh == nullptr) {
return false;
}
// TODO - Should probably do some additional verification here
return BMesh->totpoly && BMesh->totloop && BMesh->totvert;
}
+6 -4
View File
@@ -63,12 +63,14 @@ namespace Assimp
struct MLoop;
}
class BlenderBMeshConverter final : public LogFunctions< BlenderBMeshConverter >
class BlenderBMeshConverter: public LogFunctions< BlenderBMeshConverter >
{
public:
explicit BlenderBMeshConverter( const Blender::Mesh* mesh );
~BlenderBMeshConverter();
bool ContainsBMesh() const;
BlenderBMeshConverter( const Blender::Mesh* mesh );
~BlenderBMeshConverter( );
bool ContainsBMesh( ) const;
const Blender::Mesh* TriangulateBMesh( );
private:
+2 -3
View File
@@ -96,7 +96,7 @@ struct CustomDataTypeDescription {
* other (like CD_ORCO, ...) uses arrays of rawtypes or even arrays of Structures
* use a special readfunction for that cases
*/
static const std::array<CustomDataTypeDescription, CD_NUMTYPES> customDataTypeDescriptions = { {
static std::array<CustomDataTypeDescription, CD_NUMTYPES> customDataTypeDescriptions = { {
DECL_STRUCT_CUSTOMDATATYPEDESCRIPTION(MVert),
DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
@@ -142,8 +142,7 @@ static const std::array<CustomDataTypeDescription, CD_NUMTYPES> customDataTypeDe
DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION
} };
DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION } };
bool isValidCustomDataType(const int cdtype) {
return cdtype >= 0 && cdtype < CD_NUMTYPES;
+59 -34
View File
@@ -55,14 +55,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// enable verbose log output. really verbose, so be careful.
#ifdef ASSIMP_BUILD_DEBUG
# define ASSIMP_BUILD_BLENDER_DEBUG
#define ASSIMP_BUILD_BLENDER_DEBUG
#endif
// set this to non-zero to dump BlenderDNA stuff to dna.txt.
// you could set it on the assimp build command line too without touching it here.
// !!! please make sure this is set to 0 in the repo !!!
#ifndef ASSIMP_BUILD_BLENDER_DEBUG_DNA
# define ASSIMP_BUILD_BLENDER_DEBUG_DNA 0
#define ASSIMP_BUILD_BLENDER_DEBUG_DNA 0
#endif
// #define ASSIMP_BUILD_BLENDER_NO_STATS
@@ -124,14 +124,22 @@ struct ElemBase {
* they used to point to.*/
// -------------------------------------------------------------------------------
struct Pointer {
uint64_t val{0};
Pointer() :
val() {
// empty
}
uint64_t val;
};
// -------------------------------------------------------------------------------
/** Represents a generic offset within a BLEND file */
// -------------------------------------------------------------------------------
struct FileOffset {
uint64_t val{0};
FileOffset() :
val() {
// empty
}
uint64_t val;
};
// -------------------------------------------------------------------------------
@@ -196,7 +204,7 @@ enum ErrorPolicy {
};
#ifdef ASSIMP_BUILD_BLENDER_DEBUG
# define ErrorPolicy_Igno ErrorPolicy_Warn
#define ErrorPolicy_Igno ErrorPolicy_Warn
#endif
// -------------------------------------------------------------------------------
@@ -388,9 +396,10 @@ private:
mutable size_t cache_idx;
};
// -------------------------------------------------------------------------------------------------------
template<>
// --------------------------------------------------------
template <>
struct Structure::_defaultInitializer<ErrorPolicy_Warn> {
template <typename T>
void operator()(T &out, const char *reason = "<add reason>") {
ASSIMP_LOG_WARN(reason);
@@ -400,9 +409,9 @@ struct Structure::_defaultInitializer<ErrorPolicy_Warn> {
}
};
// -------------------------------------------------------------------------------------------------------
template<>
template <>
struct Structure::_defaultInitializer<ErrorPolicy_Fail> {
template <typename T>
void operator()(T & /*out*/, const char *message = "") {
// obviously, it is crucial that _DefaultInitializer is used
@@ -610,23 +619,31 @@ public:
/** Import statistics, i.e. number of file blocks read*/
// -------------------------------------------------------------------------------
class Statistics {
public:
Statistics() = default;
~Statistics() = default;
/// total number of fields we read
public:
Statistics() :
fields_read(), pointers_resolved(), cache_hits()
// , blocks_read ()
,
cached_objects() {}
public:
/** total number of fields we read */
unsigned int fields_read;
/// total number of resolved pointers
/** total number of resolved pointers */
unsigned int pointers_resolved;
/// number of pointers resolved from the cache
/** number of pointers resolved from the cache */
unsigned int cache_hits;
/// objects in FileData::cache
/** number of blocks (from FileDatabase::entries)
we did actually read from. */
// unsigned int blocks_read;
/** objects in FileData::cache */
unsigned int cached_objects;
};
#endif
// -------------------------------------------------------------------------------
@@ -639,13 +656,15 @@ public:
typedef std::map<Pointer, TOUT<ElemBase>> StructureCache;
public:
explicit ObjectCache(const FileDatabase &db) : db(db) {
ObjectCache(const FileDatabase &db) :
db(db) {
// currently there are only ~400 structure records per blend file.
// we read only a small part of them and don't cache objects
// which we don't need, so this should suffice.
caches.reserve(64);
}
public:
// --------------------------------------------------------
/** Check whether a specific item is in the cache.
* @param s Data type of the item
@@ -653,7 +672,10 @@ public:
* cache doesn't know the item yet.
* @param ptr Item address to look for. */
template <typename T>
void get( const Structure &s,TOUT<T> &out, const Pointer &ptr) const;
void get(
const Structure &s,
TOUT<T> &out,
const Pointer &ptr) const;
// --------------------------------------------------------
/** Add an item to the cache after the item has
@@ -678,7 +700,7 @@ private:
template <>
class ObjectCache<Blender::vector> {
public:
explicit ObjectCache(const FileDatabase &) {}
ObjectCache(const FileDatabase &) {}
template <typename T>
void get(const Structure &, vector<T> &, const Pointer &) {}
@@ -687,7 +709,7 @@ public:
};
#ifdef _MSC_VER
# pragma warning(disable : 4355)
#pragma warning(disable : 4355)
#endif
// -------------------------------------------------------------------------------
@@ -702,6 +724,16 @@ public:
FileDatabase() :
_cacheArrays(*this), _cache(*this), next_cache_idx() {}
public:
// publicly accessible fields
bool i64bit;
bool little;
DNA dna;
std::shared_ptr<StreamReaderAny> reader;
vector<FileBlockHead> entries;
public:
Statistics &stats() const {
return _stats;
}
@@ -720,15 +752,6 @@ public:
return _cacheArrays;
}
public:
// publicly accessible fields
bool i64bit;
bool little;
DNA dna;
std::shared_ptr<StreamReaderAny> reader;
vector<FileBlockHead> entries;
private:
#ifndef ASSIMP_BUILD_BLENDER_NO_STATS
mutable Statistics _stats;
@@ -741,19 +764,20 @@ private:
};
#ifdef _MSC_VER
# pragma warning(default : 4355)
#pragma warning(default : 4355)
#endif
// -------------------------------------------------------------------------------
/** Factory to extract a #DNA from the DNA1 file block in a BLEND file. */
// -------------------------------------------------------------------------------
class DNAParser {
public:
/** Bind the parser to a empty DNA and an input stream */
explicit DNAParser(FileDatabase &db) : db(db) {
// empty
}
DNAParser(FileDatabase &db) :
db(db) {}
public:
// --------------------------------------------------------
/** Locate the DNA in the file and parse it. The input
* stream is expected to point to the beginning of the DN1
@@ -764,6 +788,7 @@ public:
* afterwards.*/
void Parse();
public:
/** Obtain a reference to the extracted DNA information */
const Blender::DNA &GetDNA() const {
return db.dna;
+3 -3
View File
@@ -961,7 +961,7 @@ void BlenderImporter::ConvertMesh(const Scene & /*in*/, const Object * /*obj*/,
if (mesh->totface > static_cast<int>(mesh->mtface.size())) {
ThrowException("Number of UV faces is larger than the corresponding UV face array (#1)");
}
for (std::vector<aiMesh *>::iterator it = temp->begin() + old; it != temp->end(); ++it) {
for (MeshArray::iterator it = temp->begin() + old; it != temp->end(); ++it) {
ai_assert(0 != (*it)->mNumVertices);
ai_assert(0 != (*it)->mNumFaces);
const auto itMatTexUvMapping = matTexUvMappings.find((*it)->mMaterialIndex);
@@ -1030,7 +1030,7 @@ void BlenderImporter::ConvertMesh(const Scene & /*in*/, const Object * /*obj*/,
if (mesh->totface > static_cast<int>(mesh->tface.size())) {
ThrowException("Number of faces is larger than the corresponding UV face array (#2)");
}
for (std::vector<aiMesh *>::iterator it = temp->begin() + old; it != temp->end(); ++it) {
for (MeshArray::iterator it = temp->begin() + old; it != temp->end(); ++it) {
ai_assert(0 != (*it)->mNumVertices);
ai_assert(0 != (*it)->mNumFaces);
@@ -1057,7 +1057,7 @@ void BlenderImporter::ConvertMesh(const Scene & /*in*/, const Object * /*obj*/,
if (mesh->totface > static_cast<int>((mesh->mcol.size() / 4))) {
ThrowException("Number of faces is larger than the corresponding color face array");
}
for (std::vector<aiMesh *>::iterator it = temp->begin() + old; it != temp->end(); ++it) {
for (MeshArray::iterator it = temp->begin() + old; it != temp->end(); ++it) {
ai_assert(0 != (*it)->mNumVertices);
ai_assert(0 != (*it)->mNumFaces);
+1 -1
View File
@@ -105,7 +105,7 @@ class BlenderModifier;
* call it is outsourced to BlenderDNA.cpp/BlenderDNA.h. This class only performs the
* conversion from intermediate format to aiScene. */
// -------------------------------------------------------------------------------------------
class BlenderImporter final : public BaseImporter, public LogFunctions<BlenderImporter> {
class BlenderImporter : public BaseImporter, public LogFunctions<BlenderImporter> {
public:
BlenderImporter();
~BlenderImporter() override;
+2 -2
View File
@@ -114,7 +114,7 @@ private:
* Mirror modifier. Status: implemented.
*/
// -------------------------------------------------------------------------------------------
class BlenderModifier_Mirror final : public BlenderModifier {
class BlenderModifier_Mirror : public BlenderModifier {
public:
// --------------------
virtual bool IsActive( const ModifierData& modin);
@@ -131,7 +131,7 @@ public:
// -------------------------------------------------------------------------------------------
/** Subdivision modifier. Status: dummy. */
// -------------------------------------------------------------------------------------------
class BlenderModifier_Subdivision final : public BlenderModifier {
class BlenderModifier_Subdivision : public BlenderModifier {
public:
// --------------------
+48 -45
View File
@@ -47,7 +47,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "BlenderDNA.h"
namespace Assimp::Blender {
namespace Assimp {
namespace Blender {
// Minor parts of this file are extracts from blender data structures,
// declared in the ./source/blender/makesdna directory.
@@ -114,32 +115,32 @@ struct Collection;
static const size_t MaxNameLen = 1024;
// -------------------------------------------------------------------------------
struct ID final : ElemBase {
struct ID : ElemBase {
char name[MaxNameLen] WARN;
short flag;
};
// -------------------------------------------------------------------------------
struct ListBase final : ElemBase {
struct ListBase : ElemBase {
std::shared_ptr<ElemBase> first;
std::weak_ptr<ElemBase> last;
};
// -------------------------------------------------------------------------------
struct PackedFile final : ElemBase {
struct PackedFile : ElemBase {
int size WARN;
int seek WARN;
std::shared_ptr<FileOffset> data WARN;
};
// -------------------------------------------------------------------------------
struct GroupObject final : ElemBase {
struct GroupObject : ElemBase {
std::shared_ptr<GroupObject> prev, next FAIL;
std::shared_ptr<Object> ob;
};
// -------------------------------------------------------------------------------
struct Group final : ElemBase {
struct Group : ElemBase {
ID id FAIL;
int layer;
@@ -147,32 +148,32 @@ struct Group final : ElemBase {
};
// -------------------------------------------------------------------------------
struct CollectionObject final : ElemBase {
struct CollectionObject : ElemBase {
//CollectionObject* prev;
std::shared_ptr<CollectionObject> next;
Object *ob;
};
// -------------------------------------------------------------------------------
struct CollectionChild final : ElemBase {
struct CollectionChild : ElemBase {
std::shared_ptr<CollectionChild> next, prev;
std::shared_ptr<Collection> collection;
};
// -------------------------------------------------------------------------------
struct Collection final : ElemBase {
struct Collection : ElemBase {
ID id FAIL;
ListBase gobject; // CollectionObject
ListBase children; // CollectionChild
};
// -------------------------------------------------------------------------------
struct World final : ElemBase {
struct World : ElemBase {
ID id FAIL;
};
// -------------------------------------------------------------------------------
struct MVert final : ElemBase {
struct MVert : ElemBase {
float co[3] FAIL;
float no[3] FAIL; // read as short and divided through / 32767.f
char flag;
@@ -184,31 +185,31 @@ struct MVert final : ElemBase {
};
// -------------------------------------------------------------------------------
struct MEdge final : ElemBase {
struct MEdge : ElemBase {
int v1, v2 FAIL;
char crease, bweight;
short flag;
};
// -------------------------------------------------------------------------------
struct MLoop final : ElemBase {
struct MLoop : ElemBase {
int v, e;
};
// -------------------------------------------------------------------------------
struct MLoopUV final : ElemBase {
struct MLoopUV : ElemBase {
float uv[2];
int flag;
};
// -------------------------------------------------------------------------------
// Note that red and blue are not swapped, as with MCol
struct MLoopCol final : ElemBase {
struct MLoopCol : ElemBase {
unsigned char r, g, b, a;
};
// -------------------------------------------------------------------------------
struct MPoly final : ElemBase {
struct MPoly : ElemBase {
int loopstart;
int totloop;
short mat_nr;
@@ -216,26 +217,26 @@ struct MPoly final : ElemBase {
};
// -------------------------------------------------------------------------------
struct MTexPoly final : ElemBase {
struct MTexPoly : ElemBase {
Image *tpage;
char flag, transp;
short mode, tile, pad;
};
// -------------------------------------------------------------------------------
struct MCol final : ElemBase {
struct MCol : ElemBase {
char r, g, b, a FAIL;
};
// -------------------------------------------------------------------------------
struct MFace final : ElemBase {
struct MFace : ElemBase {
int v1, v2, v3, v4 FAIL;
int mat_nr FAIL;
char flag;
};
// -------------------------------------------------------------------------------
struct TFace final : ElemBase {
struct TFace : ElemBase {
float uv[4][2] FAIL;
int col[4] FAIL;
char flag;
@@ -245,7 +246,7 @@ struct TFace final : ElemBase {
};
// -------------------------------------------------------------------------------
struct MTFace final : ElemBase {
struct MTFace : ElemBase {
MTFace() :
flag(0),
mode(0),
@@ -263,24 +264,24 @@ struct MTFace final : ElemBase {
};
// -------------------------------------------------------------------------------
struct MDeformWeight final : ElemBase {
struct MDeformWeight : ElemBase {
int def_nr FAIL;
float weight FAIL;
};
// -------------------------------------------------------------------------------
struct MDeformVert final : ElemBase {
struct MDeformVert : ElemBase {
vector<MDeformWeight> dw WARN;
int totweight;
};
// -------------------------------------------------------------------------------
constexpr uint32_t MA_RAYMIRROR = 0x40000;
constexpr uint32_t MA_TRANSPARENCY = 0x10000;
constexpr uint32_t MA_RAYTRANSP = 0x20000;
constexpr uint32_t MA_ZTRANSP = 0x00040;
#define MA_RAYMIRROR 0x40000
#define MA_TRANSPARENCY 0x10000
#define MA_RAYTRANSP 0x20000
#define MA_ZTRANSP 0x00040
struct Material final : ElemBase {
struct Material : ElemBase {
ID id FAIL;
float r, g, b WARN;
@@ -402,7 +403,7 @@ CustomDataLayer 104
char name 32 64
void *data 96 8
*/
struct CustomDataLayer final : ElemBase {
struct CustomDataLayer : ElemBase {
int type;
int offset;
int flag;
@@ -440,7 +441,7 @@ CustomData 208
BLI_mempool *pool 192 8
CustomDataExternal *external 200 8
*/
struct CustomData final : ElemBase {
struct CustomData : ElemBase {
vector<std::shared_ptr<struct CustomDataLayer>> layers;
int typemap[42]; // CD_NUMTYPES
int totlayer;
@@ -453,7 +454,7 @@ struct CustomData final : ElemBase {
};
// -------------------------------------------------------------------------------
struct Mesh final : ElemBase {
struct Mesh : ElemBase {
ID id FAIL;
int totface FAIL;
@@ -490,7 +491,7 @@ struct Mesh final : ElemBase {
};
// -------------------------------------------------------------------------------
struct Library final : ElemBase {
struct Library : ElemBase {
ID id FAIL;
char name[240] WARN;
@@ -514,7 +515,7 @@ struct Camera : ElemBase {
};
// -------------------------------------------------------------------------------
struct Lamp final : ElemBase {
struct Lamp : ElemBase {
enum FalloffType {
FalloffType_Constant = 0x0,
@@ -601,7 +602,7 @@ struct Lamp final : ElemBase {
};
// -------------------------------------------------------------------------------
struct ModifierData final : ElemBase {
struct ModifierData : ElemBase {
enum ModifierType {
eModifierType_None = 0,
eModifierType_Subsurf,
@@ -651,8 +652,9 @@ struct SharedModifierData : ElemBase {
ModifierData modifier;
};
// -------------------------------------------------------------------------------
struct SubsurfModifierData final : SharedModifierData {
struct SubsurfModifierData : SharedModifierData {
enum Type {
@@ -672,7 +674,7 @@ struct SubsurfModifierData final : SharedModifierData {
};
// -------------------------------------------------------------------------------
struct MirrorModifierData final : SharedModifierData {
struct MirrorModifierData : SharedModifierData {
enum Flags {
Flags_CLIPPING = 1 << 0,
@@ -690,7 +692,7 @@ struct MirrorModifierData final : SharedModifierData {
};
// -------------------------------------------------------------------------------
struct Object final : ElemBase {
struct Object : ElemBase {
ID id FAIL;
enum Type {
@@ -731,7 +733,7 @@ struct Object final : ElemBase {
};
// -------------------------------------------------------------------------------
struct Base final : ElemBase {
struct Base : ElemBase {
Base *prev WARN;
std::shared_ptr<Base> next WARN;
std::shared_ptr<Object> object WARN;
@@ -743,7 +745,7 @@ struct Base final : ElemBase {
};
// -------------------------------------------------------------------------------
struct Scene final : ElemBase {
struct Scene : ElemBase {
ID id FAIL;
std::shared_ptr<Object> camera WARN;
@@ -757,7 +759,7 @@ struct Scene final : ElemBase {
};
// -------------------------------------------------------------------------------
struct Image final : ElemBase {
struct Image : ElemBase {
ID id FAIL;
char name[240] WARN;
@@ -787,7 +789,7 @@ struct Image final : ElemBase {
};
// -------------------------------------------------------------------------------
struct Tex final : ElemBase {
struct Tex : ElemBase {
// actually, the only texture type we support is Type_IMAGE
enum Type {
@@ -872,13 +874,14 @@ struct Tex final : ElemBase {
//char use_nodes;
Tex() : imaflag(ImageFlags_INTERPOL), type(Type_CLOUDS) {
Tex() :
imaflag(ImageFlags_INTERPOL), type(Type_CLOUDS) {
// empty
}
};
// -------------------------------------------------------------------------------
struct MTex final : ElemBase {
struct MTex : ElemBase {
enum Projection {
Proj_N = 0,
@@ -967,6 +970,6 @@ struct MTex final : ElemBase {
MTex() = default;
};
} // namespace Assimp::Blender
} // namespace Blender
} // namespace Assimp
#endif
@@ -381,14 +381,7 @@ inline PointP2T& BlenderTessellatorP2T::GetActualPointStructure( p2t::Point& poi
# pragma clang diagnostic push
# pragma clang diagnostic ignored "-Winvalid-offsetof"
#endif // __clang__
#if defined __GNUC__
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Winvalid-offsetof"
#endif // __GNUC__
unsigned int pointOffset = offsetof( PointP2T, point2D );
#if defined __GNUC__
# pragma GCC diagnostic pop
#endif // __GNUC__
#if defined __clang__
# pragma clang diagnostic pop
#endif
+8 -8
View File
@@ -166,10 +166,10 @@ void C4DImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOS
// copy meshes over
pScene->mNumMeshes = static_cast<unsigned int>(meshes.size());
pScene->mMeshes = new aiMesh*[pScene->mNumMeshes]();
std::copy(meshes.begin(), meshes.end(), pScene->mMeshes);
std::copy(mMeshes.begin(), mMeshes.end(), pScene->mMeshes);
// copy materials over, adding a default material if necessary
unsigned int mat_count = static_cast<unsigned int>(materials.size());
unsigned int mat_count = static_cast<unsigned int>(mMaterials.size());
for(aiMesh* mesh : meshes) {
ai_assert(mesh->mMaterialIndex <= mat_count);
if(mesh->mMaterialIndex >= mat_count) {
@@ -179,14 +179,14 @@ void C4DImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOS
const aiString name(AI_DEFAULT_MATERIAL_NAME);
def_material->AddProperty(&name, AI_MATKEY_NAME);
materials.push_back(def_material.release());
mMaterials.push_back(def_material.release());
break;
}
}
pScene->mNumMaterials = static_cast<unsigned int>(materials.size());
pScene->mMaterials = new aiMaterial*[pScene->mNumMaterials]();
std::copy(materials.begin(), materials.end(), pScene->mMaterials);
std::copy(mMaterials.begin(), mMaterials.end(), pScene->mMaterials);
}
// ------------------------------------------------------------------------------------------------
@@ -251,8 +251,8 @@ void C4DImporter::ReadMaterials(BaseMaterial* mat) {
while (mat) {
if (mat->GetType() == Mmaterial) {
aiMaterial* out = new aiMaterial();
material_mapping[mat] = static_cast<unsigned int>(materials.size());
materials.push_back(out);
mMaterialMapping[mat] = static_cast<unsigned int>(mMaterials.size());
mMaterials.push_back(out);
auto const ai_name = aiStringFrom(mat->GetName());
out->AddProperty(&ai_name, AI_MATKEY_NAME);
@@ -289,7 +289,7 @@ void C4DImporter::ReadMaterials(BaseMaterial* mat) {
// ------------------------------------------------------------------------------------------------
void C4DImporter::RecurseHierarchy(BaseObject* object, aiNode* parent) {
ai_assert(parent != nullptr );
std::vector<aiNode*> nodes;
NodeArray nodes;
// based on Cineware sample code
while (object) {
@@ -577,7 +577,7 @@ aiMesh* C4DImporter::ReadMesh(BaseObject* object) {
unsigned int C4DImporter::ResolveMaterial(PolygonObject* obj) {
ai_assert(obj != nullptr);
const unsigned int mat_count = static_cast<unsigned int>(materials.size());
const unsigned int mat_count = static_cast<unsigned int>(mMaterials.size());
BaseTag* tag = obj->GetTag(Ttexture);
if(tag == nullptr) {
+5 -4
View File
@@ -97,11 +97,12 @@ private:
bool ReadShader(aiMaterial* out, cineware::BaseShader* shader);
std::vector<aiMesh*> meshes;
std::vector<aiMaterial*> materials;
private:
MeshArray mMeshes;
MaterialArray materials;
typedef std::map<cineware::BaseMaterial*, unsigned int> MaterialMap;
MaterialMap material_mapping;
using MaterialMap = std::map<cineware::BaseMaterial*, unsigned int> ;
MaterialMap mMaterialMapping;
}; // !class C4DImporter
+12 -28
View File
@@ -62,7 +62,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <memory>
namespace Assimp {
using namespace Assimp::COB;
using namespace Assimp::Formatter;
@@ -110,29 +109,10 @@ void COBImporter::SetupProperties(const Importer * /*pImp*/) {
}
// ------------------------------------------------------------------------------------------------
AI_WONT_RETURN void COBImporter::ThrowException(const std::string &msg) {
/*static*/ AI_WONT_RETURN void COBImporter::ThrowException(const std::string &msg) {
throw DeadlyImportError("COB: ", msg);
}
// ------------------------------------------------------------------------------------------------
static bool isValidASCIIHeader(const char *head) {
ai_assert(head != nullptr);
if (strncmp(head, "Caligari ", 9) != 0) {
COBImporter::ThrowException("Could not found magic id: `Caligari`");
}
if (strncmp(&head[9], "V00.", 4) != 0) {
COBImporter::ThrowException("Could not found Version tag: `V00.`");
}
ASSIMP_LOG_INFO("File format tag: ", std::string(head + 9, 6));
if (head[16] != 'L') {
COBImporter::ThrowException("File is big-endian, which is not supported");
}
return true;
}
// ------------------------------------------------------------------------------------------------
// Imports the given file into the given scene structure.
void COBImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler) {
@@ -146,15 +126,19 @@ void COBImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
std::unique_ptr<StreamReaderLE> stream(new StreamReaderLE(file));
// check header
static constexpr size_t HeaderSize = 32u;
char head[HeaderSize] = {};
stream->CopyAndAdvance(head, HeaderSize);
char head[32];
stream->CopyAndAdvance(head, 32);
if (strncmp(head, "Caligari ", 9) != 0) {
ThrowException("Could not found magic id: `Caligari`");
}
ASSIMP_LOG_INFO("File format tag: ", std::string(head + 9, 6));
if (head[16] != 'L') {
ThrowException("File is big-endian, which is not supported");
}
// load data into intermediate structures
if (head[15] == 'A') {
if (!isValidASCIIHeader(head)) {
ThrowException("Invalid ASCII file header");
}
ReadAsciiFile(scene, stream.get());
} else {
ReadBinaryFile(scene, stream.get());
@@ -1186,6 +1170,6 @@ void COBImporter::ReadUnit_Binary(COB::Scene &out, StreamReaderLE &reader, const
ASSIMP_LOG_WARN("`Unit` chunk ", nfo.id, " is a child of ", nfo.parent_id, " which does not exist");
}
} // namespace Assimp
}
#endif // ASSIMP_BUILD_NO_COB_IMPORTER
+5 -6
View File
@@ -72,7 +72,7 @@ namespace COB {
*
* Currently relatively limited, loads only ASCII files and needs more test coverage. */
// -------------------------------------------------------------------------------------------
class COBImporter final : public BaseImporter {
class COBImporter : public BaseImporter {
public:
COBImporter() = default;
~COBImporter() override = default;
@@ -81,10 +81,6 @@ public:
bool CanRead(const std::string &pFile, IOSystem *pIOHandler,
bool checkSig) const override;
// -------------------------------------------------------------------
/** Prepend 'COB: ' and throw msg.*/
AI_WONT_RETURN static void ThrowException(const std::string &msg) AI_WONT_RETURN_SUFFIX;
protected:
// --------------------
const aiImporterDesc *GetInfo() const override;
@@ -97,6 +93,10 @@ protected:
IOSystem *pIOHandler) override;
private:
// -------------------------------------------------------------------
/** Prepend 'COB: ' and throw msg.*/
AI_WONT_RETURN static void ThrowException(const std::string &msg) AI_WONT_RETURN_SUFFIX;
// -------------------------------------------------------------------
/** @brief Read from an ascii scene/object file
* @param out Receives output data.
@@ -148,5 +148,4 @@ private:
}; // !class COBImporter
} // end of namespace Assimp
#endif // AI_UNREALIMPORTER_H_INC
+75 -82
View File
@@ -52,66 +52,68 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <deque>
#include <map>
namespace Assimp::COB {
namespace Assimp {
namespace COB {
// ------------------
/** Represents a single vertex index in a face */
struct VertexIndex {
struct VertexIndex
{
// intentionally uninitialized
unsigned int pos_idx,uv_idx;
};
// ------------------
/** COB Face data structure */
struct Face {
struct Face
{
// intentionally uninitialized
unsigned int material;
unsigned int flags;
unsigned int material, flags;
std::vector<VertexIndex> indices;
};
// ------------------
/** COB chunk header information */
constexpr unsigned int NO_SIZE = UINT_MAX;
const unsigned int NO_SIZE = UINT_MAX;
struct ChunkInfo {
ChunkInfo() = default;
virtual ~ChunkInfo() = default;
struct ChunkInfo
{
ChunkInfo ()
: id (0)
, parent_id (0)
, version (0)
, size (NO_SIZE)
{}
// Id of this chunk, unique within file
unsigned int id{ 0 };
unsigned int id;
// and the corresponding parent
unsigned int parent_id{ 0 };
unsigned int parent_id;
// version. v1.23 becomes 123
unsigned int version{ 0 };
unsigned int version;
// chunk size in bytes, only relevant for binary files
// NO_SIZE is also valid.
unsigned int size{NO_SIZE};
unsigned int size;
};
// ------------------
/** A node in the scenegraph */
struct Node : ChunkInfo {
struct Node : public ChunkInfo
{
enum Type {
TYPE_INVALID = -1,
TYPE_MESH = 0,
TYPE_GROUP,
TYPE_LIGHT,
TYPE_CAMERA,
TYPE_BONE,
TYPE_COUNT
TYPE_MESH,TYPE_GROUP,TYPE_LIGHT,TYPE_CAMERA,TYPE_BONE
};
~Node() override = default;
explicit Node(Type type) : type(type), unit_scale(1.f){}
virtual ~Node() = default;
Node(Type type) : type(type), unit_scale(1.f){}
Type type;
// used during resolving
using ChildList = std::deque<const Node*> ;
typedef std::deque<const Node*> ChildList;
mutable ChildList temp_children;
// unique name
@@ -126,7 +128,8 @@ struct Node : ChunkInfo {
// ------------------
/** COB Mesh data structure */
struct Mesh final : Node {
struct Mesh : public Node
{
using ChunkInfo::operator=;
enum DrawFlags {
SOLID = 0x1,
@@ -159,118 +162,107 @@ struct Mesh final : Node {
// ------------------
/** COB Group data structure */
struct Group final : Node {
struct Group : public Node
{
using ChunkInfo::operator=;
Group() : Node(TYPE_GROUP) {
// empty
}
Group() : Node(TYPE_GROUP) {}
};
// ------------------
/** COB Bone data structure */
struct Bone final : Node {
struct Bone : public Node
{
using ChunkInfo::operator=;
Bone() : Node(TYPE_BONE) {
// empty
}
Bone() : Node(TYPE_BONE) {}
};
// ------------------
/** COB Light data structure */
struct Light final : Node {
struct Light : public Node
{
enum LightType {
SPOT,
LOCAL,
INFINITE
SPOT,LOCAL,INFINITE
};
using ChunkInfo::operator=;
Light() : Node(TYPE_LIGHT), ltype() {
// empty
}
Light() : Node(TYPE_LIGHT),angle(),inner_angle(),ltype(SPOT) {}
aiColor3D color;
float angle{ 0.0f };
float inner_angle{ 0.0f };
float angle,inner_angle;
LightType ltype{SPOT};
LightType ltype;
};
// ------------------
/** COB Camera data structure */
struct Camera final : Node {
struct Camera : public Node
{
using ChunkInfo::operator=;
Camera() : Node(TYPE_CAMERA) {
// empty
}
Camera() : Node(TYPE_CAMERA) {}
};
// ------------------
/** COB Texture data structure */
struct Texture {
struct Texture
{
std::string path;
aiUVTransform transform;
};
// ------------------
/** COB Material data structure */
struct Material : ChunkInfo {
struct Material : ChunkInfo
{
using ChunkInfo::operator=;
enum Shader {
FLAT,
PHONG,
METAL
FLAT,PHONG,METAL
};
enum AutoFacet {
FACETED,
AUTOFACETED,
SMOOTH
FACETED,AUTOFACETED,SMOOTH
};
Material() : shader(FLAT) {
// empty
}
Material() : alpha(),exp(),ior(),ka(),ks(1.f),
matnum(UINT_MAX),
shader(FLAT),autofacet(FACETED),
autofacet_angle()
{}
std::string type;
aiColor3D rgb;
float alpha{ 0.0f };
float exp{ 0.0f };
float ior{ 0.0f };
float ka{ 0.0f };
float ks{ 1.0f };
unsigned int matnum{ UINT_MAX };
float alpha, exp, ior,ka,ks;
unsigned int matnum;
Shader shader;
AutoFacet autofacet{FACETED};
float autofacet_angle{ 0.0f };
AutoFacet autofacet;
float autofacet_angle;
std::shared_ptr<Texture> tex_env,tex_bump,tex_color;
};
// ------------------
/** Embedded bitmap, for instance for the thumbnail image */
struct Bitmap : ChunkInfo {
Bitmap() = default;
struct BitmapHeader {
// empty
struct Bitmap : ChunkInfo
{
Bitmap() : orig_size() {}
struct BitmapHeader
{
};
BitmapHeader head;
size_t orig_size{ 0u };
size_t orig_size;
std::vector<char> buff_zipped;
};
using NodeList = std::deque< std::shared_ptr<Node>>;
using MaterialList = std::vector< Material >;
typedef std::deque< std::shared_ptr<Node> > NodeList;
typedef std::vector< Material > MaterialList;
// ------------------
/** Represents a master COB scene, even if we loaded just a single COB file */
struct Scene {
struct Scene
{
NodeList nodes;
MaterialList materials;
@@ -278,6 +270,7 @@ struct Scene {
Bitmap thumbnail;
};
} // end Assimp::COB
} // end COB
} // end Assimp
#endif // INCLUDED_AI_COB_SCENE_H
#endif
+1 -1
View File
@@ -58,7 +58,7 @@ namespace Assimp {
* Link to file format specification:
* <max_8_dvd>\samples\Motion\Docs\CSM.rtf
*/
class CSMImporter final : public BaseImporter {
class CSMImporter : public BaseImporter {
public:
CSMImporter();
~CSMImporter() override = default;
+1 -1
View File
@@ -65,7 +65,7 @@ class IOSystem;
/// Helper class to export a given scene to a Collada file. Just for my personal
/// comfort when implementing it.
class ColladaExporter final {
class ColladaExporter {
public:
/// Constructor for a specific scene to export
ColladaExporter(const aiScene *pScene, IOSystem *pIOSystem, const std::string &path, const std::string &file);
+1 -1
View File
@@ -341,7 +341,7 @@ struct SubMesh {
/// Contains data for a single mesh
struct Mesh {
explicit Mesh(const std::string &id) :
Mesh(const std::string &id) :
mId(id) {
for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++i) {
mNumUVComponents[i] = 2;
+5 -5
View File
@@ -77,12 +77,12 @@ static constexpr aiImporterDesc desc = {
"dae xml zae"
};
static constexpr float kMillisecondsFromSeconds = 1000.f;
static const float kMillisecondsFromSeconds = 1000.f;
// Add an item of metadata to a node
// Assumes the key is not already in the list
template <typename T>
void AddNodeMetaData(aiNode *node, const std::string &key, const T &value) {
inline void AddNodeMetaData(aiNode *node, const std::string &key, const T &value) {
if (nullptr == node->mMetaData) {
node->mMetaData = new aiMetadata();
}
@@ -92,7 +92,7 @@ void AddNodeMetaData(aiNode *node, const std::string &key, const T &value) {
// ------------------------------------------------------------------------------------------------
// Reads a float value from an accessor and its data array.
static ai_real ReadFloat(const Accessor &pAccessor, const Data &pData, size_t pIndex, size_t pOffset) {
const size_t pos = pAccessor.mStride * pIndex + pAccessor.mOffset + pOffset;
size_t pos = pAccessor.mStride * pIndex + pAccessor.mOffset + pOffset;
ai_assert(pos < pData.mValues.size());
return pData.mValues[pos];
}
@@ -668,7 +668,7 @@ aiMesh *ColladaLoader::CreateMesh(const ColladaParser &pParser, const Mesh *pSrc
}
// create morph target meshes if any
std::vector<aiMesh *> targetMeshes;
MeshArray targetMeshes;
std::vector<float> targetWeights;
Collada::MorphMethod method = Normalized;
@@ -1819,4 +1819,4 @@ std::string ColladaLoader::FindNameForNode(const Node *pNode) {
} // Namespace Assimp
#endif // !! ASSIMP_BUILD_NO_COLLADA_IMPORTER
#endif // !! ASSIMP_BUILD_NO_DAE_IMPORTER
+3 -3
View File
@@ -82,7 +82,7 @@ struct ColladaMeshIndex {
* Collada is over-engineered to death, with every new iteration bringing more useless stuff,
* so I limited the data to what I think is useful for games.
*/
class ColladaLoader final : public BaseImporter {
class ColladaLoader : public BaseImporter {
public:
/// The class constructor.
ColladaLoader();
@@ -206,10 +206,10 @@ private:
std::map<std::string, size_t> mMaterialIndexByName;
/** Accumulated meshes for the target scene */
std::vector<aiMesh *> mMeshes;
MeshArray mMeshes;
/** Accumulated morph target meshes */
std::vector<aiMesh *> mTargetMeshes;
MeshArray mTargetMeshes;
/** Temporary material list */
std::vector<std::pair<Collada::Effect *, aiMaterial *>> newMats;
+2 -5
View File
@@ -1929,7 +1929,7 @@ size_t ColladaParser::ReadPrimitives(XmlNode &node, Mesh &pMesh, std::vector<Inp
void ColladaParser::CopyVertex(size_t currentVertex, size_t numOffsets, size_t numPoints, size_t perVertexOffset, Mesh &pMesh,
std::vector<InputChannel> &pPerIndexChannels, size_t currentPrimitive, const std::vector<size_t> &indices) {
// calculate the base offset of the vertex whose attributes we ant to copy
const auto baseOffset = currentPrimitive * numOffsets * numPoints + currentVertex * numOffsets;
size_t baseOffset = currentPrimitive * numOffsets * numPoints + currentVertex * numOffsets;
// don't overrun the boundaries of the index list
ai_assert((baseOffset + numOffsets - 1) < indices.size());
@@ -1944,9 +1944,6 @@ void ColladaParser::CopyVertex(size_t currentVertex, size_t numOffsets, size_t n
}
// store the vertex-data index for later assignment of bone vertex weights
if (const auto indexOffset = baseOffset + perVertexOffset; indexOffset >= indices.size()) {
throw DeadlyImportError("index offset out of range");
}
pMesh.mFacePosIndices.push_back(indices[baseOffset + perVertexOffset]);
}
@@ -2426,4 +2423,4 @@ InputType ColladaParser::GetTypeForSemantic(const std::string &semantic) {
return IT_Invalid;
}
#endif // !! ASSIMP_BUILD_NO_COLLADA_IMPORTER
#endif // !! ASSIMP_BUILD_NO_DAE_IMPORTER
+6 -4
View File
@@ -53,14 +53,15 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <vector>
#include <assimp/DefaultLogger.hpp>
namespace Assimp::DXF {
namespace Assimp {
namespace DXF {
// read pairs of lines, parse group code and value and provide utilities
// to convert the data to the target data type.
// do NOT skip empty lines. In DXF files, they count as valid data.
class LineReader {
public:
explicit LineReader(StreamReaderLE& reader) : splitter(reader,false,true), groupcode( 0 ), end() {
LineReader(StreamReaderLE& reader) : splitter(reader,false,true), groupcode( 0 ), end() {
// empty
}
@@ -100,7 +101,7 @@ public:
}
// -----------------------------------------
ai_real ValueAsFloat() const {
float ValueAsFloat() const {
return fast_atof(value.c_str());
}
@@ -202,6 +203,7 @@ struct FileData {
std::vector<Block> blocks;
};
} // namespace Assimp::DXF
} // namespace DXF
} // namespace Assimp
#endif // INCLUDED_DXFHELPER_H
+1 -1
View File
@@ -66,7 +66,7 @@ namespace DXF {
/**
* @brief DXF importer implementation.
*/
class DXFImporter final : public BaseImporter {
class DXFImporter : public BaseImporter {
public:
DXFImporter() = default;
~DXFImporter() override = default;
+4 -2
View File
@@ -47,7 +47,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef ASSIMP_BUILD_NO_FBX_EXPORTER
namespace Assimp::FBX {
namespace Assimp {
namespace FBX {
static constexpr size_t NumNullRecords = 25;
@@ -83,7 +84,8 @@ enum TransformInheritance {
TransformInheritance_MAX // end-of-enum sentinel
};
} // namespace Assimp::FBX
} // namespace FBX
} // namespace Assimp
#endif // ASSIMP_BUILD_NO_FBX_EXPORTER
+1 -1
View File
@@ -49,7 +49,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <set>
//
#if _MSC_VER > 1500 || (defined __GNUC__)
#if _MSC_VER > 1500 || (defined __GNUC___)
# define ASSIMP_FBX_USE_UNORDERED_MULTIMAP
# else
# define fbx_unordered_map map
+29 -30
View File
@@ -72,7 +72,7 @@ namespace FBX {
using namespace Util;
#define MAGIC_NODE_TAG "_$AssimpFbx$"
static constexpr char MAGIC_NODE_TAG[] = "_$AssimpFbx$";
#define CONVERT_FBX_TIME(time) static_cast<double>(time) / 46186158000LL
@@ -125,21 +125,10 @@ static void correctRootTransform(const aiScene *scene) {
FBXConverter::FBXConverter(aiScene *out, const Document &doc, bool removeEmptyBones) :
defaultMaterialIndex(),
mMeshes(),
lights(),
cameras(),
textures(),
materials_converted(),
textures_converted(),
meshes_converted(),
node_anim_chain_bits(),
mNodeNames(),
anim_fps(),
mSceneOut(out),
doc(doc),
mRemoveEmptyBones(removeEmptyBones) {
// animations need to be converted first since this will
// populate the node_anim_chain_bits map, which is needed
// to determine which nodes need to be generated.
@@ -162,7 +151,7 @@ FBXConverter::FBXConverter(aiScene *out, const Document &doc, bool removeEmptyBo
continue;
}
const Material *mat = dynamic_cast<const Material *>(ob);
auto mat = dynamic_cast<const Material *>(ob);
if (mat) {
if (materials_converted.find(mat) == materials_converted.end()) {
@@ -222,7 +211,6 @@ static std::string getAncestorBaseName(const aiNode *node) {
return std::string(nodeName, length);
}
// Make unique name
std::string FBXConverter::MakeUniqueNodeName(const Model *const model, const aiNode &parent) {
std::string original_name = FixNodeName(model->Name());
if (original_name.empty()) {
@@ -236,9 +224,18 @@ std::string FBXConverter::MakeUniqueNodeName(const Model *const model, const aiN
/// This struct manages nodes which may or may not end up in the node hierarchy.
/// When a node becomes a child of another node, that node becomes its owner and mOwnership should be released.
struct FBXConverter::PotentialNode {
PotentialNode() : mOwnership(new aiNode), mNode(mOwnership.get()) {}
explicit PotentialNode(const std::string& name) : mOwnership(new aiNode(name)), mNode(mOwnership.get()) {}
aiNode* operator->() { return mNode; }
PotentialNode() : mOwnership(new aiNode), mNode(mOwnership.get()) {
// empty
}
explicit PotentialNode(const std::string& name) : mOwnership(new aiNode(name)), mNode(mOwnership.get()) {
// empty
}
aiNode* operator->() {
return mNode;
}
std::unique_ptr<aiNode> mOwnership;
aiNode* mNode;
};
@@ -1092,14 +1089,14 @@ aiMesh *FBXConverter::SetupEmptyMesh(const Geometry &mesh, aiNode *parent) {
}
static aiSkeleton *createAiSkeleton(SkeletonBoneContainer &sbc) {
if (sbc.MeshArray.empty() || sbc.SkeletonBoneToMeshLookup.empty()) {
if (sbc.meshArray.empty() || sbc.skeletonBoneToMeshLookup.empty()) {
return nullptr;
}
aiSkeleton *skeleton = new aiSkeleton;
for (auto *mesh : sbc.MeshArray) {
auto it = sbc.SkeletonBoneToMeshLookup.find(mesh);
if (it == sbc.SkeletonBoneToMeshLookup.end()) {
for (auto *mesh : sbc.meshArray) {
auto it = sbc.skeletonBoneToMeshLookup.find(mesh);
if (it == sbc.skeletonBoneToMeshLookup.end()) {
continue;
}
SkeletonBoneArray *ba = it->second;
@@ -1547,12 +1544,12 @@ static void copyBoneToSkeletonBone(aiMesh *mesh, aiBone *bone, aiSkeletonBone *s
void FBXConverter::ConvertWeightsToSkeleton(aiMesh *out, const MeshGeometry &geo, const aiMatrix4x4 &absolute_transform, aiNode *parent, unsigned int materialIndex,
std::vector<unsigned int> *outputVertStartIndices, SkeletonBoneContainer &skeletonContainer) {
if (skeletonContainer.SkeletonBoneToMeshLookup.find(out) != skeletonContainer.SkeletonBoneToMeshLookup.end()) {
if (skeletonContainer.skeletonBoneToMeshLookup.find(out) != skeletonContainer.skeletonBoneToMeshLookup.end()) {
return;
}
ConvertWeights(out, geo, absolute_transform, parent, materialIndex, outputVertStartIndices);
skeletonContainer.MeshArray.emplace_back(out);
skeletonContainer.meshArray.emplace_back(out);
SkeletonBoneArray *ba = new SkeletonBoneArray;
for (size_t i = 0; i < out->mNumBones; ++i) {
aiBone *bone = out->mBones[i];
@@ -1563,7 +1560,7 @@ void FBXConverter::ConvertWeightsToSkeleton(aiMesh *out, const MeshGeometry &geo
copyBoneToSkeletonBone(out, bone, skeletonBone);
ba->emplace_back(skeletonBone);
}
skeletonContainer.SkeletonBoneToMeshLookup[out] = ba;
skeletonContainer.skeletonBoneToMeshLookup[out] = ba;
}
void FBXConverter::ConvertWeights(aiMesh *out, const MeshGeometry &geo, const aiMatrix4x4 &absolute_transform,
@@ -1571,8 +1568,6 @@ void FBXConverter::ConvertWeights(aiMesh *out, const MeshGeometry &geo, const ai
std::vector<unsigned int> *outputVertStartIndices) {
ai_assert(geo.DeformerSkin());
std::vector<size_t> out_indices, index_out_indices, count_out_indices;
const Skin &sk = *geo.DeformerSkin();
std::vector<aiBone*> bones;
@@ -1580,6 +1575,10 @@ void FBXConverter::ConvertWeights(aiMesh *out, const MeshGeometry &geo, const ai
ai_assert(no_mat_check || outputVertStartIndices);
try {
std::vector<size_t> count_out_indices;
std::vector<size_t> index_out_indices;
std::vector<size_t> out_indices;
// iterate over the sub deformers
for (const Cluster *cluster : sk.Clusters()) {
ai_assert(cluster);
@@ -1751,10 +1750,10 @@ unsigned int FBXConverter::GetDefaultMaterial() {
return defaultMaterialIndex - 1;
}
aiMaterial *out_mat = new aiMaterial();
auto out_mat = new aiMaterial();
materials.push_back(out_mat);
const aiColor3D diffuse = aiColor3D(0.8f, 0.8f, 0.8f);
const auto diffuse = aiColor3D(0.8f, 0.8f, 0.8f);
out_mat->AddProperty(&diffuse, 1, AI_MATKEY_COLOR_DIFFUSE);
aiString s;
@@ -1770,7 +1769,7 @@ unsigned int FBXConverter::ConvertMaterial(const Material &material, const MeshG
const PropertyTable &props = material.Props();
// generate empty output material
aiMaterial *out_mat = new aiMaterial();
auto out_mat = new aiMaterial();
materials_converted[&material] = static_cast<unsigned int>(materials.size());
materials.push_back(out_mat);
@@ -1809,7 +1808,7 @@ unsigned int FBXConverter::ConvertMaterial(const Material &material, const MeshG
unsigned int FBXConverter::ConvertVideo(const Video &video) {
// generate empty output texture
aiTexture *out_tex = new aiTexture();
auto out_tex = new aiTexture();
textures.push_back(out_tex);
// assuming the texture is compressed
+2 -2
View File
@@ -80,8 +80,8 @@ using SkeletonBoneArray = std::vector<aiSkeletonBone *>;
using SkeletonBoneToMesh = std::map<aiMesh*, SkeletonBoneArray*>;
struct SkeletonBoneContainer {
std::vector<aiMesh *> MeshArray;
SkeletonBoneToMesh SkeletonBoneToMeshLookup;
MeshArray meshArray;
SkeletonBoneToMesh skeletonBoneToMeshLookup;
};
class Document;
+29 -29
View File
@@ -174,7 +174,7 @@ class NodeAttribute : public Object {
public:
NodeAttribute(uint64_t id, const Element& element, const Document& doc, const std::string& name);
~NodeAttribute() override = default;
virtual ~NodeAttribute() = default;
const PropertyTable& Props() const {
ai_assert(props.get());
@@ -186,11 +186,11 @@ private:
};
/** DOM base class for FBX camera settings attached to a node */
class CameraSwitcher final : public NodeAttribute {
class CameraSwitcher : public NodeAttribute {
public:
CameraSwitcher(uint64_t id, const Element& element, const Document& doc, const std::string& name);
~CameraSwitcher() override= default;
virtual ~CameraSwitcher() = default;
int CameraID() const {
return cameraId;
@@ -231,11 +231,11 @@ private:
/** DOM base class for FBX cameras attached to a node */
class Camera final : public NodeAttribute {
class Camera : public NodeAttribute {
public:
Camera(uint64_t id, const Element& element, const Document& doc, const std::string& name);
~Camera() override = default;
virtual ~Camera() = default;
fbx_simple_property(Position, aiVector3D, aiVector3D(0,0,0))
fbx_simple_property(UpVector, aiVector3D, aiVector3D(0,1,0))
@@ -257,24 +257,24 @@ public:
};
/** DOM base class for FBX null markers attached to a node */
class Null final : public NodeAttribute {
class Null : public NodeAttribute {
public:
Null(uint64_t id, const Element& element, const Document& doc, const std::string& name);
~Null() override = default;
virtual ~Null() = default;
};
/** DOM base class for FBX limb node markers attached to a node */
class LimbNode final : public NodeAttribute {
class LimbNode : public NodeAttribute {
public:
LimbNode(uint64_t id, const Element& element, const Document& doc, const std::string& name);
~LimbNode() override = default;
virtual ~LimbNode() = default;
};
/** DOM base class for FBX lights attached to a node */
class Light final : public NodeAttribute {
class Light : public NodeAttribute {
public:
Light(uint64_t id, const Element& element, const Document& doc, const std::string& name);
~Light() override = default;
virtual ~Light() = default;
enum Type {
Type_Point,
@@ -329,7 +329,7 @@ public:
};
/** DOM base class for FBX models (even though its semantics are more "node" than "model" */
class Model final : public Object {
class Model : public Object {
public:
enum RotOrder {
RotOrder_EulerXYZ = 0,
@@ -354,7 +354,7 @@ public:
Model(uint64_t id, const Element& element, const Document& doc, const std::string& name);
~Model() override = default;
virtual ~Model() = default;
fbx_simple_property(QuaternionInterpolate, int, 0)
@@ -477,11 +477,11 @@ private:
};
/** DOM class for generic FBX textures */
class Texture final : public Object {
class Texture : public Object {
public:
Texture(uint64_t id, const Element& element, const Document& doc, const std::string& name);
~Texture() override;
virtual ~Texture();
const std::string& Type() const {
return type;
@@ -542,10 +542,10 @@ private:
};
/** DOM class for layered FBX textures */
class LayeredTexture final : public Object {
class LayeredTexture : public Object {
public:
LayeredTexture(uint64_t id, const Element& element, const Document& doc, const std::string& name);
~LayeredTexture() override;
virtual ~LayeredTexture();
// Can only be called after construction of the layered texture object due to construction flag.
void fillTexture(const Document& doc);
@@ -608,11 +608,11 @@ using TextureMap = std::fbx_unordered_map<std::string, const Texture*>;
using LayeredTextureMap = std::fbx_unordered_map<std::string, const LayeredTexture*>;
/** DOM class for generic FBX videos */
class Video final : public Object {
class Video : public Object {
public:
Video(uint64_t id, const Element& element, const Document& doc, const std::string& name);
~Video() override;
virtual ~Video();
const std::string& Type() const {
return type;
@@ -697,10 +697,10 @@ using KeyTimeList = std::vector<int64_t>;
using KeyValueList = std::vector<float>;
/** Represents a FBX animation curve (i.e. a 1-dimensional set of keyframes and values therefore) */
class AnimationCurve final : public Object {
class AnimationCurve : public Object {
public:
AnimationCurve(uint64_t id, const Element& element, const std::string& name, const Document& doc);
~AnimationCurve() override = default;
virtual ~AnimationCurve() = default;
/** get list of keyframe positions (time).
* Invariant: |GetKeys()| > 0 */
@@ -733,7 +733,7 @@ private:
using AnimationCurveMap = std::map<std::string, const AnimationCurve*>;
/** Represents a FBX animation curve (i.e. a mapping from single animation curves to nodes) */
class AnimationCurveNode final : public Object {
class AnimationCurveNode : public Object {
public:
/* the optional white list specifies a list of property names for which the caller
wants animations for. If the curve node does not match one of these, std::range_error
@@ -741,7 +741,7 @@ public:
AnimationCurveNode(uint64_t id, const Element& element, const std::string& name, const Document& doc,
const char *const *target_prop_whitelist = nullptr, size_t whitelist_size = 0);
~AnimationCurveNode() override = default;
virtual ~AnimationCurveNode() = default;
const PropertyTable& Props() const {
ai_assert(props.get());
@@ -783,7 +783,7 @@ private:
using AnimationCurveNodeList = std::vector<const AnimationCurveNode*>;
/** Represents a FBX animation layer (i.e. a list of node animations) */
class AnimationLayer final : public Object {
class AnimationLayer : public Object {
public:
AnimationLayer(uint64_t id, const Element& element, const std::string& name, const Document& doc);
virtual ~AnimationLayer() = default;
@@ -806,7 +806,7 @@ private:
using AnimationLayerList = std::vector<const AnimationLayer*>;
/** Represents a FBX animation stack (i.e. a list of animation layers) */
class AnimationStack final : public Object {
class AnimationStack : public Object {
public:
AnimationStack(uint64_t id, const Element& element, const std::string& name, const Document& doc);
virtual ~AnimationStack() = default;
@@ -851,7 +851,7 @@ using WeightIndexArray = std::vector<unsigned int>;
/** DOM class for BlendShapeChannel deformers */
class BlendShapeChannel final : public Deformer {
class BlendShapeChannel : public Deformer {
public:
BlendShapeChannel(uint64_t id, const Element& element, const Document& doc, const std::string& name);
@@ -876,7 +876,7 @@ private:
};
/** DOM class for BlendShape deformers */
class BlendShape final : public Deformer {
class BlendShape : public Deformer {
public:
BlendShape(uint64_t id, const Element& element, const Document& doc, const std::string& name);
@@ -891,7 +891,7 @@ private:
};
/** DOM class for skin deformer clusters (aka sub-deformers) */
class Cluster final : public Deformer {
class Cluster : public Deformer {
public:
Cluster(uint64_t id, const Element& element, const Document& doc, const std::string& name);
@@ -935,7 +935,7 @@ private:
};
/** DOM class for skin deformers */
class Skin final : public Deformer {
class Skin : public Deformer {
public:
Skin(uint64_t id, const Element& element, const Document& doc, const std::string& name);
+2 -25
View File
@@ -1582,7 +1582,6 @@ void FBXExporter::WriteObjects () {
}
}
std::map<std::string, std::string> tpath_by_image;
// FbxVideo - stores images used by textures.
for (const auto &it : uid_by_image) {
FBX::Node n("Video");
@@ -1602,21 +1601,10 @@ void FBXExporter::WriteObjects () {
std::stringstream newPath;
if (embedded_texture->mFilename.length > 0) {
newPath << embedded_texture->mFilename.C_Str();
// If newPath doesn't end in an extension, add extension from embedded_texture->achFormatHint
std::string np = newPath.str();
size_t dot_pos = np.find_last_of('.');
if (dot_pos == std::string::npos || dot_pos < np.find_last_of("/\\")) {
// No extension found, add one
newPath << "." << embedded_texture->achFormatHint;
}
} else if (embedded_texture->achFormatHint[0]) {
int texture_index = std::stoi(path.substr(1, path.size() - 1));
newPath << texture_index << "." << embedded_texture->achFormatHint;
}
auto elem = tpath_by_image.find(path);
if (elem == tpath_by_image.end()) {
tpath_by_image[path] = newPath.str();
}
path = newPath.str();
// embed the texture
size_t texture_size = static_cast<size_t>(embedded_texture->mWidth * std::max(embedded_texture->mHeight, 1u));
@@ -1735,17 +1723,6 @@ void FBXExporter::WriteObjects () {
unsigned int max = sizeof(aiUVTransform);
aiGetMaterialFloatArray(mat, AI_MATKEY_UVTRANSFORM(aiTextureType_DIFFUSE, 0), (ai_real *)&trafo, &max);
auto tp_elem = tpath_by_image.find(texture_path);
std::string tfile_path = texture_path;
if (tp_elem != tpath_by_image.end()) {
tfile_path = tp_elem->second;
} else {
std::stringstream err;
err << "Texture path not found for texure " << texture_path;
err << " on material " << i;
ASSIMP_LOG_WARN(err.str());
}
// now write the actual texture node
FBX::Node tnode("Texture");
// TODO: some way to determine texture name?
@@ -1766,8 +1743,8 @@ void FBXExporter::WriteObjects () {
// can't easily determine which texture path will be correct,
// so just store what we have in every field.
// these being incorrect is a common problem with FBX anyway.
tnode.AddChild("FileName", tp_elem->second);
tnode.AddChild("RelativeFilename", tp_elem->second);
tnode.AddChild("FileName", texture_path);
tnode.AddChild("RelativeFilename", texture_path);
tnode.AddChild("ModelUVTranslation", double(0.0), double(0.0));
tnode.AddChild("ModelUVScaling", double(1.0), double(1.0));
tnode.AddChild("Texture_Alpha_Source", "None");
+1 -1
View File
@@ -67,7 +67,7 @@ typedef class basic_formatter<char, std::char_traits<char>, std::allocator<char>
///
/// See http://en.wikipedia.org/wiki/FBX
// -------------------------------------------------------------------------------------------
class FBXImporter final : public BaseImporter, public LogFunctions<FBXImporter> {
class FBXImporter : public BaseImporter, public LogFunctions<FBXImporter> {
public:
/// @brief The class constructor.
FBXImporter() = default;
+1 -1
View File
@@ -64,7 +64,7 @@ class Parser;
class Element;
using ScopeList = std::vector<Scope*>;
using ElementMap = std::multimap< std::string, Element*>;
using ElementMap = std::fbx_unordered_multimap< std::string, Element*>;
using ElementCollection = std::pair<ElementMap::const_iterator,ElementMap::const_iterator>;
#define new_Scope new (allocator.Allocate(sizeof(Scope))) Scope
+9 -2
View File
@@ -50,7 +50,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <string>
#include <cstring>
namespace Assimp::FBX::Util {
#ifndef ASSIMP_BUILD_NO_FBX_IMPORTER
namespace Assimp {
namespace FBX {
namespace Util {
// ------------------------------------------------------------------------------------------------
const char* TokenTypeString(TokenType t)
@@ -229,5 +233,8 @@ std::string EncodeBase64(const char* data, size_t length)
return encoded_string;
}
} // namespace Assimp::FBX::Util
} // !Util
} // !FBX
} // !Assimp
#endif
+9 -1
View File
@@ -49,7 +49,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "FBXTokenizer.h"
#include <stdint.h>
namespace Assimp::FBX::Util {
namespace Assimp {
namespace FBX {
namespace Util {
/** helper for std::for_each to delete all heap-allocated items in a container */
template<typename T>
@@ -70,9 +73,12 @@ struct destructor_fun {
}
};
/** Get a string representation for a #TokenType. */
const char* TokenTypeString(TokenType t);
/** Format log/error messages using a given offset in the source binary file
*
* @param offset offset within the file
@@ -123,6 +129,8 @@ char EncodeBase64(char byte);
* @return base64-encoded string*/
std::string EncodeBase64(const char* data, size_t length);
}
}
}
#endif // ! INCLUDED_AI_FBX_UTIL_H
+3 -3
View File
@@ -162,7 +162,7 @@ aiMesh *IRRImporter::BuildSingleQuadMesh(const SkyboxVertex &v1,
}
// ------------------------------------------------------------------------------------------------
void IRRImporter::BuildSkybox(std::vector<aiMesh *> &meshes, std::vector<aiMaterial *> materials) {
void IRRImporter::BuildSkybox(MeshArray &meshes, std::vector<aiMaterial *> materials) {
// Update the material of the skybox - replace the name and disable shading for skyboxes.
for (unsigned int i = 0; i < 6; ++i) {
aiMaterial *out = (aiMaterial *)(*(materials.end() - (6 - i)));
@@ -602,7 +602,7 @@ void SetupMapping(aiMaterial *mat, aiTextureMapping mode, const aiVector3D &axis
// ------------------------------------------------------------------------------------------------
void IRRImporter::GenerateGraph(Node *root, aiNode *rootOut, aiScene *scene,
BatchLoader &batch,
std::vector<aiMesh *> &meshes,
MeshArray &meshes,
std::vector<aiNodeAnim *> &anims,
std::vector<AttachmentInfo> &attach,
std::vector<aiMaterial *> &materials,
@@ -1283,7 +1283,7 @@ void IRRImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
std::vector<aiNodeAnim *> anims;
std::vector<aiMaterial *> materials;
std::vector<AttachmentInfo> attach;
std::vector<aiMesh *> meshes;
MeshArray meshes;
// try to guess how much storage we'll need
anims.reserve(guessedAnimCnt + (guessedAnimCnt >> 2));
+2 -2
View File
@@ -229,7 +229,7 @@ private:
/// Fill the scene-graph recursively
void GenerateGraph(Node *root, aiNode *rootOut, aiScene *scene,
BatchLoader &batch,
std::vector<aiMesh *> &meshes,
MeshArray &meshes,
std::vector<aiNodeAnim *> &anims,
std::vector<AttachmentInfo> &attach,
std::vector<aiMaterial *> &materials,
@@ -248,7 +248,7 @@ private:
/// @param meshes Receives 6 output meshes
/// @param materials The last 6 materials are assigned to the newly
/// created meshes. The names of the materials are adjusted.
void BuildSkybox(std::vector<aiMesh *> &meshes,
void BuildSkybox(MeshArray &meshes,
std::vector<aiMaterial *> materials);
// -------------------------------------------------------------------
+1 -1
View File
@@ -121,7 +121,7 @@ void IRRMeshImporter::InternReadFile(const std::string &pFile,
// final data
std::vector<aiMaterial *> materials;
std::vector<aiMesh *> meshes;
MeshArray meshes;
materials.reserve(5);
meshes.reserve(5);
+1 -1
View File
@@ -239,7 +239,7 @@ void LWOImporter::InternReadFile(const std::string &pFile,
ResolveClips();
// now process all layers and build meshes and nodes
std::vector<aiMesh *> apcMeshes;
MeshArray apcMeshes;
std::map<uint16_t, aiNode *> apcNodes;
apcMeshes.reserve(mLayers->size() * std::min(((unsigned int)mSurfaces->size() / 2u), 1u));
+3 -1
View File
@@ -5,6 +5,8 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2025, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
@@ -1148,4 +1150,4 @@ void LWOImporter::LoadLWO3Surface(unsigned int size) {
}
}
#endif // ASSIMP_BUILD_NO_LWO_IMPORTER
#endif // !! ASSIMP_BUILD_NO_X_IMPORTER
+1 -1
View File
@@ -332,7 +332,7 @@ void M3DImporter::importTextures(const M3DWrapper &m3d) {
/* if we have the texture loaded, set format hint and pcData too */
tx->mWidth = t->w;
tx->mHeight = t->h;
strncpy(tx->achFormatHint, formatHint[t->f - 1], 8);
strcpy(tx->achFormatHint, formatHint[t->f - 1]);
tx->pcData = new aiTexel[tx->mWidth * tx->mHeight];
for (j = k = 0; j < tx->mWidth * tx->mHeight; j++) {
switch (t->f) {
+5 -13
View File
@@ -390,21 +390,13 @@ void MD3Importer::ValidateHeaderOffsets() {
void MD3Importer::ValidateSurfaceHeaderOffsets(const MD3::Surface *pcSurf) {
// Calculate the relative offset of the surface
const int32_t ofs = int32_t((const unsigned char *)pcSurf - this->mBuffer);
if (ofs + sizeof(MD3::Surface) > fileSize) {
throw DeadlyImportError("Surface header is outside file bounds");
}
auto inRange = [this, ofs](uint32_t rel_offset, uint32_t count, size_t elem_size) -> bool {
size_t abs_offset = ofs + rel_offset;
if (count > 0 && elem_size > 0 && count > SIZE_MAX / elem_size) return false;
size_t total = abs_offset + size_t(count) * elem_size;
return abs_offset <= fileSize && total <= fileSize;
};
// Check whether all data chunks are inside the valid range
if (!inRange(pcSurf->OFS_TRIANGLES, pcSurf->NUM_TRIANGLES, sizeof(MD3::Triangle)) ||
!inRange(pcSurf->OFS_SHADERS, pcSurf->NUM_SHADER, sizeof(MD3::Shader)) ||
!inRange(pcSurf->OFS_ST, pcSurf->NUM_VERTICES, sizeof(MD3::TexCoord)) ||
!inRange(pcSurf->OFS_XYZNORMAL, pcSurf->NUM_VERTICES, sizeof(MD3::Vertex))) {
if (pcSurf->OFS_TRIANGLES + ofs + pcSurf->NUM_TRIANGLES * sizeof(MD3::Triangle) > fileSize ||
pcSurf->OFS_SHADERS + ofs + pcSurf->NUM_SHADER * sizeof(MD3::Shader) > fileSize ||
pcSurf->OFS_ST + ofs + pcSurf->NUM_VERTICES * sizeof(MD3::TexCoord) > fileSize ||
pcSurf->OFS_XYZNORMAL + ofs + pcSurf->NUM_VERTICES * sizeof(MD3::Vertex) > fileSize) {
throw DeadlyImportError("Invalid MD3 surface header: some offsets are outside the file");
}
+6 -10
View File
@@ -361,19 +361,19 @@ void MD5Importer::LoadMD5MeshFile() {
#else
// FIX: MD5 files exported from Blender can have empty meshes
unsigned int numMaterials = 0;
for (std::vector<MD5::MeshDesc>::const_iterator it = meshParser.mMeshes.begin(), end = meshParser.mMeshes.end(); it != end; ++it) {
if (!(*it).mFaces.empty() && !(*it).mVertices.empty()) {
++numMaterials;
++mScene->mNumMaterials;
}
}
// generate all meshes
mScene->mMeshes = new aiMesh *[numMaterials];
mScene->mMaterials = new aiMaterial *[numMaterials];
mScene->mNumMeshes = mScene->mNumMaterials;
mScene->mMeshes = new aiMesh *[mScene->mNumMeshes];
mScene->mMaterials = new aiMaterial *[mScene->mNumMeshes];
// storage for node mesh indices
pcNode->mNumMeshes = numMaterials;
pcNode->mNumMeshes = mScene->mNumMeshes;
pcNode->mMeshes = new unsigned int[pcNode->mNumMeshes];
for (unsigned int m = 0; m < pcNode->mNumMeshes; ++m) {
pcNode->mMeshes[m] = m;
@@ -386,10 +386,7 @@ void MD5Importer::LoadMD5MeshFile() {
continue;
}
aiMesh* mesh = new aiMesh();
mScene->mMeshes[n] = mesh;
++mScene->mNumMeshes;
aiMesh *mesh = mScene->mMeshes[n] = new aiMesh();
mesh->mPrimitiveTypes = aiPrimitiveType_TRIANGLE;
// generate unique vertices in our internal verbose format
@@ -511,7 +508,6 @@ void MD5Importer::LoadMD5MeshFile() {
// generate a material for the mesh
aiMaterial *mat = new aiMaterial();
mScene->mMaterials[n] = mat;
++mScene->mNumMaterials;
// insert the typical doom3 textures:
// nnn_local.tga - normal map
+2 -6
View File
@@ -393,15 +393,11 @@ MD5MeshParser::MD5MeshParser(SectionArray &mSections) {
else if (TokenMatch(sz, "tri", 3)) {
AI_MD5_SKIP_SPACES(&sz, elem.end, elem.iLineNumber);
const unsigned int idx = strtoul10(sz, &sz);
if (idx >= desc.mFaces.size()) {
if (idx >= desc.mFaces.size())
desc.mFaces.resize(idx + 1);
}
aiFace &face = desc.mFaces[idx];
if (face.mNumIndices != 3) {
delete [] face.mIndices;
face.mIndices = new unsigned int[face.mNumIndices = 3];
}
face.mIndices = new unsigned int[face.mNumIndices = 3];
for (unsigned int i = 0; i < 3; ++i) {
AI_MD5_SKIP_SPACES(&sz, elem.end, elem.iLineNumber);
face.mIndices[i] = strtoul10(sz, &sz);
+1 -18
View File
@@ -160,7 +160,6 @@ void MDCImporter::ValidateSurfaceHeader(BE_NCONST MDC::Surface *pcSurf) {
AI_SWAP4(pcSurf->ulOffsetTexCoords);
AI_SWAP4(pcSurf->ulOffsetBaseVerts);
AI_SWAP4(pcSurf->ulOffsetCompVerts);
AI_SWAP4(pcSurf->ulOffsetShaders);
AI_SWAP4(pcSurf->ulOffsetFrameBaseFrames);
AI_SWAP4(pcSurf->ulOffsetFrameCompFrames);
AI_SWAP4(pcSurf->ulOffsetEnd);
@@ -173,8 +172,7 @@ void MDCImporter::ValidateSurfaceHeader(BE_NCONST MDC::Surface *pcSurf) {
pcSurf->ulOffsetTexCoords + pcSurf->ulNumVertices * sizeof(MDC::TexturCoord) > iMax ||
pcSurf->ulOffsetShaders + pcSurf->ulNumShaders * sizeof(MDC::Shader) > iMax ||
pcSurf->ulOffsetFrameBaseFrames + pcSurf->ulNumBaseFrames * 2 > iMax ||
(pcSurf->ulNumCompFrames && pcSurf->ulOffsetFrameCompFrames + pcSurf->ulNumCompFrames * 2 > iMax) ||
pcSurf->ulOffsetEnd > iMax) {
(pcSurf->ulNumCompFrames && pcSurf->ulOffsetFrameCompFrames + pcSurf->ulNumCompFrames * 2 > iMax)) {
throw DeadlyImportError("Some of the offset values in the MDC surface header "
"are invalid and point somewhere behind the file.");
}
@@ -326,15 +324,6 @@ void MDCImporter::InternReadFile(
#endif
// boundary check for pcVerts
auto surfStart = reinterpret_cast<const uint8_t*>(pcSurface);
const uint8_t* surfEnd = surfStart + pcSurface->ulOffsetEnd;
auto vertBufStart = reinterpret_cast<const uint8_t*>(pcVerts);
const size_t needVertBytes = sizeof(MDC::BaseVertex) * pcSurface->ulNumVertices;
if (vertBufStart < surfStart || vertBufStart + needVertBytes > surfEnd) {
throw DeadlyImportError("MDCImporter: pcVerts points outside of surface block.");
}
const MDC::CompressedVertex *pcCVerts = nullptr;
int16_t *mdcCompVert = nullptr;
@@ -346,12 +335,6 @@ void MDCImporter::InternReadFile(
pcCVerts = (const MDC::CompressedVertex *)((int8_t *)pcSurface +
pcSurface->ulOffsetCompVerts) +
*mdcCompVert * pcSurface->ulNumVertices;
auto cvertBufStart = reinterpret_cast<const uint8_t*>(pcCVerts);
const size_t needCompVertBytes = sizeof(MDC::CompressedVertex) * pcSurface->ulNumVertices;
if (cvertBufStart < surfStart || cvertBufStart > surfEnd ||
needCompVertBytes > static_cast<size_t>(surfEnd - cvertBufStart)) {
throw DeadlyImportError("MDCImporter: pcCVerts points outside of surface block.");
}
} else
mdcCompVert = nullptr;
}
-182
View File
@@ -1,182 +0,0 @@
/*
---------------------------------------------------------------------------
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2026, 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 HL1DataBuffer.h
* @brief Declaration of the Half-Life 1 data buffer.
*/
#ifndef AI_HL1DATABUFFER_INCLUDED
#define AI_HL1DATABUFFER_INCLUDED
#include <assimp/Exceptional.h>
#include <assimp/defs.h>
#include <cstddef>
#include <memory>
namespace Assimp {
namespace MDL {
namespace HalfLife {
/**
* \brief Lightweight byte buffer wrapper for HL1 binary parsing.
*
* Acts as either:
* - a non-owning view into external memory, or
* - an owning buffer backed by a unique_ptr.
*
* Copy is disabled to avoid accidental double-ownership; move is supported.
*/
class HL1DataBuffer {
public:
/** \brief Construct an empty buffer (null view). */
HL1DataBuffer() AI_NO_EXCEPT : data_(nullptr),
length_(0),
owner_(nullptr) {}
/** \brief Non-copyable (buffer may own memory). */
HL1DataBuffer(const HL1DataBuffer &) = delete;
/** \brief Non-copyable (buffer may own memory). */
HL1DataBuffer &operator=(const HL1DataBuffer &) = delete;
/** \brief Move-construct, transferring ownership/view state. */
HL1DataBuffer(HL1DataBuffer &&other) AI_NO_EXCEPT : data_(other.data_),
length_(other.length_),
owner_(std::move(other.owner_)) {
other.data_ = nullptr;
other.length_ = 0;
other.owner_ = nullptr;
}
/** \brief Move-assign, transferring ownership/view state. */
HL1DataBuffer &operator=(HL1DataBuffer &&other) AI_NO_EXCEPT {
if (this != &other) {
data_ = other.data_;
length_ = other.length_;
owner_ = std::move(other.owner_);
other.data_ = nullptr;
other.length_ = 0;
other.owner_ = nullptr;
}
return *this;
}
/**
* \brief Create a non-owning view into external bytes.
*
* \param[in] data Pointer to raw bytes (must outlive the view).
* \param[in] length Size in bytes.
*/
static HL1DataBuffer view(const unsigned char *data, size_t length) {
HL1DataBuffer b;
b.data_ = data;
b.length_ = length;
b.owner_ = nullptr;
return b;
}
/**
* \brief Create a non-owning view of another buffer.
*
* \param[in] other Source buffer.
*/
static HL1DataBuffer view(const HL1DataBuffer &other) {
HL1DataBuffer b;
b.data_ = other.data_;
b.length_ = other.length_;
b.owner_ = nullptr;
return b;
}
/**
* \brief Create an owning buffer by taking ownership of allocated storage.
*
* \param[in] buffer Unique buffer storage.
* \param[in] length Size in bytes.
*/
static HL1DataBuffer owning(std::unique_ptr<unsigned char[]> buffer, size_t length) {
HL1DataBuffer b;
b.data_ = buffer.get();
b.length_ = length;
b.owner_ = std::move(buffer);
return b;
}
/**
* \brief Return a typed pointer into the buffer with bounds checks.
*
* \param[in] offset Byte offset from the start of the buffer.
* \param[in] elements Number of elements to access.
* \return Pointer to the requested typed data inside the buffer.
* \throws DeadlyImportError if the request is out of range.
*/
template <typename DataType>
const DataType *get_data(int offset, int elements) const {
if (offset < 0 || elements < 0) {
throw DeadlyImportError("MDL file contains invalid data");
}
const size_t uoffset = static_cast<size_t>(offset);
const size_t uelements = static_cast<size_t>(elements);
if (uoffset > length_ || uelements > (length_ - uoffset) / sizeof(DataType)) {
throw DeadlyImportError("MDL file contains invalid data");
}
return reinterpret_cast<const DataType *>(data_ + uoffset);
}
private:
/** Raw byte pointer (points to owner_.get() when owning, otherwise external). */
const unsigned char *data_;
/** Buffer length in bytes. */
size_t length_;
/** Owning storage (null for views). */
std::unique_ptr<unsigned char[]> owner_;
};
} // namespace HalfLife
} // namespace MDL
} // namespace Assimp
#endif // AI_HL1DATABUFFER_INCLUDED
+77 -58
View File
@@ -78,19 +78,18 @@ HL1MDLLoader::HL1MDLLoader(
aiScene *scene,
IOSystem *io,
const unsigned char *buffer,
size_t buffer_length,
const std::string &file_path,
const HL1ImportSettings &import_settings) :
scene_(scene),
io_(io),
buffer_(HL1DataBuffer::view(buffer, buffer_length)),
buffer_(buffer),
file_path_(file_path),
import_settings_(import_settings),
header_(nullptr),
texture_header_(nullptr),
anim_headers_(),
texture_buffer_(),
anim_buffers_(),
anim_headers_(nullptr),
texture_buffer_(nullptr),
anim_buffers_(nullptr),
num_sequence_groups_(0),
rootnode_children_(),
unique_name_generator_(),
@@ -109,6 +108,28 @@ HL1MDLLoader::~HL1MDLLoader() {
// ------------------------------------------------------------------------------------------------
void HL1MDLLoader::release_resources() {
if (buffer_ != texture_buffer_) {
delete[] texture_buffer_;
texture_buffer_ = nullptr;
}
if (num_sequence_groups_ && anim_buffers_) {
for (int i = 1; i < num_sequence_groups_; ++i) {
if (anim_buffers_[i]) {
delete[] anim_buffers_[i];
anim_buffers_[i] = nullptr;
}
}
delete[] anim_buffers_;
anim_buffers_ = nullptr;
}
if (anim_headers_) {
delete[] anim_headers_;
anim_headers_ = nullptr;
}
// Root has some children nodes. so let's proceed them
if (!rootnode_children_.empty()) {
// Here, it means that the nodes were not added to the
@@ -126,7 +147,7 @@ void HL1MDLLoader::release_resources() {
// ------------------------------------------------------------------------------------------------
void HL1MDLLoader::load_file() {
try {
header_ = get_buffer_data<Header_HL1>(0, 1);
header_ = (const Header_HL1 *)buffer_;
validate_header(header_, false);
// Create the root scene node.
@@ -265,10 +286,10 @@ void HL1MDLLoader::load_texture_file() {
load_file_into_buffer<Header_HL1>(texture_file_path, texture_buffer_);
} else {
// Model has no external texture file. This means the texture is stored inside the main MDL file.
texture_buffer_ = HL1DataBuffer::view(buffer_);
texture_buffer_ = const_cast<unsigned char *>(buffer_);
}
texture_header_ = get_texture_buffer_data<Header_HL1>(0, 1);
texture_header_ = (const Header_HL1 *)texture_buffer_;
// Validate texture header.
validate_header(texture_header_, true);
@@ -297,8 +318,12 @@ void HL1MDLLoader::load_sequence_groups_files() {
num_sequence_groups_ = header_->numseqgroups;
anim_buffers_.resize(num_sequence_groups_);
anim_headers_.resize(num_sequence_groups_, nullptr);
anim_buffers_ = new unsigned char *[num_sequence_groups_];
anim_headers_ = new SequenceHeader_HL1 *[num_sequence_groups_];
for (int i = 0; i < num_sequence_groups_; ++i) {
anim_buffers_[i] = nullptr;
anim_headers_[i] = nullptr;
}
std::string file_path_without_extension =
DefaultIOSystem::absolutePath(file_path_) +
@@ -315,14 +340,14 @@ void HL1MDLLoader::load_sequence_groups_files() {
load_file_into_buffer<SequenceHeader_HL1>(sequence_file_path, anim_buffers_[i]);
anim_headers_[i] = get_anim_buffer_data<SequenceHeader_HL1>(i, 0, 1);
anim_headers_[i] = (SequenceHeader_HL1 *)anim_buffers_[i];
}
}
// ------------------------------------------------------------------------------------------------
// Read an MDL texture.
void HL1MDLLoader::read_texture(const Texture_HL1 *ptexture,
const uint8_t *data, const uint8_t *pal, aiTexture *pResult,
uint8_t *data, uint8_t *pal, aiTexture *pResult,
aiColor3D &last_palette_color) {
pResult->mFilename = ptexture->name;
pResult->mWidth = static_cast<unsigned int>(ptexture->width);
@@ -356,24 +381,24 @@ void HL1MDLLoader::read_texture(const Texture_HL1 *ptexture,
// ------------------------------------------------------------------------------------------------
void HL1MDLLoader::read_textures() {
scene_->mTextures = new aiTexture *[texture_header_->numtextures];
scene_->mMaterials = new aiMaterial *[texture_header_->numtextures];
const Texture_HL1 *ptexture = (const Texture_HL1 *)((uint8_t *)texture_header_ + texture_header_->textureindex);
unsigned char *pin = texture_buffer_;
const Texture_HL1 *ptexture = get_texture_buffer_data<Texture_HL1>(texture_header_->textureindex, texture_header_->numtextures);
scene_->mNumTextures = scene_->mNumMaterials = texture_header_->numtextures;
scene_->mTextures = new aiTexture *[scene_->mNumTextures];
scene_->mMaterials = new aiMaterial *[scene_->mNumMaterials];
for (int i = 0; i < texture_header_->numtextures; ++i) {
scene_->mTextures[i] = new aiTexture();
++scene_->mNumTextures;
const uint8_t *data = get_texture_buffer_data<uint8_t>(ptexture[i].index, ptexture[i].width * ptexture[i].height);
const uint8_t *pal = get_texture_buffer_data<uint8_t>(ptexture[i].index + ptexture[i].width * ptexture[i].height, 256 * 3);
aiColor3D last_palette_color;
read_texture(&ptexture[i], data, pal, scene_->mTextures[i], last_palette_color);
read_texture(&ptexture[i],
pin + ptexture[i].index,
pin + ptexture[i].width * ptexture[i].height + ptexture[i].index,
scene_->mTextures[i],
last_palette_color);
aiMaterial *scene_material = new aiMaterial();
scene_->mMaterials[i] = scene_material;
++scene_->mNumMaterials;
aiMaterial *scene_material = scene_->mMaterials[i] = new aiMaterial();
const aiTextureType texture_type = aiTextureType_DIFFUSE;
aiString texture_name(ptexture[i].name);
@@ -410,14 +435,10 @@ void HL1MDLLoader::read_skins() {
}
// Pointer to base texture index.
const short *default_skin_ptr = get_texture_buffer_data<short>(
texture_header_->skinindex,
texture_header_->numskinref);
short *default_skin_ptr = (short *)((uint8_t *)texture_header_ + texture_header_->skinindex);
// Start at first replacement skin.
const short *replacement_skin_ptr = get_texture_buffer_data<short>(
texture_header_->skinindex + texture_header_->numskinref * sizeof(short),
(texture_header_->numskinfamilies - 1) * texture_header_->numskinref);
short *replacement_skin_ptr = default_skin_ptr + texture_header_->numskinref;
for (int i = 1; i < texture_header_->numskinfamilies; ++i, replacement_skin_ptr += texture_header_->numskinref) {
for (int j = 0; j < texture_header_->numskinref; ++j) {
@@ -436,7 +457,7 @@ void HL1MDLLoader::read_bones() {
return;
}
const Bone_HL1 *pbone = get_buffer_data<Bone_HL1>(header_->boneindex, header_->numbones);
const Bone_HL1 *pbone = (const Bone_HL1 *)((uint8_t *)header_ + header_->boneindex);
std::vector<std::string> unique_bones_names(header_->numbones);
for (int i = 0; i < header_->numbones; ++i) {
@@ -568,12 +589,12 @@ void HL1MDLLoader::read_meshes() {
int total_triangles = 0;
total_models_ = 0;
const Bodypart_HL1 *pbodypart = get_buffer_data<Bodypart_HL1>(header_->bodypartindex, header_->numbodyparts);
const Bodypart_HL1 *pbodypart = (const Bodypart_HL1 *)((uint8_t *)header_ + header_->bodypartindex);
const Model_HL1 *pmodel = nullptr;
const Mesh_HL1 *pmesh = nullptr;
const Texture_HL1 *ptexture = get_texture_buffer_data<Texture_HL1>(texture_header_->textureindex, texture_header_->numtextures);
const short *pskinref = get_texture_buffer_data<short>(texture_header_->skinindex, texture_header_->numskinref);
const Texture_HL1 *ptexture = (const Texture_HL1 *)((uint8_t *)texture_header_ + texture_header_->textureindex);
short *pskinref = (short *)((uint8_t *)texture_header_ + texture_header_->skinindex);
scene_->mNumMeshes = 0;
@@ -585,7 +606,7 @@ void HL1MDLLoader::read_meshes() {
for (int i = 0; i < header_->numbodyparts; ++i, ++pbodypart) {
unique_bodyparts_names[i] = pbodypart->name;
pmodel = get_buffer_data<Model_HL1>(pbodypart->modelindex, pbodypart->nummodels);
pmodel = (Model_HL1 *)((uint8_t *)header_ + pbodypart->modelindex);
for (int j = 0; j < pbodypart->nummodels; ++j, ++pmodel) {
scene_->mNumMeshes += pmodel->nummesh;
total_verts += pmodel->numverts;
@@ -612,7 +633,7 @@ void HL1MDLLoader::read_meshes() {
unique_name_generator_.make_unique(unique_bodyparts_names);
// Now do the same for each model.
pbodypart = get_buffer_data<Bodypart_HL1>(header_->bodypartindex, header_->numbodyparts);
pbodypart = (const Bodypart_HL1 *)((uint8_t *)header_ + header_->bodypartindex);
// Prepare template name for bodypart models.
std::vector<std::string> unique_models_names;
@@ -621,7 +642,7 @@ void HL1MDLLoader::read_meshes() {
unsigned int model_index = 0;
for (int i = 0; i < header_->numbodyparts; ++i, ++pbodypart) {
pmodel = get_buffer_data<Model_HL1>(pbodypart->modelindex, pbodypart->nummodels);
pmodel = (Model_HL1 *)((uint8_t *)header_ + pbodypart->modelindex);
for (int j = 0; j < pbodypart->nummodels; ++j, ++pmodel, ++model_index)
unique_models_names[model_index] = pmodel->name;
}
@@ -633,7 +654,7 @@ void HL1MDLLoader::read_meshes() {
scene_->mMeshes = new aiMesh *[scene_->mNumMeshes];
pbodypart = get_buffer_data<Bodypart_HL1>(header_->bodypartindex, header_->numbodyparts);
pbodypart = (const Bodypart_HL1 *)((uint8_t *)header_ + header_->bodypartindex);
/* Create a node that will represent the mesh hierarchy.
@@ -717,7 +738,7 @@ void HL1MDLLoader::read_meshes() {
model_index = 0;
for (int i = 0; i < header_->numbodyparts; ++i, ++pbodypart, ++bodyparts_node_ptr) {
pmodel = get_buffer_data<Model_HL1>(pbodypart->modelindex, pbodypart->nummodels);
pmodel = (const Model_HL1 *)((uint8_t *)header_ + pbodypart->modelindex);
// Create bodypart node for the mesh tree hierarchy.
aiNode *bodypart_node = (*bodyparts_node_ptr) = new aiNode(unique_bodyparts_names[i]);
@@ -732,12 +753,12 @@ void HL1MDLLoader::read_meshes() {
for (int j = 0; j < pbodypart->nummodels;
++j, ++pmodel, ++bodypart_models_ptr, ++model_index) {
pmesh = get_buffer_data<Mesh_HL1>(pmodel->meshindex, pmodel->nummesh);
pmesh = (const Mesh_HL1 *)((uint8_t *)header_ + pmodel->meshindex);
const uint8_t *pvertbone = get_buffer_data<uint8_t>(pmodel->vertinfoindex, pmodel->numverts);
const uint8_t *pnormbone = get_buffer_data<uint8_t>(pmodel->norminfoindex, pmodel->numnorms);
const vec3_t *pstudioverts = get_buffer_data<vec3_t>(pmodel->vertindex, pmodel->numverts);
const vec3_t *pstudionorms = get_buffer_data<vec3_t>(pmodel->normindex, pmodel->numnorms);
uint8_t *pvertbone = ((uint8_t *)header_ + pmodel->vertinfoindex);
uint8_t *pnormbone = ((uint8_t *)header_ + pmodel->norminfoindex);
vec3_t *pstudioverts = (vec3_t *)((uint8_t *)header_ + pmodel->vertindex);
vec3_t *pstudionorms = (vec3_t *)((uint8_t *)header_ + pmodel->normindex);
// Each vertex and normal is in local space, so transform
// each of them to bring them in bind pose.
@@ -943,7 +964,7 @@ void HL1MDLLoader::read_animations() {
return;
}
const SequenceDesc_HL1 *pseqdesc = get_buffer_data<SequenceDesc_HL1>(header_->seqindex, header_->numseq);
const SequenceDesc_HL1 *pseqdesc = (const SequenceDesc_HL1 *)((uint8_t *)header_ + header_->seqindex);
const SequenceGroup_HL1 *pseqgroup = nullptr;
const AnimValueOffset_HL1 *panim = nullptr;
const AnimValue_HL1 *panimvalue = nullptr;
@@ -969,22 +990,22 @@ void HL1MDLLoader::read_animations() {
// Get the number of available blend controllers for global info.
get_num_blend_controllers(highest_num_blend_animations, num_blend_controllers_);
pseqdesc = get_buffer_data<SequenceDesc_HL1>(header_->seqindex, header_->numseq);
pseqdesc = (const SequenceDesc_HL1 *)((uint8_t *)header_ + header_->seqindex);
aiAnimation **scene_animations_ptr = scene_->mAnimations = new aiAnimation *[scene_->mNumAnimations];
for (int sequence = 0; sequence < header_->numseq; ++sequence, ++pseqdesc) {
pseqgroup = get_buffer_data<SequenceGroup_HL1>(header_->seqgroupindex + pseqdesc->seqgroup * sizeof(SequenceGroup_HL1), 1);
pseqgroup = (const SequenceGroup_HL1 *)((uint8_t *)header_ + header_->seqgroupindex) + pseqdesc->seqgroup;
if (pseqdesc->seqgroup == 0) {
panim = get_buffer_data<AnimValueOffset_HL1>(pseqgroup->unused2 + pseqdesc->animindex, pseqdesc->numblends * header_->numbones);
panim = (const AnimValueOffset_HL1 *)((uint8_t *)header_ + pseqgroup->unused2 + pseqdesc->animindex);
} else {
panim = get_anim_buffer_data<AnimValueOffset_HL1>(pseqdesc->seqgroup, pseqdesc->animindex, pseqdesc->numblends * header_->numbones);
panim = (const AnimValueOffset_HL1 *)((uint8_t *)anim_headers_[pseqdesc->seqgroup] + pseqdesc->animindex);
}
for (int blend = 0; blend < pseqdesc->numblends; ++blend, ++scene_animations_ptr) {
const Bone_HL1 *pbone = get_buffer_data<Bone_HL1>(header_->boneindex, header_->numbones);
const Bone_HL1 *pbone = (const Bone_HL1 *)((uint8_t *)header_ + header_->boneindex);
aiAnimation *scene_animation = (*scene_animations_ptr) = new aiAnimation();
@@ -1053,7 +1074,7 @@ void HL1MDLLoader::read_sequence_groups_info() {
sequence_groups_node->mNumChildren = static_cast<unsigned int>(header_->numseqgroups);
sequence_groups_node->mChildren = new aiNode *[sequence_groups_node->mNumChildren];
const SequenceGroup_HL1 *pseqgroup = get_buffer_data<SequenceGroup_HL1>(header_->seqgroupindex, header_->numseqgroups);
const SequenceGroup_HL1 *pseqgroup = (const SequenceGroup_HL1 *)((uint8_t *)header_ + header_->seqgroupindex);
unique_sequence_groups_names_.resize(header_->numseqgroups);
for (int i = 0; i < header_->numseqgroups; ++i) {
@@ -1085,7 +1106,7 @@ void HL1MDLLoader::read_sequence_infos() {
return;
}
const SequenceDesc_HL1 *pseqdesc = get_buffer_data<SequenceDesc_HL1>(header_->seqindex, header_->numseq);
const SequenceDesc_HL1 *pseqdesc = (const SequenceDesc_HL1 *)((uint8_t *)header_ + header_->seqindex);
aiNode *sequence_infos_node = new aiNode(AI_MDL_HL1_NODE_SEQUENCE_INFOS);
rootnode_children_.push_back(sequence_infos_node);
@@ -1157,7 +1178,7 @@ void HL1MDLLoader::read_sequence_infos() {
pseqdesc->numevents, "animation events");
}
const AnimEvent_HL1 *pevent = get_buffer_data<AnimEvent_HL1>(pseqdesc->eventindex, pseqdesc->numevents);
const AnimEvent_HL1 *pevent = (const AnimEvent_HL1 *)((uint8_t *)header_ + pseqdesc->eventindex);
aiNode *pEventsNode = new aiNode(AI_MDL_HL1_NODE_ANIMATION_EVENTS);
sequence_info_node_children.push_back(pEventsNode);
@@ -1194,7 +1215,7 @@ void HL1MDLLoader::read_sequence_transitions() {
aiNode *transition_graph_node = new aiNode(AI_MDL_HL1_NODE_SEQUENCE_TRANSITION_GRAPH);
rootnode_children_.push_back(transition_graph_node);
const uint8_t *ptransitions = get_buffer_data<uint8_t>(header_->transitionindex, header_->numtransitions * header_->numtransitions);
uint8_t *ptransitions = ((uint8_t *)header_ + header_->transitionindex);
aiMetadata *md = transition_graph_node->mMetaData = aiMetadata::Alloc(header_->numtransitions * header_->numtransitions);
for (unsigned int i = 0; i < md->mNumProperties; ++i)
md->Set(i, std::to_string(i), static_cast<int>(ptransitions[i]));
@@ -1205,7 +1226,7 @@ void HL1MDLLoader::read_attachments() {
return;
}
const Attachment_HL1 *pattach = get_buffer_data<Attachment_HL1>(header_->attachmentindex, header_->numattachments);
const Attachment_HL1 *pattach = (const Attachment_HL1 *)((uint8_t *)header_ + header_->attachmentindex);
aiNode *attachments_node = new aiNode(AI_MDL_HL1_NODE_ATTACHMENTS);
rootnode_children_.push_back(attachments_node);
@@ -1229,7 +1250,7 @@ void HL1MDLLoader::read_hitboxes() {
return;
}
const Hitbox_HL1 *phitbox = get_buffer_data<Hitbox_HL1>(header_->hitboxindex, header_->numhitboxes);
const Hitbox_HL1 *phitbox = (const Hitbox_HL1 *)((uint8_t *)header_ + header_->hitboxindex);
aiNode *hitboxes_node = new aiNode(AI_MDL_HL1_NODE_HITBOXES);
rootnode_children_.push_back(hitboxes_node);
@@ -1256,9 +1277,7 @@ void HL1MDLLoader::read_bone_controllers() {
return;
}
const BoneController_HL1 *pbonecontroller = get_buffer_data<BoneController_HL1>(
header_->bonecontrollerindex,
header_->numbonecontrollers);
const BoneController_HL1 *pbonecontroller = (const BoneController_HL1 *)((uint8_t *)header_ + header_->bonecontrollerindex);
aiNode *bones_controller_node = new aiNode(AI_MDL_HL1_NODE_BONE_CONTROLLERS);
rootnode_children_.push_back(bones_controller_node);
+11 -56
View File
@@ -47,7 +47,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define AI_HL1MDLLOADER_INCLUDED
#include "HL1FileData.h"
#include "HL1DataBuffer.h"
#include "HL1ImportSettings.h"
#include "UniqueNameGenerator.h"
@@ -75,7 +74,6 @@ public:
aiScene *scene,
IOSystem *io,
const unsigned char *buffer,
size_t buffer_length,
const std::string &file_path,
const HL1ImportSettings &import_settings);
@@ -111,32 +109,10 @@ private:
/** \brief Load a file and copy it's content to a buffer.
* \param file_path The path to the file to be loaded.
* \param buffer A buffer to receive the data.
* \param buffer A pointer to a buffer to receive the data.
*/
template <typename MDLFileHeader>
void load_file_into_buffer(const std::string &file_path, HL1DataBuffer &buffer);
/** \brief Get a pointer to the specified data type in texture buffer.
* \param offset Offset in bytes.
* \param elements Elements count.
*/
template <typename DataType>
const DataType *get_texture_buffer_data(int offset, int elements);
/** \brief Get a pointer to the specified data type in animation buffer.
* \param animation Animation index.
* \param offset Offset in bytes.
* \param elements Elements count.
*/
template <typename DataType>
const DataType *get_anim_buffer_data(int animation, int offset, int elements);
/** \brief Get a pointer to the specified data type in MDL buffer.
* \param offset Offset in bytes.
* \param elements Elements count.
*/
template <typename DataType>
const DataType *get_buffer_data(int offset, int elements);
void load_file_into_buffer(const std::string &file_path, unsigned char *&buffer);
/** \brief Read an MDL texture.
* \param[in] ptexture A pointer to an MDL texture.
@@ -146,7 +122,7 @@ private:
* \param[in,out] last_palette_color The last color from the image palette.
*/
void read_texture(const Texture_HL1 *ptexture,
const uint8_t *data, const uint8_t *pal, aiTexture *pResult,
uint8_t *data, uint8_t *pal, aiTexture *pResult,
aiColor3D &last_palette_color);
/** \brief This method reads a compressed anim value.
@@ -182,7 +158,7 @@ private:
IOSystem *io_;
/** Buffer from MDLLoader class. */
const HL1DataBuffer buffer_;
const unsigned char *buffer_;
/** The full file path to the MDL file we are trying to load.
* Used to locate other MDL files since MDL may store resources
@@ -200,13 +176,13 @@ private:
/** External MDL animation headers.
* One for each loaded animation file. */
std::vector<const SequenceHeader_HL1*> anim_headers_;
SequenceHeader_HL1 **anim_headers_;
/** Texture file data. */
HL1DataBuffer texture_buffer_;
unsigned char *texture_buffer_;
/** Animation files data. */
std::vector<HL1DataBuffer> anim_buffers_;
unsigned char **anim_buffers_;
/** The number of sequence groups. */
int num_sequence_groups_;
@@ -250,7 +226,7 @@ private:
// ------------------------------------------------------------------------------------------------
template <typename MDLFileHeader>
void HL1MDLLoader::load_file_into_buffer(const std::string &file_path, HL1DataBuffer &buffer) {
void HL1MDLLoader::load_file_into_buffer(const std::string &file_path, unsigned char *&buffer) {
if (!io_->Exists(file_path))
throw DeadlyImportError("Missing file ", DefaultIOSystem::fileName(file_path), ".");
@@ -265,30 +241,9 @@ void HL1MDLLoader::load_file_into_buffer(const std::string &file_path, HL1DataBu
throw DeadlyImportError("MDL file is too small.");
}
std::unique_ptr<unsigned char[]> data(new unsigned char[1 + file_size]);
file->Read(data.get(), 1, file_size);
data[file_size] = '\0';
buffer = HL1DataBuffer::owning(std::move(data), file_size);
}
template <typename DataType>
const DataType *HL1MDLLoader::get_texture_buffer_data(int offset, int elements) {
return texture_buffer_.get_data<DataType>(offset, elements);
}
template <typename DataType>
const DataType *HL1MDLLoader::get_anim_buffer_data(int animation, int offset, int elements) {
if (animation < 0 || animation >= num_sequence_groups_) {
throw DeadlyImportError("MDL file contains invalid sequence group index (", animation, ")");
}
return anim_buffers_[animation].get_data<DataType>(offset, elements);
}
template <typename DataType>
const DataType *HL1MDLLoader::get_buffer_data(int offset, int elements) {
return buffer_.get_data<DataType>(offset, elements);
buffer = new unsigned char[1 + file_size];
file->Read((void *)buffer, 1, file_size);
buffer[file_size] = '\0';
}
} // namespace HalfLife
+5 -16
View File
@@ -3,7 +3,7 @@
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2026, assimp team
Copyright (c) 2006-2025, assimp team
All rights reserved.
@@ -602,9 +602,6 @@ void MDLImporter::SetupMaterialProperties_3DGS_MDL5_Quake1() {
// Read a MDL 3,4,5 file
void MDLImporter::InternReadFile_3DGS_MDL345() {
ai_assert(nullptr != pScene);
if (pScene == nullptr) {
throw DeadlyImportError("INvalid scene pointer detected.");
}
// the header of MDL 3/4/5 is nearly identical to the original Quake1 header
BE_NCONST MDL::Header *pcHeader = (BE_NCONST MDL::Header *)this->mBuffer;
@@ -613,10 +610,6 @@ void MDLImporter::InternReadFile_3DGS_MDL345() {
#endif
ValidateHeader_Quake1(pcHeader);
if (pcHeader->synctype < 0) {
throw DeadlyImportError("Invalid synctype value in MDL header; possible corrupt file.");
}
// current cursor position in the file
const unsigned char *szCurrent = (const unsigned char *)(pcHeader + 1);
const unsigned char *szEnd = mBuffer + iFileSize;
@@ -626,7 +619,8 @@ void MDLImporter::InternReadFile_3DGS_MDL345() {
if (szCurrent + sizeof(uint32_t) > szEnd) {
throw DeadlyImportError("Texture data past end of file.");
}
BE_NCONST MDL::Skin *pcSkin = (BE_NCONST MDL::Skin *)szCurrent;
BE_NCONST MDL::Skin *pcSkin;
pcSkin = (BE_NCONST MDL::Skin *)szCurrent;
AI_SWAP4(pcSkin->group);
// create one output image
unsigned int iSkip = i ? UINT_MAX : 0;
@@ -1411,10 +1405,10 @@ void MDLImporter::InternReadFile_3DGS_MDL7() {
sharedData.apcOutBones = this->LoadBones_3DGS_MDL7();
// vector to held all created meshes
std::vector<aiMesh *> *avOutList;
MeshArray *avOutList;
// 3 meshes per group - that should be OK for most models
avOutList = new std::vector<aiMesh *>[pcHeader->groups_num];
avOutList = new MeshArray[pcHeader->groups_num];
for (uint32_t i = 0; i < pcHeader->groups_num; ++i)
avOutList[i].reserve(3);
@@ -1844,10 +1838,6 @@ void MDLImporter::GenerateOutputMeshes_3DGS_MDL7(
const unsigned int iNumOutBones = pcHeader->bones_num;
for (std::vector<aiMaterial *>::size_type i = 0; i < shared.pcMats.size(); ++i) {
if (splitGroupData.aiSplit == nullptr) {
continue;
}
if (!splitGroupData.aiSplit[i]->empty()) {
// allocate the output mesh
@@ -2001,7 +1991,6 @@ void MDLImporter::InternReadFile_HL1(const std::string &pFile, const uint32_t iM
pScene,
mIOHandler,
mBuffer,
iFileSize,
pFile,
mHL1ImportSettings);
}
+7 -4
View File
@@ -5,6 +5,8 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2025, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
@@ -44,8 +46,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* Written against http://chumbalum.swissquake.ch/ms3d/ms3dspec.txt
*/
#ifndef ASSIMP_BUILD_NO_MS3D_IMPORTER
// internal headers
#include "MS3DLoader.h"
#include <assimp/StreamReader.h>
#include <assimp/DefaultLogger.hpp>
@@ -388,14 +392,13 @@ void MS3DImporter::InternReadFile( const std::string& pFile,
if (need_default && materials.size()) {
ASSIMP_LOG_WARN("MS3D: Found group with no material assigned, spawning default material");
// if one of the groups has no material assigned, but there are other
// if one of the groups has no material assigned, but there are other
// groups with materials, a default material needs to be added (
// scenepreprocessor adds a default material only if nummat==0).
materials.emplace_back();
TempMaterial& m = materials.back();
constexpr char DefaultMat[18] = "<MS3D_DefaultMat>";
strncpy(m.name, DefaultMat, sizeof(m.name));
m.name[18]='\0';
strcpy(m.name,"<MS3D_DefaultMat>");
m.diffuse = aiColor4D(0.6f,0.6f,0.6f,1.0);
m.transparency = 1.f;
m.shininess = 0.f;
+15 -3
View File
@@ -3,7 +3,7 @@
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2026, assimp team
Copyright (c) 2006-2025, assimp team
All rights reserved.
@@ -80,7 +80,7 @@ ObjFileParser::ObjFileParser(IOStreamBuffer<char> &streamBuffer, const std::stri
m_buffer(),
m_pIO(io),
m_progress(progress),
m_originalObjFileName(originalObjFileName) {
m_originalObjFileName(originalObjFileName) {
std::fill_n(m_buffer, Buffersize, '\0');
// Create the model instance to store all the data
@@ -471,7 +471,19 @@ void ObjFileParser::getFace(aiPrimitiveType type) {
iPos = 0;
} else {
//OBJ USES 1 Base ARRAYS!!!!
const int iVal = ::atoi(&(*m_DataIt));
int iVal;
auto end = m_DataIt;
// find either the buffer end or the '\0'
while (end < m_DataItEnd && *end != '\0')
++end;
// avoid temporary string allocation if there is a zero
if (end != m_DataItEnd) {
iVal = ::atoi(&(*m_DataIt));
} else {
// otherwise make a zero terminated copy, which is safe to pass to atoi
std::string number(&(*m_DataIt), m_DataItEnd - m_DataIt);
iVal = ::atoi(number.c_str());
}
// increment iStep position based off of the sign and # of digits
int tmp = iVal;
+1 -1
View File
@@ -270,7 +270,7 @@ void Q3BSPFileImporter::CreateNodes(const Q3BSP::Q3BSPModel *pModel, aiScene *pS
}
unsigned int matIdx(0);
std::vector<aiMesh *> MeshArray;
MeshArray MeshArray;
std::vector<aiNode *> NodeArray;
for (FaceMapIt it = m_MaterialLookupMap.begin(); it != m_MaterialLookupMap.end(); ++it) {
std::vector<Q3BSP::sQ3BSPFace *> *pArray = (*it).second;
+1 -13
View File
@@ -55,8 +55,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/DefaultLogger.hpp>
#include <assimp/IOSystem.hpp>
#include <limits>
namespace Assimp {
static constexpr aiImporterDesc desc = {
@@ -311,11 +309,6 @@ void Q3DImporter::InternReadFile(const std::string &pFile,
throw DeadlyImportError("Quick3D: Invalid texture. Width or height is zero");
}
const unsigned int uint_max = std::numeric_limits<unsigned int>::max();
if (tex->mWidth > (uint_max / tex->mHeight)) {
throw DeadlyImportError("Quick3D: Texture dimensions are too large, resulting in overflow.");
}
unsigned int mul = tex->mWidth * tex->mHeight;
aiTexel *begin = tex->pcData = new aiTexel[mul];
aiTexel *const end = &begin[mul - 1] + 1;
@@ -379,12 +372,7 @@ void Q3DImporter::InternReadFile(const std::string &pFile,
light->mColorSpecular = light->mColorDiffuse;
// We don't need the rest, but we need to know where this chunk ends.
const auto t1 = stream.GetI4();
const auto t2 = stream.GetI4();
if (t1 < 0 || t2 < 0) {
throw DeadlyImportError("Quick3D: Overflow detected.");
}
const unsigned int temp = static_cast<unsigned int>(t1*t2);
unsigned int temp = (unsigned int)(stream.GetI4() * stream.GetI4());
// skip the background file name
while (stream.GetI1())
+1 -1
View File
@@ -116,7 +116,7 @@ struct SIBObject {
struct SIB {
std::vector<aiMaterial *> mtls;
std::vector<aiMesh *> meshes;
MeshArray meshes;
std::vector<aiLight *> lights;
std::vector<SIBObject> objs, insts;
};
+1 -1
View File
@@ -222,7 +222,7 @@ void STLImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
// ------------------------------------------------------------------------------------------------
// Read an ASCII STL file
void STLImporter::LoadASCIIFile(aiNode *root) {
std::vector<aiMesh *> meshes;
MeshArray meshes;
std::vector<aiNode *> nodes;
const char *sz = mBuffer;
const char *bufferEnd = mBuffer + mFileSize;
+1 -5
View File
@@ -58,7 +58,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# pragma warning(disable : 4127 4456 4245 4512 )
#endif // _MSC_VER
#if _MSC_VER > 1500 || (defined __GNUC__)
#if _MSC_VER > 1500 || (defined __GNUC___)
# define ASSIMP_STEP_USE_UNORDERED_MULTIMAP
#else
# define step_unordered_map map
@@ -919,10 +919,6 @@ private:
#pragma warning(pop)
#endif // _MSC_VER
#if _MSC_VER > 1920
#pragma warning(pop)
#endif
} // namespace STEP
} // namespace Assimp
+1 -1
View File
@@ -63,7 +63,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <memory>
//
#if _MSC_VER > 1500 || (defined __GNUC__)
#if _MSC_VER > 1500 || (defined __GNUC___)
# define ASSIMP_STEP_USE_UNORDERED_MULTIMAP
# else
# define step_unordered_map map
+1
View File
@@ -77,6 +77,7 @@ static constexpr aiImporterDesc desc = {
};
namespace Assimp {
using namespace std;
// Constructor to be privately used by Importer
USDImporter::USDImporter() :
+1 -6
View File
@@ -53,14 +53,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "USDLoaderImplTinyusdz.h"
namespace Assimp {
/// @brief USD Importer class
class USDImporter final : public BaseImporter {
class USDImporter : public BaseImporter {
public:
/// @brief Constructor
USDImporter();
/// @brief Destructor
~USDImporter() override = default;
/// \brief Returns whether the class can handle the format of the given file.
+157 -111
View File
@@ -44,33 +44,31 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef ASSIMP_BUILD_NO_USD_IMPORTER
#include "USDLoaderImplTinyusdz.h"
#include "USDLoaderImplTinyusdzHelper.h"
#include "USDLoaderUtil.h"
#include "USDPreprocessor.h"
#include "io-util.hh" // namespace tinyusdz::io
#include "tydra/scene-access.hh"
#include "tydra/shader-network.hh"
#include <memory>
#include <sstream>
// internal headers
#include "assimp/MemoryIOWrapper.h"
#include <assimp/CreateAnimMesh.h>
#include <assimp/DefaultIOSystem.h>
#include <assimp/IOStreamBuffer.h>
#include <assimp/StreamReader.h>
#include <assimp/StringUtils.h>
#include <assimp/ai_assert.h>
#include <assimp/anim.h>
#include <assimp/fast_atof.h>
#include <assimp/importerdesc.h>
#include <assimp/CreateAnimMesh.h>
#include <assimp/DefaultIOSystem.h>
#include <assimp/DefaultLogger.hpp>
#include <assimp/IOSystem.hpp>
#include <assimp/fast_atof.h>
#include <assimp/Importer.hpp>
#include <assimp/importerdesc.h>
#include <assimp/IOStreamBuffer.h>
#include <assimp/IOSystem.hpp>
#include "assimp/MemoryIOWrapper.h"
#include <assimp/StringUtils.h>
#include <assimp/StreamReader.h>
#include "io-util.hh" // namespace tinyusdz::io
#include "tydra/scene-access.hh"
#include "tydra/shader-network.hh"
#include "USDLoaderImplTinyusdzHelper.h"
#include "USDLoaderImplTinyusdz.h"
#include "USDLoaderUtil.h"
#include "USDPreprocessor.h"
#include "../../../contrib/tinyusdz/assimp_tinyusdz_logging.inc"
@@ -79,18 +77,17 @@ namespace {
}
namespace Assimp {
using namespace std;
using Assimp::tinyUsdzMat4ToAiMat4;
using Assimp::tinyusdzNodeTypeFor;
using tinyusdz::tydra::NodeType;
using namespace tinyusdz::tydra;
void USDImporterImplTinyusdz::InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler) {
void USDImporterImplTinyusdz::InternReadFile(
const std::string &pFile,
aiScene *pScene,
IOSystem *pIOHandler) {
// Grab filename for logging purposes
size_t pos = pFile.find_last_of('/');
std::string basePath = pFile.substr(0, pos);
std::string nameWExt = pFile.substr(pos + 1);
std::stringstream ss;
string basePath = pFile.substr(0, pos);
string nameWExt = pFile.substr(pos + 1);
stringstream ss;
ss.str("");
ss << "InternReadFile(): model" << nameWExt;
TINYUSDZLOGD(TAG, "%s", ss.str().c_str());
@@ -163,10 +160,9 @@ void USDImporterImplTinyusdz::InternReadFile(const std::string &pFile, aiScene *
TINYUSDZLOGE(TAG, "%s", ss.str().c_str());
return;
}
RenderScene render_scene;
RenderSceneConverter converter;
RenderSceneConverterEnv env(stage);
tinyusdz::tydra::RenderScene render_scene;
tinyusdz::tydra::RenderSceneConverter converter;
tinyusdz::tydra::RenderSceneConverterEnv env(stage);
std::string usd_basedir = tinyusdz::io::GetBaseDir(pFile);
env.set_search_paths({ usd_basedir }); // {} needed to convert to vector of char
@@ -227,8 +223,9 @@ void USDImporterImplTinyusdz::InternReadFile(const std::string &pFile, aiScene *
setupBlendShapes(render_scene, pScene, nameWExt);
}
void USDImporterImplTinyusdz::animations(const tinyusdz::tydra::RenderScene &render_scene, aiScene *pScene) {
void USDImporterImplTinyusdz::animations(
const tinyusdz::tydra::RenderScene& render_scene,
aiScene* pScene) {
if (render_scene.animations.empty()) {
return;
}
@@ -268,7 +265,7 @@ void USDImporterImplTinyusdz::animations(const tinyusdz::tydra::RenderScene &ren
for (const auto &[channelType, animChannel] : animationChannelMap) {
switch (channelType) {
case AnimationChannel::ChannelType::Rotation:
case tinyusdz::tydra::AnimationChannel::ChannelType::Rotation:
if (animChannel.rotations.static_value.has_value()) {
rotationKeys.emplace_back(0, tinyUsdzQuatToAiQuat(animChannel.rotations.static_value.value()));
}
@@ -280,7 +277,7 @@ void USDImporterImplTinyusdz::animations(const tinyusdz::tydra::RenderScene &ren
rotationKeys.emplace_back(rotationAnimSampler.t, tinyUsdzQuatToAiQuat(rotationAnimSampler.value));
}
break;
case AnimationChannel::ChannelType::Scale:
case tinyusdz::tydra::AnimationChannel::ChannelType::Scale:
if (animChannel.scales.static_value.has_value()) {
scalingKeys.emplace_back(0, tinyUsdzScaleOrPosToAssimp(animChannel.scales.static_value.value()));
}
@@ -291,7 +288,7 @@ void USDImporterImplTinyusdz::animations(const tinyusdz::tydra::RenderScene &ren
scalingKeys.emplace_back(scaleAnimSampler.t, tinyUsdzScaleOrPosToAssimp(scaleAnimSampler.value));
}
break;
case AnimationChannel::ChannelType::Transform:
case tinyusdz::tydra::AnimationChannel::ChannelType::Transform:
if (animChannel.transforms.static_value.has_value()) {
aiVector3D position;
aiVector3D scale;
@@ -317,7 +314,7 @@ void USDImporterImplTinyusdz::animations(const tinyusdz::tydra::RenderScene &ren
rotationKeys.emplace_back(transformAnimSampler.t, rotation);
}
break;
case AnimationChannel::ChannelType::Translation:
case tinyusdz::tydra::AnimationChannel::ChannelType::Translation:
if (animChannel.translations.static_value.has_value()) {
positionKeys.emplace_back(0, tinyUsdzScaleOrPosToAssimp(animChannel.translations.static_value.value()));
}
@@ -355,7 +352,7 @@ void USDImporterImplTinyusdz::meshes(
const tinyusdz::tydra::RenderScene &render_scene,
aiScene *pScene,
const std::string &nameWExt) {
std::stringstream ss;
stringstream ss;
pScene->mNumMeshes = static_cast<unsigned int>(render_scene.meshes.size());
pScene->mMeshes = new aiMesh *[pScene->mNumMeshes]();
ss.str("");
@@ -367,7 +364,10 @@ void USDImporterImplTinyusdz::meshes(
pScene->mMeshes[meshIdx] = new aiMesh();
pScene->mMeshes[meshIdx]->mName.Set(render_scene.meshes[meshIdx].prim_name);
ss.str("");
ss << " mesh[" << meshIdx << "]: " << render_scene.meshes[meshIdx].joint_and_weights.jointIndices.size() << " jointIndices, " << render_scene.meshes[meshIdx].joint_and_weights.jointWeights.size() << " jointWeights, elementSize: " << render_scene.meshes[meshIdx].joint_and_weights.elementSize;
ss << " mesh[" << meshIdx << "]: " <<
render_scene.meshes[meshIdx].joint_and_weights.jointIndices.size() << " jointIndices, " <<
render_scene.meshes[meshIdx].joint_and_weights.jointWeights.size() << " jointWeights, elementSize: " <<
render_scene.meshes[meshIdx].joint_and_weights.elementSize;
TINYUSDZLOGD(TAG, "%s", ss.str().c_str());
ss.str("");
ss << " skel_id: " << render_scene.meshes[meshIdx].skel_id;
@@ -386,8 +386,12 @@ void USDImporterImplTinyusdz::meshes(
}
}
void USDImporterImplTinyusdz::verticesForMesh(const tinyusdz::tydra::RenderScene &render_scene,
aiScene *pScene, size_t meshIdx, const std::string &) {
void USDImporterImplTinyusdz::verticesForMesh(
const tinyusdz::tydra::RenderScene &render_scene,
aiScene *pScene,
size_t meshIdx,
const std::string &nameWExt) {
UNUSED(nameWExt);
const auto numVertices = static_cast<unsigned int>(render_scene.meshes[meshIdx].points.size());
pScene->mMeshes[meshIdx]->mNumVertices = numVertices;
pScene->mMeshes[meshIdx]->mVertices = new aiVector3D[pScene->mMeshes[meshIdx]->mNumVertices];
@@ -446,7 +450,7 @@ void USDImporterImplTinyusdz::verticesForMesh(const tinyusdz::tydra::RenderScene
std::swap_ranges(aiBonesVertexWeights[boneIndex].begin(), aiBonesVertexWeights[boneIndex].end(), pScene->mMeshes[meshIdx]->mBones[boneIndex]->mWeights);
}
} // Skinned mesh end
} // Skinned mesh end
for (size_t j = 0; j < pScene->mMeshes[meshIdx]->mNumVertices; ++j) {
pScene->mMeshes[meshIdx]->mVertices[j].x = render_scene.meshes[meshIdx].points[j][0];
@@ -455,8 +459,12 @@ void USDImporterImplTinyusdz::verticesForMesh(const tinyusdz::tydra::RenderScene
}
}
void USDImporterImplTinyusdz::facesForMesh(const RenderScene &render_scene, aiScene *pScene,
size_t meshIdx, const std::string &) {
void USDImporterImplTinyusdz::facesForMesh(
const tinyusdz::tydra::RenderScene &render_scene,
aiScene *pScene,
size_t meshIdx,
const std::string &nameWExt) {
UNUSED(nameWExt);
pScene->mMeshes[meshIdx]->mNumFaces = static_cast<unsigned int>(render_scene.meshes[meshIdx].faceVertexCounts().size());
pScene->mMeshes[meshIdx]->mFaces = new aiFace[pScene->mMeshes[meshIdx]->mNumFaces]();
size_t faceVertIdxOffset = 0;
@@ -471,8 +479,12 @@ void USDImporterImplTinyusdz::facesForMesh(const RenderScene &render_scene, aiSc
}
}
void USDImporterImplTinyusdz::normalsForMesh(const RenderScene &render_scene, aiScene *pScene,
size_t meshIdx, const std::string &) {
void USDImporterImplTinyusdz::normalsForMesh(
const tinyusdz::tydra::RenderScene &render_scene,
aiScene *pScene,
size_t meshIdx,
const std::string &nameWExt) {
UNUSED(nameWExt);
pScene->mMeshes[meshIdx]->mNormals = new aiVector3D[pScene->mMeshes[meshIdx]->mNumVertices];
const float *floatPtr = reinterpret_cast<const float *>(render_scene.meshes[meshIdx].normals.get_data().data());
for (size_t vertIdx = 0, fpj = 0; vertIdx < pScene->mMeshes[meshIdx]->mNumVertices; ++vertIdx, fpj += 3) {
@@ -482,16 +494,20 @@ void USDImporterImplTinyusdz::normalsForMesh(const RenderScene &render_scene, ai
}
}
void USDImporterImplTinyusdz::materialsForMesh(const RenderScene&, aiScene*,
size_t, const std::string&) {
// todo
void USDImporterImplTinyusdz::materialsForMesh(
const tinyusdz::tydra::RenderScene &render_scene,
aiScene *pScene,
size_t meshIdx,
const std::string &nameWExt) {
UNUSED(render_scene); UNUSED(pScene); UNUSED(meshIdx); UNUSED(nameWExt);
}
void USDImporterImplTinyusdz::uvsForMesh(
const tinyusdz::tydra::RenderScene &render_scene,
aiScene *pScene,
size_t meshIdx,
const std::string&) {
const std::string &nameWExt) {
UNUSED(nameWExt);
const size_t uvSlotsCount = render_scene.meshes[meshIdx].texcoords.size();
if (uvSlotsCount < 1) {
return;
@@ -519,8 +535,10 @@ static aiColor3D *ownedColorPtrFor(const std::array<float, 3> &color) {
return colorPtr;
}
static std::string nameForTextureWithId(const RenderScene &render_scene, const int targetId) {
std::stringstream ss;
static std::string nameForTextureWithId(
const tinyusdz::tydra::RenderScene &render_scene,
const int targetId) {
stringstream ss;
std::string texName;
for (const auto &image : render_scene.images) {
if (image.buffer_id == targetId) {
@@ -538,15 +556,16 @@ static std::string nameForTextureWithId(const RenderScene &render_scene, const i
}
static void assignTexture(
const RenderScene &render_scene,
const RenderMaterial &,
const tinyusdz::tydra::RenderScene &render_scene,
const tinyusdz::tydra::RenderMaterial &material,
aiMaterial *mat,
const int textureId,
const int aiTextureType) {
UNUSED(material);
std::string name = nameForTextureWithId(render_scene, textureId);
aiString *texName = new aiString();
texName->Set(name);
std::stringstream ss;
stringstream ss;
ss.str("");
ss << "assignTexture(): name: " << name;
TINYUSDZLOGD(TAG, "%s", ss.str().c_str());
@@ -558,8 +577,9 @@ void USDImporterImplTinyusdz::materials(
const tinyusdz::tydra::RenderScene &render_scene,
aiScene *pScene,
const std::string &nameWExt) {
const size_t numMaterials{ render_scene.materials.size() };
std::stringstream ss;
const size_t numMaterials{render_scene.materials.size()};
(void) numMaterials; // Ignore unused variable when -Werror enabled
stringstream ss;
ss.str("");
ss << "materials(): model" << nameWExt << ", numMaterials: " << numMaterials;
TINYUSDZLOGD(TAG, "%s", ss.str().c_str());
@@ -567,7 +587,6 @@ void USDImporterImplTinyusdz::materials(
if (render_scene.materials.empty()) {
return;
}
pScene->mMaterials = new aiMaterial *[render_scene.materials.size()];
for (const auto &material : render_scene.materials) {
ss.str("");
@@ -650,18 +669,22 @@ void USDImporterImplTinyusdz::materials(
void USDImporterImplTinyusdz::textures(
const tinyusdz::tydra::RenderScene &render_scene,
aiScene*,
aiScene *pScene,
const std::string &nameWExt) {
const size_t numTextures{ render_scene.textures.size() };
std::stringstream ss;
UNUSED(pScene);
const size_t numTextures{render_scene.textures.size()};
UNUSED(numTextures); // Ignore unused variable when -Werror enabled
stringstream ss;
ss.str("");
ss << "textures(): model" << nameWExt << ", numTextures: " << numTextures;
TINYUSDZLOGD(TAG, "%s", ss.str().c_str());
size_t i{ 0 };
size_t i{0};
UNUSED(i);
for (const auto &texture : render_scene.textures) {
UNUSED(texture);
ss.str("");
ss << " texture[" << i << "]: id: " << texture.texture_image_id << ", disp name: |" << texture.display_name << "|, varname_uv: " << texture.varname_uv << ", prim_name: |" << texture.prim_name << "|, abs_path: |" << texture.abs_path << "|";
ss << " texture[" << i << "]: id: " << texture.texture_image_id << ", disp name: |" << texture.display_name << "|, varname_uv: " <<
texture.varname_uv << ", prim_name: |" << texture.prim_name << "|, abs_path: |" << texture.abs_path << "|";
TINYUSDZLOGD(TAG, "%s", ss.str().c_str());
++i;
}
@@ -675,12 +698,15 @@ void USDImporterImplTinyusdz::textures(
* @param nameWExt filename w/ext (use to extract file type hint)
* @return aiTexture ptr
*/
static aiTexture *ownedEmbeddedTextureFor(const RenderScene &render_scene, const TextureImage &image,
const std::string&) {
std::stringstream ss;
static aiTexture *ownedEmbeddedTextureFor(
const tinyusdz::tydra::RenderScene &render_scene,
const tinyusdz::tydra::TextureImage &image,
const std::string &nameWExt) {
UNUSED(nameWExt);
stringstream ss;
aiTexture *tex = new aiTexture();
size_t pos = image.asset_identifier.find_last_of('/');
std::string embTexName{ image.asset_identifier.substr(pos + 1) };
string embTexName{image.asset_identifier.substr(pos + 1)};
tex->mFilename.Set(image.asset_identifier.c_str());
tex->mHeight = image.height;
@@ -688,20 +714,20 @@ static aiTexture *ownedEmbeddedTextureFor(const RenderScene &render_scene, const
if (tex->mHeight == 0) {
pos = embTexName.find_last_of('.');
strncpy(tex->achFormatHint, embTexName.substr(pos + 1).c_str(), 3);
const size_t imageBytesCount{ render_scene.buffers[image.buffer_id].data.size() };
tex->pcData = (aiTexel *)new char[imageBytesCount];
const size_t imageBytesCount{render_scene.buffers[image.buffer_id].data.size()};
tex->pcData = (aiTexel *) new char[imageBytesCount];
memcpy(tex->pcData, &render_scene.buffers[image.buffer_id].data[0], imageBytesCount);
} else {
std::string formatHint{ "rgba8888" };
string formatHint{"rgba8888"};
strncpy(tex->achFormatHint, formatHint.c_str(), 8);
const size_t imageTexelsCount{ tex->mWidth * tex->mHeight };
tex->pcData = (aiTexel *)new char[imageTexelsCount * image.channels];
const size_t imageTexelsCount{tex->mWidth * tex->mHeight};
tex->pcData = (aiTexel *) new char[imageTexelsCount * image.channels];
const float *floatPtr = reinterpret_cast<const float *>(&render_scene.buffers[image.buffer_id].data[0]);
ss.str("");
ss << "ownedEmbeddedTextureFor(): manual fill...";
TINYUSDZLOGD(TAG, "%s", ss.str().c_str());
for (size_t i = 0, fpi = 0; i < imageTexelsCount; ++i, fpi += 4) {
tex->pcData[i].b = static_cast<uint8_t>(floatPtr[fpi] * 255);
tex->pcData[i].b = static_cast<uint8_t>(floatPtr[fpi] * 255);
tex->pcData[i].g = static_cast<uint8_t>(floatPtr[fpi + 1] * 255);
tex->pcData[i].r = static_cast<uint8_t>(floatPtr[fpi + 2] * 255);
tex->pcData[i].a = static_cast<uint8_t>(floatPtr[fpi + 3] * 255);
@@ -713,9 +739,13 @@ static aiTexture *ownedEmbeddedTextureFor(const RenderScene &render_scene, const
return tex;
}
void USDImporterImplTinyusdz::textureImages(const RenderScene &render_scene, aiScene *pScene, const std::string &nameWExt) {
std::stringstream ss;
const size_t numTextureImages{ render_scene.images.size() };
void USDImporterImplTinyusdz::textureImages(
const tinyusdz::tydra::RenderScene &render_scene,
aiScene *pScene,
const std::string &nameWExt) {
stringstream ss;
const size_t numTextureImages{render_scene.images.size()};
UNUSED(numTextureImages); // Ignore unused variable when -Werror enabled
ss.str("");
ss << "textureImages(): model" << nameWExt << ", numTextureImages: " << numTextureImages;
TINYUSDZLOGD(TAG, "%s", ss.str().c_str());
@@ -723,15 +753,13 @@ void USDImporterImplTinyusdz::textureImages(const RenderScene &render_scene, aiS
pScene->mNumTextures = 0;
for (const auto &image : render_scene.images) {
ss.str("");
ss << " image[" << pScene->mNumTextures << "]: |" << image.asset_identifier << "| w: "
<< image.width << ", h: " << image.height << ", channels: " << image.channels << ", miplevel: "
<< image.miplevel << ", buffer id: " << image.buffer_id << "\n"
<< " buffers.size(): " << render_scene.buffers.size() << ", data empty? "
<< render_scene.buffers[image.buffer_id].data.empty();
ss << " image[" << pScene->mNumTextures << "]: |" << image.asset_identifier << "| w: " << image.width << ", h: " << image.height <<
", channels: " << image.channels << ", miplevel: " << image.miplevel << ", buffer id: " << image.buffer_id << "\n" <<
" buffers.size(): " << render_scene.buffers.size() << ", data empty? " << render_scene.buffers[image.buffer_id].data.empty();
TINYUSDZLOGD(TAG, "%s", ss.str().c_str());
if (image.buffer_id > -1 &&
image.buffer_id < static_cast<long int>(render_scene.buffers.size()) &&
!render_scene.buffers[image.buffer_id].data.empty()) {
image.buffer_id < static_cast<long int>(render_scene.buffers.size()) &&
!render_scene.buffers[image.buffer_id].data.empty()) {
aiTexture *tex = ownedEmbeddedTextureFor(
render_scene,
image,
@@ -743,8 +771,8 @@ void USDImporterImplTinyusdz::textureImages(const RenderScene &render_scene, aiS
pScene->mTextures = new aiTexture *[render_scene.images.size()];
}
ss.str("");
ss << " pScene->mTextures[" << pScene->mNumTextures << "] name: |" << tex->mFilename.C_Str()
<< "|, w: " << tex->mWidth << ", h: " << tex->mHeight << ", hint: " << tex->achFormatHint;
ss << " pScene->mTextures[" << pScene->mNumTextures << "] name: |" << tex->mFilename.C_Str() <<
"|, w: " << tex->mWidth << ", h: " << tex->mHeight << ", hint: " << tex->achFormatHint;
TINYUSDZLOGD(TAG, "%s", ss.str().c_str());
pScene->mTextures[pScene->mNumTextures++] = tex;
}
@@ -752,9 +780,12 @@ void USDImporterImplTinyusdz::textureImages(const RenderScene &render_scene, aiS
}
void USDImporterImplTinyusdz::buffers(
const RenderScene &render_scene, aiScene*, const std::string &nameWExt) {
const size_t numBuffers{ render_scene.buffers.size() };
std::stringstream ss;
const tinyusdz::tydra::RenderScene &render_scene,
aiScene *pScene,
const std::string &nameWExt) {
const size_t numBuffers{render_scene.buffers.size()};
UNUSED(pScene); UNUSED(numBuffers); // Ignore unused variable when -Werror enabled
stringstream ss;
ss.str("");
ss << "buffers(): model" << nameWExt << ", numBuffers: " << numBuffers;
TINYUSDZLOGD(TAG, "%s", ss.str().c_str());
@@ -767,9 +798,14 @@ void USDImporterImplTinyusdz::buffers(
}
}
aiNode *USDImporterImplTinyusdz::nodesRecursive(aiNode *pNodeParent, const tinyusdz::tydra::Node &node,
const std::vector<SkelHierarchy> &skeletons) {
std::stringstream ss;
using Assimp::tinyusdzNodeTypeFor;
using Assimp::tinyUsdzMat4ToAiMat4;
using tinyusdz::tydra::NodeType;
aiNode *USDImporterImplTinyusdz::nodesRecursive(
aiNode *pNodeParent,
const tinyusdz::tydra::Node &node,
const std::vector<tinyusdz::tydra::SkelHierarchy> &skeletons) {
stringstream ss;
aiNode *cNode = new aiNode();
cNode->mParent = pNodeParent;
cNode->mName.Set(node.prim_name);
@@ -782,9 +818,9 @@ aiNode *USDImporterImplTinyusdz::nodesRecursive(aiNode *pNodeParent, const tinyu
}
ss.str("");
ss << "nodesRecursive(): node " << cNode->mName.C_Str() << " type: |"
<< tinyusdzNodeTypeFor(node.nodeType)
<< "|, disp " << node.display_name << ", abs " << node.abs_path;
ss << "nodesRecursive(): node " << cNode->mName.C_Str() <<
" type: |" << tinyusdzNodeTypeFor(node.nodeType) <<
"|, disp " << node.display_name << ", abs " << node.abs_path;
if (cNode->mParent != nullptr) {
ss << " (parent " << cNode->mParent->mName.C_Str() << ")";
}
@@ -825,15 +861,15 @@ aiNode *USDImporterImplTinyusdz::nodesRecursive(aiNode *pNodeParent, const tinyu
if (skelNode != nullptr) {
// Convert USD skeleton into an Assimp node and make it the last child
cNode->mChildren[cNode->mNumChildren - 1] = skeletonNodesRecursive(cNode, *skelNode);
cNode->mChildren[cNode->mNumChildren-1] = skeletonNodesRecursive(cNode, *skelNode);
}
return cNode;
}
aiNode *USDImporterImplTinyusdz::skeletonNodesRecursive(
aiNode *pNodeParent,
const SkelNode &joint) {
aiNode* pNodeParent,
const tinyusdz::tydra::SkelNode& joint) {
auto *cNode = new aiNode(joint.joint_path);
cNode->mParent = pNodeParent;
cNode->mNumMeshes = 0; // not a mesh node
@@ -848,7 +884,7 @@ aiNode *USDImporterImplTinyusdz::skeletonNodesRecursive(
cNode->mChildren = new aiNode *[cNode->mNumChildren];
for (unsigned i = 0; i < cNode->mNumChildren; ++i) {
const SkelNode &childJoint = joint.children[i];
const tinyusdz::tydra::SkelNode &childJoint = joint.children[i];
cNode->mChildren[i] = skeletonNodesRecursive(cNode, childJoint);
}
@@ -857,7 +893,7 @@ aiNode *USDImporterImplTinyusdz::skeletonNodesRecursive(
void USDImporterImplTinyusdz::sanityCheckNodesRecursive(
aiNode *cNode) {
std::stringstream ss;
stringstream ss;
ss.str("");
ss << "sanityCheckNodesRecursive(): node " << cNode->mName.C_Str();
if (cNode->mParent != nullptr) {
@@ -870,14 +906,16 @@ void USDImporterImplTinyusdz::sanityCheckNodesRecursive(
}
}
void USDImporterImplTinyusdz::setupBlendShapes(const RenderScene &render_scene, aiScene *pScene,
void USDImporterImplTinyusdz::setupBlendShapes(
const tinyusdz::tydra::RenderScene &render_scene,
aiScene *pScene,
const std::string &nameWExt) {
std::stringstream ss;
stringstream ss;
ss.str("");
ss << "setupBlendShapes(): iterating over " << pScene->mNumMeshes << " meshes for model" << nameWExt;
TINYUSDZLOGD(TAG, "%s", ss.str().c_str());
for (size_t meshIdx = 0; meshIdx < pScene->mNumMeshes; meshIdx++) {
blendShapesForMesh(render_scene, pScene, meshIdx, nameWExt);
blendShapesForMesh(render_scene, pScene, meshIdx, nameWExt);
}
}
@@ -885,9 +923,10 @@ void USDImporterImplTinyusdz::blendShapesForMesh(
const tinyusdz::tydra::RenderScene &render_scene,
aiScene *pScene,
size_t meshIdx,
const std::string &) {
std::stringstream ss;
const unsigned int numBlendShapeTargets{ static_cast<unsigned int>(render_scene.meshes[meshIdx].targets.size()) };
const std::string &nameWExt) {
UNUSED(nameWExt);
stringstream ss;
const unsigned int numBlendShapeTargets{static_cast<unsigned int>(render_scene.meshes[meshIdx].targets.size())};
UNUSED(numBlendShapeTargets); // Ignore unused variable when -Werror enabled
ss.str("");
ss << " blendShapesForMesh(): mesh[" << meshIdx << "], numBlendShapeTargets: " << numBlendShapeTargets;
@@ -897,13 +936,15 @@ void USDImporterImplTinyusdz::blendShapesForMesh(
pScene->mMeshes[meshIdx]->mAnimMeshes = new aiAnimMesh *[pScene->mMeshes[meshIdx]->mNumAnimMeshes];
}
auto mapIter = render_scene.meshes[meshIdx].targets.begin();
size_t animMeshIdx{ 0 };
size_t animMeshIdx{0};
for (; mapIter != render_scene.meshes[meshIdx].targets.end(); ++mapIter) {
const std::string name{ mapIter->first };
const tinyusdz::tydra::ShapeTarget shapeTarget{ mapIter->second };
const std::string name{mapIter->first};
const tinyusdz::tydra::ShapeTarget shapeTarget{mapIter->second};
pScene->mMeshes[meshIdx]->mAnimMeshes[animMeshIdx] = aiCreateAnimMesh(pScene->mMeshes[meshIdx]);
ss.str("");
ss << " mAnimMeshes[" << animMeshIdx << "]: mNumVertices: " << pScene->mMeshes[meshIdx]->mAnimMeshes[animMeshIdx]->mNumVertices << ", target: " << shapeTarget.pointIndices.size() << " pointIndices, " << shapeTarget.pointOffsets.size() << " pointOffsets, " << shapeTarget.normalOffsets.size() << " normalOffsets";
ss << " mAnimMeshes[" << animMeshIdx << "]: mNumVertices: " << pScene->mMeshes[meshIdx]->mAnimMeshes[animMeshIdx]->mNumVertices <<
", target: " << shapeTarget.pointIndices.size() << " pointIndices, " << shapeTarget.pointOffsets.size() <<
" pointOffsets, " << shapeTarget.normalOffsets.size() << " normalOffsets";
TINYUSDZLOGD(TAG, "%s", ss.str().c_str());
for (size_t iVert = 0; iVert < shapeTarget.pointOffsets.size(); ++iVert) {
pScene->mMeshes[meshIdx]->mAnimMeshes[animMeshIdx]->mVertices[shapeTarget.pointIndices[iVert]] +=
@@ -914,7 +955,12 @@ void USDImporterImplTinyusdz::blendShapesForMesh(
tinyUsdzScaleOrPosToAssimp(shapeTarget.normalOffsets[iVert]);
}
ss.str("");
ss << " target[" << animMeshIdx << "]: name: " << name << ", prim_name: " << shapeTarget.prim_name << ", abs_path: " << shapeTarget.abs_path << ", display_name: " << shapeTarget.display_name << ", " << shapeTarget.pointIndices.size() << " pointIndices, " << shapeTarget.pointOffsets.size() << " pointOffsets, " << shapeTarget.normalOffsets.size() << " normalOffsets, " << shapeTarget.inbetweens.size() << " inbetweens";
ss << " target[" << animMeshIdx << "]: name: " << name << ", prim_name: " <<
shapeTarget.prim_name << ", abs_path: " << shapeTarget.abs_path <<
", display_name: " << shapeTarget.display_name << ", " << shapeTarget.pointIndices.size() <<
" pointIndices, " << shapeTarget.pointOffsets.size() << " pointOffsets, " <<
shapeTarget.normalOffsets.size() << " normalOffsets, " << shapeTarget.inbetweens.size() <<
" inbetweens";
TINYUSDZLOGD(TAG, "%s", ss.str().c_str());
++animMeshIdx;
}
+3 -13
View File
@@ -43,29 +43,21 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* @brief Declaration of the USD importer class.
*/
#pragma once
#ifndef AI_USDLOADER_IMPL_TINYUSDZ_H_INCLUDED
#define AI_USDLOADER_IMPL_TINYUSDZ_H_INCLUDED
#include "tinyusdz.hh"
#include "tydra/render-data.hh"
#include <assimp/BaseImporter.h>
#include <assimp/scene.h>
#include <assimp/types.h>
#include <cstdint>
#include <vector>
#include <cstdint>
#include "tinyusdz.hh"
#include "tydra/render-data.hh"
namespace Assimp {
/**
* @brief USD Importer implementation using tinyusdz.
*/
class USDImporterImplTinyusdz {
public:
/// @brief The class constructor.
USDImporterImplTinyusdz() = default;
/// @brief The class destructor.
~USDImporterImplTinyusdz() = default;
void InternReadFile(
@@ -155,7 +147,5 @@ public:
size_t meshIdx,
const std::string &nameWExt);
};
} // namespace Assimp
#endif // AI_USDLOADER_IMPL_TINYUSDZ_H_INCLUDED
+1 -1
View File
@@ -45,7 +45,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <string>
#if !defined(ASSIMP_BUILD_NO_VRML_IMPORTER)
#include "meshlabplugins/io_x3d/vrml/Parser.h"
#include "contrib/meshlab/autoclone/meshlab_repo-src/src/meshlabplugins/io_x3d/vrml/Parser.h"
#endif // #if !defined(ASSIMP_BUILD_NO_VRML_IMPORTER)
namespace Assimp {
+1 -1
View File
@@ -219,7 +219,7 @@ void XFileImporter::CreateMeshes(aiScene *pScene, aiNode *pNode, const std::vect
}
// create a mesh for each mesh-material combination in the source node
std::vector<aiMesh *> meshes;
MeshArray meshes;
for (unsigned int a = 0; a < pMeshes.size(); ++a) {
XFile::Mesh *sourceMesh = pMeshes[a];
if (nullptr == sourceMesh) {
+1 -1
View File
@@ -139,7 +139,7 @@ void XGLImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
ReadWorld(*worldNode, scope);
}
std::vector<aiMesh *> &meshes = scope.meshes_linear;
MeshArray &meshes = scope.meshes_linear;
std::vector<aiMaterial *> &materials = scope.materials_linear;
if (meshes.empty() || materials.empty()) {
ThrowException("failed to extract data from XGL file, no meshes loaded");
+5 -1
View File
@@ -49,6 +49,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef GLTFASSET_H_INC
#define GLTFASSET_H_INC
#if !defined(ASSIMP_BUILD_NO_GLTF_IMPORTER) && !defined(ASSIMP_BUILD_NO_GLTF1_IMPORTER)
#include "AssetLib/glTFCommon/glTFCommon.h"
#include <assimp/Exceptional.h>
#include <list>
@@ -81,7 +83,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endif
#if _MSC_VER > 1500 || (defined __GNUC__)
#if _MSC_VER > 1500 || (defined __GNUC___)
# define ASSIMP_GLTF_USE_UNORDERED_MULTIMAP
# else
# define gltf_unordered_map map
@@ -1006,4 +1008,6 @@ private:
// Include the implementation of the methods
#include "glTFAsset.inl"
#endif // ASSIMP_BUILD_NO_GLTF_IMPORTER
#endif // GLTFASSET_H_INC

Some files were not shown because too many files have changed in this diff Show More