Merge branch 'master' into master
commit
9ca94b0137
|
@ -16,7 +16,7 @@ jobs:
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
name: [ubuntu-latest-g++, macos-latest-clang++, windows-latest-cl.exe, ubuntu-latest-clang++, ubuntu-gcc-hunter, macos-clang-hunter, windows-msvc-hunter]
|
name: [ubuntu-latest-g++, macos-latest-clang++, windows-latest-cl.exe, ubuntu-latest-clang++]
|
||||||
# For Windows msvc, for Linux and macOS let's use the clang compiler, use gcc for Linux.
|
# For Windows msvc, for Linux and macOS let's use the clang compiler, use gcc for Linux.
|
||||||
include:
|
include:
|
||||||
- name: windows-latest-cl.exe
|
- name: windows-latest-cl.exe
|
||||||
|
@ -35,18 +35,9 @@ jobs:
|
||||||
os: ubuntu-latest
|
os: ubuntu-latest
|
||||||
cxx: g++
|
cxx: g++
|
||||||
cc: gcc
|
cc: gcc
|
||||||
- name: ubuntu-gcc-hunter
|
|
||||||
os: ubuntu-latest
|
|
||||||
toolchain: ninja-gcc-cxx17-fpic
|
|
||||||
- name: macos-clang-hunter
|
|
||||||
os: macos-latest
|
|
||||||
toolchain: ninja-clang-cxx17-fpic
|
|
||||||
- name: windows-msvc-hunter
|
|
||||||
os: windows-latest
|
|
||||||
toolchain: ninja-vs-win64-cxx17
|
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
submodules: true
|
submodules: true
|
||||||
|
|
||||||
|
@ -55,31 +46,11 @@ jobs:
|
||||||
- uses: ilammy/msvc-dev-cmd@v1
|
- uses: ilammy/msvc-dev-cmd@v1
|
||||||
|
|
||||||
- name: Set Compiler Environment
|
- name: Set Compiler Environment
|
||||||
if: "!endsWith(matrix.name, 'hunter')"
|
|
||||||
uses: lukka/set-shell-env@v1
|
uses: lukka/set-shell-env@v1
|
||||||
with:
|
with:
|
||||||
CXX: ${{ matrix.cxx }}
|
CXX: ${{ matrix.cxx }}
|
||||||
CC: ${{ matrix.cc }}
|
CC: ${{ matrix.cc }}
|
||||||
|
|
||||||
- name: Set Compiler Environment for Hunter on Windows
|
|
||||||
if: startsWith(matrix.name, 'windows') && endsWith(matrix.name, 'hunter')
|
|
||||||
uses: lukka/set-shell-env@v1
|
|
||||||
with:
|
|
||||||
VS160COMNTOOLS: C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\Common7\Tools
|
|
||||||
|
|
||||||
- name: Checkout Hunter toolchains
|
|
||||||
if: endsWith(matrix.name, 'hunter')
|
|
||||||
uses: actions/checkout@v3
|
|
||||||
with:
|
|
||||||
repository: cpp-pm/polly
|
|
||||||
path: cmake/polly
|
|
||||||
|
|
||||||
- name: Remove contrib directory for Hunter builds
|
|
||||||
if: contains(matrix.name, 'hunter')
|
|
||||||
uses: JesseTG/rm@v1.0.3
|
|
||||||
with:
|
|
||||||
path: contrib
|
|
||||||
|
|
||||||
- name: Cache DX SDK
|
- name: Cache DX SDK
|
||||||
id: dxcache
|
id: dxcache
|
||||||
if: contains(matrix.name, 'windows')
|
if: contains(matrix.name, 'windows')
|
||||||
|
@ -127,7 +98,7 @@ jobs:
|
||||||
run: cd build/bin && ./unit ${{ steps.hunter_extra_test_args.outputs.args }}
|
run: cd build/bin && ./unit ${{ steps.hunter_extra_test_args.outputs.args }}
|
||||||
shell: bash
|
shell: bash
|
||||||
|
|
||||||
- uses: actions/upload-artifact@v3
|
- uses: actions/upload-artifact@v4
|
||||||
if: matrix.name == 'windows-msvc'
|
if: matrix.name == 'windows-msvc'
|
||||||
with:
|
with:
|
||||||
name: 'assimp-bins-${{ matrix.name }}-${{ github.sha }}'
|
name: 'assimp-bins-${{ matrix.name }}-${{ github.sha }}'
|
||||||
|
|
|
@ -19,7 +19,7 @@ jobs:
|
||||||
dry-run: false
|
dry-run: false
|
||||||
language: c++
|
language: c++
|
||||||
- name: Upload Crash
|
- name: Upload Crash
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v4
|
||||||
if: failure() && steps.build.outcome == 'success'
|
if: failure() && steps.build.outcome == 'success'
|
||||||
with:
|
with:
|
||||||
name: artifacts
|
name: artifacts
|
||||||
|
|
|
@ -14,7 +14,7 @@ jobs:
|
||||||
name: adress-sanitizer
|
name: adress-sanitizer
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
- uses: lukka/get-cmake@latest
|
- uses: lukka/get-cmake@latest
|
||||||
- uses: lukka/set-shell-env@v1
|
- uses: lukka/set-shell-env@v1
|
||||||
with:
|
with:
|
||||||
|
@ -38,7 +38,7 @@ jobs:
|
||||||
name: undefined-behavior-sanitizer
|
name: undefined-behavior-sanitizer
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
- uses: lukka/get-cmake@latest
|
- uses: lukka/get-cmake@latest
|
||||||
- uses: lukka/set-shell-env@v1
|
- uses: lukka/set-shell-env@v1
|
||||||
with:
|
with:
|
||||||
|
@ -62,7 +62,7 @@ jobs:
|
||||||
name: printf-sanitizer
|
name: printf-sanitizer
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: run scan_printf script
|
- name: run scan_printf script
|
||||||
run: ./scripts/scan_printf.sh
|
run: ./scripts/scan_printf.sh
|
||||||
|
|
1
Build.md
1
Build.md
|
@ -43,6 +43,7 @@ cd assimp
|
||||||
cmake CMakeLists.txt
|
cmake CMakeLists.txt
|
||||||
cmake --build .
|
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
|
### Build instructions for Windows with Visual-Studio
|
||||||
|
|
||||||
|
|
|
@ -49,14 +49,13 @@ option(ASSIMP_HUNTER_ENABLED "Enable Hunter package manager support" OFF)
|
||||||
IF(ASSIMP_HUNTER_ENABLED)
|
IF(ASSIMP_HUNTER_ENABLED)
|
||||||
include("cmake-modules/HunterGate.cmake")
|
include("cmake-modules/HunterGate.cmake")
|
||||||
HunterGate(
|
HunterGate(
|
||||||
URL "https://github.com/cpp-pm/hunter/archive/v0.24.17.tar.gz"
|
URL "https://github.com/cpp-pm/hunter/archive/v0.24.18.tar.gz"
|
||||||
SHA1 "e6396699e414120e32557fe92db097b7655b760b"
|
SHA1 "1292e4d661e1770d6d6ca08c12c07cf34a0bf718"
|
||||||
)
|
)
|
||||||
|
|
||||||
add_definitions(-DASSIMP_USE_HUNTER)
|
add_definitions(-DASSIMP_USE_HUNTER)
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
PROJECT(Assimp VERSION 5.2.5)
|
PROJECT(Assimp VERSION 5.3.0)
|
||||||
|
|
||||||
# All supported options ###############################################
|
# All supported options ###############################################
|
||||||
|
|
||||||
|
@ -138,7 +137,7 @@ IF (WIN32)
|
||||||
ELSE()
|
ELSE()
|
||||||
OPTION( ASSIMP_BUILD_ZLIB
|
OPTION( ASSIMP_BUILD_ZLIB
|
||||||
"Build your own zlib"
|
"Build your own zlib"
|
||||||
ON
|
OFF
|
||||||
)
|
)
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
|
@ -201,12 +200,9 @@ SET (ASSIMP_VERSION ${ASSIMP_VERSION_MAJOR}.${ASSIMP_VERSION_MINOR}.${ASSIMP_VER
|
||||||
SET (ASSIMP_SOVERSION 5)
|
SET (ASSIMP_SOVERSION 5)
|
||||||
|
|
||||||
SET( ASSIMP_PACKAGE_VERSION "0" CACHE STRING "the package-specific version used for uploading the sources" )
|
SET( ASSIMP_PACKAGE_VERSION "0" CACHE STRING "the package-specific version used for uploading the sources" )
|
||||||
if(NOT ASSIMP_HUNTER_ENABLED)
|
|
||||||
# Enable C++17 support globally
|
|
||||||
set(CMAKE_CXX_STANDARD 17)
|
set(CMAKE_CXX_STANDARD 17)
|
||||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
set(CMAKE_C_STANDARD 99)
|
set(CMAKE_C_STANDARD 99)
|
||||||
endif()
|
|
||||||
|
|
||||||
IF(NOT ASSIMP_IGNORE_GIT_HASH)
|
IF(NOT ASSIMP_IGNORE_GIT_HASH)
|
||||||
# Get the current working branch
|
# Get the current working branch
|
||||||
|
@ -254,8 +250,7 @@ IF( UNIX )
|
||||||
# Use GNUInstallDirs for Unix predefined directories
|
# Use GNUInstallDirs for Unix predefined directories
|
||||||
INCLUDE(GNUInstallDirs)
|
INCLUDE(GNUInstallDirs)
|
||||||
# Ensure that we do not run into issues like http://www.tcm.phy.cam.ac.uk/sw/inodes64.html on 32 bit linux
|
# Ensure that we do not run into issues like http://www.tcm.phy.cam.ac.uk/sw/inodes64.html on 32 bit linux
|
||||||
IF( ${OPERATING_SYSTEM} MATCHES "Android")
|
IF(NOT ${OPERATING_SYSTEM} MATCHES "Android")
|
||||||
ELSE()
|
|
||||||
IF ( CMAKE_SIZEOF_VOID_P EQUAL 4) # only necessary for 32-bit linux
|
IF ( CMAKE_SIZEOF_VOID_P EQUAL 4) # only necessary for 32-bit linux
|
||||||
ADD_DEFINITIONS(-D_FILE_OFFSET_BITS=64 )
|
ADD_DEFINITIONS(-D_FILE_OFFSET_BITS=64 )
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
@ -263,9 +258,8 @@ IF( UNIX )
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
# Grouped compiler settings ########################################
|
# Grouped compiler settings ########################################
|
||||||
IF ((CMAKE_C_COMPILER_ID MATCHES "GNU") AND NOT MINGW)
|
IF ((CMAKE_C_COMPILER_ID MATCHES "GNU") AND NOT MINGW AND NOT HAIKU)
|
||||||
IF(NOT ASSIMP_HUNTER_ENABLED)
|
IF(NOT ASSIMP_HUNTER_ENABLED)
|
||||||
SET(CMAKE_CXX_STANDARD 17)
|
|
||||||
SET(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
SET(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
|
@ -302,7 +296,6 @@ ELSEIF(MSVC)
|
||||||
SET(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} /DEBUG:FULL /PDBALTPATH:%_PDB% /OPT:REF /OPT:ICF")
|
SET(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} /DEBUG:FULL /PDBALTPATH:%_PDB% /OPT:REF /OPT:ICF")
|
||||||
ELSEIF (CMAKE_CXX_COMPILER_ID MATCHES "Clang" )
|
ELSEIF (CMAKE_CXX_COMPILER_ID MATCHES "Clang" )
|
||||||
IF(NOT ASSIMP_HUNTER_ENABLED)
|
IF(NOT ASSIMP_HUNTER_ENABLED)
|
||||||
SET(CMAKE_CXX_STANDARD 17)
|
|
||||||
SET(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
SET(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
||||||
ENDIF()
|
ENDIF()
|
||||||
SET(CMAKE_CXX_FLAGS "-fvisibility=hidden -fno-strict-aliasing -Wall -Wno-long-long ${CMAKE_CXX_FLAGS}" )
|
SET(CMAKE_CXX_FLAGS "-fvisibility=hidden -fno-strict-aliasing -Wall -Wno-long-long ${CMAKE_CXX_FLAGS}" )
|
||||||
|
@ -332,12 +325,12 @@ IF ( IOS AND NOT ASSIMP_HUNTER_ENABLED)
|
||||||
ELSE()
|
ELSE()
|
||||||
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fembed-bitcode -O3")
|
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fembed-bitcode -O3")
|
||||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fembed-bitcode -O3")
|
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fembed-bitcode -O3")
|
||||||
# Experimental for pdb generation
|
|
||||||
ENDIF()
|
ENDIF()
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
IF (ASSIMP_COVERALLS)
|
IF (ASSIMP_COVERALLS)
|
||||||
MESSAGE(STATUS "Coveralls enabled")
|
MESSAGE(STATUS "Coveralls enabled")
|
||||||
|
|
||||||
INCLUDE(Coveralls)
|
INCLUDE(Coveralls)
|
||||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -O0 -fprofile-arcs -ftest-coverage")
|
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -O0 -fprofile-arcs -ftest-coverage")
|
||||||
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g -O0 -fprofile-arcs -ftest-coverage")
|
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g -O0 -fprofile-arcs -ftest-coverage")
|
||||||
|
@ -345,12 +338,14 @@ ENDIF()
|
||||||
|
|
||||||
IF (ASSIMP_ASAN)
|
IF (ASSIMP_ASAN)
|
||||||
MESSAGE(STATUS "AddressSanitizer enabled")
|
MESSAGE(STATUS "AddressSanitizer enabled")
|
||||||
|
|
||||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address")
|
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address")
|
||||||
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address")
|
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address")
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
IF (ASSIMP_UBSAN)
|
IF (ASSIMP_UBSAN)
|
||||||
MESSAGE(STATUS "Undefined Behavior sanitizer enabled")
|
MESSAGE(STATUS "Undefined Behavior sanitizer enabled")
|
||||||
|
|
||||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=undefined,shift,shift-exponent,integer-divide-by-zero,unreachable,vla-bound,null,return,signed-integer-overflow,bounds,float-divide-by-zero,float-cast-overflow,nonnull-attribute,returns-nonnull-attribute,bool,enum,vptr,pointer-overflow,builtin -fno-sanitize-recover=all")
|
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=undefined,shift,shift-exponent,integer-divide-by-zero,unreachable,vla-bound,null,return,signed-integer-overflow,bounds,float-divide-by-zero,float-cast-overflow,nonnull-attribute,returns-nonnull-attribute,bool,enum,vptr,pointer-overflow,builtin -fno-sanitize-recover=all")
|
||||||
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=undefined,shift,shift-exponent,integer-divide-by-zero,unreachable,vla-bound,null,return,signed-integer-overflow,bounds,float-divide-by-zero,float-cast-overflow,nonnull-attribute,returns-nonnull-attribute,bool,enum,vptr,pointer-overflow,builtin -fno-sanitize-recover=all")
|
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=undefined,shift,shift-exponent,integer-divide-by-zero,unreachable,vla-bound,null,return,signed-integer-overflow,bounds,float-divide-by-zero,float-cast-overflow,nonnull-attribute,returns-nonnull-attribute,bool,enum,vptr,pointer-overflow,builtin -fno-sanitize-recover=all")
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
@ -697,7 +692,6 @@ ELSE()
|
||||||
COMPONENT ${LIBASSIMP_COMPONENT}
|
COMPONENT ${LIBASSIMP_COMPONENT}
|
||||||
INCLUDES DESTINATION include
|
INCLUDES DESTINATION include
|
||||||
)
|
)
|
||||||
|
|
||||||
ENDIF()
|
ENDIF()
|
||||||
ENDIF()
|
ENDIF()
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
@ -783,7 +777,7 @@ IF ( ASSIMP_INSTALL )
|
||||||
SET(CPACK_DEBIAN_PACKAGE_SECTION "libs" )
|
SET(CPACK_DEBIAN_PACKAGE_SECTION "libs" )
|
||||||
SET(CPACK_DEBIAN_PACKAGE_DEPENDS "${CPACK_COMPONENTS_ALL}")
|
SET(CPACK_DEBIAN_PACKAGE_DEPENDS "${CPACK_COMPONENTS_ALL}")
|
||||||
SET(CPACK_DEBIAN_PACKAGE_SUGGESTS)
|
SET(CPACK_DEBIAN_PACKAGE_SUGGESTS)
|
||||||
SET(cPACK_DEBIAN_PACKAGE_NAME "assimp")
|
SET(CPACK_DEBIAN_PACKAGE_NAME "assimp")
|
||||||
SET(CPACK_DEBIAN_PACKAGE_REMOVE_SOURCE_FILES contrib/gtest contrib/zlib workspaces test doc obj samples packaging)
|
SET(CPACK_DEBIAN_PACKAGE_REMOVE_SOURCE_FILES contrib/gtest contrib/zlib workspaces test doc obj samples packaging)
|
||||||
SET(CPACK_DEBIAN_PACKAGE_SOURCE_COPY svn export --force)
|
SET(CPACK_DEBIAN_PACKAGE_SOURCE_COPY svn export --force)
|
||||||
SET(CPACK_DEBIAN_CHANGELOG)
|
SET(CPACK_DEBIAN_CHANGELOG)
|
||||||
|
|
29
Readme.md
29
Readme.md
|
@ -6,25 +6,19 @@ Open Asset Import Library is a library to load various 3d file formats into a sh
|
||||||
### Current project status ###
|
### Current project status ###
|
||||||
[](https://opencollective.com/assimp)
|
[](https://opencollective.com/assimp)
|
||||||

|

|
||||||
<a href="https://scan.coverity.com/projects/5607">
|
|
||||||
<img alt="Coverity Scan Build Status"
|
|
||||||
src="https://scan.coverity.com/projects/5607/badge.svg"/>
|
|
||||||
</a>
|
|
||||||
[](https://www.codacy.com/gh/assimp/assimp/dashboard?utm_source=github.com&utm_medium=referral&utm_content=assimp/assimp&utm_campaign=Badge_Grade)
|
[](https://www.codacy.com/gh/assimp/assimp/dashboard?utm_source=github.com&utm_medium=referral&utm_content=assimp/assimp&utm_campaign=Badge_Grade)
|
||||||
|
|
||||||
[](https://coveralls.io/github/assimp/assimp?branch=master)
|
|
||||||
[](https://gitter.im/assimp/assimp?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
[](https://gitter.im/assimp/assimp?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||||
[](http://isitmaintained.com/project/assimp/assimp "Average time to resolve an issue")
|
[](http://isitmaintained.com/project/assimp/assimp "Average time to resolve an issue")
|
||||||
[](http://isitmaintained.com/project/assimp/assimp "Percentage of issues still open")
|
[](http://isitmaintained.com/project/assimp/assimp "Percentage of issues still open")
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
APIs are provided for C and C++. There are various bindings to other languages (C#, Java, Python, Delphi, D). Assimp also runs on Android and iOS.
|
APIs are provided for C and C++. There are various bindings 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.
|
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.
|
||||||
|
|
||||||
### Latest Doc's ###
|
### Documentation ###
|
||||||
Please check the latest documents at [Asset-Importer-Lib-Doc](https://assimp-docs.readthedocs.io/en/latest/).
|
Please check the latest documents at [Asset-Importer-Lib-Doc](https://assimp-docs.readthedocs.io/en/latest/).
|
||||||
|
|
||||||
### Prebuild binaries ###
|
### Pre-built binaries ###
|
||||||
Please check our [Itchi Projectspace](https://kimkulling.itch.io/the-asset-importer-lib)
|
Please check our [Itchi Projectspace](https://kimkulling.itch.io/the-asset-importer-lib)
|
||||||
|
|
||||||
If you want to check our Model-Database, use the following repo: https://github.com/assimp/assimp-mdb
|
If you want to check our Model-Database, use the following repo: https://github.com/assimp/assimp-mdb
|
||||||
|
@ -41,7 +35,7 @@ And we also have a Gitter-channel:Gitter [
|
You can find the complete list of supported file-formats [here](https://github.com/assimp/assimp/blob/master/doc/Fileformats.md)
|
||||||
|
|
||||||
### Building ###
|
### Building ###
|
||||||
Take a look into the https://github.com/assimp/assimp/blob/master/Build.md file. 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.
|
Take a look [here](https://github.com/assimp/assimp/blob/master/Build.md) to get started. 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)
|
* [Android](port/AndroidJNI/README.md)
|
||||||
|
@ -58,20 +52,21 @@ Take a look into the https://github.com/assimp/assimp/blob/master/Build.md file.
|
||||||
|
|
||||||
### Other tools ###
|
### Other tools ###
|
||||||
[open3mod](https://github.com/acgessler/open3mod) is a powerful 3D model viewer based on Assimp's import and export abilities.
|
[open3mod](https://github.com/acgessler/open3mod) is a powerful 3D model viewer based on Assimp's import and export abilities.
|
||||||
|
[Assimp-Viewer](https://github.com/assimp/assimp_view) is an experimental implementation for an Asset-Viewer based on ImGUI and Assimp (experimental).
|
||||||
|
|
||||||
#### Repository structure ####
|
#### Repository structure ####
|
||||||
Open Asset Import Library is implemented in C++. The directory structure looks like:
|
Open Asset Import Library is implemented in C++. The directory structure looks like this:
|
||||||
|
|
||||||
/code Source code
|
/code Source code
|
||||||
/contrib Third-party libraries
|
/contrib Third-party libraries
|
||||||
/doc Documentation (doxysource and pre-compiled docs)
|
/doc Documentation (doxysource and pre-compiled docs)
|
||||||
/fuzz Contains the test-code for the Google-Fuzzer project
|
/fuzz Contains the test code for the Google Fuzzer project
|
||||||
/include Public header C and C++ header files
|
/include Public header C and C++ header files
|
||||||
/scripts Scripts used to generate the loading code for some formats
|
/scripts Scripts are used to generate the loading code for some formats
|
||||||
/port Ports to other languages and scripts to maintain those.
|
/port Ports to other languages and scripts to maintain those.
|
||||||
/test Unit- and regression tests, test suite of models
|
/test Unit- and regression tests, test suite of models
|
||||||
/tools Tools (old assimp viewer, command line `assimp`)
|
/tools Tools (old assimp viewer, command line `assimp`)
|
||||||
/samples A small number of samples to illustrate possible use-cases for Assimp
|
/samples A small number of samples to illustrate possible use cases for Assimp
|
||||||
|
|
||||||
The source code is organized in the following way:
|
The source code is organized in the following way:
|
||||||
|
|
||||||
|
@ -79,9 +74,9 @@ The source code is organized in the following way:
|
||||||
code/CApi Special implementations which are only used for the C-API
|
code/CApi Special implementations which are only used for the C-API
|
||||||
code/Geometry A collection of geometry tools
|
code/Geometry A collection of geometry tools
|
||||||
code/Material The material system
|
code/Material The material system
|
||||||
code/PBR An exporter for physical based models
|
code/PBR An exporter for physical-based models
|
||||||
code/PostProcessing The post-processing steps
|
code/PostProcessing The post-processing steps
|
||||||
code/AssetLib/<FormatName> Implementation for import and export for the format
|
code/AssetLib/<FormatName> Implementation for import and export of the format
|
||||||
|
|
||||||
### Contributing ###
|
### Contributing ###
|
||||||
Contributions to assimp are highly appreciated. The easiest way to get involved is to submit
|
Contributions to assimp are highly appreciated. The easiest way to get involved is to submit
|
||||||
|
@ -118,4 +113,4 @@ and don't sue us if our code doesn't work. Note that, unlike LGPLed code, you ma
|
||||||
For the legal details, see the `LICENSE` file.
|
For the legal details, see the `LICENSE` file.
|
||||||
|
|
||||||
### Why this name ###
|
### Why this name ###
|
||||||
Sorry, we're germans :-), no english native speakers ...
|
Sorry, we're germans :-), no English native speakers ...
|
||||||
|
|
|
@ -52,9 +52,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <cctype>
|
#include <cctype>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
using namespace Assimp;
|
namespace Assimp {
|
||||||
|
|
||||||
static const unsigned int NotSet = 0xcdcdcdcd;
|
static constexpr unsigned int NotSet = 0xcdcdcdcd;
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Setup final material indices, generae a default material if necessary
|
// Setup final material indices, generae a default material if necessary
|
||||||
|
@ -593,7 +593,7 @@ void Discreet3DSImporter::AddNodeToGraph(aiScene *pcSOut, aiNode *pcOut,
|
||||||
|
|
||||||
// Cameras or lights define their transformation in their parent node and in the
|
// Cameras or lights define their transformation in their parent node and in the
|
||||||
// corresponding light or camera chunks. However, we read and process the latter
|
// corresponding light or camera chunks. However, we read and process the latter
|
||||||
// to to be able to return valid cameras/lights even if no scenegraph is given.
|
// to be able to return valid cameras/lights even if no scenegraph is given.
|
||||||
for (unsigned int n = 0; n < pcSOut->mNumCameras; ++n) {
|
for (unsigned int n = 0; n < pcSOut->mNumCameras; ++n) {
|
||||||
if (pcSOut->mCameras[n]->mName == pcOut->mName) {
|
if (pcSOut->mCameras[n]->mName == pcOut->mName) {
|
||||||
pcSOut->mCameras[n]->mLookAt = aiVector3D(0.f, 0.f, 1.f);
|
pcSOut->mCameras[n]->mLookAt = aiVector3D(0.f, 0.f, 1.f);
|
||||||
|
@ -805,4 +805,6 @@ void Discreet3DSImporter::ConvertScene(aiScene *pcOut) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace Assimp
|
||||||
|
|
||||||
#endif // !! ASSIMP_BUILD_NO_3DS_IMPORTER
|
#endif // !! ASSIMP_BUILD_NO_3DS_IMPORTER
|
||||||
|
|
|
@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
|
||||||
|
|
||||||
Copyright (c) 2006-2022, assimp team
|
Copyright (c) 2006-2022, assimp team
|
||||||
|
|
||||||
|
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use of this software in source and binary forms,
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
@ -57,8 +56,7 @@ struct aiNode;
|
||||||
struct aiMaterial;
|
struct aiMaterial;
|
||||||
struct aiMesh;
|
struct aiMesh;
|
||||||
|
|
||||||
namespace Assimp
|
namespace Assimp {
|
||||||
{
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
/**
|
/**
|
||||||
|
@ -88,7 +86,7 @@ private:
|
||||||
|
|
||||||
std::map<const aiNode*, aiMatrix4x4> trafos;
|
std::map<const aiNode*, aiMatrix4x4> trafos;
|
||||||
|
|
||||||
typedef std::multimap<const aiNode*, unsigned int> MeshesByNodeMap;
|
using MeshesByNodeMap = std::multimap<const aiNode*, unsigned int>;
|
||||||
MeshesByNodeMap meshes;
|
MeshesByNodeMap meshes;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -54,9 +54,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <assimp/DefaultLogger.hpp>
|
#include <assimp/DefaultLogger.hpp>
|
||||||
#include <assimp/IOSystem.hpp>
|
#include <assimp/IOSystem.hpp>
|
||||||
|
|
||||||
using namespace Assimp;
|
namespace Assimp {
|
||||||
|
|
||||||
static const aiImporterDesc desc = {
|
static constexpr aiImporterDesc desc = {
|
||||||
"Discreet 3DS Importer",
|
"Discreet 3DS Importer",
|
||||||
"",
|
"",
|
||||||
"",
|
"",
|
||||||
|
@ -103,10 +103,6 @@ Discreet3DSImporter::Discreet3DSImporter() :
|
||||||
// empty
|
// empty
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
// Destructor, private as well
|
|
||||||
Discreet3DSImporter::~Discreet3DSImporter() = default;
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Returns whether the class can handle the format of the given file.
|
// Returns whether the class can handle the format of the given file.
|
||||||
bool Discreet3DSImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /*checkSig*/) const {
|
bool Discreet3DSImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /*checkSig*/) const {
|
||||||
|
@ -369,7 +365,7 @@ void Discreet3DSImporter::ParseChunk(const char *name, unsigned int num) {
|
||||||
// IMPLEMENTATION NOTE;
|
// IMPLEMENTATION NOTE;
|
||||||
// Cameras or lights define their transformation in their parent node and in the
|
// Cameras or lights define their transformation in their parent node and in the
|
||||||
// corresponding light or camera chunks. However, we read and process the latter
|
// corresponding light or camera chunks. However, we read and process the latter
|
||||||
// to to be able to return valid cameras/lights even if no scenegraph is given.
|
// to be able to return valid cameras/lights even if no scenegraph is given.
|
||||||
|
|
||||||
// get chunk type
|
// get chunk type
|
||||||
switch (chunk.Flag) {
|
switch (chunk.Flag) {
|
||||||
|
@ -1339,4 +1335,6 @@ void Discreet3DSImporter::ParseColorChunk(aiColor3D *out, bool acceptPercent) {
|
||||||
(void)bGamma;
|
(void)bGamma;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace Assimp
|
||||||
|
|
||||||
#endif // !! ASSIMP_BUILD_NO_3DS_IMPORTER
|
#endif // !! ASSIMP_BUILD_NO_3DS_IMPORTER
|
||||||
|
|
|
@ -59,7 +59,6 @@ struct aiNode;
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
|
|
||||||
|
|
||||||
using namespace D3DS;
|
using namespace D3DS;
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------------
|
||||||
|
@ -68,7 +67,7 @@ using namespace D3DS;
|
||||||
class Discreet3DSImporter : public BaseImporter {
|
class Discreet3DSImporter : public BaseImporter {
|
||||||
public:
|
public:
|
||||||
Discreet3DSImporter();
|
Discreet3DSImporter();
|
||||||
~Discreet3DSImporter() override;
|
~Discreet3DSImporter() override = default;
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Returns whether the class can handle the format of the given file.
|
/** Returns whether the class can handle the format of the given file.
|
||||||
|
|
|
@ -68,7 +68,7 @@ namespace Assimp {
|
||||||
|
|
||||||
using namespace D3MF;
|
using namespace D3MF;
|
||||||
|
|
||||||
static const aiImporterDesc desc = {
|
static constexpr aiImporterDesc desc = {
|
||||||
"3mf Importer",
|
"3mf Importer",
|
||||||
"",
|
"",
|
||||||
"",
|
"",
|
||||||
|
@ -81,16 +81,17 @@ static const aiImporterDesc desc = {
|
||||||
"3mf"
|
"3mf"
|
||||||
};
|
};
|
||||||
|
|
||||||
D3MFImporter::D3MFImporter() = default;
|
bool D3MFImporter::CanRead(const std::string &filename, IOSystem *pIOHandler, bool ) const {
|
||||||
|
|
||||||
D3MFImporter::~D3MFImporter() = default;
|
|
||||||
|
|
||||||
bool D3MFImporter::CanRead(const std::string &filename, IOSystem *pIOHandler, bool /*checkSig*/) const {
|
|
||||||
if (!ZipArchiveIOSystem::isZipArchive(pIOHandler, filename)) {
|
if (!ZipArchiveIOSystem::isZipArchive(pIOHandler, filename)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
D3MF::D3MFOpcPackage opcPackage(pIOHandler, filename);
|
static const char *const ModelRef = "3D/3dmodel.model";
|
||||||
return opcPackage.validate();
|
ZipArchiveIOSystem archive(pIOHandler, filename);
|
||||||
|
if (!archive.Exists(ModelRef)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void D3MFImporter::SetupProperties(const Importer*) {
|
void D3MFImporter::SetupProperties(const Importer*) {
|
||||||
|
|
|
@ -56,10 +56,10 @@ namespace Assimp {
|
||||||
class D3MFImporter : public BaseImporter {
|
class D3MFImporter : public BaseImporter {
|
||||||
public:
|
public:
|
||||||
/// @brief The default class constructor.
|
/// @brief The default class constructor.
|
||||||
D3MFImporter();
|
D3MFImporter() = default;
|
||||||
|
|
||||||
/// @brief The class destructor.
|
/// @brief The class destructor.
|
||||||
~D3MFImporter() override;
|
~D3MFImporter() override = default;
|
||||||
|
|
||||||
/// @brief Performs the data format detection.
|
/// @brief Performs the data format detection.
|
||||||
/// @param pFile The filename to check.
|
/// @param pFile The filename to check.
|
||||||
|
|
|
@ -68,7 +68,7 @@ using OpcPackageRelationshipPtr = std::shared_ptr<OpcPackageRelationship>;
|
||||||
class OpcPackageRelationshipReader {
|
class OpcPackageRelationshipReader {
|
||||||
public:
|
public:
|
||||||
OpcPackageRelationshipReader(XmlParser &parser) :
|
OpcPackageRelationshipReader(XmlParser &parser) :
|
||||||
m_relationShips() {
|
mRelations() {
|
||||||
XmlNode root = parser.getRootNode();
|
XmlNode root = parser.getRootNode();
|
||||||
ParseRootNode(root);
|
ParseRootNode(root);
|
||||||
}
|
}
|
||||||
|
@ -108,13 +108,13 @@ public:
|
||||||
relPtr->type = currentNode.attribute(XmlTag::RELS_ATTRIB_TYPE).as_string();
|
relPtr->type = currentNode.attribute(XmlTag::RELS_ATTRIB_TYPE).as_string();
|
||||||
relPtr->target = currentNode.attribute(XmlTag::RELS_ATTRIB_TARGET).as_string();
|
relPtr->target = currentNode.attribute(XmlTag::RELS_ATTRIB_TARGET).as_string();
|
||||||
if (validateRels(relPtr)) {
|
if (validateRels(relPtr)) {
|
||||||
m_relationShips.push_back(relPtr);
|
mRelations.push_back(relPtr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<OpcPackageRelationshipPtr> m_relationShips;
|
std::vector<OpcPackageRelationshipPtr> mRelations;
|
||||||
};
|
};
|
||||||
|
|
||||||
static bool IsEmbeddedTexture( const std::string &filename ) {
|
static bool IsEmbeddedTexture( const std::string &filename ) {
|
||||||
|
@ -186,9 +186,6 @@ D3MFOpcPackage::D3MFOpcPackage(IOSystem *pIOHandler, const std::string &rFile) :
|
||||||
D3MFOpcPackage::~D3MFOpcPackage() {
|
D3MFOpcPackage::~D3MFOpcPackage() {
|
||||||
mZipArchive->Close(mRootStream);
|
mZipArchive->Close(mRootStream);
|
||||||
delete mZipArchive;
|
delete mZipArchive;
|
||||||
for (auto tex : mEmbeddedTextures) {
|
|
||||||
delete tex;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
IOStream *D3MFOpcPackage::RootStream() const {
|
IOStream *D3MFOpcPackage::RootStream() const {
|
||||||
|
@ -217,11 +214,11 @@ std::string D3MFOpcPackage::ReadPackageRootRelationship(IOStream *stream) {
|
||||||
|
|
||||||
OpcPackageRelationshipReader reader(xmlParser);
|
OpcPackageRelationshipReader reader(xmlParser);
|
||||||
|
|
||||||
auto itr = std::find_if(reader.m_relationShips.begin(), reader.m_relationShips.end(), [](const OpcPackageRelationshipPtr &rel) {
|
auto itr = std::find_if(reader.mRelations.begin(), reader.mRelations.end(), [](const OpcPackageRelationshipPtr &rel) {
|
||||||
return rel->type == XmlTag::PACKAGE_START_PART_RELATIONSHIP_TYPE;
|
return rel->type == XmlTag::PACKAGE_START_PART_RELATIONSHIP_TYPE;
|
||||||
});
|
});
|
||||||
|
|
||||||
if (itr == reader.m_relationShips.end()) {
|
if (itr == reader.mRelations.end()) {
|
||||||
throw DeadlyImportError("Cannot find ", XmlTag::PACKAGE_START_PART_RELATIONSHIP_TYPE);
|
throw DeadlyImportError("Cannot find ", XmlTag::PACKAGE_START_PART_RELATIONSHIP_TYPE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -49,12 +49,12 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
namespace D3MF {
|
namespace D3MF {
|
||||||
|
|
||||||
static const int IdNotSet = -1;
|
static constexpr int IdNotSet = -1;
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
static const size_t ColRGBA_Len = 9;
|
static constexpr size_t ColRGBA_Len = 9;
|
||||||
static const size_t ColRGB_Len = 7;
|
static constexpr size_t ColRGB_Len = 7;
|
||||||
|
|
||||||
// format of the color string: #RRGGBBAA or #RRGGBB (3MF Core chapter 5.1.1)
|
// format of the color string: #RRGGBBAA or #RRGGBB (3MF Core chapter 5.1.1)
|
||||||
bool validateColorString(const char *color) {
|
bool validateColorString(const char *color) {
|
||||||
|
|
|
@ -60,9 +60,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <assimp/Importer.hpp>
|
#include <assimp/Importer.hpp>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
using namespace Assimp;
|
namespace Assimp {
|
||||||
|
|
||||||
static const aiImporterDesc desc = {
|
static constexpr aiImporterDesc desc = {
|
||||||
"AC3D Importer",
|
"AC3D Importer",
|
||||||
"",
|
"",
|
||||||
"",
|
"",
|
||||||
|
@ -862,4 +862,6 @@ void AC3DImporter::InternReadFile(const std::string &pFile,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace Assimp
|
||||||
|
|
||||||
#endif //!defined ASSIMP_BUILD_NO_AC_IMPORTER
|
#endif //!defined ASSIMP_BUILD_NO_AC_IMPORTER
|
||||||
|
|
|
@ -53,7 +53,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
|
|
||||||
const aiImporterDesc AMFImporter::Description = {
|
static constexpr aiImporterDesc Description = {
|
||||||
"Additive manufacturing file format(AMF) Importer",
|
"Additive manufacturing file format(AMF) Importer",
|
||||||
"smalcom",
|
"smalcom",
|
||||||
"",
|
"",
|
||||||
|
|
|
@ -98,8 +98,12 @@ namespace Assimp {
|
||||||
/// old - <map> and children <u1>, <u2>, <u3>, <v1>, <v2>, <v3>
|
/// old - <map> and children <u1>, <u2>, <u3>, <v1>, <v2>, <v3>
|
||||||
///
|
///
|
||||||
class AMFImporter : public BaseImporter {
|
class AMFImporter : public BaseImporter {
|
||||||
private:
|
using AMFMetaDataArray = std::vector<AMFMetadata *>;
|
||||||
struct SPP_Material; // forward declaration
|
using MeshArray = std::vector<aiMesh *>;
|
||||||
|
using NodeArray = std::vector<aiNode *>;
|
||||||
|
|
||||||
|
public:
|
||||||
|
struct SPP_Material;
|
||||||
|
|
||||||
/// Data type for post-processing step. More suitable container for part of material's composition.
|
/// Data type for post-processing step. More suitable container for part of material's composition.
|
||||||
struct SPP_Composite {
|
struct SPP_Composite {
|
||||||
|
@ -107,22 +111,6 @@ private:
|
||||||
std::string Formula; ///< Formula for calculating ratio of \ref Material.
|
std::string Formula; ///< Formula for calculating ratio of \ref Material.
|
||||||
};
|
};
|
||||||
|
|
||||||
/// \struct SPP_Material
|
|
||||||
/// Data type for post-processing step. More suitable container for material.
|
|
||||||
struct SPP_Material {
|
|
||||||
std::string ID; ///< Material ID.
|
|
||||||
std::list<AMFMetadata *> Metadata; ///< Metadata of material.
|
|
||||||
AMFColor *Color; ///< Color of material.
|
|
||||||
std::list<SPP_Composite> Composition; ///< List of child materials if current material is composition of few another.
|
|
||||||
|
|
||||||
/// Return color calculated for specified coordinate.
|
|
||||||
/// \param [in] pX - "x" coordinate.
|
|
||||||
/// \param [in] pY - "y" coordinate.
|
|
||||||
/// \param [in] pZ - "z" coordinate.
|
|
||||||
/// \return calculated color.
|
|
||||||
aiColor4D GetColor(const float pX, const float pY, const float pZ) const;
|
|
||||||
};
|
|
||||||
|
|
||||||
/// Data type for post-processing step. More suitable container for texture.
|
/// Data type for post-processing step. More suitable container for texture.
|
||||||
struct SPP_Texture {
|
struct SPP_Texture {
|
||||||
std::string ID;
|
std::string ID;
|
||||||
|
@ -139,10 +127,52 @@ private:
|
||||||
const AMFTexMap *TexMap; ///< Face texture mapping data. Equal to nullptr if texture mapping is not set for the face.
|
const AMFTexMap *TexMap; ///< Face texture mapping data. Equal to nullptr if texture mapping is not set for the face.
|
||||||
};
|
};
|
||||||
|
|
||||||
using AMFMetaDataArray = std::vector<AMFMetadata*>;
|
/// Data type for post-processing step. More suitable container for material.
|
||||||
using MeshArray = std::vector<aiMesh*>;
|
struct SPP_Material {
|
||||||
using NodeArray = std::vector<aiNode*>;
|
std::string ID; ///< Material ID.
|
||||||
|
std::list<AMFMetadata *> Metadata; ///< Metadata of material.
|
||||||
|
AMFColor *Color; ///< Color of material.
|
||||||
|
std::list<SPP_Composite> Composition; ///< List of child materials if current material is composition of few another.
|
||||||
|
|
||||||
|
/// Return color calculated for specified coordinate.
|
||||||
|
/// \param [in] pX - "x" coordinate.
|
||||||
|
/// \param [in] pY - "y" coordinate.
|
||||||
|
/// \param [in] pZ - "z" coordinate.
|
||||||
|
/// \return calculated color.
|
||||||
|
aiColor4D GetColor(const float pX, const float pY, const float pZ) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Default constructor.
|
||||||
|
AMFImporter() AI_NO_EXCEPT;
|
||||||
|
|
||||||
|
/// Default destructor.
|
||||||
|
~AMFImporter() override;
|
||||||
|
|
||||||
|
/// Parse AMF file and fill scene graph. The function has no return value. Result can be found by analyzing the generated graph.
|
||||||
|
/// Also exception can be thrown if trouble will found.
|
||||||
|
/// \param [in] pFile - name of file to be parsed.
|
||||||
|
/// \param [in] pIOHandler - pointer to IO helper object.
|
||||||
|
void ParseFile(const std::string &pFile, IOSystem *pIOHandler);
|
||||||
|
void ParseHelper_Node_Enter(AMFNodeElementBase *child);
|
||||||
|
void ParseHelper_Node_Exit();
|
||||||
|
bool CanRead(const std::string &pFile, IOSystem *pIOHandler, bool pCheckSig) const override;
|
||||||
|
void InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler) override;
|
||||||
|
const aiImporterDesc *GetInfo() const override;
|
||||||
|
bool Find_NodeElement(const std::string &pID, const AMFNodeElementBase::EType pType, AMFNodeElementBase **pNodeElement) const;
|
||||||
|
bool Find_ConvertedNode(const std::string &pID, NodeArray &nodeArray, aiNode **pNode) const;
|
||||||
|
bool Find_ConvertedMaterial(const std::string &pID, const SPP_Material **pConvertedMaterial) const;
|
||||||
|
AI_WONT_RETURN void Throw_CloseNotFound(const std::string &nodeName) AI_WONT_RETURN_SUFFIX;
|
||||||
|
AI_WONT_RETURN void Throw_IncorrectAttr(const std::string &nodeName, const std::string &pAttrName) AI_WONT_RETURN_SUFFIX;
|
||||||
|
AI_WONT_RETURN void Throw_IncorrectAttrValue(const std::string &nodeName, const std::string &pAttrName) AI_WONT_RETURN_SUFFIX;
|
||||||
|
AI_WONT_RETURN void Throw_MoreThanOnceDefined(const std::string &nodeName, const std::string &pNodeType, const std::string &pDescription) AI_WONT_RETURN_SUFFIX;
|
||||||
|
AI_WONT_RETURN void Throw_ID_NotFound(const std::string &pID) const AI_WONT_RETURN_SUFFIX;
|
||||||
|
void XML_CheckNode_MustHaveChildren(pugi::xml_node &node);
|
||||||
|
bool XML_SearchNode(const std::string &nodeName);
|
||||||
|
void ParseHelper_FixTruncatedFloatString(const char *pInStr, std::string &pOutString);
|
||||||
|
AMFImporter(const AMFImporter &pScene) = delete;
|
||||||
|
AMFImporter &operator=(const AMFImporter &pScene) = delete;
|
||||||
|
|
||||||
|
private:
|
||||||
/// Clear all temporary data.
|
/// Clear all temporary data.
|
||||||
void Clear();
|
void Clear();
|
||||||
|
|
||||||
|
@ -262,40 +292,9 @@ private:
|
||||||
/// \param [in] pUseOldName - if true then use old name of node(and children) - <map>, instead of new name - <texmap>.
|
/// \param [in] pUseOldName - if true then use old name of node(and children) - <map>, instead of new name - <texmap>.
|
||||||
void ParseNode_TexMap(XmlNode &node, const bool pUseOldName = false);
|
void ParseNode_TexMap(XmlNode &node, const bool pUseOldName = false);
|
||||||
|
|
||||||
public:
|
|
||||||
/// Default constructor.
|
|
||||||
AMFImporter() AI_NO_EXCEPT;
|
|
||||||
|
|
||||||
/// Default destructor.
|
|
||||||
~AMFImporter() override;
|
|
||||||
|
|
||||||
/// Parse AMF file and fill scene graph. The function has no return value. Result can be found by analyzing the generated graph.
|
|
||||||
/// Also exception can be thrown if trouble will found.
|
|
||||||
/// \param [in] pFile - name of file to be parsed.
|
|
||||||
/// \param [in] pIOHandler - pointer to IO helper object.
|
|
||||||
void ParseFile(const std::string &pFile, IOSystem *pIOHandler);
|
|
||||||
void ParseHelper_Node_Enter(AMFNodeElementBase *child);
|
|
||||||
void ParseHelper_Node_Exit();
|
|
||||||
bool CanRead(const std::string &pFile, IOSystem *pIOHandler, bool pCheckSig) const override;
|
|
||||||
void InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler) override;
|
|
||||||
const aiImporterDesc *GetInfo() const override;
|
|
||||||
bool Find_NodeElement(const std::string &pID, const AMFNodeElementBase::EType pType, AMFNodeElementBase **pNodeElement) const;
|
|
||||||
bool Find_ConvertedNode(const std::string &pID, NodeArray &nodeArray, aiNode **pNode) const;
|
|
||||||
bool Find_ConvertedMaterial(const std::string &pID, const SPP_Material **pConvertedMaterial) const;
|
|
||||||
AI_WONT_RETURN void Throw_CloseNotFound(const std::string &nodeName) AI_WONT_RETURN_SUFFIX;
|
|
||||||
AI_WONT_RETURN void Throw_IncorrectAttr(const std::string &nodeName, const std::string &pAttrName) AI_WONT_RETURN_SUFFIX;
|
|
||||||
AI_WONT_RETURN void Throw_IncorrectAttrValue(const std::string &nodeName, const std::string &pAttrName) AI_WONT_RETURN_SUFFIX;
|
|
||||||
AI_WONT_RETURN void Throw_MoreThanOnceDefined(const std::string &nodeName, const std::string &pNodeType, const std::string &pDescription) AI_WONT_RETURN_SUFFIX;
|
|
||||||
AI_WONT_RETURN void Throw_ID_NotFound(const std::string &pID) const AI_WONT_RETURN_SUFFIX;
|
|
||||||
void XML_CheckNode_MustHaveChildren(pugi::xml_node &node);
|
|
||||||
bool XML_SearchNode(const std::string &nodeName);
|
|
||||||
void ParseHelper_FixTruncatedFloatString(const char *pInStr, std::string &pOutString);
|
|
||||||
AMFImporter(const AMFImporter &pScene) = delete;
|
|
||||||
AMFImporter &operator=(const AMFImporter &pScene) = delete;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static const aiImporterDesc Description;
|
|
||||||
|
|
||||||
AMFNodeElementBase *mNodeElement_Cur; ///< Current element.
|
AMFNodeElementBase *mNodeElement_Cur; ///< Current element.
|
||||||
std::list<AMFNodeElementBase *> mNodeElement_List; ///< All elements of scene graph.
|
std::list<AMFNodeElementBase *> mNodeElement_List; ///< All elements of scene graph.
|
||||||
XmlParser *mXmlParser;
|
XmlParser *mXmlParser;
|
||||||
|
|
|
@ -63,10 +63,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
// utilities
|
// utilities
|
||||||
#include <assimp/fast_atof.h>
|
#include <assimp/fast_atof.h>
|
||||||
|
|
||||||
using namespace Assimp;
|
namespace Assimp {
|
||||||
using namespace Assimp::ASE;
|
using namespace Assimp::ASE;
|
||||||
|
|
||||||
static const aiImporterDesc desc = {
|
static constexpr aiImporterDesc desc = {
|
||||||
"ASE Importer",
|
"ASE Importer",
|
||||||
"",
|
"",
|
||||||
"",
|
"",
|
||||||
|
@ -904,7 +904,7 @@ void ASEImporter::ConvertMeshes(ASE::Mesh &mesh, std::vector<aiMesh *> &avOutMes
|
||||||
ASSIMP_LOG_WARN("Material index is out of range");
|
ASSIMP_LOG_WARN("Material index is out of range");
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the material the mesh is assigned to is consisting of submeshes, split it
|
// If the material the mesh is assigned to consists of submeshes, split it
|
||||||
if (!mParser->m_vMaterials[mesh.iMaterialIndex].avSubMaterials.empty()) {
|
if (!mParser->m_vMaterials[mesh.iMaterialIndex].avSubMaterials.empty()) {
|
||||||
std::vector<ASE::Material> vSubMaterials = mParser->m_vMaterials[mesh.iMaterialIndex].avSubMaterials;
|
std::vector<ASE::Material> vSubMaterials = mParser->m_vMaterials[mesh.iMaterialIndex].avSubMaterials;
|
||||||
|
|
||||||
|
@ -1262,6 +1262,8 @@ bool ASEImporter::GenerateNormals(ASE::Mesh &mesh) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
#endif // ASSIMP_BUILD_NO_3DS_IMPORTER
|
#endif // ASSIMP_BUILD_NO_3DS_IMPORTER
|
||||||
|
|
||||||
#endif // !! ASSIMP_BUILD_NO_BASE_IMPORTER
|
#endif // !! ASSIMP_BUILD_NO_BASE_IMPORTER
|
||||||
|
|
|
@ -53,7 +53,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <assimp/fast_atof.h>
|
#include <assimp/fast_atof.h>
|
||||||
#include <assimp/DefaultLogger.hpp>
|
#include <assimp/DefaultLogger.hpp>
|
||||||
|
|
||||||
using namespace Assimp;
|
namespace Assimp {
|
||||||
using namespace Assimp::ASE;
|
using namespace Assimp::ASE;
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
@ -1864,6 +1864,8 @@ void Parser::ParseLV4MeshLong(unsigned int &iOut) {
|
||||||
iOut = strtoul10(filePtr, &filePtr);
|
iOut = strtoul10(filePtr, &filePtr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
#endif // ASSIMP_BUILD_NO_3DS_IMPORTER
|
#endif // ASSIMP_BUILD_NO_3DS_IMPORTER
|
||||||
|
|
||||||
#endif // !! ASSIMP_BUILD_NO_BASE_IMPORTER
|
#endif // !! ASSIMP_BUILD_NO_BASE_IMPORTER
|
||||||
|
|
|
@ -50,11 +50,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <assimp/version.h>
|
#include <assimp/version.h>
|
||||||
#include <assimp/IOStream.hpp>
|
#include <assimp/IOStream.hpp>
|
||||||
|
|
||||||
#ifdef ASSIMP_BUILD_NO_OWN_ZLIB
|
#include "zlib.h"
|
||||||
#include <zlib.h>
|
|
||||||
#else
|
|
||||||
#include "../contrib/zlib/zlib.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
|
|
||||||
|
|
|
@ -65,7 +65,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
using namespace Assimp;
|
using namespace Assimp;
|
||||||
|
|
||||||
static const aiImporterDesc desc = {
|
static constexpr aiImporterDesc desc = {
|
||||||
"Assimp Binary Importer",
|
"Assimp Binary Importer",
|
||||||
"Gargaj / Conspiracy",
|
"Gargaj / Conspiracy",
|
||||||
"",
|
"",
|
||||||
|
|
|
@ -59,10 +59,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
using namespace Assimp;
|
namespace Assimp {
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
static const aiImporterDesc desc = {
|
static constexpr aiImporterDesc desc = {
|
||||||
"BlitzBasic 3D Importer",
|
"BlitzBasic 3D Importer",
|
||||||
"",
|
"",
|
||||||
"",
|
"",
|
||||||
|
@ -738,4 +738,6 @@ void B3DImporter::ReadBB3D(aiScene *scene) {
|
||||||
flip.Execute(scene);
|
flip.Execute(scene);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace Assimp
|
||||||
|
|
||||||
#endif // !! ASSIMP_BUILD_NO_B3D_IMPORTER
|
#endif // !! ASSIMP_BUILD_NO_B3D_IMPORTER
|
||||||
|
|
|
@ -55,10 +55,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
using namespace Assimp;
|
namespace Assimp {
|
||||||
|
|
||||||
using namespace Assimp::Formatter;
|
using namespace Assimp::Formatter;
|
||||||
|
|
||||||
static const aiImporterDesc desc = {
|
static constexpr aiImporterDesc desc = {
|
||||||
"BVH Importer (MoCap)",
|
"BVH Importer (MoCap)",
|
||||||
"",
|
"",
|
||||||
"",
|
"",
|
||||||
|
@ -487,24 +488,21 @@ void BVHLoader::CreateAnimation(aiScene *pScene) {
|
||||||
aiMatrix3x3 rotMatrix;
|
aiMatrix3x3 rotMatrix;
|
||||||
for (unsigned int channelIdx = 0; channelIdx < node.mChannels.size(); ++channelIdx) {
|
for (unsigned int channelIdx = 0; channelIdx < node.mChannels.size(); ++channelIdx) {
|
||||||
switch (node.mChannels[channelIdx]) {
|
switch (node.mChannels[channelIdx]) {
|
||||||
case Channel_RotationX:
|
case Channel_RotationX: {
|
||||||
{
|
|
||||||
const float angle = node.mChannelValues[fr * node.mChannels.size() + channelIdx] * float(AI_MATH_PI) / 180.0f;
|
const float angle = node.mChannelValues[fr * node.mChannels.size() + channelIdx] * float(AI_MATH_PI) / 180.0f;
|
||||||
aiMatrix4x4::RotationX( angle, temp); rotMatrix *= aiMatrix3x3( temp);
|
aiMatrix4x4::RotationX(angle, temp);
|
||||||
}
|
rotMatrix *= aiMatrix3x3(temp);
|
||||||
break;
|
} break;
|
||||||
case Channel_RotationY:
|
case Channel_RotationY: {
|
||||||
{
|
|
||||||
const float angle = node.mChannelValues[fr * node.mChannels.size() + channelIdx] * float(AI_MATH_PI) / 180.0f;
|
const float angle = node.mChannelValues[fr * node.mChannels.size() + channelIdx] * float(AI_MATH_PI) / 180.0f;
|
||||||
aiMatrix4x4::RotationY( angle, temp); rotMatrix *= aiMatrix3x3( temp);
|
aiMatrix4x4::RotationY(angle, temp);
|
||||||
}
|
rotMatrix *= aiMatrix3x3(temp);
|
||||||
break;
|
} break;
|
||||||
case Channel_RotationZ:
|
case Channel_RotationZ: {
|
||||||
{
|
|
||||||
const float angle = node.mChannelValues[fr * node.mChannels.size() + channelIdx] * float(AI_MATH_PI) / 180.0f;
|
const float angle = node.mChannelValues[fr * node.mChannels.size() + channelIdx] * float(AI_MATH_PI) / 180.0f;
|
||||||
aiMatrix4x4::RotationZ( angle, temp); rotMatrix *= aiMatrix3x3( temp);
|
aiMatrix4x4::RotationZ(angle, temp);
|
||||||
}
|
rotMatrix *= aiMatrix3x3(temp);
|
||||||
break;
|
} break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -525,4 +523,6 @@ void BVHLoader::CreateAnimation(aiScene *pScene) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace Assimp
|
||||||
|
|
||||||
#endif // !! ASSIMP_BUILD_NO_BVH_IMPORTER
|
#endif // !! ASSIMP_BUILD_NO_BVH_IMPORTER
|
||||||
|
|
|
@ -69,11 +69,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
// zlib is needed for compressed blend files
|
// zlib is needed for compressed blend files
|
||||||
#ifndef ASSIMP_BUILD_NO_COMPRESSED_BLEND
|
#ifndef ASSIMP_BUILD_NO_COMPRESSED_BLEND
|
||||||
#include "Common/Compression.h"
|
#include "Common/Compression.h"
|
||||||
/* #ifdef ASSIMP_BUILD_NO_OWN_ZLIB
|
|
||||||
# include <zlib.h>
|
|
||||||
# else
|
|
||||||
# include "../contrib/zlib/zlib.h"
|
|
||||||
# endif*/
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
|
@ -89,7 +84,7 @@ using namespace Assimp;
|
||||||
using namespace Assimp::Blender;
|
using namespace Assimp::Blender;
|
||||||
using namespace Assimp::Formatter;
|
using namespace Assimp::Formatter;
|
||||||
|
|
||||||
static const aiImporterDesc blenderDesc = {
|
static constexpr aiImporterDesc blenderDesc = {
|
||||||
"Blender 3D Importer (http://www.blender3d.org)",
|
"Blender 3D Importer (http://www.blender3d.org)",
|
||||||
"",
|
"",
|
||||||
"",
|
"",
|
||||||
|
|
|
@ -283,6 +283,11 @@ void BlenderModifier_Subdivision ::DoIt(aiNode &out, ConversionData &conv_data,
|
||||||
if (conv_data.meshes->empty()) {
|
if (conv_data.meshes->empty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
const size_t meshIndex = conv_data.meshes->size() - out.mNumMeshes;
|
||||||
|
if (meshIndex >= conv_data.meshes->size()) {
|
||||||
|
ASSIMP_LOG_ERROR("Invalid index detected.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
aiMesh **const meshes = &conv_data.meshes[conv_data.meshes->size() - out.mNumMeshes];
|
aiMesh **const meshes = &conv_data.meshes[conv_data.meshes->size() - out.mNumMeshes];
|
||||||
std::unique_ptr<aiMesh *[]> tempmeshes(new aiMesh *[out.mNumMeshes]());
|
std::unique_ptr<aiMesh *[]> tempmeshes(new aiMesh *[out.mNumMeshes]());
|
||||||
|
|
||||||
|
|
|
@ -102,10 +102,6 @@ void Structure::Convert<CollectionObject>(
|
||||||
|
|
||||||
ReadFieldPtr<ErrorPolicy_Fail>(dest.next, "*next", db);
|
ReadFieldPtr<ErrorPolicy_Fail>(dest.next, "*next", db);
|
||||||
{
|
{
|
||||||
//std::shared_ptr<CollectionObject> prev;
|
|
||||||
//ReadFieldPtr<ErrorPolicy_Fail>(prev, "*prev", db);
|
|
||||||
//dest.prev = prev.get();
|
|
||||||
|
|
||||||
std::shared_ptr<Object> ob;
|
std::shared_ptr<Object> ob;
|
||||||
ReadFieldPtr<ErrorPolicy_Igno>(ob, "*ob", db);
|
ReadFieldPtr<ErrorPolicy_Igno>(ob, "*ob", db);
|
||||||
dest.ob = ob.get();
|
dest.ob = ob.get();
|
||||||
|
@ -301,7 +297,7 @@ void Structure ::Convert<Base>(
|
||||||
const FileDatabase &db) const {
|
const FileDatabase &db) const {
|
||||||
// note: as per https://github.com/assimp/assimp/issues/128,
|
// note: as per https://github.com/assimp/assimp/issues/128,
|
||||||
// reading the Object linked list recursively is prone to stack overflow.
|
// reading the Object linked list recursively is prone to stack overflow.
|
||||||
// This structure converter is therefore an hand-written exception that
|
// This structure converter is therefore a hand-written exception that
|
||||||
// does it iteratively.
|
// does it iteratively.
|
||||||
|
|
||||||
const int initial_pos = db.reader->GetCurrentPos();
|
const int initial_pos = db.reader->GetCurrentPos();
|
||||||
|
|
|
@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
|
||||||
|
|
||||||
Copyright (c) 2006-2022, assimp team
|
Copyright (c) 2006-2022, assimp team
|
||||||
|
|
||||||
|
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use of this software in source and binary forms,
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
@ -40,10 +39,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** @file BlenderTessellator.cpp
|
/// @file BlenderTessellator.cpp
|
||||||
* @brief A simple tessellation wrapper
|
/// @brief A simple tessellation wrapper
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef ASSIMP_BUILD_NO_BLEND_IMPORTER
|
#ifndef ASSIMP_BUILD_NO_BLEND_IMPORTER
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
|
||||||
|
|
||||||
Copyright (c) 2006-2022, assimp team
|
Copyright (c) 2006-2022, assimp team
|
||||||
|
|
||||||
|
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use of this software in source and binary forms,
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
@ -144,11 +143,7 @@ namespace Assimp
|
||||||
|
|
||||||
#if ASSIMP_BLEND_WITH_POLY_2_TRI
|
#if ASSIMP_BLEND_WITH_POLY_2_TRI
|
||||||
|
|
||||||
#ifdef ASSIMP_USE_HUNTER
|
#include "contrib/poly2tri/poly2tri/poly2tri.h"
|
||||||
# include <poly2tri/poly2tri.h>
|
|
||||||
#else
|
|
||||||
# include "../contrib/poly2tri/poly2tri/poly2tri.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace Assimp
|
namespace Assimp
|
||||||
{
|
{
|
||||||
|
|
|
@ -61,11 +61,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
using namespace Assimp;
|
namespace Assimp {
|
||||||
using namespace Assimp::COB;
|
using namespace Assimp::COB;
|
||||||
using namespace Assimp::Formatter;
|
using namespace Assimp::Formatter;
|
||||||
|
|
||||||
static const float units[] = {
|
static constexpr float units[] = {
|
||||||
1000.f,
|
1000.f,
|
||||||
100.f,
|
100.f,
|
||||||
1.f,
|
1.f,
|
||||||
|
@ -76,7 +76,7 @@ static const float units[] = {
|
||||||
1.f / 1609.344f
|
1.f / 1609.344f
|
||||||
};
|
};
|
||||||
|
|
||||||
static const aiImporterDesc desc = {
|
static constexpr aiImporterDesc desc = {
|
||||||
"TrueSpace Object Importer",
|
"TrueSpace Object Importer",
|
||||||
"",
|
"",
|
||||||
"",
|
"",
|
||||||
|
@ -89,14 +89,6 @@ static const aiImporterDesc desc = {
|
||||||
"cob scn"
|
"cob scn"
|
||||||
};
|
};
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
// Constructor to be privately used by Importer
|
|
||||||
COBImporter::COBImporter() = default;
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
// Destructor, private as well
|
|
||||||
COBImporter::~COBImporter() = default;
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Returns whether the class can handle the format of the given file.
|
// Returns whether the class can handle the format of the given file.
|
||||||
bool COBImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /*checkSig*/) const {
|
bool COBImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /*checkSig*/) const {
|
||||||
|
@ -1172,4 +1164,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");
|
ASSIMP_LOG_WARN("`Unit` chunk ", nfo.id, " is a child of ", nfo.parent_id, " which does not exist");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
#endif // ASSIMP_BUILD_NO_COB_IMPORTER
|
#endif // ASSIMP_BUILD_NO_COB_IMPORTER
|
||||||
|
|
|
@ -75,8 +75,8 @@ struct Scene;
|
||||||
// -------------------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------------
|
||||||
class COBImporter : public BaseImporter {
|
class COBImporter : public BaseImporter {
|
||||||
public:
|
public:
|
||||||
COBImporter();
|
COBImporter() = default;
|
||||||
~COBImporter() override;
|
~COBImporter() override = default;
|
||||||
|
|
||||||
// --------------------
|
// --------------------
|
||||||
bool CanRead(const std::string &pFile, IOSystem *pIOHandler,
|
bool CanRead(const std::string &pFile, IOSystem *pIOHandler,
|
||||||
|
|
|
@ -44,9 +44,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
/** @file CSMLoader.cpp
|
/** @file CSMLoader.cpp
|
||||||
* Implementation of the CSM importer class.
|
* Implementation of the CSM importer class.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef ASSIMP_BUILD_NO_CSM_IMPORTER
|
#ifndef ASSIMP_BUILD_NO_CSM_IMPORTER
|
||||||
|
|
||||||
#include "CSMLoader.h"
|
#include "CSMLoader.h"
|
||||||
|
@ -63,7 +60,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
using namespace Assimp;
|
using namespace Assimp;
|
||||||
|
|
||||||
static const aiImporterDesc desc = {
|
static constexpr aiImporterDesc desc = {
|
||||||
"CharacterStudio Motion Importer (MoCap)",
|
"CharacterStudio Motion Importer (MoCap)",
|
||||||
"",
|
"",
|
||||||
"",
|
"",
|
||||||
|
@ -79,13 +76,9 @@ static const aiImporterDesc desc = {
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Constructor to be privately used by Importer
|
// Constructor to be privately used by Importer
|
||||||
CSMImporter::CSMImporter()
|
CSMImporter::CSMImporter() : noSkeletonMesh(){
|
||||||
: noSkeletonMesh()
|
// empty
|
||||||
{}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
// Destructor, private as well
|
|
||||||
CSMImporter::~CSMImporter() = default;
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Returns whether the class can handle the format of the given file.
|
// Returns whether the class can handle the format of the given file.
|
||||||
|
|
|
@ -61,7 +61,7 @@ namespace Assimp {
|
||||||
class CSMImporter : public BaseImporter {
|
class CSMImporter : public BaseImporter {
|
||||||
public:
|
public:
|
||||||
CSMImporter();
|
CSMImporter();
|
||||||
~CSMImporter() override;
|
~CSMImporter() override = default;
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
bool CanRead(const std::string &pFile, IOSystem *pIOHandler,
|
bool CanRead(const std::string &pFile, IOSystem *pIOHandler,
|
||||||
|
@ -81,9 +81,8 @@ protected:
|
||||||
private:
|
private:
|
||||||
bool noSkeletonMesh;
|
bool noSkeletonMesh;
|
||||||
|
|
||||||
}; // end of class CSMImporter
|
};
|
||||||
|
|
||||||
} // end of namespace Assimp
|
} // namespace Assimp
|
||||||
|
|
||||||
#endif // AI_AC3DIMPORTER_H_INC
|
#endif // AI_AC3DIMPORTER_H_INC
|
||||||
|
|
||||||
|
|
|
@ -64,7 +64,7 @@ namespace Assimp {
|
||||||
using namespace Assimp::Formatter;
|
using namespace Assimp::Formatter;
|
||||||
using namespace Assimp::Collada;
|
using namespace Assimp::Collada;
|
||||||
|
|
||||||
static const aiImporterDesc desc = {
|
static constexpr aiImporterDesc desc = {
|
||||||
"Collada Importer",
|
"Collada Importer",
|
||||||
"",
|
"",
|
||||||
"",
|
"",
|
||||||
|
@ -101,10 +101,6 @@ ColladaLoader::ColladaLoader() :
|
||||||
// empty
|
// empty
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
// Destructor, private as well
|
|
||||||
ColladaLoader::~ColladaLoader() = default;
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Returns whether the class can handle the format of the given file.
|
// Returns whether the class can handle the format of the given file.
|
||||||
bool ColladaLoader::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /*checkSig*/) const {
|
bool ColladaLoader::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /*checkSig*/) const {
|
||||||
|
|
|
@ -86,7 +86,7 @@ public:
|
||||||
ColladaLoader();
|
ColladaLoader();
|
||||||
|
|
||||||
/// The class destructor.
|
/// The class destructor.
|
||||||
~ColladaLoader() override;
|
~ColladaLoader() override = default;
|
||||||
|
|
||||||
/// Returns whether the class can handle the format of the given file.
|
/// Returns whether the class can handle the format of the given file.
|
||||||
/// @see BaseImporter::CanRead() for more details.
|
/// @see BaseImporter::CanRead() for more details.
|
||||||
|
|
|
@ -814,7 +814,6 @@ void ColladaParser::ReadImage(XmlNode &node, Collada::Image &pImage) {
|
||||||
if (!pImage.mFileName.length()) {
|
if (!pImage.mFileName.length()) {
|
||||||
pImage.mFileName = "unknown_texture";
|
pImage.mFileName = "unknown_texture";
|
||||||
}
|
}
|
||||||
}
|
|
||||||
} else if (mFormat == FV_1_5_n) {
|
} else if (mFormat == FV_1_5_n) {
|
||||||
std::string value;
|
std::string value;
|
||||||
XmlNode refChild = currentNode.child("ref");
|
XmlNode refChild = currentNode.child("ref");
|
||||||
|
@ -851,6 +850,7 @@ void ColladaParser::ReadImage(XmlNode &node, Collada::Image &pImage) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Reads the material library
|
// Reads the material library
|
||||||
|
@ -1274,9 +1274,7 @@ void ColladaParser::ReadEffectParam(XmlNode &node, Collada::EffectParam &pParam)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
XmlNodeIterator xmlIt(node, XmlNodeIterator::PreOrderMode);
|
for (XmlNode ¤tNode : node.children()) {
|
||||||
XmlNode currentNode;
|
|
||||||
while (xmlIt.getNext(currentNode)) {
|
|
||||||
const std::string ¤tName = currentNode.name();
|
const std::string ¤tName = currentNode.name();
|
||||||
if (currentName == "surface") {
|
if (currentName == "surface") {
|
||||||
// image ID given inside <init_from> tags
|
// image ID given inside <init_from> tags
|
||||||
|
@ -1289,22 +1287,24 @@ void ColladaParser::ReadEffectParam(XmlNode &node, Collada::EffectParam &pParam)
|
||||||
}
|
}
|
||||||
} else if (currentName == "sampler2D" && (FV_1_4_n == mFormat || FV_1_3_n == mFormat)) {
|
} else if (currentName == "sampler2D" && (FV_1_4_n == mFormat || FV_1_3_n == mFormat)) {
|
||||||
// surface ID is given inside <source> tags
|
// surface ID is given inside <source> tags
|
||||||
const char *content = currentNode.value();
|
XmlNode source = currentNode.child("source");
|
||||||
|
if (source) {
|
||||||
|
std::string v;
|
||||||
|
XmlParser::getValueAsString(source, v);
|
||||||
pParam.mType = Param_Sampler;
|
pParam.mType = Param_Sampler;
|
||||||
pParam.mReference = content;
|
pParam.mReference = v.c_str();
|
||||||
|
}
|
||||||
} else if (currentName == "sampler2D") {
|
} else if (currentName == "sampler2D") {
|
||||||
// surface ID is given inside <instance_image> tags
|
// surface ID is given inside <instance_image> tags
|
||||||
|
XmlNode instance_image = currentNode.child("instance_image");
|
||||||
|
if (instance_image) {
|
||||||
std::string url;
|
std::string url;
|
||||||
XmlParser::getStdStrAttribute(currentNode, "url", url);
|
XmlParser::getStdStrAttribute(instance_image, "url", url);
|
||||||
if (url[0] != '#') {
|
if (url[0] != '#') {
|
||||||
throw DeadlyImportError("Unsupported URL format in instance_image");
|
throw DeadlyImportError("Unsupported URL format in instance_image");
|
||||||
}
|
}
|
||||||
pParam.mType = Param_Sampler;
|
pParam.mType = Param_Sampler;
|
||||||
pParam.mReference = url.c_str() + 1;
|
pParam.mReference = url.c_str() + 1;
|
||||||
} else if (currentName == "source") {
|
|
||||||
const char *source = currentNode.child_value();
|
|
||||||
if (nullptr != source) {
|
|
||||||
pParam.mReference = source;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1867,7 +1867,7 @@ size_t ColladaParser::ReadPrimitives(XmlNode &node, Mesh &pMesh, std::vector<Inp
|
||||||
|
|
||||||
///@note This function won't work correctly if both PerIndex and PerVertex channels have same channels.
|
///@note This function won't work correctly if both PerIndex and PerVertex channels have same channels.
|
||||||
///For example if TEXCOORD present in both <vertices> and <polylist> tags this function will create wrong uv coordinates.
|
///For example if TEXCOORD present in both <vertices> and <polylist> tags this function will create wrong uv coordinates.
|
||||||
///It's not clear from COLLADA documentation is this allowed or not. For now only exporter fixed to avoid such behavior
|
///It's not clear from COLLADA documentation whether this is allowed or not. For now only exporter fixed to avoid such behavior
|
||||||
void ColladaParser::CopyVertex(size_t currentVertex, size_t numOffsets, size_t numPoints, size_t perVertexOffset, Mesh &pMesh,
|
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) {
|
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
|
// calculate the base offset of the vertex whose attributes we ant to copy
|
||||||
|
|
|
@ -70,7 +70,7 @@ static const aiColor4D AI_DXF_DEFAULT_COLOR(aiColor4D(0.6f, 0.6f, 0.6f, 0.6f));
|
||||||
|
|
||||||
// color indices for DXF - 16 are supported, the table is
|
// color indices for DXF - 16 are supported, the table is
|
||||||
// taken directly from the DXF spec.
|
// taken directly from the DXF spec.
|
||||||
static aiColor4D g_aclrDxfIndexColors[] = {
|
static const aiColor4D g_aclrDxfIndexColors[] = {
|
||||||
aiColor4D(0.6f, 0.6f, 0.6f, 1.0f),
|
aiColor4D(0.6f, 0.6f, 0.6f, 1.0f),
|
||||||
aiColor4D (1.0f, 0.0f, 0.0f, 1.0f), // red
|
aiColor4D (1.0f, 0.0f, 0.0f, 1.0f), // red
|
||||||
aiColor4D (0.0f, 1.0f, 0.0f, 1.0f), // green
|
aiColor4D (0.0f, 1.0f, 0.0f, 1.0f), // green
|
||||||
|
@ -97,7 +97,7 @@ static const int GroupCode_XComp = 10;
|
||||||
static const int GroupCode_YComp = 20;
|
static const int GroupCode_YComp = 20;
|
||||||
static const int GroupCode_ZComp = 30;
|
static const int GroupCode_ZComp = 30;
|
||||||
|
|
||||||
static const aiImporterDesc desc = {
|
static constexpr aiImporterDesc desc = {
|
||||||
"Drawing Interchange Format (DXF) Importer",
|
"Drawing Interchange Format (DXF) Importer",
|
||||||
"",
|
"",
|
||||||
"",
|
"",
|
||||||
|
|
|
@ -51,6 +51,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include "FBXUtil.h"
|
#include "FBXUtil.h"
|
||||||
#include <assimp/defs.h>
|
#include <assimp/defs.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <cstdint>
|
||||||
#include <assimp/Exceptional.h>
|
#include <assimp/Exceptional.h>
|
||||||
#include <assimp/ByteSwapper.h>
|
#include <assimp/ByteSwapper.h>
|
||||||
#include <assimp/DefaultLogger.hpp>
|
#include <assimp/DefaultLogger.hpp>
|
||||||
|
|
|
@ -55,9 +55,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
#include <assimp/MathFunctions.h>
|
#include <assimp/MathFunctions.h>
|
||||||
#include <assimp/StringComparison.h>
|
#include <assimp/StringComparison.h>
|
||||||
|
|
||||||
#include <assimp/scene.h>
|
#include <assimp/scene.h>
|
||||||
|
|
||||||
#include <assimp/CreateAnimMesh.h>
|
#include <assimp/CreateAnimMesh.h>
|
||||||
#include <assimp/StringUtils.h>
|
#include <assimp/StringUtils.h>
|
||||||
#include <assimp/commonMetaData.h>
|
#include <assimp/commonMetaData.h>
|
||||||
|
@ -577,16 +575,17 @@ void FBXConverter::GetRotationMatrix(Model::RotOrder mode, const aiVector3D &rot
|
||||||
bool is_id[3] = { true, true, true };
|
bool is_id[3] = { true, true, true };
|
||||||
|
|
||||||
aiMatrix4x4 temp[3];
|
aiMatrix4x4 temp[3];
|
||||||
if (std::fabs(rotation.z) > angle_epsilon) {
|
const auto rot = AI_DEG_TO_RAD(rotation);
|
||||||
aiMatrix4x4::RotationZ(AI_DEG_TO_RAD(rotation.z), temp[2]);
|
if (std::fabs(rot.z) > angle_epsilon) {
|
||||||
|
aiMatrix4x4::RotationZ(rot.z, temp[2]);
|
||||||
is_id[2] = false;
|
is_id[2] = false;
|
||||||
}
|
}
|
||||||
if (std::fabs(rotation.y) > angle_epsilon) {
|
if (std::fabs(rot.y) > angle_epsilon) {
|
||||||
aiMatrix4x4::RotationY(AI_DEG_TO_RAD(rotation.y), temp[1]);
|
aiMatrix4x4::RotationY(rot.y, temp[1]);
|
||||||
is_id[1] = false;
|
is_id[1] = false;
|
||||||
}
|
}
|
||||||
if (std::fabs(rotation.x) > angle_epsilon) {
|
if (std::fabs(rot.x) > angle_epsilon) {
|
||||||
aiMatrix4x4::RotationX(AI_DEG_TO_RAD(rotation.x), temp[0]);
|
aiMatrix4x4::RotationX(rot.x, temp[0]);
|
||||||
is_id[0] = false;
|
is_id[0] = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1205,7 +1204,7 @@ unsigned int FBXConverter::ConvertMeshSingleMaterial(const MeshGeometry &mesh, c
|
||||||
const auto &curNormals = shapeGeometry->GetNormals();
|
const auto &curNormals = shapeGeometry->GetNormals();
|
||||||
const auto &curIndices = shapeGeometry->GetIndices();
|
const auto &curIndices = shapeGeometry->GetIndices();
|
||||||
//losing channel name if using shapeGeometry->Name()
|
//losing channel name if using shapeGeometry->Name()
|
||||||
// if blendShapeChannel Name is empty or don't have a ".", add geoMetryName;
|
// if blendShapeChannel Name is empty or doesn't have a ".", add geoMetryName;
|
||||||
auto aniName = FixAnimMeshName(blendShapeChannel->Name());
|
auto aniName = FixAnimMeshName(blendShapeChannel->Name());
|
||||||
auto geoMetryName = FixAnimMeshName(shapeGeometry->Name());
|
auto geoMetryName = FixAnimMeshName(shapeGeometry->Name());
|
||||||
if (aniName.empty()) {
|
if (aniName.empty()) {
|
||||||
|
@ -1603,7 +1602,7 @@ void FBXConverter::ConvertWeights(aiMesh *out, const MeshGeometry &geo, const ai
|
||||||
|
|
||||||
void FBXConverter::ConvertCluster(std::vector<aiBone*> &local_mesh_bones, const Cluster *cluster,
|
void FBXConverter::ConvertCluster(std::vector<aiBone*> &local_mesh_bones, const Cluster *cluster,
|
||||||
std::vector<size_t> &out_indices, std::vector<size_t> &index_out_indices,
|
std::vector<size_t> &out_indices, std::vector<size_t> &index_out_indices,
|
||||||
std::vector<size_t> &count_out_indices, const aiMatrix4x4 & /* absolute_transform*/,
|
std::vector<size_t> &count_out_indices, const aiMatrix4x4 &absolute_transform,
|
||||||
aiNode *) {
|
aiNode *) {
|
||||||
ai_assert(cluster != nullptr); // make sure cluster valid
|
ai_assert(cluster != nullptr); // make sure cluster valid
|
||||||
|
|
||||||
|
@ -1620,16 +1619,16 @@ void FBXConverter::ConvertCluster(std::vector<aiBone*> &local_mesh_bones, const
|
||||||
bone = new aiBone();
|
bone = new aiBone();
|
||||||
bone->mName = bone_name;
|
bone->mName = bone_name;
|
||||||
|
|
||||||
bone->mOffsetMatrix = cluster->Transform();
|
//bone->mOffsetMatrix = cluster->Transform();
|
||||||
// store local transform link for post processing
|
// store local transform link for post processing
|
||||||
/*
|
|
||||||
bone->mOffsetMatrix = cluster->TransformLink();
|
bone->mOffsetMatrix = cluster->TransformLink();
|
||||||
bone->mOffsetMatrix.Inverse();
|
bone->mOffsetMatrix.Inverse();
|
||||||
|
|
||||||
aiMatrix4x4 matrix = (aiMatrix4x4)absolute_transform;
|
const aiMatrix4x4 matrix = (aiMatrix4x4)absolute_transform;
|
||||||
|
|
||||||
bone->mOffsetMatrix = bone->mOffsetMatrix * matrix; // * mesh_offset
|
bone->mOffsetMatrix = bone->mOffsetMatrix * matrix; // * mesh_offset
|
||||||
*/
|
|
||||||
//
|
//
|
||||||
// Now calculate the aiVertexWeights
|
// Now calculate the aiVertexWeights
|
||||||
//
|
//
|
||||||
|
@ -3225,7 +3224,6 @@ aiNodeAnim* FBXConverter::GenerateSimpleNodeAnim(const std::string& name,
|
||||||
aiVector3D defTranslate = PropertyGet(props, "Lcl Translation", aiVector3D(0.f, 0.f, 0.f));
|
aiVector3D defTranslate = PropertyGet(props, "Lcl Translation", aiVector3D(0.f, 0.f, 0.f));
|
||||||
aiVector3D defRotation = PropertyGet(props, "Lcl Rotation", aiVector3D(0.f, 0.f, 0.f));
|
aiVector3D defRotation = PropertyGet(props, "Lcl Rotation", aiVector3D(0.f, 0.f, 0.f));
|
||||||
aiVector3D defScale = PropertyGet(props, "Lcl Scaling", aiVector3D(1.f, 1.f, 1.f));
|
aiVector3D defScale = PropertyGet(props, "Lcl Scaling", aiVector3D(1.f, 1.f, 1.f));
|
||||||
aiQuaternion defQuat = EulerToQuaternion(defRotation, rotOrder);
|
|
||||||
|
|
||||||
aiVectorKey* outTranslations = new aiVectorKey[keyCount];
|
aiVectorKey* outTranslations = new aiVectorKey[keyCount];
|
||||||
aiQuatKey* outRotations = new aiQuatKey[keyCount];
|
aiQuatKey* outRotations = new aiQuatKey[keyCount];
|
||||||
|
@ -3241,8 +3239,9 @@ aiNodeAnim* FBXConverter::GenerateSimpleNodeAnim(const std::string& name,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (keyframeLists[TransformationComp_Rotation].size() > 0) {
|
if (keyframeLists[TransformationComp_Rotation].size() > 0) {
|
||||||
InterpolateKeys(outRotations, keytimes, keyframeLists[TransformationComp_Rotation], defRotation, maxTime, minTime, rotOrder);
|
InterpolateKeys(outRotations, keytimes, keyframeLists[TransformationComp_Rotation], AI_DEG_TO_RAD(defRotation), maxTime, minTime, rotOrder);
|
||||||
} else {
|
} else {
|
||||||
|
aiQuaternion defQuat = EulerToQuaternion(AI_DEG_TO_RAD(defRotation), rotOrder);
|
||||||
for (size_t i = 0; i < keyCount; ++i) {
|
for (size_t i = 0; i < keyCount; ++i) {
|
||||||
outRotations[i].mTime = CONVERT_FBX_TIME(keytimes[i]) * anim_fps;
|
outRotations[i].mTime = CONVERT_FBX_TIME(keytimes[i]) * anim_fps;
|
||||||
outRotations[i].mValue = defQuat;
|
outRotations[i].mValue = defQuat;
|
||||||
|
@ -3264,7 +3263,7 @@ aiNodeAnim* FBXConverter::GenerateSimpleNodeAnim(const std::string& name,
|
||||||
|
|
||||||
const aiVector3D& preRotation = PropertyGet<aiVector3D>(props, "PreRotation", ok);
|
const aiVector3D& preRotation = PropertyGet<aiVector3D>(props, "PreRotation", ok);
|
||||||
if (ok && preRotation.SquareLength() > zero_epsilon) {
|
if (ok && preRotation.SquareLength() > zero_epsilon) {
|
||||||
const aiQuaternion preQuat = EulerToQuaternion(preRotation, Model::RotOrder_EulerXYZ);
|
const aiQuaternion preQuat = EulerToQuaternion(AI_DEG_TO_RAD(preRotation), Model::RotOrder_EulerXYZ);
|
||||||
for (size_t i = 0; i < keyCount; ++i) {
|
for (size_t i = 0; i < keyCount; ++i) {
|
||||||
outRotations[i].mValue = preQuat * outRotations[i].mValue;
|
outRotations[i].mValue = preQuat * outRotations[i].mValue;
|
||||||
}
|
}
|
||||||
|
@ -3272,7 +3271,7 @@ aiNodeAnim* FBXConverter::GenerateSimpleNodeAnim(const std::string& name,
|
||||||
|
|
||||||
const aiVector3D& postRotation = PropertyGet<aiVector3D>(props, "PostRotation", ok);
|
const aiVector3D& postRotation = PropertyGet<aiVector3D>(props, "PostRotation", ok);
|
||||||
if (ok && postRotation.SquareLength() > zero_epsilon) {
|
if (ok && postRotation.SquareLength() > zero_epsilon) {
|
||||||
const aiQuaternion postQuat = EulerToQuaternion(postRotation, Model::RotOrder_EulerXYZ);
|
const aiQuaternion postQuat = EulerToQuaternion(AI_DEG_TO_RAD(postRotation), Model::RotOrder_EulerXYZ);
|
||||||
for (size_t i = 0; i < keyCount; ++i) {
|
for (size_t i = 0; i < keyCount; ++i) {
|
||||||
outRotations[i].mValue = outRotations[i].mValue * postQuat;
|
outRotations[i].mValue = outRotations[i].mValue * postQuat;
|
||||||
}
|
}
|
||||||
|
|
|
@ -84,7 +84,7 @@ Cluster::Cluster(uint64_t id, const Element& element, const Document& doc, const
|
||||||
transform = ReadMatrix(Transform);
|
transform = ReadMatrix(Transform);
|
||||||
transformLink = ReadMatrix(TransformLink);
|
transformLink = ReadMatrix(TransformLink);
|
||||||
|
|
||||||
// it is actually possible that there be Deformer's with no weights
|
// it is actually possible that there are Deformer's with no weights
|
||||||
if (!!Indexes != !!Weights) {
|
if (!!Indexes != !!Weights) {
|
||||||
DOMError("either Indexes or Weights are missing from Cluster",&element);
|
DOMError("either Indexes or Weights are missing from Cluster",&element);
|
||||||
}
|
}
|
||||||
|
|
|
@ -390,7 +390,7 @@ void Document::ReadObjects() {
|
||||||
const auto foundObject = objects.find(id);
|
const auto foundObject = objects.find(id);
|
||||||
if(foundObject != objects.end()) {
|
if(foundObject != objects.end()) {
|
||||||
DOMWarning("encountered duplicate object id, ignoring first occurrence",el.second);
|
DOMWarning("encountered duplicate object id, ignoring first occurrence",el.second);
|
||||||
delete foundObject->second;
|
delete_LazyObject(foundObject->second);
|
||||||
}
|
}
|
||||||
|
|
||||||
objects[id] = new_LazyObject(id, *el.second, *this);
|
objects[id] = new_LazyObject(id, *el.second, *this);
|
||||||
|
|
|
@ -74,8 +74,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
// https://code.blender.org/2013/08/fbx-binary-file-format-specification/
|
// https://code.blender.org/2013/08/fbx-binary-file-format-specification/
|
||||||
// https://wiki.blender.org/index.php/User:Mont29/Foundation/FBX_File_Structure
|
// https://wiki.blender.org/index.php/User:Mont29/Foundation/FBX_File_Structure
|
||||||
|
|
||||||
const ai_real DEG = ai_real( 57.29577951308232087679815481 ); // degrees per radian
|
|
||||||
|
|
||||||
using namespace Assimp;
|
using namespace Assimp;
|
||||||
using namespace Assimp::FBX;
|
using namespace Assimp::FBX;
|
||||||
|
|
||||||
|
@ -1063,14 +1061,14 @@ aiMatrix4x4 get_world_transform(const aiNode* node, const aiScene* scene)
|
||||||
return transform;
|
return transform;
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t to_ktime(double ticks, const aiAnimation* anim) {
|
inline int64_t to_ktime(double ticks, const aiAnimation* anim) {
|
||||||
if (anim->mTicksPerSecond <= 0) {
|
if (anim->mTicksPerSecond <= 0) {
|
||||||
return static_cast<int64_t>(ticks) * FBX::SECOND;
|
return static_cast<int64_t>(ticks) * FBX::SECOND;
|
||||||
}
|
}
|
||||||
return (static_cast<int64_t>(ticks) / static_cast<int64_t>(anim->mTicksPerSecond)) * FBX::SECOND;
|
return (static_cast<int64_t>(ticks / anim->mTicksPerSecond)) * FBX::SECOND;
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t to_ktime(double time) {
|
inline int64_t to_ktime(double time) {
|
||||||
return (static_cast<int64_t>(time * FBX::SECOND));
|
return (static_cast<int64_t>(time * FBX::SECOND));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1391,7 +1389,7 @@ void FBXExporter::WriteObjects ()
|
||||||
aiMaterial* m = mScene->mMaterials[i];
|
aiMaterial* m = mScene->mMaterials[i];
|
||||||
|
|
||||||
// these are used to receive material data
|
// these are used to receive material data
|
||||||
float f; aiColor3D c;
|
ai_real f; aiColor3D c;
|
||||||
|
|
||||||
// start the node record
|
// start the node record
|
||||||
FBX::Node n("Material");
|
FBX::Node n("Material");
|
||||||
|
@ -2415,7 +2413,7 @@ void FBXExporter::WriteObjects ()
|
||||||
// position/translation
|
// position/translation
|
||||||
for (size_t ki = 0; ki < na->mNumPositionKeys; ++ki) {
|
for (size_t ki = 0; ki < na->mNumPositionKeys; ++ki) {
|
||||||
const aiVectorKey& k = na->mPositionKeys[ki];
|
const aiVectorKey& k = na->mPositionKeys[ki];
|
||||||
times.push_back(to_ktime(k.mTime));
|
times.push_back(to_ktime(k.mTime, anim));
|
||||||
xval.push_back(k.mValue.x);
|
xval.push_back(k.mValue.x);
|
||||||
yval.push_back(k.mValue.y);
|
yval.push_back(k.mValue.y);
|
||||||
zval.push_back(k.mValue.z);
|
zval.push_back(k.mValue.z);
|
||||||
|
@ -2429,12 +2427,12 @@ void FBXExporter::WriteObjects ()
|
||||||
times.clear(); xval.clear(); yval.clear(); zval.clear();
|
times.clear(); xval.clear(); yval.clear(); zval.clear();
|
||||||
for (size_t ki = 0; ki < na->mNumRotationKeys; ++ki) {
|
for (size_t ki = 0; ki < na->mNumRotationKeys; ++ki) {
|
||||||
const aiQuatKey& k = na->mRotationKeys[ki];
|
const aiQuatKey& k = na->mRotationKeys[ki];
|
||||||
times.push_back(to_ktime(k.mTime));
|
times.push_back(to_ktime(k.mTime, anim));
|
||||||
// TODO: aiQuaternion method to convert to Euler...
|
// TODO: aiQuaternion method to convert to Euler...
|
||||||
aiMatrix4x4 m(k.mValue.GetMatrix());
|
aiMatrix4x4 m(k.mValue.GetMatrix());
|
||||||
aiVector3D qs, qr, qt;
|
aiVector3D qs, qr, qt;
|
||||||
m.Decompose(qs, qr, qt);
|
m.Decompose(qs, qr, qt);
|
||||||
qr *= DEG;
|
qr = AI_RAD_TO_DEG(qr);
|
||||||
xval.push_back(qr.x);
|
xval.push_back(qr.x);
|
||||||
yval.push_back(qr.y);
|
yval.push_back(qr.y);
|
||||||
zval.push_back(qr.z);
|
zval.push_back(qr.z);
|
||||||
|
@ -2447,7 +2445,7 @@ void FBXExporter::WriteObjects ()
|
||||||
times.clear(); xval.clear(); yval.clear(); zval.clear();
|
times.clear(); xval.clear(); yval.clear(); zval.clear();
|
||||||
for (size_t ki = 0; ki < na->mNumScalingKeys; ++ki) {
|
for (size_t ki = 0; ki < na->mNumScalingKeys; ++ki) {
|
||||||
const aiVectorKey& k = na->mScalingKeys[ki];
|
const aiVectorKey& k = na->mScalingKeys[ki];
|
||||||
times.push_back(to_ktime(k.mTime));
|
times.push_back(to_ktime(k.mTime, anim));
|
||||||
xval.push_back(k.mValue.x);
|
xval.push_back(k.mValue.x);
|
||||||
yval.push_back(k.mValue.y);
|
yval.push_back(k.mValue.y);
|
||||||
zval.push_back(k.mValue.z);
|
zval.push_back(k.mValue.z);
|
||||||
|
@ -2515,9 +2513,10 @@ void FBXExporter::WriteModelNode(
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (r != zero) {
|
if (r != zero) {
|
||||||
|
r = AI_RAD_TO_DEG(r);
|
||||||
p.AddP70(
|
p.AddP70(
|
||||||
"Lcl Rotation", "Lcl Rotation", "", "A",
|
"Lcl Rotation", "Lcl Rotation", "", "A",
|
||||||
double(DEG*r.x), double(DEG*r.y), double(DEG*r.z)
|
double(r.x), double(r.y), double(r.z)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (s != one) {
|
if (s != one) {
|
||||||
|
@ -2601,8 +2600,7 @@ void FBXExporter::WriteModelNodes(
|
||||||
transform_chain.emplace_back(elem->first, t);
|
transform_chain.emplace_back(elem->first, t);
|
||||||
break;
|
break;
|
||||||
case 'r': // rotation
|
case 'r': // rotation
|
||||||
r *= float(DEG);
|
transform_chain.emplace_back(elem->first, AI_RAD_TO_DEG(r));
|
||||||
transform_chain.emplace_back(elem->first, r);
|
|
||||||
break;
|
break;
|
||||||
case 's': // scale
|
case 's': // scale
|
||||||
transform_chain.emplace_back(elem->first, s);
|
transform_chain.emplace_back(elem->first, s);
|
||||||
|
|
|
@ -72,8 +72,7 @@ using namespace Assimp::Formatter;
|
||||||
using namespace Assimp::FBX;
|
using namespace Assimp::FBX;
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
static constexpr aiImporterDesc desc = {
|
||||||
static const aiImporterDesc desc = {
|
|
||||||
"Autodesk FBX Importer",
|
"Autodesk FBX Importer",
|
||||||
"",
|
"",
|
||||||
"",
|
"",
|
||||||
|
@ -87,15 +86,11 @@ static const aiImporterDesc desc = {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
// Constructor to be privately used by #Importer
|
|
||||||
FBXImporter::FBXImporter() = default;
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Returns whether the class can handle the format of the given file.
|
// Returns whether the class can handle the format of the given file.
|
||||||
bool FBXImporter::CanRead(const std::string & pFile, IOSystem * pIOHandler, bool /*checkSig*/) const {
|
bool FBXImporter::CanRead(const std::string & pFile, IOSystem * pIOHandler, bool /*checkSig*/) const {
|
||||||
// at least ASCII-FBX files usually have a 'FBX' somewhere in their head
|
// at least ASCII-FBX files usually have a 'FBX' somewhere in their head
|
||||||
static const char *tokens[] = { "fbx" };
|
static const char *tokens[] = { " \n\r\n " };
|
||||||
return SearchFileHeaderForToken(pIOHandler, pFile, tokens, AI_COUNT_OF(tokens));
|
return SearchFileHeaderForToken(pIOHandler, pFile, tokens, AI_COUNT_OF(tokens));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -70,7 +70,7 @@ typedef class basic_formatter<char, std::char_traits<char>, std::allocator<char>
|
||||||
class FBXImporter : public BaseImporter, public LogFunctions<FBXImporter> {
|
class FBXImporter : public BaseImporter, public LogFunctions<FBXImporter> {
|
||||||
public:
|
public:
|
||||||
/// @brief The class constructor.
|
/// @brief The class constructor.
|
||||||
FBXImporter();
|
FBXImporter() = default;
|
||||||
|
|
||||||
/// @brief The class destructor, default implementation.
|
/// @brief The class destructor, default implementation.
|
||||||
~FBXImporter() override = default;
|
~FBXImporter() override = default;
|
||||||
|
|
|
@ -367,8 +367,10 @@ Video::Video(uint64_t id, const Element &element, const Document &doc, const std
|
||||||
}
|
}
|
||||||
|
|
||||||
Video::~Video() {
|
Video::~Video() {
|
||||||
|
if (contentLength > 0) {
|
||||||
delete[] content;
|
delete[] content;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} //!FBX
|
} //!FBX
|
||||||
} //!Assimp
|
} //!Assimp
|
||||||
|
|
|
@ -467,9 +467,9 @@ void ResolveVertexDataArray(std::vector<T>& data_out, const Scope& source,
|
||||||
std::vector<int> uvIndices;
|
std::vector<int> uvIndices;
|
||||||
ParseVectorDataArray(uvIndices,GetRequiredElement(source,indexDataElementName));
|
ParseVectorDataArray(uvIndices,GetRequiredElement(source,indexDataElementName));
|
||||||
|
|
||||||
if (uvIndices.size() != vertex_count) {
|
if (uvIndices.size() != mapping_offsets.size()) {
|
||||||
FBXImporter::LogError("length of input data unexpected for ByVertice mapping: ",
|
FBXImporter::LogError("length of input data unexpected for ByVertice mapping: ",
|
||||||
uvIndices.size(), ", expected ", vertex_count);
|
uvIndices.size(), ", expected ", mapping_offsets.size());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -45,12 +45,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
#ifndef ASSIMP_BUILD_NO_FBX_IMPORTER
|
#ifndef ASSIMP_BUILD_NO_FBX_IMPORTER
|
||||||
|
|
||||||
//#ifdef ASSIMP_BUILD_NO_OWN_ZLIB
|
|
||||||
#include "Common/Compression.h"
|
#include "Common/Compression.h"
|
||||||
//# include <zlib.h>
|
|
||||||
//#else
|
|
||||||
//# include "../contrib/zlib/zlib.h"
|
|
||||||
//#endif
|
|
||||||
|
|
||||||
#include "FBXTokenizer.h"
|
#include "FBXTokenizer.h"
|
||||||
#include "FBXParser.h"
|
#include "FBXParser.h"
|
||||||
|
|
|
@ -155,7 +155,7 @@ size_t DecodeBase64(const char* in, size_t inLength, uint8_t* out, size_t maxOut
|
||||||
const size_t realLength = inLength - size_t(in[inLength - 1] == '=') - size_t(in[inLength - 2] == '=');
|
const size_t realLength = inLength - size_t(in[inLength - 1] == '=') - size_t(in[inLength - 2] == '=');
|
||||||
size_t dst_offset = 0;
|
size_t dst_offset = 0;
|
||||||
int val = 0, valb = -8;
|
int val = 0, valb = -8;
|
||||||
for (size_t src_offset = 0; src_offset < realLength; ++src_offset)
|
for (size_t src_offset = 0; src_offset < realLength && dst_offset < maxOutLength; ++src_offset)
|
||||||
{
|
{
|
||||||
const uint8_t table_value = Util::DecodeBase64(in[src_offset]);
|
const uint8_t table_value = Util::DecodeBase64(in[src_offset]);
|
||||||
if (table_value == 255)
|
if (table_value == 255)
|
||||||
|
|
|
@ -57,7 +57,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
using namespace Assimp;
|
using namespace Assimp;
|
||||||
|
|
||||||
static const aiImporterDesc desc = {
|
static constexpr aiImporterDesc desc = {
|
||||||
"3D GameStudio Heightmap (HMP) Importer",
|
"3D GameStudio Heightmap (HMP) Importer",
|
||||||
"",
|
"",
|
||||||
"",
|
"",
|
||||||
|
|
|
@ -38,9 +38,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** @file IFCBoolean.cpp
|
/// @file IFCBoolean.cpp
|
||||||
* @brief Implements a subset of Ifc boolean operations
|
/// @brief Implements a subset of Ifc boolean operations
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef ASSIMP_BUILD_NO_IFC_IMPORTER
|
#ifndef ASSIMP_BUILD_NO_IFC_IMPORTER
|
||||||
|
|
||||||
|
@ -48,7 +47,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include "Common/PolyTools.h"
|
#include "Common/PolyTools.h"
|
||||||
#include "PostProcessing/ProcessHelper.h"
|
#include "PostProcessing/ProcessHelper.h"
|
||||||
|
|
||||||
|
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
@ -67,8 +65,9 @@ bool IntersectSegmentPlane(const IfcVector3 &p, const IfcVector3 &n, const IfcVe
|
||||||
|
|
||||||
// if segment ends on plane, do not report a hit. We stay on that side until a following segment starting at this
|
// if segment ends on plane, do not report a hit. We stay on that side until a following segment starting at this
|
||||||
// point leaves the plane through the other side
|
// point leaves the plane through the other side
|
||||||
if (std::abs(dotOne + dotTwo) < ai_epsilon)
|
if (std::abs(dotOne + dotTwo) < ai_epsilon) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// if segment starts on the plane, report a hit only if the end lies on the *other* side
|
// if segment starts on the plane, report a hit only if the end lies on the *other* side
|
||||||
if (std::abs(dotTwo) < ai_epsilon) {
|
if (std::abs(dotTwo) < ai_epsilon) {
|
||||||
|
@ -82,13 +81,15 @@ bool IntersectSegmentPlane(const IfcVector3 &p, const IfcVector3 &n, const IfcVe
|
||||||
|
|
||||||
// ignore if segment is parallel to plane and far away from it on either side
|
// ignore if segment is parallel to plane and far away from it on either side
|
||||||
// Warning: if there's a few thousand of such segments which slowly accumulate beyond the epsilon, no hit would be registered
|
// Warning: if there's a few thousand of such segments which slowly accumulate beyond the epsilon, no hit would be registered
|
||||||
if (std::abs(dotOne) < ai_epsilon)
|
if (std::abs(dotOne) < ai_epsilon) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// t must be in [0..1] if the intersection point is within the given segment
|
// t must be in [0..1] if the intersection point is within the given segment
|
||||||
const IfcFloat t = dotTwo / dotOne;
|
const IfcFloat t = dotTwo / dotOne;
|
||||||
if (t > 1.0 || t < 0.0)
|
if (t > 1.0 || t < 0.0) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
out = e0 + t * seg;
|
out = e0 + t * seg;
|
||||||
return true;
|
return true;
|
||||||
|
@ -110,12 +111,14 @@ void FilterPolygon(std::vector<IfcVector3> &resultpoly) {
|
||||||
FuzzyVectorCompare fz(epsilon);
|
FuzzyVectorCompare fz(epsilon);
|
||||||
std::vector<IfcVector3>::iterator e = std::unique(resultpoly.begin(), resultpoly.end(), fz);
|
std::vector<IfcVector3>::iterator e = std::unique(resultpoly.begin(), resultpoly.end(), fz);
|
||||||
|
|
||||||
if (e != resultpoly.end())
|
if (e != resultpoly.end()) {
|
||||||
resultpoly.erase(e, resultpoly.end());
|
resultpoly.erase(e, resultpoly.end());
|
||||||
|
}
|
||||||
|
|
||||||
if (!resultpoly.empty() && fz(resultpoly.front(), resultpoly.back()))
|
if (!resultpoly.empty() && fz(resultpoly.front(), resultpoly.back())) {
|
||||||
resultpoly.pop_back();
|
resultpoly.pop_back();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void WritePolygon(std::vector<IfcVector3> &resultpoly, TempMesh &result) {
|
void WritePolygon(std::vector<IfcVector3> &resultpoly, TempMesh &result) {
|
||||||
|
@ -291,8 +294,9 @@ bool IntersectsBoundaryProfile(const IfcVector3 &e0, const IfcVector3 &e1, const
|
||||||
}
|
}
|
||||||
|
|
||||||
// Line segment ends at boundary -> ignore any hit, it will be handled by possibly following segments
|
// Line segment ends at boundary -> ignore any hit, it will be handled by possibly following segments
|
||||||
if (endsAtSegment && !halfOpen)
|
if (endsAtSegment && !halfOpen) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// Line segment starts at boundary -> generate a hit only if following that line would change the INSIDE/OUTSIDE
|
// Line segment starts at boundary -> generate a hit only if following that line would change the INSIDE/OUTSIDE
|
||||||
// state. This should catch the case where a connected set of segments has a point directly on the boundary,
|
// state. This should catch the case where a connected set of segments has a point directly on the boundary,
|
||||||
|
@ -301,16 +305,18 @@ bool IntersectsBoundaryProfile(const IfcVector3 &e0, const IfcVector3 &e1, const
|
||||||
if (startsAtSegment) {
|
if (startsAtSegment) {
|
||||||
IfcVector3 inside_dir = IfcVector3(b.y, -b.x, 0.0) * windingOrder;
|
IfcVector3 inside_dir = IfcVector3(b.y, -b.x, 0.0) * windingOrder;
|
||||||
bool isGoingInside = (inside_dir * e) > 0.0;
|
bool isGoingInside = (inside_dir * e) > 0.0;
|
||||||
if (isGoingInside == isStartAssumedInside)
|
if (isGoingInside == isStartAssumedInside) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// only insert the point into the list if it is sufficiently far away from the previous intersection point.
|
// only insert the point into the list if it is sufficiently far away from the previous intersection point.
|
||||||
// This way, we avoid duplicate detection if the intersection is directly on the vertex between two segments.
|
// This way, we avoid duplicate detection if the intersection is directly on the vertex between two segments.
|
||||||
if (!intersect_results.empty() && intersect_results.back().first == i - 1) {
|
if (!intersect_results.empty() && intersect_results.back().first == i - 1) {
|
||||||
const IfcVector3 diff = intersect_results.back().second - e0;
|
const IfcVector3 diff = intersect_results.back().second - e0;
|
||||||
if (IfcVector2(diff.x, diff.y).SquareLength() < 1e-10)
|
if (IfcVector2(diff.x, diff.y).SquareLength() < 1e-10) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
intersect_results.emplace_back(i, e0);
|
intersect_results.emplace_back(i, e0);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -322,9 +328,10 @@ bool IntersectsBoundaryProfile(const IfcVector3 &e0, const IfcVector3 &e1, const
|
||||||
// This way, we avoid duplicate detection if the intersection is directly on the vertex between two segments.
|
// This way, we avoid duplicate detection if the intersection is directly on the vertex between two segments.
|
||||||
if (!intersect_results.empty() && intersect_results.back().first == i - 1) {
|
if (!intersect_results.empty() && intersect_results.back().first == i - 1) {
|
||||||
const IfcVector3 diff = intersect_results.back().second - p;
|
const IfcVector3 diff = intersect_results.back().second - p;
|
||||||
if (IfcVector2(diff.x, diff.y).SquareLength() < 1e-10)
|
if (IfcVector2(diff.x, diff.y).SquareLength() < 1e-10) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
intersect_results.emplace_back(i, p);
|
intersect_results.emplace_back(i, p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -662,7 +669,8 @@ void ProcessPolygonalBoundedBooleanHalfSpaceDifference(const Schema_2x3::IfcPoly
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void ProcessBooleanExtrudedAreaSolidDifference(const Schema_2x3::IfcExtrudedAreaSolid *as, TempMesh &result,
|
void ProcessBooleanExtrudedAreaSolidDifference(const Schema_2x3::IfcExtrudedAreaSolid *as,
|
||||||
|
TempMesh &result,
|
||||||
const TempMesh &first_operand,
|
const TempMesh &first_operand,
|
||||||
ConversionData &conv) {
|
ConversionData &conv) {
|
||||||
ai_assert(as != nullptr);
|
ai_assert(as != nullptr);
|
||||||
|
@ -763,4 +771,4 @@ void ProcessBoolean(const Schema_2x3::IfcBooleanResult &boolean, TempMesh &resul
|
||||||
} // namespace IFC
|
} // namespace IFC
|
||||||
} // namespace Assimp
|
} // namespace Assimp
|
||||||
|
|
||||||
#endif
|
#endif // ASSIMP_BUILD_NO_IFC_IMPORTER
|
||||||
|
|
|
@ -39,15 +39,15 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** @file IFCProfile.cpp
|
/// @file IFCProfile.cpp
|
||||||
* @brief Read profile and curves entities from IFC files
|
/// @brief Read profile and curves entities from IFC files
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef ASSIMP_BUILD_NO_IFC_IMPORTER
|
#ifndef ASSIMP_BUILD_NO_IFC_IMPORTER
|
||||||
#include "IFCUtil.h"
|
#include "IFCUtil.h"
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
namespace IFC {
|
namespace IFC {
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------
|
||||||
|
@ -56,8 +56,7 @@ namespace {
|
||||||
class Conic : public Curve {
|
class Conic : public Curve {
|
||||||
public:
|
public:
|
||||||
// --------------------------------------------------
|
// --------------------------------------------------
|
||||||
Conic(const Schema_2x3::IfcConic& entity, ConversionData& conv)
|
Conic(const Schema_2x3::IfcConic& entity, ConversionData& conv) : Curve(entity,conv) {
|
||||||
: Curve(entity,conv) {
|
|
||||||
IfcMatrix4 trafo;
|
IfcMatrix4 trafo;
|
||||||
ConvertAxisPlacement(trafo,*entity.Position,conv);
|
ConvertAxisPlacement(trafo,*entity.Position,conv);
|
||||||
|
|
||||||
|
@ -69,12 +68,12 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
// --------------------------------------------------
|
// --------------------------------------------------
|
||||||
bool IsClosed() const {
|
bool IsClosed() const override {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// --------------------------------------------------
|
// --------------------------------------------------
|
||||||
size_t EstimateSampleCount(IfcFloat a, IfcFloat b) const {
|
size_t EstimateSampleCount(IfcFloat a, IfcFloat b) const override {
|
||||||
ai_assert( InRange( a ) );
|
ai_assert( InRange( a ) );
|
||||||
ai_assert( InRange( b ) );
|
ai_assert( InRange( b ) );
|
||||||
|
|
||||||
|
@ -88,7 +87,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
// --------------------------------------------------
|
// --------------------------------------------------
|
||||||
ParamRange GetParametricRange() const {
|
ParamRange GetParametricRange() const override {
|
||||||
return std::make_pair(static_cast<IfcFloat>( 0. ), static_cast<IfcFloat>( AI_MATH_TWO_PI / conv.angle_scale ));
|
return std::make_pair(static_cast<IfcFloat>( 0. ), static_cast<IfcFloat>( AI_MATH_TWO_PI / conv.angle_scale ));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,14 +101,13 @@ protected:
|
||||||
class Circle : public Conic {
|
class Circle : public Conic {
|
||||||
public:
|
public:
|
||||||
// --------------------------------------------------
|
// --------------------------------------------------
|
||||||
Circle(const Schema_2x3::IfcCircle& entity, ConversionData& conv)
|
Circle(const Schema_2x3::IfcCircle& entity, ConversionData& conv) : Conic(entity,conv) , entity(entity) {}
|
||||||
: Conic(entity,conv)
|
|
||||||
, entity(entity)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------------
|
// --------------------------------------------------
|
||||||
IfcVector3 Eval(IfcFloat u) const {
|
~Circle() override = default;
|
||||||
|
|
||||||
|
// --------------------------------------------------
|
||||||
|
IfcVector3 Eval(IfcFloat u) const override {
|
||||||
u = -conv.angle_scale * u;
|
u = -conv.angle_scale * u;
|
||||||
return location + static_cast<IfcFloat>(entity.Radius)*(static_cast<IfcFloat>(std::cos(u))*p[0] +
|
return location + static_cast<IfcFloat>(entity.Radius)*(static_cast<IfcFloat>(std::cos(u))*p[0] +
|
||||||
static_cast<IfcFloat>(std::sin(u))*p[1]);
|
static_cast<IfcFloat>(std::sin(u))*p[1]);
|
||||||
|
@ -132,7 +130,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
// --------------------------------------------------
|
// --------------------------------------------------
|
||||||
IfcVector3 Eval(IfcFloat u) const {
|
IfcVector3 Eval(IfcFloat u) const override {
|
||||||
u = -conv.angle_scale * u;
|
u = -conv.angle_scale * u;
|
||||||
return location + static_cast<IfcFloat>(entity.SemiAxis1)*static_cast<IfcFloat>(std::cos(u))*p[0] +
|
return location + static_cast<IfcFloat>(entity.SemiAxis1)*static_cast<IfcFloat>(std::cos(u))*p[0] +
|
||||||
static_cast<IfcFloat>(entity.SemiAxis2)*static_cast<IfcFloat>(std::sin(u))*p[1];
|
static_cast<IfcFloat>(entity.SemiAxis2)*static_cast<IfcFloat>(std::sin(u))*p[1];
|
||||||
|
@ -155,17 +153,17 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
// --------------------------------------------------
|
// --------------------------------------------------
|
||||||
bool IsClosed() const {
|
bool IsClosed() const override {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// --------------------------------------------------
|
// --------------------------------------------------
|
||||||
IfcVector3 Eval(IfcFloat u) const {
|
IfcVector3 Eval(IfcFloat u) const override {
|
||||||
return p + u*v;
|
return p + u*v;
|
||||||
}
|
}
|
||||||
|
|
||||||
// --------------------------------------------------
|
// --------------------------------------------------
|
||||||
size_t EstimateSampleCount(IfcFloat a, IfcFloat b) const {
|
size_t EstimateSampleCount(IfcFloat a, IfcFloat b) const override {
|
||||||
ai_assert( InRange( a ) );
|
ai_assert( InRange( a ) );
|
||||||
ai_assert( InRange( b ) );
|
ai_assert( InRange( b ) );
|
||||||
// two points are always sufficient for a line segment
|
// two points are always sufficient for a line segment
|
||||||
|
@ -174,7 +172,7 @@ public:
|
||||||
|
|
||||||
|
|
||||||
// --------------------------------------------------
|
// --------------------------------------------------
|
||||||
void SampleDiscrete(TempMesh& out,IfcFloat a, IfcFloat b) const {
|
void SampleDiscrete(TempMesh& out,IfcFloat a, IfcFloat b) const override {
|
||||||
ai_assert( InRange( a ) );
|
ai_assert( InRange( a ) );
|
||||||
ai_assert( InRange( b ) );
|
ai_assert( InRange( b ) );
|
||||||
|
|
||||||
|
@ -188,7 +186,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
// --------------------------------------------------
|
// --------------------------------------------------
|
||||||
ParamRange GetParametricRange() const {
|
ParamRange GetParametricRange() const override {
|
||||||
const IfcFloat inf = std::numeric_limits<IfcFloat>::infinity();
|
const IfcFloat inf = std::numeric_limits<IfcFloat>::infinity();
|
||||||
|
|
||||||
return std::make_pair(-inf,+inf);
|
return std::make_pair(-inf,+inf);
|
||||||
|
@ -234,7 +232,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
// --------------------------------------------------
|
// --------------------------------------------------
|
||||||
IfcVector3 Eval(IfcFloat u) const {
|
IfcVector3 Eval(IfcFloat u) const override {
|
||||||
if (curves.empty()) {
|
if (curves.empty()) {
|
||||||
return IfcVector3();
|
return IfcVector3();
|
||||||
}
|
}
|
||||||
|
@ -254,7 +252,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
// --------------------------------------------------
|
// --------------------------------------------------
|
||||||
size_t EstimateSampleCount(IfcFloat a, IfcFloat b) const {
|
size_t EstimateSampleCount(IfcFloat a, IfcFloat b) const override {
|
||||||
ai_assert( InRange( a ) );
|
ai_assert( InRange( a ) );
|
||||||
ai_assert( InRange( b ) );
|
ai_assert( InRange( b ) );
|
||||||
size_t cnt = 0;
|
size_t cnt = 0;
|
||||||
|
@ -275,7 +273,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
// --------------------------------------------------
|
// --------------------------------------------------
|
||||||
void SampleDiscrete(TempMesh& out,IfcFloat a, IfcFloat b) const {
|
void SampleDiscrete(TempMesh& out,IfcFloat a, IfcFloat b) const override {
|
||||||
ai_assert( InRange( a ) );
|
ai_assert( InRange( a ) );
|
||||||
ai_assert( InRange( b ) );
|
ai_assert( InRange( b ) );
|
||||||
|
|
||||||
|
@ -293,7 +291,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
// --------------------------------------------------
|
// --------------------------------------------------
|
||||||
ParamRange GetParametricRange() const {
|
ParamRange GetParametricRange() const override {
|
||||||
return std::make_pair(static_cast<IfcFloat>( 0. ),total);
|
return std::make_pair(static_cast<IfcFloat>( 0. ),total);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -373,27 +371,27 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
// --------------------------------------------------
|
// --------------------------------------------------
|
||||||
IfcVector3 Eval(IfcFloat p) const {
|
IfcVector3 Eval(IfcFloat p) const override {
|
||||||
ai_assert(InRange(p));
|
ai_assert(InRange(p));
|
||||||
return base->Eval( TrimParam(p) );
|
return base->Eval( TrimParam(p) );
|
||||||
}
|
}
|
||||||
|
|
||||||
// --------------------------------------------------
|
// --------------------------------------------------
|
||||||
size_t EstimateSampleCount(IfcFloat a, IfcFloat b) const {
|
size_t EstimateSampleCount(IfcFloat a, IfcFloat b) const override {
|
||||||
ai_assert( InRange( a ) );
|
ai_assert( InRange( a ) );
|
||||||
ai_assert( InRange( b ) );
|
ai_assert( InRange( b ) );
|
||||||
return base->EstimateSampleCount(TrimParam(a),TrimParam(b));
|
return base->EstimateSampleCount(TrimParam(a),TrimParam(b));
|
||||||
}
|
}
|
||||||
|
|
||||||
// --------------------------------------------------
|
// --------------------------------------------------
|
||||||
void SampleDiscrete(TempMesh& out,IfcFloat a,IfcFloat b) const {
|
void SampleDiscrete(TempMesh& out,IfcFloat a,IfcFloat b) const override {
|
||||||
ai_assert(InRange(a));
|
ai_assert(InRange(a));
|
||||||
ai_assert(InRange(b));
|
ai_assert(InRange(b));
|
||||||
return base->SampleDiscrete(out,TrimParam(a),TrimParam(b));
|
return base->SampleDiscrete(out,TrimParam(a),TrimParam(b));
|
||||||
}
|
}
|
||||||
|
|
||||||
// --------------------------------------------------
|
// --------------------------------------------------
|
||||||
ParamRange GetParametricRange() const {
|
ParamRange GetParametricRange() const override {
|
||||||
return std::make_pair(static_cast<IfcFloat>( 0. ),maxval);
|
return std::make_pair(static_cast<IfcFloat>( 0. ),maxval);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -431,7 +429,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
// --------------------------------------------------
|
// --------------------------------------------------
|
||||||
IfcVector3 Eval(IfcFloat p) const {
|
IfcVector3 Eval(IfcFloat p) const override {
|
||||||
ai_assert(InRange(p));
|
ai_assert(InRange(p));
|
||||||
|
|
||||||
const size_t b = static_cast<size_t>(std::floor(p));
|
const size_t b = static_cast<size_t>(std::floor(p));
|
||||||
|
@ -444,14 +442,14 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
// --------------------------------------------------
|
// --------------------------------------------------
|
||||||
size_t EstimateSampleCount(IfcFloat a, IfcFloat b) const {
|
size_t EstimateSampleCount(IfcFloat a, IfcFloat b) const override {
|
||||||
ai_assert(InRange(a));
|
ai_assert(InRange(a));
|
||||||
ai_assert(InRange(b));
|
ai_assert(InRange(b));
|
||||||
return static_cast<size_t>( std::ceil(b) - std::floor(a) );
|
return static_cast<size_t>( std::ceil(b) - std::floor(a) );
|
||||||
}
|
}
|
||||||
|
|
||||||
// --------------------------------------------------
|
// --------------------------------------------------
|
||||||
ParamRange GetParametricRange() const {
|
ParamRange GetParametricRange() const override {
|
||||||
return std::make_pair(static_cast<IfcFloat>( 0. ),static_cast<IfcFloat>(points.size()-1));
|
return std::make_pair(static_cast<IfcFloat>( 0. ),static_cast<IfcFloat>(points.size()-1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -516,7 +514,7 @@ size_t Curve::EstimateSampleCount(IfcFloat a, IfcFloat b) const {
|
||||||
ai_assert( InRange( a ) );
|
ai_assert( InRange( a ) );
|
||||||
ai_assert( InRange( b ) );
|
ai_assert( InRange( b ) );
|
||||||
|
|
||||||
// arbitrary default value, deriving classes should supply better suited values
|
// arbitrary default value, deriving classes should supply better-suited values
|
||||||
return 16;
|
return 16;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -38,24 +38,15 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** @file IFCGeometry.cpp
|
/// @file IFCGeometry.cpp
|
||||||
* @brief Geometry conversion and synthesis for IFC
|
/// @brief Geometry conversion and synthesis for IFC
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef ASSIMP_BUILD_NO_IFC_IMPORTER
|
#ifndef ASSIMP_BUILD_NO_IFC_IMPORTER
|
||||||
#include "IFCUtil.h"
|
#include "IFCUtil.h"
|
||||||
#include "Common/PolyTools.h"
|
#include "Common/PolyTools.h"
|
||||||
#include "PostProcessing/ProcessHelper.h"
|
#include "PostProcessing/ProcessHelper.h"
|
||||||
|
#include "contrib/poly2tri/poly2tri/poly2tri.h"
|
||||||
#ifdef ASSIMP_USE_HUNTER
|
#include "contrib/clipper/clipper.hpp"
|
||||||
# include <poly2tri/poly2tri.h>
|
|
||||||
# include <polyclipping/clipper.hpp>
|
|
||||||
#else
|
|
||||||
# include "../contrib/poly2tri/poly2tri/poly2tri.h"
|
|
||||||
# include "../contrib/clipper/clipper.hpp"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
@ -65,8 +56,7 @@ namespace Assimp {
|
||||||
namespace IFC {
|
namespace IFC {
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
bool ProcessPolyloop(const Schema_2x3::IfcPolyLoop& loop, TempMesh& meshout, ConversionData& /*conv*/)
|
bool ProcessPolyloop(const Schema_2x3::IfcPolyLoop& loop, TempMesh& meshout, ConversionData& /*conv*/) {
|
||||||
{
|
|
||||||
size_t cnt = 0;
|
size_t cnt = 0;
|
||||||
for(const Schema_2x3::IfcCartesianPoint& c : loop.Polygon) {
|
for(const Schema_2x3::IfcCartesianPoint& c : loop.Polygon) {
|
||||||
IfcVector3 tmp;
|
IfcVector3 tmp;
|
||||||
|
@ -91,8 +81,7 @@ bool ProcessPolyloop(const Schema_2x3::IfcPolyLoop& loop, TempMesh& meshout, Con
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void ProcessPolygonBoundaries(TempMesh& result, const TempMesh& inmesh, size_t master_bounds = (size_t)-1)
|
void ProcessPolygonBoundaries(TempMesh& result, const TempMesh& inmesh, size_t master_bounds = (size_t)-1) {
|
||||||
{
|
|
||||||
// handle all trivial cases
|
// handle all trivial cases
|
||||||
if(inmesh.mVertcnt.empty()) {
|
if(inmesh.mVertcnt.empty()) {
|
||||||
return;
|
return;
|
||||||
|
@ -127,8 +116,7 @@ void ProcessPolygonBoundaries(TempMesh& result, const TempMesh& inmesh, size_t m
|
||||||
if (master_bounds != (size_t)-1) {
|
if (master_bounds != (size_t)-1) {
|
||||||
ai_assert(master_bounds < inmesh.mVertcnt.size());
|
ai_assert(master_bounds < inmesh.mVertcnt.size());
|
||||||
outer_polygon_it = begin + master_bounds;
|
outer_polygon_it = begin + master_bounds;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
for(iit = begin; iit != end; ++iit) {
|
for(iit = begin; iit != end; ++iit) {
|
||||||
// find the polygon with the largest area and take it as the outer bound.
|
// find the polygon with the largest area and take it as the outer bound.
|
||||||
IfcVector3& n = normals[std::distance(begin,iit)];
|
IfcVector3& n = normals[std::distance(begin,iit)];
|
||||||
|
@ -139,6 +127,7 @@ void ProcessPolygonBoundaries(TempMesh& result, const TempMesh& inmesh, size_t m
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (outer_polygon_it == end) {
|
if (outer_polygon_it == end) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -205,40 +194,20 @@ void ProcessConnectedFaceSet(const Schema_2x3::IfcConnectedFaceSet& fset, TempMe
|
||||||
|
|
||||||
if(const Schema_2x3::IfcPolyLoop* const polyloop = bound.Bound->ToPtr<Schema_2x3::IfcPolyLoop>()) {
|
if(const Schema_2x3::IfcPolyLoop* const polyloop = bound.Bound->ToPtr<Schema_2x3::IfcPolyLoop>()) {
|
||||||
if(ProcessPolyloop(*polyloop, meshout,conv)) {
|
if(ProcessPolyloop(*polyloop, meshout,conv)) {
|
||||||
|
|
||||||
// The outer boundary is better determined by checking which
|
// The outer boundary is better determined by checking which
|
||||||
// polygon covers the largest area.
|
// polygon covers the largest area.
|
||||||
|
|
||||||
//if(bound.ToPtr<IfcFaceOuterBound>()) {
|
|
||||||
// ob = cnt;
|
|
||||||
//}
|
|
||||||
//++cnt;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
IFCImporter::LogWarn("skipping unknown IfcFaceBound entity, type is ", bound.Bound->GetClassName());
|
IFCImporter::LogWarn("skipping unknown IfcFaceBound entity, type is ", bound.Bound->GetClassName());
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// And this, even though it is sometimes TRUE and sometimes FALSE,
|
|
||||||
// does not really improve results.
|
|
||||||
|
|
||||||
/*if(!IsTrue(bound.Orientation)) {
|
|
||||||
size_t c = 0;
|
|
||||||
for(unsigned int& c : meshout.vertcnt) {
|
|
||||||
std::reverse(result.verts.begin() + cnt,result.verts.begin() + cnt + c);
|
|
||||||
cnt += c;
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
}
|
}
|
||||||
ProcessPolygonBoundaries(result, meshout);
|
ProcessPolygonBoundaries(result, meshout);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void ProcessRevolvedAreaSolid(const Schema_2x3::IfcRevolvedAreaSolid& solid, TempMesh& result, ConversionData& conv)
|
void ProcessRevolvedAreaSolid(const Schema_2x3::IfcRevolvedAreaSolid& solid, TempMesh& result, ConversionData& conv) {
|
||||||
{
|
|
||||||
TempMesh meshout;
|
TempMesh meshout;
|
||||||
|
|
||||||
// first read the profile description
|
// first read the profile description
|
||||||
|
@ -265,7 +234,8 @@ void ProcessRevolvedAreaSolid(const Schema_2x3::IfcRevolvedAreaSolid& solid, Tem
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const unsigned int cnt_segments = std::max(2u,static_cast<unsigned int>(conv.settings.cylindricalTessellation * std::fabs(max_angle)/AI_MATH_HALF_PI_F));
|
const unsigned int cnt_segments =
|
||||||
|
std::max(2u,static_cast<unsigned int>(conv.settings.cylindricalTessellation * std::fabs(max_angle)/AI_MATH_HALF_PI_F));
|
||||||
const IfcFloat delta = max_angle/cnt_segments;
|
const IfcFloat delta = max_angle/cnt_segments;
|
||||||
|
|
||||||
has_area = has_area && std::fabs(max_angle) < AI_MATH_TWO_PI_F*0.99;
|
has_area = has_area && std::fabs(max_angle) < AI_MATH_TWO_PI_F*0.99;
|
||||||
|
@ -324,8 +294,9 @@ void ProcessRevolvedAreaSolid(const Schema_2x3::IfcRevolvedAreaSolid& solid, Tem
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void ProcessSweptDiskSolid(const Schema_2x3::IfcSweptDiskSolid &solid, TempMesh& result, ConversionData& conv)
|
void ProcessSweptDiskSolid(const Schema_2x3::IfcSweptDiskSolid &solid,
|
||||||
{
|
TempMesh& result,
|
||||||
|
ConversionData& conv) {
|
||||||
const Curve* const curve = Curve::Convert(*solid.Directrix, conv);
|
const Curve* const curve = Curve::Convert(*solid.Directrix, conv);
|
||||||
if(!curve) {
|
if(!curve) {
|
||||||
IFCImporter::LogError("failed to convert Directrix curve (IfcSweptDiskSolid)");
|
IFCImporter::LogError("failed to convert Directrix curve (IfcSweptDiskSolid)");
|
||||||
|
@ -460,8 +431,7 @@ void ProcessSweptDiskSolid(const Schema_2x3::IfcSweptDiskSolid &solid, TempMesh&
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
IfcMatrix3 DerivePlaneCoordinateSpace(const TempMesh& curmesh, bool& ok, IfcVector3& norOut)
|
IfcMatrix3 DerivePlaneCoordinateSpace(const TempMesh& curmesh, bool& ok, IfcVector3& norOut) {
|
||||||
{
|
|
||||||
const std::vector<IfcVector3>& out = curmesh.mVerts;
|
const std::vector<IfcVector3>& out = curmesh.mVerts;
|
||||||
IfcMatrix3 m;
|
IfcMatrix3 m;
|
||||||
|
|
||||||
|
@ -504,10 +474,6 @@ IfcMatrix3 DerivePlaneCoordinateSpace(const TempMesh& curmesh, bool& ok, IfcVect
|
||||||
IfcVector3 r = (out[idx]-any_point);
|
IfcVector3 r = (out[idx]-any_point);
|
||||||
r.Normalize();
|
r.Normalize();
|
||||||
|
|
||||||
//if(d) {
|
|
||||||
// *d = -any_point * nor;
|
|
||||||
//}
|
|
||||||
|
|
||||||
// Reconstruct orthonormal basis
|
// Reconstruct orthonormal basis
|
||||||
// XXX use Gram Schmidt for increased robustness
|
// XXX use Gram Schmidt for increased robustness
|
||||||
IfcVector3 u = r ^ nor;
|
IfcVector3 u = r ^ nor;
|
||||||
|
@ -531,8 +497,7 @@ IfcMatrix3 DerivePlaneCoordinateSpace(const TempMesh& curmesh, bool& ok, IfcVect
|
||||||
const auto closeDistance = ai_epsilon;
|
const auto closeDistance = ai_epsilon;
|
||||||
|
|
||||||
bool areClose(Schema_2x3::IfcCartesianPoint pt1,Schema_2x3::IfcCartesianPoint pt2) {
|
bool areClose(Schema_2x3::IfcCartesianPoint pt1,Schema_2x3::IfcCartesianPoint pt2) {
|
||||||
if(pt1.Coordinates.size() != pt2.Coordinates.size())
|
if(pt1.Coordinates.size() != pt2.Coordinates.size()) {
|
||||||
{
|
|
||||||
IFCImporter::LogWarn("unable to compare differently-dimensioned points");
|
IFCImporter::LogWarn("unable to compare differently-dimensioned points");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -540,11 +505,11 @@ bool areClose(Schema_2x3::IfcCartesianPoint pt1,Schema_2x3::IfcCartesianPoint pt
|
||||||
auto coord2 = pt2.Coordinates.begin();
|
auto coord2 = pt2.Coordinates.begin();
|
||||||
// we're just testing each dimension separately rather than doing euclidean distance, as we're
|
// we're just testing each dimension separately rather than doing euclidean distance, as we're
|
||||||
// looking for very close coordinates
|
// looking for very close coordinates
|
||||||
for(; coord1 != pt1.Coordinates.end(); coord1++,coord2++)
|
for(; coord1 != pt1.Coordinates.end(); coord1++,coord2++) {
|
||||||
{
|
if(std::fabs(*coord1 - *coord2) > closeDistance) {
|
||||||
if(std::fabs(*coord1 - *coord2) > closeDistance)
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -553,6 +518,7 @@ bool areClose(IfcVector3 pt1,IfcVector3 pt2) {
|
||||||
std::fabs(pt1.y - pt2.y) < closeDistance &&
|
std::fabs(pt1.y - pt2.y) < closeDistance &&
|
||||||
std::fabs(pt1.z - pt2.z) < closeDistance);
|
std::fabs(pt1.z - pt2.z) < closeDistance);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Extrudes the given polygon along the direction, converts it into an opening or applies all openings as necessary.
|
// Extrudes the given polygon along the direction, converts it into an opening or applies all openings as necessary.
|
||||||
void ProcessExtrudedArea(const Schema_2x3::IfcExtrudedAreaSolid& solid, const TempMesh& curve,
|
void ProcessExtrudedArea(const Schema_2x3::IfcExtrudedAreaSolid& solid, const TempMesh& curve,
|
||||||
const IfcVector3& extrusionDir, TempMesh& result, ConversionData &conv, bool collect_openings)
|
const IfcVector3& extrusionDir, TempMesh& result, ConversionData &conv, bool collect_openings)
|
||||||
|
@ -590,8 +556,9 @@ void ProcessExtrudedArea(const Schema_2x3::IfcExtrudedAreaSolid& solid, const Te
|
||||||
|
|
||||||
// reverse profile polygon if it's winded in the wrong direction in relation to the extrusion direction
|
// reverse profile polygon if it's winded in the wrong direction in relation to the extrusion direction
|
||||||
IfcVector3 profileNormal = TempMesh::ComputePolygonNormal(in.data(), in.size());
|
IfcVector3 profileNormal = TempMesh::ComputePolygonNormal(in.data(), in.size());
|
||||||
if( profileNormal * dir < 0.0 )
|
if( profileNormal * dir < 0.0 ) {
|
||||||
std::reverse(in.begin(), in.end());
|
std::reverse(in.begin(), in.end());
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<IfcVector3> nors;
|
std::vector<IfcVector3> nors;
|
||||||
const bool openings = !!conv.apply_openings && conv.apply_openings->size();
|
const bool openings = !!conv.apply_openings && conv.apply_openings->size();
|
||||||
|
@ -678,8 +645,7 @@ void ProcessExtrudedArea(const Schema_2x3::IfcExtrudedAreaSolid& solid, const Te
|
||||||
if(n > 0) {
|
if(n > 0) {
|
||||||
for(size_t i = 0; i < in.size(); ++i)
|
for(size_t i = 0; i < in.size(); ++i)
|
||||||
out.push_back(in[i] + dir);
|
out.push_back(in[i] + dir);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
for(size_t i = in.size(); i--; )
|
for(size_t i = in.size(); i--; )
|
||||||
out.push_back(in[i]);
|
out.push_back(in[i]);
|
||||||
}
|
}
|
||||||
|
@ -721,9 +687,10 @@ void ProcessExtrudedArea(const Schema_2x3::IfcExtrudedAreaSolid& solid, const Te
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void ProcessExtrudedAreaSolid(const Schema_2x3::IfcExtrudedAreaSolid& solid, TempMesh& result,
|
void ProcessExtrudedAreaSolid(const Schema_2x3::IfcExtrudedAreaSolid& solid,
|
||||||
ConversionData& conv, bool collect_openings)
|
TempMesh& result,
|
||||||
{
|
ConversionData& conv,
|
||||||
|
bool collect_openings) {
|
||||||
TempMesh meshout;
|
TempMesh meshout;
|
||||||
|
|
||||||
// First read the profile description.
|
// First read the profile description.
|
||||||
|
@ -761,24 +728,23 @@ void ProcessExtrudedAreaSolid(const Schema_2x3::IfcExtrudedAreaSolid& solid, Tem
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void ProcessSweptAreaSolid(const Schema_2x3::IfcSweptAreaSolid& swept, TempMesh& meshout,
|
void ProcessSweptAreaSolid(const Schema_2x3::IfcSweptAreaSolid& swept,
|
||||||
ConversionData& conv)
|
TempMesh& meshout,
|
||||||
{
|
ConversionData& conv) {
|
||||||
if(const Schema_2x3::IfcExtrudedAreaSolid* const solid = swept.ToPtr<Schema_2x3::IfcExtrudedAreaSolid>()) {
|
if(const Schema_2x3::IfcExtrudedAreaSolid* const solid = swept.ToPtr<Schema_2x3::IfcExtrudedAreaSolid>()) {
|
||||||
ProcessExtrudedAreaSolid(*solid,meshout,conv, !!conv.collect_openings);
|
ProcessExtrudedAreaSolid(*solid,meshout,conv, !!conv.collect_openings);
|
||||||
}
|
} else if(const Schema_2x3::IfcRevolvedAreaSolid* const rev = swept.ToPtr<Schema_2x3::IfcRevolvedAreaSolid>()) {
|
||||||
else if(const Schema_2x3::IfcRevolvedAreaSolid* const rev = swept.ToPtr<Schema_2x3::IfcRevolvedAreaSolid>()) {
|
|
||||||
ProcessRevolvedAreaSolid(*rev,meshout,conv);
|
ProcessRevolvedAreaSolid(*rev,meshout,conv);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
IFCImporter::LogWarn("skipping unknown IfcSweptAreaSolid entity, type is ", swept.GetClassName());
|
IFCImporter::LogWarn("skipping unknown IfcSweptAreaSolid entity, type is ", swept.GetClassName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
bool ProcessGeometricItem(const Schema_2x3::IfcRepresentationItem& geo, unsigned int matid, std::set<unsigned int>& mesh_indices,
|
bool ProcessGeometricItem(const Schema_2x3::IfcRepresentationItem& geo,
|
||||||
ConversionData& conv)
|
unsigned int matid,
|
||||||
{
|
std::set<unsigned int>& mesh_indices,
|
||||||
|
ConversionData& conv) {
|
||||||
bool fix_orientation = false;
|
bool fix_orientation = false;
|
||||||
std::shared_ptr< TempMesh > meshtmp = std::make_shared<TempMesh>();
|
std::shared_ptr< TempMesh > meshtmp = std::make_shared<TempMesh>();
|
||||||
if(const Schema_2x3::IfcShellBasedSurfaceModel* shellmod = geo.ToPtr<Schema_2x3::IfcShellBasedSurfaceModel>()) {
|
if(const Schema_2x3::IfcShellBasedSurfaceModel* shellmod = geo.ToPtr<Schema_2x3::IfcShellBasedSurfaceModel>()) {
|
||||||
|
@ -788,41 +754,32 @@ bool ProcessGeometricItem(const Schema_2x3::IfcRepresentationItem& geo, unsigned
|
||||||
const Schema_2x3::IfcConnectedFaceSet& fs = conv.db.MustGetObject(e).To<Schema_2x3::IfcConnectedFaceSet>();
|
const Schema_2x3::IfcConnectedFaceSet& fs = conv.db.MustGetObject(e).To<Schema_2x3::IfcConnectedFaceSet>();
|
||||||
|
|
||||||
ProcessConnectedFaceSet(fs, *meshtmp, conv);
|
ProcessConnectedFaceSet(fs, *meshtmp, conv);
|
||||||
}
|
} catch(std::bad_cast&) {
|
||||||
catch(std::bad_cast&) {
|
|
||||||
IFCImporter::LogWarn("unexpected type error, IfcShell ought to inherit from IfcConnectedFaceSet");
|
IFCImporter::LogWarn("unexpected type error, IfcShell ought to inherit from IfcConnectedFaceSet");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fix_orientation = true;
|
fix_orientation = true;
|
||||||
}
|
} else if(const Schema_2x3::IfcConnectedFaceSet* fset = geo.ToPtr<Schema_2x3::IfcConnectedFaceSet>()) {
|
||||||
else if(const Schema_2x3::IfcConnectedFaceSet* fset = geo.ToPtr<Schema_2x3::IfcConnectedFaceSet>()) {
|
|
||||||
ProcessConnectedFaceSet(*fset, *meshtmp, conv);
|
ProcessConnectedFaceSet(*fset, *meshtmp, conv);
|
||||||
fix_orientation = true;
|
fix_orientation = true;
|
||||||
}
|
} else if(const Schema_2x3::IfcSweptAreaSolid* swept = geo.ToPtr<Schema_2x3::IfcSweptAreaSolid>()) {
|
||||||
else if(const Schema_2x3::IfcSweptAreaSolid* swept = geo.ToPtr<Schema_2x3::IfcSweptAreaSolid>()) {
|
|
||||||
ProcessSweptAreaSolid(*swept, *meshtmp, conv);
|
ProcessSweptAreaSolid(*swept, *meshtmp, conv);
|
||||||
}
|
} else if(const Schema_2x3::IfcSweptDiskSolid* disk = geo.ToPtr<Schema_2x3::IfcSweptDiskSolid>()) {
|
||||||
else if(const Schema_2x3::IfcSweptDiskSolid* disk = geo.ToPtr<Schema_2x3::IfcSweptDiskSolid>()) {
|
|
||||||
ProcessSweptDiskSolid(*disk, *meshtmp, conv);
|
ProcessSweptDiskSolid(*disk, *meshtmp, conv);
|
||||||
}
|
} else if(const Schema_2x3::IfcManifoldSolidBrep* brep = geo.ToPtr<Schema_2x3::IfcManifoldSolidBrep>()) {
|
||||||
else if(const Schema_2x3::IfcManifoldSolidBrep* brep = geo.ToPtr<Schema_2x3::IfcManifoldSolidBrep>()) {
|
|
||||||
ProcessConnectedFaceSet(brep->Outer, *meshtmp, conv);
|
ProcessConnectedFaceSet(brep->Outer, *meshtmp, conv);
|
||||||
fix_orientation = true;
|
fix_orientation = true;
|
||||||
}
|
} else if(const Schema_2x3::IfcFaceBasedSurfaceModel* surf = geo.ToPtr<Schema_2x3::IfcFaceBasedSurfaceModel>()) {
|
||||||
else if(const Schema_2x3::IfcFaceBasedSurfaceModel* surf = geo.ToPtr<Schema_2x3::IfcFaceBasedSurfaceModel>()) {
|
|
||||||
for(const Schema_2x3::IfcConnectedFaceSet& fc : surf->FbsmFaces) {
|
for(const Schema_2x3::IfcConnectedFaceSet& fc : surf->FbsmFaces) {
|
||||||
ProcessConnectedFaceSet(fc, *meshtmp, conv);
|
ProcessConnectedFaceSet(fc, *meshtmp, conv);
|
||||||
}
|
}
|
||||||
fix_orientation = true;
|
fix_orientation = true;
|
||||||
}
|
} else if(const Schema_2x3::IfcBooleanResult* boolean = geo.ToPtr<Schema_2x3::IfcBooleanResult>()) {
|
||||||
else if(const Schema_2x3::IfcBooleanResult* boolean = geo.ToPtr<Schema_2x3::IfcBooleanResult>()) {
|
|
||||||
ProcessBoolean(*boolean, *meshtmp, conv);
|
ProcessBoolean(*boolean, *meshtmp, conv);
|
||||||
}
|
} else if(geo.ToPtr<Schema_2x3::IfcBoundingBox>()) {
|
||||||
else if(geo.ToPtr<Schema_2x3::IfcBoundingBox>()) {
|
|
||||||
// silently skip over bounding boxes
|
// silently skip over bounding boxes
|
||||||
return false;
|
return false;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
std::stringstream toLog;
|
std::stringstream toLog;
|
||||||
toLog << "skipping unknown IfcGeometricRepresentationItem entity, type is " << geo.GetClassName() << " id is " << geo.GetID();
|
toLog << "skipping unknown IfcGeometricRepresentationItem entity, type is " << geo.GetClassName() << " id is " << geo.GetID();
|
||||||
IFCImporter::LogWarn(toLog.str().c_str());
|
IFCImporter::LogWarn(toLog.str().c_str());
|
||||||
|
@ -868,9 +825,7 @@ bool ProcessGeometricItem(const Schema_2x3::IfcRepresentationItem& geo, unsigned
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void AssignAddedMeshes(std::set<unsigned int>& mesh_indices,aiNode* nd,
|
void AssignAddedMeshes(std::set<unsigned int>& mesh_indices,aiNode* nd, ConversionData& /*conv*/) {
|
||||||
ConversionData& /*conv*/)
|
|
||||||
{
|
|
||||||
if (!mesh_indices.empty()) {
|
if (!mesh_indices.empty()) {
|
||||||
std::set<unsigned int>::const_iterator it = mesh_indices.cbegin();
|
std::set<unsigned int>::const_iterator it = mesh_indices.cbegin();
|
||||||
std::set<unsigned int>::const_iterator end = mesh_indices.cend();
|
std::set<unsigned int>::const_iterator end = mesh_indices.cend();
|
||||||
|
@ -886,9 +841,9 @@ void AssignAddedMeshes(std::set<unsigned int>& mesh_indices,aiNode* nd,
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
bool TryQueryMeshCache(const Schema_2x3::IfcRepresentationItem& item,
|
bool TryQueryMeshCache(const Schema_2x3::IfcRepresentationItem& item,
|
||||||
std::set<unsigned int>& mesh_indices, unsigned int mat_index,
|
std::set<unsigned int>& mesh_indices,
|
||||||
ConversionData& conv)
|
unsigned int mat_index,
|
||||||
{
|
ConversionData& conv) {
|
||||||
ConversionData::MeshCacheIndex idx(&item, mat_index);
|
ConversionData::MeshCacheIndex idx(&item, mat_index);
|
||||||
ConversionData::MeshCache::const_iterator it = conv.cached_meshes.find(idx);
|
ConversionData::MeshCache::const_iterator it = conv.cached_meshes.find(idx);
|
||||||
if (it != conv.cached_meshes.end()) {
|
if (it != conv.cached_meshes.end()) {
|
||||||
|
@ -900,18 +855,18 @@ bool TryQueryMeshCache(const Schema_2x3::IfcRepresentationItem& item,
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void PopulateMeshCache(const Schema_2x3::IfcRepresentationItem& item,
|
void PopulateMeshCache(const Schema_2x3::IfcRepresentationItem& item,
|
||||||
const std::set<unsigned int>& mesh_indices, unsigned int mat_index,
|
const std::set<unsigned int>& mesh_indices,
|
||||||
ConversionData& conv)
|
unsigned int mat_index,
|
||||||
{
|
ConversionData& conv) {
|
||||||
ConversionData::MeshCacheIndex idx(&item, mat_index);
|
ConversionData::MeshCacheIndex idx(&item, mat_index);
|
||||||
conv.cached_meshes[idx] = mesh_indices;
|
conv.cached_meshes[idx] = mesh_indices;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
bool ProcessRepresentationItem(const Schema_2x3::IfcRepresentationItem& item, unsigned int matid,
|
bool ProcessRepresentationItem(const Schema_2x3::IfcRepresentationItem& item,
|
||||||
|
unsigned int matid,
|
||||||
std::set<unsigned int>& mesh_indices,
|
std::set<unsigned int>& mesh_indices,
|
||||||
ConversionData& conv)
|
ConversionData& conv) {
|
||||||
{
|
|
||||||
// determine material
|
// determine material
|
||||||
unsigned int localmatid = ProcessMaterials(item.GetID(), matid, conv, true);
|
unsigned int localmatid = ProcessMaterials(item.GetID(), matid, conv, true);
|
||||||
|
|
||||||
|
@ -920,8 +875,9 @@ bool ProcessRepresentationItem(const Schema_2x3::IfcRepresentationItem& item, un
|
||||||
if(mesh_indices.size()) {
|
if(mesh_indices.size()) {
|
||||||
PopulateMeshCache(item,mesh_indices,localmatid,conv);
|
PopulateMeshCache(item,mesh_indices,localmatid,conv);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
else return false;
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -930,4 +886,4 @@ bool ProcessRepresentationItem(const Schema_2x3::IfcRepresentationItem& item, un
|
||||||
} // ! IFC
|
} // ! IFC
|
||||||
} // ! Assimp
|
} // ! Assimp
|
||||||
|
|
||||||
#endif
|
#endif // ASSIMP_BUILD_NO_IFC_IMPORTER
|
||||||
|
|
|
@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
|
||||||
|
|
||||||
Copyright (c) 2006-2022, assimp team
|
Copyright (c) 2006-2022, assimp team
|
||||||
|
|
||||||
|
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use of this software in source and binary forms,
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
@ -40,9 +39,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** @file IFCLoad.cpp
|
/// @file IFCLoad.cpp
|
||||||
* @brief Implementation of the Industry Foundation Classes loader.
|
/// @brief Implementation of the Industry Foundation Classes loader.
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef ASSIMP_BUILD_NO_IFC_IMPORTER
|
#ifndef ASSIMP_BUILD_NO_IFC_IMPORTER
|
||||||
|
|
||||||
|
@ -92,7 +90,6 @@ using namespace Assimp::IFC;
|
||||||
IfcUnitAssignment
|
IfcUnitAssignment
|
||||||
IfcClosedShell
|
IfcClosedShell
|
||||||
IfcDoor
|
IfcDoor
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
@ -106,7 +103,7 @@ void ConvertUnit(const ::Assimp::STEP::EXPRESS::DataType &dt, ConversionData &co
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
static const aiImporterDesc desc = {
|
static constexpr aiImporterDesc desc = {
|
||||||
"Industry Foundation Classes (IFC) Importer",
|
"Industry Foundation Classes (IFC) Importer",
|
||||||
"",
|
"",
|
||||||
"",
|
"",
|
||||||
|
@ -119,14 +116,6 @@ static const aiImporterDesc desc = {
|
||||||
"ifc ifczip step stp"
|
"ifc ifczip step stp"
|
||||||
};
|
};
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
// Constructor to be privately used by Importer
|
|
||||||
IFCImporter::IFCImporter() = default;
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
// Destructor, private as well
|
|
||||||
IFCImporter::~IFCImporter() = default;
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Returns whether the class can handle the format of the given file.
|
// Returns whether the class can handle the format of the given file.
|
||||||
bool IFCImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /*checkSig*/) const {
|
bool IFCImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /*checkSig*/) const {
|
||||||
|
@ -196,7 +185,7 @@ void IFCImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
|
||||||
size_t total = 0;
|
size_t total = 0;
|
||||||
int read = 0;
|
int read = 0;
|
||||||
do {
|
do {
|
||||||
int bufferSize = fileInfo.uncompressed_size < INT16_MAX ? fileInfo.uncompressed_size : INT16_MAX;
|
unsigned bufferSize = fileInfo.uncompressed_size < INT16_MAX ? static_cast<unsigned>(fileInfo.uncompressed_size) : INT16_MAX;
|
||||||
void *buffer = malloc(bufferSize);
|
void *buffer = malloc(bufferSize);
|
||||||
read = unzReadCurrentFile(zip, buffer, bufferSize);
|
read = unzReadCurrentFile(zip, buffer, bufferSize);
|
||||||
if (read > 0) {
|
if (read > 0) {
|
||||||
|
@ -256,7 +245,12 @@ void IFCImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
|
||||||
|
|
||||||
// tell the reader for which types we need to simulate STEPs reverse indices
|
// tell the reader for which types we need to simulate STEPs reverse indices
|
||||||
static const char *const inverse_indices_to_track[] = {
|
static const char *const inverse_indices_to_track[] = {
|
||||||
"ifcrelcontainedinspatialstructure", "ifcrelaggregates", "ifcrelvoidselement", "ifcreldefinesbyproperties", "ifcpropertyset", "ifcstyleditem"
|
"ifcrelcontainedinspatialstructure",
|
||||||
|
"ifcrelaggregates",
|
||||||
|
"ifcrelvoidselement",
|
||||||
|
"ifcreldefinesbyproperties",
|
||||||
|
"ifcpropertyset",
|
||||||
|
"ifcstyleditem"
|
||||||
};
|
};
|
||||||
|
|
||||||
// feed the IFC schema into the reader and pre-parse all lines
|
// feed the IFC schema into the reader and pre-parse all lines
|
||||||
|
@ -928,4 +922,4 @@ void MakeTreeRelative(ConversionData &conv) {
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
#endif
|
#endif // ASSIMP_BUILD_NO_IFC_IMPORTER
|
||||||
|
|
|
@ -87,8 +87,8 @@ public:
|
||||||
int cylindricalTessellation;
|
int cylindricalTessellation;
|
||||||
};
|
};
|
||||||
|
|
||||||
IFCImporter();
|
IFCImporter() = default;
|
||||||
~IFCImporter() override;
|
~IFCImporter() override = default;
|
||||||
|
|
||||||
// --------------------
|
// --------------------
|
||||||
bool CanRead(const std::string &pFile,
|
bool CanRead(const std::string &pFile,
|
||||||
|
|
|
@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
|
||||||
|
|
||||||
Copyright (c) 2006-2022, assimp team
|
Copyright (c) 2006-2022, assimp team
|
||||||
|
|
||||||
|
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use of this software in source and binary forms,
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
@ -40,9 +39,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** @file IFCMaterial.cpp
|
/// @file IFCMaterial.cpp
|
||||||
* @brief Implementation of conversion routines to convert IFC materials to aiMaterial
|
/// @brief Implementation of conversion routines to convert IFC materials to aiMaterial
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef ASSIMP_BUILD_NO_IFC_IMPORTER
|
#ifndef ASSIMP_BUILD_NO_IFC_IMPORTER
|
||||||
|
|
||||||
|
@ -174,7 +172,6 @@ unsigned int ProcessMaterials(uint64_t id, unsigned int prevMatId, ConversionDat
|
||||||
|
|
||||||
aiString name;
|
aiString name;
|
||||||
name.Set("<IFCDefault>");
|
name.Set("<IFCDefault>");
|
||||||
// ConvertColorToString( color, name);
|
|
||||||
|
|
||||||
// look if there's already a default material with this base color
|
// look if there's already a default material with this base color
|
||||||
for( size_t a = 0; a < conv.materials.size(); ++a ) {
|
for( size_t a = 0; a < conv.materials.size(); ++a ) {
|
||||||
|
|
|
@ -38,24 +38,17 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** @file IFCOpenings.cpp
|
/// @file IFCOpenings.cpp
|
||||||
* @brief Implements a subset of Ifc CSG operations for pouring
|
/// @brief Implements a subset of Ifc CSG operations for pouring
|
||||||
* holes for windows and doors into walls.
|
/// holes for windows and doors into walls.
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef ASSIMP_BUILD_NO_IFC_IMPORTER
|
#ifndef ASSIMP_BUILD_NO_IFC_IMPORTER
|
||||||
|
|
||||||
#include "IFCUtil.h"
|
#include "IFCUtil.h"
|
||||||
#include "Common/PolyTools.h"
|
#include "Common/PolyTools.h"
|
||||||
#include "PostProcessing/ProcessHelper.h"
|
#include "PostProcessing/ProcessHelper.h"
|
||||||
|
#include "contrib/poly2tri/poly2tri/poly2tri.h"
|
||||||
#ifdef ASSIMP_USE_HUNTER
|
#include "contrib/clipper/clipper.hpp"
|
||||||
# include <poly2tri/poly2tri.h>
|
|
||||||
# include <polyclipping/clipper.hpp>
|
|
||||||
#else
|
|
||||||
# include "../contrib/poly2tri/poly2tri/poly2tri.h"
|
|
||||||
# include "../contrib/clipper/clipper.hpp"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <deque>
|
#include <deque>
|
||||||
#include <forward_list>
|
#include <forward_list>
|
||||||
|
@ -66,29 +59,37 @@ namespace Assimp {
|
||||||
namespace IFC {
|
namespace IFC {
|
||||||
|
|
||||||
using ClipperLib::ulong64;
|
using ClipperLib::ulong64;
|
||||||
|
|
||||||
// XXX use full -+ range ...
|
// XXX use full -+ range ...
|
||||||
const ClipperLib::long64 max_ulong64 = 1518500249; // clipper.cpp / hiRange var
|
const ClipperLib::long64 max_ulong64 = 1518500249; // clipper.cpp / hiRange var
|
||||||
|
|
||||||
//#define to_int64(p) (static_cast<ulong64>( std::max( 0., std::min( static_cast<IfcFloat>((p)), 1.) ) * max_ulong64 ))
|
AI_FORCE_INLINE ulong64 to_int64(IfcFloat p) {
|
||||||
#define to_int64(p) (static_cast<ulong64>(static_cast<IfcFloat>((p) ) * max_ulong64 ))
|
return (static_cast<ulong64>(static_cast<IfcFloat>((p) ) * max_ulong64 ));
|
||||||
#define from_int64(p) (static_cast<IfcFloat>((p)) / max_ulong64)
|
}
|
||||||
#define one_vec (IfcVector2(static_cast<IfcFloat>(1.0),static_cast<IfcFloat>(1.0)))
|
|
||||||
|
|
||||||
|
AI_FORCE_INLINE IfcFloat from_int64(ulong64 p) {
|
||||||
|
return (static_cast<IfcFloat>((p)) / max_ulong64);
|
||||||
|
}
|
||||||
|
|
||||||
|
AI_FORCE_INLINE void fillRectangle(const IfcVector2& pmin, const IfcVector2& pmax, std::vector<IfcVector2>& out) {
|
||||||
|
out.emplace_back(pmin.x, pmin.y);
|
||||||
|
out.emplace_back(pmin.x, pmax.y);
|
||||||
|
out.emplace_back(pmax.x, pmax.y);
|
||||||
|
out.emplace_back(pmax.x, pmin.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
const IfcVector2 one_vec(IfcVector2(static_cast<IfcFloat>(1.0),static_cast<IfcFloat>(1.0)));
|
||||||
|
|
||||||
// fallback method to generate wall openings
|
// fallback method to generate wall openings
|
||||||
bool TryAddOpenings_Poly2Tri(const std::vector<TempOpening>& openings,
|
bool TryAddOpenings_Poly2Tri(const std::vector<TempOpening>& openings, TempMesh& curmesh);
|
||||||
TempMesh& curmesh);
|
|
||||||
|
|
||||||
|
|
||||||
typedef std::pair< IfcVector2, IfcVector2 > BoundingBox;
|
|
||||||
typedef std::map<IfcVector2,size_t,XYSorter> XYSortedField;
|
|
||||||
|
|
||||||
|
using BoundingBox = std::pair< IfcVector2, IfcVector2 >;
|
||||||
|
using XYSortedField = std::map<IfcVector2,size_t,XYSorter>;
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void QuadrifyPart(const IfcVector2& pmin, const IfcVector2& pmax, XYSortedField& field,
|
void QuadrifyPart(const IfcVector2& pmin, const IfcVector2& pmax, XYSortedField& field,
|
||||||
const std::vector< BoundingBox >& bbs,
|
const std::vector< BoundingBox >& bbs,
|
||||||
std::vector<IfcVector2>& out)
|
std::vector<IfcVector2>& out) {
|
||||||
{
|
|
||||||
if (!(pmin.x-pmax.x) || !(pmin.y-pmax.y)) {
|
if (!(pmin.x-pmax.x) || !(pmin.y-pmax.y)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -114,10 +115,7 @@ void QuadrifyPart(const IfcVector2& pmin, const IfcVector2& pmax, XYSortedField&
|
||||||
|
|
||||||
if (!found) {
|
if (!found) {
|
||||||
// the rectangle [pmin,pend] is opaque, fill it
|
// the rectangle [pmin,pend] is opaque, fill it
|
||||||
out.push_back(pmin);
|
fillRectangle(pmin, pmax, out);
|
||||||
out.emplace_back(pmin.x,pmax.y);
|
|
||||||
out.push_back(pmax);
|
|
||||||
out.emplace_back(pmax.x,pmin.y);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -142,19 +140,12 @@ void QuadrifyPart(const IfcVector2& pmin, const IfcVector2& pmax, XYSortedField&
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bb.second.y > ylast) {
|
if (bb.second.y > ylast) {
|
||||||
|
|
||||||
found = true;
|
found = true;
|
||||||
const IfcFloat ys = std::max(bb.first.y,pmin.y), ye = std::min(bb.second.y,pmax.y);
|
const IfcFloat ys = std::max(bb.first.y,pmin.y), ye = std::min(bb.second.y,pmax.y);
|
||||||
if (ys - ylast > 0.0f) {
|
if (ys - ylast > 0.0f) {
|
||||||
QuadrifyPart( IfcVector2(xs,ylast), IfcVector2(xe,ys) ,field,bbs,out);
|
QuadrifyPart( IfcVector2(xs,ylast), IfcVector2(xe,ys) ,field,bbs,out);
|
||||||
}
|
}
|
||||||
|
|
||||||
// the following are the window vertices
|
|
||||||
|
|
||||||
/*wnd.push_back(IfcVector2(xs,ys));
|
|
||||||
wnd.push_back(IfcVector2(xs,ye));
|
|
||||||
wnd.push_back(IfcVector2(xe,ye));
|
|
||||||
wnd.push_back(IfcVector2(xe,ys));*/
|
|
||||||
ylast = ye;
|
ylast = ye;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -176,23 +167,19 @@ void QuadrifyPart(const IfcVector2& pmin, const IfcVector2& pmax, XYSortedField&
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef std::vector<IfcVector2> Contour;
|
using Contour = std::vector<IfcVector2>;
|
||||||
typedef std::vector<bool> SkipList; // should probably use int for performance reasons
|
using SkipList = std::vector<bool>; // should probably use int for performance reasons
|
||||||
|
|
||||||
struct ProjectedWindowContour
|
struct ProjectedWindowContour {
|
||||||
{
|
|
||||||
Contour contour;
|
Contour contour;
|
||||||
BoundingBox bb;
|
BoundingBox bb;
|
||||||
SkipList skiplist;
|
SkipList skiplist;
|
||||||
bool is_rectangular;
|
bool is_rectangular;
|
||||||
|
|
||||||
|
|
||||||
ProjectedWindowContour(const Contour& contour, const BoundingBox& bb, bool is_rectangular)
|
ProjectedWindowContour(const Contour& contour, const BoundingBox& bb, bool is_rectangular)
|
||||||
: contour(contour)
|
: contour(contour), bb(bb) , is_rectangular(is_rectangular) {}
|
||||||
, bb(bb)
|
|
||||||
, is_rectangular(is_rectangular)
|
|
||||||
{}
|
|
||||||
|
|
||||||
|
~ProjectedWindowContour() = default;
|
||||||
|
|
||||||
bool IsInvalid() const {
|
bool IsInvalid() const {
|
||||||
return contour.empty();
|
return contour.empty();
|
||||||
|
@ -207,19 +194,17 @@ struct ProjectedWindowContour
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::vector< ProjectedWindowContour > ContourVector;
|
using ContourVector = std::vector<ProjectedWindowContour>;
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
bool BoundingBoxesOverlapping( const BoundingBox &ibb, const BoundingBox &bb )
|
static bool BoundingBoxesOverlapping( const BoundingBox &ibb, const BoundingBox &bb ) {
|
||||||
{
|
|
||||||
// count the '=' case as non-overlapping but as adjacent to each other
|
// count the '=' case as non-overlapping but as adjacent to each other
|
||||||
return ibb.first.x < bb.second.x && ibb.second.x > bb.first.x &&
|
return ibb.first.x < bb.second.x && ibb.second.x > bb.first.x &&
|
||||||
ibb.first.y < bb.second.y && ibb.second.y > bb.first.y;
|
ibb.first.y < bb.second.y && ibb.second.y > bb.first.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
bool IsDuplicateVertex(const IfcVector2& vv, const std::vector<IfcVector2>& temp_contour)
|
static bool IsDuplicateVertex(const IfcVector2& vv, const std::vector<IfcVector2>& temp_contour) {
|
||||||
{
|
|
||||||
// sanity check for duplicate vertices
|
// sanity check for duplicate vertices
|
||||||
for(const IfcVector2& cp : temp_contour) {
|
for(const IfcVector2& cp : temp_contour) {
|
||||||
if ((cp-vv).SquareLength() < 1e-5f) {
|
if ((cp-vv).SquareLength() < 1e-5f) {
|
||||||
|
@ -230,9 +215,8 @@ bool IsDuplicateVertex(const IfcVector2& vv, const std::vector<IfcVector2>& temp
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void ExtractVerticesFromClipper(const ClipperLib::Polygon& poly, std::vector<IfcVector2>& temp_contour,
|
void ExtractVerticesFromClipper(const ClipperLib::Path& poly, std::vector<IfcVector2>& temp_contour,
|
||||||
bool filter_duplicates = false)
|
bool filter_duplicates = false) {
|
||||||
{
|
|
||||||
temp_contour.clear();
|
temp_contour.clear();
|
||||||
for(const ClipperLib::IntPoint& point : poly) {
|
for(const ClipperLib::IntPoint& point : poly) {
|
||||||
IfcVector2 vv = IfcVector2( from_int64(point.X), from_int64(point.Y));
|
IfcVector2 vv = IfcVector2( from_int64(point.X), from_int64(point.Y));
|
||||||
|
@ -246,8 +230,7 @@ void ExtractVerticesFromClipper(const ClipperLib::Polygon& poly, std::vector<Ifc
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
BoundingBox GetBoundingBox(const ClipperLib::Polygon& poly)
|
BoundingBox GetBoundingBox(const ClipperLib::Path& poly) {
|
||||||
{
|
|
||||||
IfcVector2 newbb_min, newbb_max;
|
IfcVector2 newbb_min, newbb_max;
|
||||||
MinMaxChooser<IfcVector2>()(newbb_min, newbb_max);
|
MinMaxChooser<IfcVector2>()(newbb_min, newbb_max);
|
||||||
|
|
||||||
|
@ -265,10 +248,7 @@ BoundingBox GetBoundingBox(const ClipperLib::Polygon& poly)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void InsertWindowContours(const ContourVector& contours,
|
void InsertWindowContours(const ContourVector& contours, const std::vector<TempOpening>& /*openings*/, TempMesh& curmesh) {
|
||||||
const std::vector<TempOpening>& /*openings*/,
|
|
||||||
TempMesh& curmesh)
|
|
||||||
{
|
|
||||||
// fix windows - we need to insert the real, polygonal shapes into the quadratic holes that we have now
|
// fix windows - we need to insert the real, polygonal shapes into the quadratic holes that we have now
|
||||||
for (size_t i = 0; i < contours.size(); ++i) {
|
for (size_t i = 0; i < contours.size(); ++i) {
|
||||||
const BoundingBox& bb = contours[i].bb;
|
const BoundingBox& bb = contours[i].bb;
|
||||||
|
@ -287,8 +267,7 @@ void InsertWindowContours(const ContourVector& contours,
|
||||||
const std::set<IfcVector2,XYSorter>::const_iterator end = verts.end();
|
const std::set<IfcVector2,XYSorter>::const_iterator end = verts.end();
|
||||||
if (verts.find(bb.first)!=end && verts.find(bb.second)!=end
|
if (verts.find(bb.first)!=end && verts.find(bb.second)!=end
|
||||||
&& verts.find(IfcVector2(bb.first.x,bb.second.y))!=end
|
&& verts.find(IfcVector2(bb.first.x,bb.second.y))!=end
|
||||||
&& verts.find(IfcVector2(bb.second.x,bb.first.y))!=end
|
&& verts.find(IfcVector2(bb.second.x,bb.first.y))!=end ) {
|
||||||
) {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -313,8 +292,7 @@ void InsertWindowContours(const ContourVector& contours,
|
||||||
if (std::fabs(v.x-bb.first.x)<epsilon) {
|
if (std::fabs(v.x-bb.first.x)<epsilon) {
|
||||||
edge.x = bb.first.x;
|
edge.x = bb.first.x;
|
||||||
hit = true;
|
hit = true;
|
||||||
}
|
} else if (std::fabs(v.x-bb.second.x)<epsilon) {
|
||||||
else if (std::fabs(v.x-bb.second.x)<epsilon) {
|
|
||||||
edge.x = bb.second.x;
|
edge.x = bb.second.x;
|
||||||
hit = true;
|
hit = true;
|
||||||
}
|
}
|
||||||
|
@ -322,8 +300,7 @@ void InsertWindowContours(const ContourVector& contours,
|
||||||
if (std::fabs(v.y-bb.first.y)<epsilon) {
|
if (std::fabs(v.y-bb.first.y)<epsilon) {
|
||||||
edge.y = bb.first.y;
|
edge.y = bb.first.y;
|
||||||
hit = true;
|
hit = true;
|
||||||
}
|
} else if (std::fabs(v.y-bb.second.y)<epsilon) {
|
||||||
else if (std::fabs(v.y-bb.second.y)<epsilon) {
|
|
||||||
edge.y = bb.second.y;
|
edge.y = bb.second.y;
|
||||||
hit = true;
|
hit = true;
|
||||||
}
|
}
|
||||||
|
@ -347,26 +324,22 @@ void InsertWindowContours(const ContourVector& contours,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (edge != contour[last_hit]) {
|
if (edge != contour[last_hit]) {
|
||||||
|
|
||||||
IfcVector2 corner = edge;
|
IfcVector2 corner = edge;
|
||||||
|
|
||||||
if (std::fabs(contour[last_hit].x-bb.first.x)<epsilon) {
|
if (std::fabs(contour[last_hit].x-bb.first.x)<epsilon) {
|
||||||
corner.x = bb.first.x;
|
corner.x = bb.first.x;
|
||||||
}
|
} else if (std::fabs(contour[last_hit].x-bb.second.x)<epsilon) {
|
||||||
else if (std::fabs(contour[last_hit].x-bb.second.x)<epsilon) {
|
|
||||||
corner.x = bb.second.x;
|
corner.x = bb.second.x;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (std::fabs(contour[last_hit].y-bb.first.y)<epsilon) {
|
if (std::fabs(contour[last_hit].y-bb.first.y)<epsilon) {
|
||||||
corner.y = bb.first.y;
|
corner.y = bb.first.y;
|
||||||
}
|
} else if (std::fabs(contour[last_hit].y-bb.second.y)<epsilon) {
|
||||||
else if (std::fabs(contour[last_hit].y-bb.second.y)<epsilon) {
|
|
||||||
corner.y = bb.second.y;
|
corner.y = bb.second.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
curmesh.mVerts.emplace_back(corner.x, corner.y, 0.0f);
|
curmesh.mVerts.emplace_back(corner.x, corner.y, 0.0f);
|
||||||
}
|
} else if (cnt == 1) {
|
||||||
else if (cnt == 1) {
|
|
||||||
// avoid degenerate polygons (also known as lines or points)
|
// avoid degenerate polygons (also known as lines or points)
|
||||||
curmesh.mVerts.erase(curmesh.mVerts.begin()+old,curmesh.mVerts.end());
|
curmesh.mVerts.erase(curmesh.mVerts.begin()+old,curmesh.mVerts.end());
|
||||||
}
|
}
|
||||||
|
@ -378,8 +351,7 @@ void InsertWindowContours(const ContourVector& contours,
|
||||||
if (n == very_first_hit) {
|
if (n == very_first_hit) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
very_first_hit = n;
|
very_first_hit = n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -390,14 +362,12 @@ void InsertWindowContours(const ContourVector& contours,
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void MergeWindowContours (const std::vector<IfcVector2>& a,
|
void MergeWindowContours (const std::vector<IfcVector2>& a, const std::vector<IfcVector2>& b,
|
||||||
const std::vector<IfcVector2>& b,
|
ClipperLib::Paths& out) {
|
||||||
ClipperLib::ExPolygons& out)
|
|
||||||
{
|
|
||||||
out.clear();
|
out.clear();
|
||||||
|
|
||||||
ClipperLib::Clipper clipper;
|
ClipperLib::Clipper clipper;
|
||||||
ClipperLib::Polygon clip;
|
ClipperLib::Path clip;
|
||||||
|
|
||||||
for(const IfcVector2& pip : a) {
|
for(const IfcVector2& pip : a) {
|
||||||
clip.emplace_back(to_int64(pip.x), to_int64(pip.y));
|
clip.emplace_back(to_int64(pip.x), to_int64(pip.y));
|
||||||
|
@ -407,7 +377,7 @@ void MergeWindowContours (const std::vector<IfcVector2>& a,
|
||||||
std::reverse(clip.begin(), clip.end());
|
std::reverse(clip.begin(), clip.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
clipper.AddPolygon(clip, ClipperLib::ptSubject);
|
clipper.AddPath(clip, ClipperLib::ptSubject, true);
|
||||||
clip.clear();
|
clip.clear();
|
||||||
|
|
||||||
for(const IfcVector2& pip : b) {
|
for(const IfcVector2& pip : b) {
|
||||||
|
@ -418,7 +388,7 @@ void MergeWindowContours (const std::vector<IfcVector2>& a,
|
||||||
std::reverse(clip.begin(), clip.end());
|
std::reverse(clip.begin(), clip.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
clipper.AddPolygon(clip, ClipperLib::ptSubject);
|
clipper.AddPath(clip, ClipperLib::ptSubject, true);
|
||||||
clipper.Execute(ClipperLib::ctUnion, out,ClipperLib::pftNonZero,ClipperLib::pftNonZero);
|
clipper.Execute(ClipperLib::ctUnion, out,ClipperLib::pftNonZero,ClipperLib::pftNonZero);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -426,13 +396,11 @@ void MergeWindowContours (const std::vector<IfcVector2>& a,
|
||||||
// Subtract a from b
|
// Subtract a from b
|
||||||
void MakeDisjunctWindowContours (const std::vector<IfcVector2>& a,
|
void MakeDisjunctWindowContours (const std::vector<IfcVector2>& a,
|
||||||
const std::vector<IfcVector2>& b,
|
const std::vector<IfcVector2>& b,
|
||||||
ClipperLib::ExPolygons& out)
|
ClipperLib::Paths& out) {
|
||||||
{
|
|
||||||
out.clear();
|
out.clear();
|
||||||
|
|
||||||
ClipperLib::Clipper clipper;
|
ClipperLib::Clipper clipper;
|
||||||
ClipperLib::Polygon clip;
|
ClipperLib::Path clip;
|
||||||
|
|
||||||
for(const IfcVector2& pip : a) {
|
for(const IfcVector2& pip : a) {
|
||||||
clip.emplace_back(to_int64(pip.x), to_int64(pip.y));
|
clip.emplace_back(to_int64(pip.x), to_int64(pip.y));
|
||||||
}
|
}
|
||||||
|
@ -441,7 +409,7 @@ void MakeDisjunctWindowContours (const std::vector<IfcVector2>& a,
|
||||||
std::reverse(clip.begin(), clip.end());
|
std::reverse(clip.begin(), clip.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
clipper.AddPolygon(clip, ClipperLib::ptClip);
|
clipper.AddPath(clip, ClipperLib::ptClip, true);
|
||||||
clip.clear();
|
clip.clear();
|
||||||
|
|
||||||
for(const IfcVector2& pip : b) {
|
for(const IfcVector2& pip : b) {
|
||||||
|
@ -452,30 +420,28 @@ void MakeDisjunctWindowContours (const std::vector<IfcVector2>& a,
|
||||||
std::reverse(clip.begin(), clip.end());
|
std::reverse(clip.begin(), clip.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
clipper.AddPolygon(clip, ClipperLib::ptSubject);
|
clipper.AddPath(clip, ClipperLib::ptSubject, true);
|
||||||
clipper.Execute(ClipperLib::ctDifference, out,ClipperLib::pftNonZero,ClipperLib::pftNonZero);
|
clipper.Execute(ClipperLib::ctDifference, out,ClipperLib::pftNonZero,ClipperLib::pftNonZero);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void CleanupWindowContour(ProjectedWindowContour& window)
|
void CleanupWindowContour(ProjectedWindowContour& window) {
|
||||||
{
|
|
||||||
std::vector<IfcVector2> scratch;
|
std::vector<IfcVector2> scratch;
|
||||||
std::vector<IfcVector2>& contour = window.contour;
|
std::vector<IfcVector2>& contour = window.contour;
|
||||||
|
|
||||||
ClipperLib::Polygon subject;
|
ClipperLib::Path subject;
|
||||||
ClipperLib::Clipper clipper;
|
ClipperLib::Clipper clipper;
|
||||||
ClipperLib::ExPolygons clipped;
|
ClipperLib::Paths clipped;
|
||||||
|
|
||||||
for(const IfcVector2& pip : contour) {
|
for(const IfcVector2& pip : contour) {
|
||||||
subject.emplace_back(to_int64(pip.x), to_int64(pip.y));
|
subject.emplace_back(to_int64(pip.x), to_int64(pip.y));
|
||||||
}
|
}
|
||||||
|
|
||||||
clipper.AddPolygon(subject,ClipperLib::ptSubject);
|
clipper.AddPath(subject,ClipperLib::ptSubject, true);
|
||||||
clipper.Execute(ClipperLib::ctUnion,clipped,ClipperLib::pftNonZero,ClipperLib::pftNonZero);
|
clipper.Execute(ClipperLib::ctUnion,clipped,ClipperLib::pftNonZero,ClipperLib::pftNonZero);
|
||||||
|
|
||||||
// This should yield only one polygon or something went wrong
|
// This should yield only one polygon or something went wrong
|
||||||
if (clipped.size() != 1) {
|
if (clipped.size() != 1) {
|
||||||
|
|
||||||
// Empty polygon? drop the contour altogether
|
// Empty polygon? drop the contour altogether
|
||||||
if(clipped.empty()) {
|
if(clipped.empty()) {
|
||||||
IFCImporter::LogError("error during polygon clipping, window contour is degenerate");
|
IFCImporter::LogError("error during polygon clipping, window contour is degenerate");
|
||||||
|
@ -487,28 +453,25 @@ void CleanupWindowContour(ProjectedWindowContour& window)
|
||||||
IFCImporter::LogError("error during polygon clipping, window contour is not convex");
|
IFCImporter::LogError("error during polygon clipping, window contour is not convex");
|
||||||
}
|
}
|
||||||
|
|
||||||
ExtractVerticesFromClipper(clipped[0].outer, scratch);
|
|
||||||
// Assume the bounding box doesn't change during this operation
|
// Assume the bounding box doesn't change during this operation
|
||||||
|
ExtractVerticesFromClipper(clipped[0], scratch);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void CleanupWindowContours(ContourVector& contours)
|
void CleanupWindowContours(ContourVector& contours) {
|
||||||
{
|
|
||||||
// Use PolyClipper to clean up window contours
|
// Use PolyClipper to clean up window contours
|
||||||
try {
|
try {
|
||||||
for(ProjectedWindowContour& window : contours) {
|
for(ProjectedWindowContour& window : contours) {
|
||||||
CleanupWindowContour(window);
|
CleanupWindowContour(window);
|
||||||
}
|
}
|
||||||
}
|
} catch (const char* sx) {
|
||||||
catch (const char* sx) {
|
|
||||||
IFCImporter::LogError("error during polygon clipping, window shape may be wrong: (Clipper: "
|
IFCImporter::LogError("error during polygon clipping, window shape may be wrong: (Clipper: "
|
||||||
+ std::string(sx) + ")");
|
+ std::string(sx) + ")");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void CleanupOuterContour(const std::vector<IfcVector2>& contour_flat, TempMesh& curmesh)
|
void CleanupOuterContour(const std::vector<IfcVector2>& contour_flat, TempMesh& curmesh) {
|
||||||
{
|
|
||||||
std::vector<IfcVector3> vold;
|
std::vector<IfcVector3> vold;
|
||||||
std::vector<unsigned int> iold;
|
std::vector<unsigned int> iold;
|
||||||
|
|
||||||
|
@ -517,12 +480,11 @@ void CleanupOuterContour(const std::vector<IfcVector2>& contour_flat, TempMesh&
|
||||||
|
|
||||||
// Fix the outer contour using polyclipper
|
// Fix the outer contour using polyclipper
|
||||||
try {
|
try {
|
||||||
|
ClipperLib::Path subject;
|
||||||
ClipperLib::Polygon subject;
|
|
||||||
ClipperLib::Clipper clipper;
|
ClipperLib::Clipper clipper;
|
||||||
ClipperLib::ExPolygons clipped;
|
ClipperLib::Paths clipped;
|
||||||
|
|
||||||
ClipperLib::Polygon clip;
|
ClipperLib::Path clip;
|
||||||
clip.reserve(contour_flat.size());
|
clip.reserve(contour_flat.size());
|
||||||
for(const IfcVector2& pip : contour_flat) {
|
for(const IfcVector2& pip : contour_flat) {
|
||||||
clip.emplace_back(to_int64(pip.x), to_int64(pip.y));
|
clip.emplace_back(to_int64(pip.x), to_int64(pip.y));
|
||||||
|
@ -551,18 +513,15 @@ void CleanupOuterContour(const std::vector<IfcVector2>& contour_flat, TempMesh&
|
||||||
std::reverse(subject.begin(), subject.end());
|
std::reverse(subject.begin(), subject.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
clipper.AddPolygon(subject,ClipperLib::ptSubject);
|
clipper.AddPath(subject,ClipperLib::ptSubject, true);
|
||||||
clipper.AddPolygon(clip,ClipperLib::ptClip);
|
clipper.AddPath(clip,ClipperLib::ptClip, true);
|
||||||
|
|
||||||
clipper.Execute(ClipperLib::ctIntersection,clipped,ClipperLib::pftNonZero,ClipperLib::pftNonZero);
|
clipper.Execute(ClipperLib::ctIntersection,clipped,ClipperLib::pftNonZero,ClipperLib::pftNonZero);
|
||||||
|
|
||||||
for(const ClipperLib::ExPolygon& ex : clipped) {
|
for(const ClipperLib::Path& ex : clipped) {
|
||||||
iold.push_back(static_cast<unsigned int>(ex.outer.size()));
|
iold.push_back(static_cast<unsigned int>(ex.size()));
|
||||||
for(const ClipperLib::IntPoint& point : ex.outer) {
|
for(const ClipperLib::IntPoint& point : ex) {
|
||||||
vold.emplace_back(
|
vold.emplace_back(from_int64(point.X), from_int64(point.Y), 0.0f);
|
||||||
from_int64(point.X),
|
|
||||||
from_int64(point.Y),
|
|
||||||
0.0f);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -571,8 +530,7 @@ void CleanupOuterContour(const std::vector<IfcVector2>& contour_flat, TempMesh&
|
||||||
clipper.Clear();
|
clipper.Clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} catch (const char* sx) {
|
||||||
catch (const char* sx) {
|
|
||||||
IFCImporter::LogError("Ifc: error during polygon clipping, wall contour line may be wrong: (Clipper: "
|
IFCImporter::LogError("Ifc: error during polygon clipping, wall contour line may be wrong: (Clipper: "
|
||||||
+ std::string(sx) + ")");
|
+ std::string(sx) + ")");
|
||||||
|
|
||||||
|
@ -584,17 +542,14 @@ void CleanupOuterContour(const std::vector<IfcVector2>& contour_flat, TempMesh&
|
||||||
std::swap(iold,curmesh.mVertcnt);
|
std::swap(iold,curmesh.mVertcnt);
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef std::vector<TempOpening*> OpeningRefs;
|
using OpeningRefs = std::vector<TempOpening*> ;
|
||||||
typedef std::vector<OpeningRefs > OpeningRefVector;
|
using OpeningRefVector = std::vector<OpeningRefs >;
|
||||||
|
using ContourRefVector = std::vector<std::pair<
|
||||||
typedef std::vector<std::pair<
|
|
||||||
ContourVector::const_iterator,
|
ContourVector::const_iterator,
|
||||||
Contour::const_iterator>
|
Contour::const_iterator> >;
|
||||||
> ContourRefVector;
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
bool BoundingBoxesAdjacent(const BoundingBox& bb, const BoundingBox& ibb)
|
bool BoundingBoxesAdjacent(const BoundingBox& bb, const BoundingBox& ibb) {
|
||||||
{
|
|
||||||
// TODO: I'm pretty sure there is a much more compact way to check this
|
// TODO: I'm pretty sure there is a much more compact way to check this
|
||||||
const IfcFloat epsilon = Math::getEpsilon<float>();
|
const IfcFloat epsilon = Math::getEpsilon<float>();
|
||||||
return (std::fabs(bb.second.x - ibb.first.x) < epsilon && bb.first.y <= ibb.second.y && bb.second.y >= ibb.first.y) ||
|
return (std::fabs(bb.second.x - ibb.first.x) < epsilon && bb.first.y <= ibb.second.y && bb.second.y >= ibb.first.y) ||
|
||||||
|
@ -608,8 +563,7 @@ bool BoundingBoxesAdjacent(const BoundingBox& bb, const BoundingBox& ibb)
|
||||||
// output the intersection points on n0,n1
|
// output the intersection points on n0,n1
|
||||||
bool IntersectingLineSegments(const IfcVector2& n0, const IfcVector2& n1,
|
bool IntersectingLineSegments(const IfcVector2& n0, const IfcVector2& n1,
|
||||||
const IfcVector2& m0, const IfcVector2& m1,
|
const IfcVector2& m0, const IfcVector2& m1,
|
||||||
IfcVector2& out0, IfcVector2& out1)
|
IfcVector2& out0, IfcVector2& out1) {
|
||||||
{
|
|
||||||
const IfcVector2 n0_to_n1 = n1 - n0;
|
const IfcVector2 n0_to_n1 = n1 - n0;
|
||||||
|
|
||||||
const IfcVector2 n0_to_m0 = m0 - n0;
|
const IfcVector2 n0_to_m0 = m0 - n0;
|
||||||
|
@ -648,8 +602,7 @@ bool IntersectingLineSegments(const IfcVector2& n0, const IfcVector2& n1,
|
||||||
if (std::fabs(s1) == inf && std::fabs(n0_to_m1.x) < smalle) {
|
if (std::fabs(s1) == inf && std::fabs(n0_to_m1.x) < smalle) {
|
||||||
s1 = 0.;
|
s1 = 0.;
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
s0 = n0_to_m0.y / n0_to_n1.y;
|
s0 = n0_to_m0.y / n0_to_n1.y;
|
||||||
s1 = n0_to_m1.y / n0_to_n1.y;
|
s1 = n0_to_m1.y / n0_to_n1.y;
|
||||||
|
|
||||||
|
@ -682,8 +635,7 @@ bool IntersectingLineSegments(const IfcVector2& n0, const IfcVector2& n1,
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void FindAdjacentContours(ContourVector::iterator current, const ContourVector& contours)
|
void FindAdjacentContours(ContourVector::iterator current, const ContourVector& contours) {
|
||||||
{
|
|
||||||
const IfcFloat sqlen_epsilon = static_cast<IfcFloat>(Math::getEpsilon<float>());
|
const IfcFloat sqlen_epsilon = static_cast<IfcFloat>(Math::getEpsilon<float>());
|
||||||
const BoundingBox& bb = (*current).bb;
|
const BoundingBox& bb = (*current).bb;
|
||||||
|
|
||||||
|
@ -698,13 +650,6 @@ void FindAdjacentContours(ContourVector::iterator current, const ContourVector&
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// this left here to make clear we also run on the current contour
|
|
||||||
// to check for overlapping contour segments (which can happen due
|
|
||||||
// to projection artifacts).
|
|
||||||
//if(it == current) {
|
|
||||||
// continue;
|
|
||||||
//}
|
|
||||||
|
|
||||||
const bool is_me = it == current;
|
const bool is_me = it == current;
|
||||||
|
|
||||||
const BoundingBox& ibb = (*it).bb;
|
const BoundingBox& ibb = (*it).bb;
|
||||||
|
@ -740,8 +685,7 @@ void FindAdjacentContours(ContourVector::iterator current, const ContourVector&
|
||||||
|
|
||||||
ncontour.insert(ncontour.begin() + n, isect0);
|
ncontour.insert(ncontour.begin() + n, isect0);
|
||||||
skiplist.insert(skiplist.begin() + n, true);
|
skiplist.insert(skiplist.begin() + n, true);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
skiplist[n] = true;
|
skiplist[n] = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -759,15 +703,13 @@ void FindAdjacentContours(ContourVector::iterator current, const ContourVector&
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
AI_FORCE_INLINE bool LikelyBorder(const IfcVector2& vdelta)
|
AI_FORCE_INLINE bool LikelyBorder(const IfcVector2& vdelta) {
|
||||||
{
|
|
||||||
const IfcFloat dot_point_epsilon = static_cast<IfcFloat>(Math::getEpsilon<float>());
|
const IfcFloat dot_point_epsilon = static_cast<IfcFloat>(Math::getEpsilon<float>());
|
||||||
return std::fabs(vdelta.x * vdelta.y) < dot_point_epsilon;
|
return std::fabs(vdelta.x * vdelta.y) < dot_point_epsilon;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void FindBorderContours(ContourVector::iterator current)
|
void FindBorderContours(ContourVector::iterator current) {
|
||||||
{
|
|
||||||
const IfcFloat border_epsilon_upper = static_cast<IfcFloat>(1-1e-4);
|
const IfcFloat border_epsilon_upper = static_cast<IfcFloat>(1-1e-4);
|
||||||
const IfcFloat border_epsilon_lower = static_cast<IfcFloat>(1e-4);
|
const IfcFloat border_epsilon_lower = static_cast<IfcFloat>(1e-4);
|
||||||
|
|
||||||
|
@ -787,20 +729,17 @@ void FindBorderContours(ContourVector::iterator current)
|
||||||
// not have any geometry to close them (think of door openings).
|
// not have any geometry to close them (think of door openings).
|
||||||
if (proj_point.x <= border_epsilon_lower || proj_point.x >= border_epsilon_upper ||
|
if (proj_point.x <= border_epsilon_lower || proj_point.x >= border_epsilon_upper ||
|
||||||
proj_point.y <= border_epsilon_lower || proj_point.y >= border_epsilon_upper) {
|
proj_point.y <= border_epsilon_lower || proj_point.y >= border_epsilon_upper) {
|
||||||
|
|
||||||
if (outer_border) {
|
if (outer_border) {
|
||||||
ai_assert(cit != cbegin);
|
ai_assert(cit != cbegin);
|
||||||
if (LikelyBorder(proj_point - last_proj_point)) {
|
if (LikelyBorder(proj_point - last_proj_point)) {
|
||||||
skiplist[std::distance(cbegin, cit) - 1] = true;
|
skiplist[std::distance(cbegin, cit) - 1] = true;
|
||||||
}
|
}
|
||||||
}
|
} else if (cit == cbegin) {
|
||||||
else if (cit == cbegin) {
|
|
||||||
start_on_outer_border = true;
|
start_on_outer_border = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
outer_border = true;
|
outer_border = true;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
outer_border = false;
|
outer_border = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -817,16 +756,14 @@ void FindBorderContours(ContourVector::iterator current)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
AI_FORCE_INLINE bool LikelyDiagonal(IfcVector2 vdelta)
|
AI_FORCE_INLINE bool LikelyDiagonal(IfcVector2 vdelta) {
|
||||||
{
|
|
||||||
vdelta.x = std::fabs(vdelta.x);
|
vdelta.x = std::fabs(vdelta.x);
|
||||||
vdelta.y = std::fabs(vdelta.y);
|
vdelta.y = std::fabs(vdelta.y);
|
||||||
return (std::fabs(vdelta.x-vdelta.y) < 0.8 * std::max(vdelta.x, vdelta.y));
|
return (std::fabs(vdelta.x-vdelta.y) < 0.8 * std::max(vdelta.x, vdelta.y));
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void FindLikelyCrossingLines(ContourVector::iterator current)
|
void FindLikelyCrossingLines(ContourVector::iterator current) {
|
||||||
{
|
|
||||||
SkipList& skiplist = (*current).skiplist;
|
SkipList& skiplist = (*current).skiplist;
|
||||||
IfcVector2 last_proj_point;
|
IfcVector2 last_proj_point;
|
||||||
|
|
||||||
|
@ -854,8 +791,7 @@ void FindLikelyCrossingLines(ContourVector::iterator current)
|
||||||
size_t CloseWindows(ContourVector& contours,
|
size_t CloseWindows(ContourVector& contours,
|
||||||
const IfcMatrix4& minv,
|
const IfcMatrix4& minv,
|
||||||
OpeningRefVector& contours_to_openings,
|
OpeningRefVector& contours_to_openings,
|
||||||
TempMesh& curmesh)
|
TempMesh& curmesh) {
|
||||||
{
|
|
||||||
size_t closed = 0;
|
size_t closed = 0;
|
||||||
// For all contour points, check if one of the assigned openings does
|
// For all contour points, check if one of the assigned openings does
|
||||||
// already have points assigned to it. In this case, assume this is
|
// already have points assigned to it. In this case, assume this is
|
||||||
|
@ -964,8 +900,7 @@ size_t CloseWindows(ContourVector& contours,
|
||||||
if (drop_this_edge) {
|
if (drop_this_edge) {
|
||||||
curmesh.mVerts.pop_back();
|
curmesh.mVerts.pop_back();
|
||||||
curmesh.mVerts.pop_back();
|
curmesh.mVerts.pop_back();
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
curmesh.mVerts.push_back(((cit == cbegin) != reverseCountourFaces) ? world_point : bestv);
|
curmesh.mVerts.push_back(((cit == cbegin) != reverseCountourFaces) ? world_point : bestv);
|
||||||
curmesh.mVerts.push_back(((cit == cbegin) != reverseCountourFaces) ? bestv : world_point);
|
curmesh.mVerts.push_back(((cit == cbegin) != reverseCountourFaces) ? bestv : world_point);
|
||||||
|
|
||||||
|
@ -992,16 +927,13 @@ size_t CloseWindows(ContourVector& contours,
|
||||||
curmesh.mVertcnt.pop_back();
|
curmesh.mVertcnt.pop_back();
|
||||||
curmesh.mVerts.pop_back();
|
curmesh.mVerts.pop_back();
|
||||||
curmesh.mVerts.pop_back();
|
curmesh.mVerts.pop_back();
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
curmesh.mVerts.push_back(reverseCountourFaces ? start0 : start1);
|
curmesh.mVerts.push_back(reverseCountourFaces ? start0 : start1);
|
||||||
curmesh.mVerts.push_back(reverseCountourFaces ? start1 : start0);
|
curmesh.mVerts.push_back(reverseCountourFaces ? start1 : start0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
|
|
||||||
const Contour::const_iterator cbegin = (*it).contour.begin(), cend = (*it).contour.end();
|
const Contour::const_iterator cbegin = (*it).contour.begin(), cend = (*it).contour.end();
|
||||||
for(TempOpening* opening : refs) {
|
for(TempOpening* opening : refs) {
|
||||||
ai_assert(opening->wallPoints.empty());
|
ai_assert(opening->wallPoints.empty());
|
||||||
|
@ -1018,8 +950,7 @@ size_t CloseWindows(ContourVector& contours,
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void Quadrify(const std::vector< BoundingBox >& bbs, TempMesh& curmesh)
|
void Quadrify(const std::vector< BoundingBox >& bbs, TempMesh& curmesh) {
|
||||||
{
|
|
||||||
ai_assert(curmesh.IsEmpty());
|
ai_assert(curmesh.IsEmpty());
|
||||||
|
|
||||||
std::vector<IfcVector2> quads;
|
std::vector<IfcVector2> quads;
|
||||||
|
@ -1045,8 +976,7 @@ void Quadrify(const std::vector< BoundingBox >& bbs, TempMesh& curmesh)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void Quadrify(const ContourVector& contours, TempMesh& curmesh)
|
void Quadrify(const ContourVector& contours, TempMesh& curmesh) {
|
||||||
{
|
|
||||||
std::vector<BoundingBox> bbs;
|
std::vector<BoundingBox> bbs;
|
||||||
bbs.reserve(contours.size());
|
bbs.reserve(contours.size());
|
||||||
|
|
||||||
|
@ -1058,12 +988,17 @@ void Quadrify(const ContourVector& contours, TempMesh& curmesh)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
IfcMatrix4 ProjectOntoPlane(std::vector<IfcVector2>& out_contour, const TempMesh& in_mesh,
|
IfcMatrix4 ProjectOntoPlane(std::vector<IfcVector2>& out_contour,
|
||||||
bool &ok, IfcVector3& nor_out)
|
const TempMesh& in_mesh,
|
||||||
{
|
bool &ok,
|
||||||
|
IfcVector3& nor_out) {
|
||||||
const std::vector<IfcVector3>& in_verts = in_mesh.mVerts;
|
const std::vector<IfcVector3>& in_verts = in_mesh.mVerts;
|
||||||
ok = true;
|
if (in_verts.empty()){
|
||||||
|
ok = false;
|
||||||
|
return IfcMatrix4();
|
||||||
|
}
|
||||||
|
|
||||||
|
ok = true;
|
||||||
IfcMatrix4 m = IfcMatrix4(DerivePlaneCoordinateSpace(in_mesh, ok, nor_out));
|
IfcMatrix4 m = IfcMatrix4(DerivePlaneCoordinateSpace(in_mesh, ok, nor_out));
|
||||||
if(!ok) {
|
if(!ok) {
|
||||||
return IfcMatrix4();
|
return IfcMatrix4();
|
||||||
|
@ -1076,7 +1011,6 @@ IfcMatrix4 ProjectOntoPlane(std::vector<IfcVector2>& out_contour, const TempMesh
|
||||||
IfcFloat zcoord = 0;
|
IfcFloat zcoord = 0;
|
||||||
out_contour.reserve(in_verts.size());
|
out_contour.reserve(in_verts.size());
|
||||||
|
|
||||||
|
|
||||||
IfcVector3 vmin, vmax;
|
IfcVector3 vmin, vmax;
|
||||||
MinMaxChooser<IfcVector3>()(vmin, vmax);
|
MinMaxChooser<IfcVector3>()(vmin, vmax);
|
||||||
|
|
||||||
|
@ -1087,11 +1021,6 @@ IfcMatrix4 ProjectOntoPlane(std::vector<IfcVector2>& out_contour, const TempMesh
|
||||||
// (which are present, of course), this should be the same value for
|
// (which are present, of course), this should be the same value for
|
||||||
// all polygon vertices (assuming the polygon is planar).
|
// all polygon vertices (assuming the polygon is planar).
|
||||||
|
|
||||||
// XXX this should be guarded, but we somehow need to pick a suitable
|
|
||||||
// epsilon
|
|
||||||
// if(coord != -1.0f) {
|
|
||||||
// assert(std::fabs(coord - vv.z) < 1e-3f);
|
|
||||||
// }
|
|
||||||
zcoord += vv.z;
|
zcoord += vv.z;
|
||||||
vmin = std::min(vv, vmin);
|
vmin = std::min(vv, vmin);
|
||||||
vmax = std::max(vv, vmax);
|
vmax = std::max(vv, vmax);
|
||||||
|
@ -1146,8 +1075,7 @@ bool GenerateOpenings(std::vector<TempOpening>& openings,
|
||||||
TempMesh& curmesh,
|
TempMesh& curmesh,
|
||||||
bool check_intersection,
|
bool check_intersection,
|
||||||
bool generate_connection_geometry,
|
bool generate_connection_geometry,
|
||||||
const IfcVector3& wall_extrusion_axis)
|
const IfcVector3& wall_extrusion_axis) {
|
||||||
{
|
|
||||||
OpeningRefVector contours_to_openings;
|
OpeningRefVector contours_to_openings;
|
||||||
|
|
||||||
// Try to derive a solid base plane within the current surface for use as
|
// Try to derive a solid base plane within the current surface for use as
|
||||||
|
@ -1183,8 +1111,7 @@ bool GenerateOpenings(std::vector<TempOpening>& openings,
|
||||||
IfcVector3 norm_extrusion_dir = opening.extrusionDir;
|
IfcVector3 norm_extrusion_dir = opening.extrusionDir;
|
||||||
if (norm_extrusion_dir.SquareLength() > 1e-10) {
|
if (norm_extrusion_dir.SquareLength() > 1e-10) {
|
||||||
norm_extrusion_dir.Normalize();
|
norm_extrusion_dir.Normalize();
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
norm_extrusion_dir = IfcVector3();
|
norm_extrusion_dir = IfcVector3();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1249,10 +1176,8 @@ bool GenerateOpenings(std::vector<TempOpening>& openings,
|
||||||
const IfcVector3 v = m * x;
|
const IfcVector3 v = m * x;
|
||||||
IfcVector2 vv(v.x, v.y);
|
IfcVector2 vv(v.x, v.y);
|
||||||
|
|
||||||
//if(check_intersection) {
|
|
||||||
dmin = std::min(dmin, v.z);
|
dmin = std::min(dmin, v.z);
|
||||||
dmax = std::max(dmax, v.z);
|
dmax = std::max(dmax, v.z);
|
||||||
//}
|
|
||||||
|
|
||||||
// sanity rounding
|
// sanity rounding
|
||||||
vv = std::max(vv,IfcVector2());
|
vv = std::max(vv,IfcVector2());
|
||||||
|
@ -1261,8 +1186,7 @@ bool GenerateOpenings(std::vector<TempOpening>& openings,
|
||||||
if(side_flag) {
|
if(side_flag) {
|
||||||
vpmin = std::min(vpmin,vv);
|
vpmin = std::min(vpmin,vv);
|
||||||
vpmax = std::max(vpmax,vv);
|
vpmax = std::max(vpmax,vv);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
vpmin2 = std::min(vpmin2,vv);
|
vpmin2 = std::min(vpmin2,vv);
|
||||||
vpmax2 = std::max(vpmax2,vv);
|
vpmax2 = std::max(vpmax2,vv);
|
||||||
}
|
}
|
||||||
|
@ -1310,28 +1234,25 @@ bool GenerateOpenings(std::vector<TempOpening>& openings,
|
||||||
// See if this BB intersects or is in close adjacency to any other BB we have so far.
|
// See if this BB intersects or is in close adjacency to any other BB we have so far.
|
||||||
for (ContourVector::iterator it = contours.begin(); it != contours.end(); ) {
|
for (ContourVector::iterator it = contours.begin(); it != contours.end(); ) {
|
||||||
const BoundingBox& ibb = (*it).bb;
|
const BoundingBox& ibb = (*it).bb;
|
||||||
|
|
||||||
if (BoundingBoxesOverlapping(ibb, bb)) {
|
if (BoundingBoxesOverlapping(ibb, bb)) {
|
||||||
|
|
||||||
if (!(*it).is_rectangular) {
|
if (!(*it).is_rectangular) {
|
||||||
is_rectangle = false;
|
is_rectangle = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::vector<IfcVector2>& other = (*it).contour;
|
const std::vector<IfcVector2>& other = (*it).contour;
|
||||||
ClipperLib::ExPolygons poly;
|
ClipperLib::Paths poly;
|
||||||
|
|
||||||
// First check whether subtracting the old contour (to which ibb belongs)
|
// First check whether subtracting the old contour (to which ibb belongs)
|
||||||
// from the new contour (to which bb belongs) yields an updated bb which
|
// from the new contour (to which bb belongs) yields an updated bb which
|
||||||
// no longer overlaps ibb
|
// no longer overlaps ibb
|
||||||
MakeDisjunctWindowContours(other, temp_contour, poly);
|
MakeDisjunctWindowContours(other, temp_contour, poly);
|
||||||
if(poly.size() == 1) {
|
if(poly.size() == 1) {
|
||||||
|
const BoundingBox newbb = GetBoundingBox(poly[0]);
|
||||||
const BoundingBox newbb = GetBoundingBox(poly[0].outer);
|
|
||||||
if (!BoundingBoxesOverlapping(ibb, newbb )) {
|
if (!BoundingBoxesOverlapping(ibb, newbb )) {
|
||||||
// Good guy bounding box
|
// Good guy bounding box
|
||||||
bb = newbb ;
|
bb = newbb ;
|
||||||
|
|
||||||
ExtractVerticesFromClipper(poly[0].outer, temp_contour, false);
|
ExtractVerticesFromClipper(poly[0], temp_contour, false);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1343,15 +1264,13 @@ bool GenerateOpenings(std::vector<TempOpening>& openings,
|
||||||
|
|
||||||
if (poly.size() > 1) {
|
if (poly.size() > 1) {
|
||||||
return TryAddOpenings_Poly2Tri(openings, curmesh);
|
return TryAddOpenings_Poly2Tri(openings, curmesh);
|
||||||
}
|
} else if (poly.empty()) {
|
||||||
else if (poly.size() == 0) {
|
|
||||||
IFCImporter::LogWarn("ignoring duplicate opening");
|
IFCImporter::LogWarn("ignoring duplicate opening");
|
||||||
temp_contour.clear();
|
temp_contour.clear();
|
||||||
break;
|
break;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
IFCImporter::LogVerboseDebug("merging overlapping openings");
|
IFCImporter::LogVerboseDebug("merging overlapping openings");
|
||||||
ExtractVerticesFromClipper(poly[0].outer, temp_contour, false);
|
ExtractVerticesFromClipper(poly[0], temp_contour, false);
|
||||||
|
|
||||||
// Generate the union of the bounding boxes
|
// Generate the union of the bounding boxes
|
||||||
bb.first = std::min(bb.first, ibb.first);
|
bb.first = std::min(bb.first, ibb.first);
|
||||||
|
@ -1429,9 +1348,14 @@ bool GenerateOpenings(std::vector<TempOpening>& openings,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<IfcVector2> GetContourInPlane2D(const std::shared_ptr<TempMesh>& mesh,IfcMatrix3 planeSpace,
|
std::vector<IfcVector2> GetContourInPlane2D(const std::shared_ptr<TempMesh>& mesh,
|
||||||
IfcVector3 planeNor,IfcFloat planeOffset,
|
IfcMatrix3 planeSpace,
|
||||||
IfcVector3 extrusionDir,IfcVector3& wall_extrusion,bool& first,bool& ok) {
|
IfcVector3 planeNor,
|
||||||
|
IfcFloat planeOffset,
|
||||||
|
IfcVector3 extrusionDir,
|
||||||
|
IfcVector3& wall_extrusion,
|
||||||
|
bool& first,
|
||||||
|
bool& ok) {
|
||||||
std::vector<IfcVector2> contour;
|
std::vector<IfcVector2> contour;
|
||||||
|
|
||||||
const auto outernor = ((mesh->mVerts[2] - mesh->mVerts[0]) ^ (mesh->mVerts[1] - mesh->mVerts[0])).Normalize();
|
const auto outernor = ((mesh->mVerts[2] - mesh->mVerts[0]) ^ (mesh->mVerts[1] - mesh->mVerts[0])).Normalize();
|
||||||
|
@ -1448,7 +1372,7 @@ std::vector<IfcVector2> GetContourInPlane2D(const std::shared_ptr<TempMesh>& mes
|
||||||
const std::vector<IfcVector3>& va = mesh->mVerts;
|
const std::vector<IfcVector3>& va = mesh->mVerts;
|
||||||
if(va.size() <= 2) {
|
if(va.size() <= 2) {
|
||||||
std::stringstream msg;
|
std::stringstream msg;
|
||||||
msg << "Skipping: Only " << va.size() << " verticies in opening mesh.";
|
msg << "Skipping: Only " << va.size() << " vertices in opening mesh.";
|
||||||
IFCImporter::LogDebug(msg.str().c_str());
|
IFCImporter::LogDebug(msg.str().c_str());
|
||||||
ok = false;
|
ok = false;
|
||||||
return contour;
|
return contour;
|
||||||
|
@ -1494,7 +1418,6 @@ static void logSegment(std::pair<IfcVector2,IfcVector2> segment) {
|
||||||
|
|
||||||
std::vector<std::vector<IfcVector2>> GetContoursInPlane3D(const std::shared_ptr<TempMesh>& mesh,IfcMatrix3 planeSpace,
|
std::vector<std::vector<IfcVector2>> GetContoursInPlane3D(const std::shared_ptr<TempMesh>& mesh,IfcMatrix3 planeSpace,
|
||||||
IfcFloat planeOffset) {
|
IfcFloat planeOffset) {
|
||||||
|
|
||||||
{
|
{
|
||||||
std::stringstream msg;
|
std::stringstream msg;
|
||||||
msg << "GetContoursInPlane3D: planeSpace is \n";
|
msg << "GetContoursInPlane3D: planeSpace is \n";
|
||||||
|
@ -1521,8 +1444,8 @@ std::vector<std::vector<IfcVector2>> GetContoursInPlane3D(const std::shared_ptr<
|
||||||
IFCImporter::LogInfo(msg.str().c_str());
|
IFCImporter::LogInfo(msg.str().c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
if(nVertices <= 2) // not a plane, a point or line
|
// not a plane, a point or line
|
||||||
{
|
if(nVertices <= 2) {
|
||||||
std::stringstream msg;
|
std::stringstream msg;
|
||||||
msg << "GetContoursInPlane3D: found point or line when expecting plane (only " << nVertices << " vertices)";
|
msg << "GetContoursInPlane3D: found point or line when expecting plane (only " << nVertices << " vertices)";
|
||||||
IFCImporter::LogWarn(msg.str().c_str());
|
IFCImporter::LogWarn(msg.str().c_str());
|
||||||
|
@ -1552,15 +1475,12 @@ std::vector<std::vector<IfcVector2>> GetContoursInPlane3D(const std::shared_ptr<
|
||||||
if(std::fabs(vn.z - planeOffset) < close) {
|
if(std::fabs(vn.z - planeOffset) < close) {
|
||||||
// on the plane
|
// on the plane
|
||||||
intersection = vn;
|
intersection = vn;
|
||||||
}
|
} else if((vn.z > planeOffset) != (vp.z > planeOffset)) {
|
||||||
else if((vn.z > planeOffset) != (vp.z > planeOffset))
|
|
||||||
{
|
|
||||||
// passes through the plane
|
// passes through the plane
|
||||||
auto vdir = vn - vp;
|
auto vdir = vn - vp;
|
||||||
auto scale = (planeOffset - vp.z) / vdir.z;
|
auto scale = (planeOffset - vp.z) / vdir.z;
|
||||||
intersection = vp + scale * vdir;
|
intersection = vp + scale * vdir;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
// nowhere near - move on
|
// nowhere near - move on
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -1575,15 +1495,13 @@ std::vector<std::vector<IfcVector2>> GetContoursInPlane3D(const std::shared_ptr<
|
||||||
logSegment(s);
|
logSegment(s);
|
||||||
lineSegments.push_back(s);
|
lineSegments.push_back(s);
|
||||||
// next firstpoint should be this one
|
// next firstpoint should be this one
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
// store the first intersection point
|
// store the first intersection point
|
||||||
firstPoint.x = intersection.x;
|
firstPoint.x = intersection.x;
|
||||||
firstPoint.y = intersection.y;
|
firstPoint.y = intersection.y;
|
||||||
gotFirstPoint = true;
|
gotFirstPoint = true;
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
// now got the second point, so store the pair
|
// now got the second point, so store the pair
|
||||||
IfcVector2 secondPoint(intersection.x,intersection.y);
|
IfcVector2 secondPoint(intersection.x,intersection.y);
|
||||||
auto s = std::pair<IfcVector2,IfcVector2>(firstPoint,secondPoint);
|
auto s = std::pair<IfcVector2,IfcVector2>(firstPoint,secondPoint);
|
||||||
|
@ -1691,29 +1609,28 @@ std::vector<std::vector<IfcVector2>> GetContoursInPlane3D(const std::shared_ptr<
|
||||||
return contours;
|
return contours;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::vector<IfcVector2>> GetContoursInPlane(const std::shared_ptr<TempMesh>& mesh,IfcMatrix3 planeSpace,
|
std::vector<std::vector<IfcVector2>> GetContoursInPlane(const std::shared_ptr<TempMesh>& mesh,
|
||||||
IfcVector3 planeNor,IfcFloat planeOffset,
|
IfcMatrix3 planeSpace,
|
||||||
IfcVector3 extrusionDir,IfcVector3& wall_extrusion,bool& first) {
|
IfcVector3 planeNor,
|
||||||
|
IfcFloat planeOffset,
|
||||||
if(mesh->mVertcnt.size() == 1)
|
IfcVector3 extrusionDir,
|
||||||
{
|
IfcVector3& wall_extrusion,
|
||||||
|
bool& first) {
|
||||||
|
if(mesh->mVertcnt.size() == 1) {
|
||||||
bool ok;
|
bool ok;
|
||||||
auto contour = GetContourInPlane2D(mesh,planeSpace,planeNor,planeOffset,extrusionDir,wall_extrusion,first,ok);
|
auto contour = GetContourInPlane2D(mesh,planeSpace,planeNor,planeOffset,extrusionDir,wall_extrusion,first,ok);
|
||||||
if(ok)
|
if(ok)
|
||||||
return std::vector<std::vector<IfcVector2>> {std::move(contour)};
|
return std::vector<std::vector<IfcVector2>> {std::move(contour)};
|
||||||
else
|
else
|
||||||
return std::vector<std::vector<IfcVector2>> {};
|
return std::vector<std::vector<IfcVector2>> {};
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
return GetContoursInPlane3D(mesh,planeSpace,planeOffset);
|
return GetContoursInPlane3D(mesh,planeSpace,planeOffset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
bool TryAddOpenings_Poly2Tri(const std::vector<TempOpening>& openings,
|
bool TryAddOpenings_Poly2Tri(const std::vector<TempOpening>& openings,
|
||||||
TempMesh& curmesh)
|
TempMesh& curmesh) {
|
||||||
{
|
|
||||||
IFCImporter::LogWarn("forced to use poly2tri fallback method to generate wall openings");
|
IFCImporter::LogWarn("forced to use poly2tri fallback method to generate wall openings");
|
||||||
std::vector<IfcVector3>& out = curmesh.mVerts;
|
std::vector<IfcVector3>& out = curmesh.mVerts;
|
||||||
|
|
||||||
|
@ -1746,14 +1663,6 @@ bool TryAddOpenings_Poly2Tri(const std::vector<TempOpening>& openings,
|
||||||
// keep Z offset in the plane coordinate system. Ignoring precision issues
|
// keep Z offset in the plane coordinate system. Ignoring precision issues
|
||||||
// (which are present, of course), this should be the same value for
|
// (which are present, of course), this should be the same value for
|
||||||
// all polygon vertices (assuming the polygon is planar).
|
// all polygon vertices (assuming the polygon is planar).
|
||||||
|
|
||||||
|
|
||||||
// XXX this should be guarded, but we somehow need to pick a suitable
|
|
||||||
// epsilon
|
|
||||||
// if(coord != -1.0f) {
|
|
||||||
// assert(std::fabs(coord - vv.z) < 1e-3f);
|
|
||||||
// }
|
|
||||||
|
|
||||||
coord = vv.z;
|
coord = vv.z;
|
||||||
|
|
||||||
vmin = std::min(IfcVector2(vv.x, vv.y), vmin);
|
vmin = std::min(IfcVector2(vv.x, vv.y), vmin);
|
||||||
|
@ -1771,15 +1680,13 @@ bool TryAddOpenings_Poly2Tri(const std::vector<TempOpening>& openings,
|
||||||
// If this happens then the projection must have been wrong.
|
// If this happens then the projection must have been wrong.
|
||||||
ai_assert(vmax.Length());
|
ai_assert(vmax.Length());
|
||||||
|
|
||||||
ClipperLib::ExPolygons clipped;
|
ClipperLib::Paths clipped;
|
||||||
ClipperLib::Polygons holes_union;
|
ClipperLib::Paths holes_union;
|
||||||
|
|
||||||
|
|
||||||
IfcVector3 wall_extrusion;
|
IfcVector3 wall_extrusion;
|
||||||
bool first = true;
|
bool first = true;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
ClipperLib::Clipper clipper_holes;
|
ClipperLib::Clipper clipper_holes;
|
||||||
|
|
||||||
for(const TempOpening& t : openings) {
|
for(const TempOpening& t : openings) {
|
||||||
|
@ -1787,7 +1694,7 @@ bool TryAddOpenings_Poly2Tri(const std::vector<TempOpening>& openings,
|
||||||
|
|
||||||
for(auto& contour : contours) {
|
for(auto& contour : contours) {
|
||||||
// scale to clipping space
|
// scale to clipping space
|
||||||
ClipperLib::Polygon hole;
|
ClipperLib::Path hole;
|
||||||
for(IfcVector2& pip : contour) {
|
for(IfcVector2& pip : contour) {
|
||||||
pip.x = (pip.x - vmin.x) / vmax.x;
|
pip.x = (pip.x - vmin.x) / vmax.x;
|
||||||
pip.y = (pip.y - vmin.y) / vmax.y;
|
pip.y = (pip.y - vmin.y) / vmax.y;
|
||||||
|
@ -1797,16 +1704,9 @@ bool TryAddOpenings_Poly2Tri(const std::vector<TempOpening>& openings,
|
||||||
|
|
||||||
if(!ClipperLib::Orientation(hole)) {
|
if(!ClipperLib::Orientation(hole)) {
|
||||||
std::reverse(hole.begin(),hole.end());
|
std::reverse(hole.begin(),hole.end());
|
||||||
// assert(ClipperLib::Orientation(hole));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*ClipperLib::Polygons pol_temp(1), pol_temp2(1);
|
clipper_holes.AddPath(hole,ClipperLib::ptSubject, true);
|
||||||
pol_temp[0] = hole;
|
|
||||||
|
|
||||||
ClipperLib::OffsetPolygons(pol_temp,pol_temp2,5.0);
|
|
||||||
hole = pol_temp2[0];*/
|
|
||||||
|
|
||||||
clipper_holes.AddPolygon(hole,ClipperLib::ptSubject);
|
|
||||||
{
|
{
|
||||||
std::stringstream msg;
|
std::stringstream msg;
|
||||||
msg << "- added polygon ";
|
msg << "- added polygon ";
|
||||||
|
@ -1829,7 +1729,7 @@ bool TryAddOpenings_Poly2Tri(const std::vector<TempOpening>& openings,
|
||||||
// Now that we have the big union of all holes, subtract it from the outer contour
|
// Now that we have the big union of all holes, subtract it from the outer contour
|
||||||
// to obtain the final polygon to feed into the triangulator.
|
// to obtain the final polygon to feed into the triangulator.
|
||||||
{
|
{
|
||||||
ClipperLib::Polygon poly;
|
ClipperLib::Path poly;
|
||||||
for(IfcVector2& pip : contour_flat) {
|
for(IfcVector2& pip : contour_flat) {
|
||||||
pip.x = (pip.x - vmin.x) / vmax.x;
|
pip.x = (pip.x - vmin.x) / vmax.x;
|
||||||
pip.y = (pip.y - vmin.y) / vmax.y;
|
pip.y = (pip.y - vmin.y) / vmax.y;
|
||||||
|
@ -1841,16 +1741,14 @@ bool TryAddOpenings_Poly2Tri(const std::vector<TempOpening>& openings,
|
||||||
std::reverse(poly.begin(), poly.end());
|
std::reverse(poly.begin(), poly.end());
|
||||||
}
|
}
|
||||||
clipper_holes.Clear();
|
clipper_holes.Clear();
|
||||||
clipper_holes.AddPolygon(poly,ClipperLib::ptSubject);
|
clipper_holes.AddPath(poly,ClipperLib::ptSubject, true);
|
||||||
|
|
||||||
clipper_holes.AddPolygons(holes_union,ClipperLib::ptClip);
|
clipper_holes.AddPaths(holes_union,ClipperLib::ptClip, true);
|
||||||
clipper_holes.Execute(ClipperLib::ctDifference,clipped,
|
clipper_holes.Execute(ClipperLib::ctDifference,clipped,
|
||||||
ClipperLib::pftNonZero,
|
ClipperLib::pftNonZero,
|
||||||
ClipperLib::pftNonZero);
|
ClipperLib::pftNonZero);
|
||||||
}
|
}
|
||||||
|
} catch (const char* sx) {
|
||||||
}
|
|
||||||
catch (const char* sx) {
|
|
||||||
IFCImporter::LogError("Ifc: error during polygon clipping, skipping openings for this face: (Clipper: "
|
IFCImporter::LogError("Ifc: error during polygon clipping, skipping openings for this face: (Clipper: "
|
||||||
+ std::string(sx) + ")");
|
+ std::string(sx) + ")");
|
||||||
|
|
||||||
|
@ -1864,13 +1762,13 @@ bool TryAddOpenings_Poly2Tri(const std::vector<TempOpening>& openings,
|
||||||
old_vertcnt.swap(curmesh.mVertcnt);
|
old_vertcnt.swap(curmesh.mVertcnt);
|
||||||
|
|
||||||
std::vector< std::vector<p2t::Point*> > contours;
|
std::vector< std::vector<p2t::Point*> > contours;
|
||||||
for(ClipperLib::ExPolygon& clip : clipped) {
|
for(ClipperLib::Path &clip : clipped) {
|
||||||
|
|
||||||
contours.clear();
|
contours.clear();
|
||||||
|
|
||||||
// Build the outer polygon contour line for feeding into poly2tri
|
// Build the outer polygon contour line for feeding into poly2tri
|
||||||
std::vector<p2t::Point*> contour_points;
|
std::vector<p2t::Point*> contour_points;
|
||||||
for(ClipperLib::IntPoint& point : clip.outer) {
|
for(ClipperLib::IntPoint& point : clip) {
|
||||||
contour_points.push_back( new p2t::Point(from_int64(point.X), from_int64(point.Y)) );
|
contour_points.push_back( new p2t::Point(from_int64(point.X), from_int64(point.Y)) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1881,16 +1779,14 @@ bool TryAddOpenings_Poly2Tri(const std::vector<TempOpening>& openings,
|
||||||
// happen in production use if the input data is broken. An assertion would be
|
// happen in production use if the input data is broken. An assertion would be
|
||||||
// inappropriate.
|
// inappropriate.
|
||||||
cdt = new p2t::CDT(contour_points);
|
cdt = new p2t::CDT(contour_points);
|
||||||
}
|
} catch(const std::exception& e) {
|
||||||
catch(const std::exception& e) {
|
|
||||||
IFCImporter::LogError("Ifc: error during polygon triangulation, skipping some openings: (poly2tri: "
|
IFCImporter::LogError("Ifc: error during polygon triangulation, skipping some openings: (poly2tri: "
|
||||||
+ std::string(e.what()) + ")");
|
+ std::string(e.what()) + ")");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Build the poly2tri inner contours for all holes we got from ClipperLib
|
// Build the poly2tri inner contours for all holes we got from ClipperLib
|
||||||
for(ClipperLib::Polygon& opening : clip.holes) {
|
for(ClipperLib::Path& opening : holes_union) {
|
||||||
|
|
||||||
contours.emplace_back();
|
contours.emplace_back();
|
||||||
std::vector<p2t::Point*>& contour = contours.back();
|
std::vector<p2t::Point*>& contour = contours.back();
|
||||||
|
@ -1905,8 +1801,7 @@ bool TryAddOpenings_Poly2Tri(const std::vector<TempOpening>& openings,
|
||||||
try {
|
try {
|
||||||
// Note: See above
|
// Note: See above
|
||||||
cdt->Triangulate();
|
cdt->Triangulate();
|
||||||
}
|
} catch(const std::exception& e) {
|
||||||
catch(const std::exception& e) {
|
|
||||||
IFCImporter::LogError("Ifc: error during polygon triangulation, skipping some openings: (poly2tri: "
|
IFCImporter::LogError("Ifc: error during polygon triangulation, skipping some openings: (poly2tri: "
|
||||||
+ std::string(e.what()) + ")");
|
+ std::string(e.what()) + ")");
|
||||||
continue;
|
continue;
|
||||||
|
@ -1945,7 +1840,6 @@ bool TryAddOpenings_Poly2Tri(const std::vector<TempOpening>& openings,
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
} // ! IFC
|
} // ! IFC
|
||||||
} // ! Assimp
|
} // ! Assimp
|
||||||
|
|
||||||
|
@ -1953,4 +1847,4 @@ bool TryAddOpenings_Poly2Tri(const std::vector<TempOpening>& openings,
|
||||||
#undef from_int64
|
#undef from_int64
|
||||||
#undef one_vec
|
#undef one_vec
|
||||||
|
|
||||||
#endif
|
#endif // ASSIMP_BUILD_NO_IFC_IMPORTER
|
||||||
|
|
|
@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
|
||||||
|
|
||||||
Copyright (c) 2006-2022, assimp team
|
Copyright (c) 2006-2022, assimp team
|
||||||
|
|
||||||
|
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use of this software in source and binary forms,
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
@ -40,9 +39,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** @file IFCProfile.cpp
|
/// @file IFCProfile.cpp
|
||||||
* @brief Read profile and curves entities from IFC files
|
/// @brief Read profile and curves entities from IFC files
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef ASSIMP_BUILD_NO_IFC_IMPORTER
|
#ifndef ASSIMP_BUILD_NO_IFC_IMPORTER
|
||||||
|
|
||||||
|
@ -52,8 +50,9 @@ namespace Assimp {
|
||||||
namespace IFC {
|
namespace IFC {
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void ProcessPolyLine(const Schema_2x3::IfcPolyline& def, TempMesh& meshout, ConversionData& /*conv*/)
|
void ProcessPolyLine(const Schema_2x3::IfcPolyline& def,
|
||||||
{
|
TempMesh& meshout,
|
||||||
|
ConversionData& /*conv*/) {
|
||||||
// this won't produce a valid mesh, it just spits out a list of vertices
|
// this won't produce a valid mesh, it just spits out a list of vertices
|
||||||
IfcVector3 t;
|
IfcVector3 t;
|
||||||
for(const Schema_2x3::IfcCartesianPoint& cp : def.Points) {
|
for(const Schema_2x3::IfcCartesianPoint& cp : def.Points) {
|
||||||
|
@ -64,8 +63,9 @@ void ProcessPolyLine(const Schema_2x3::IfcPolyline& def, TempMesh& meshout, Conv
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
bool ProcessCurve(const Schema_2x3::IfcCurve& curve, TempMesh& meshout, ConversionData& conv)
|
bool ProcessCurve(const Schema_2x3::IfcCurve& curve,
|
||||||
{
|
TempMesh& meshout,
|
||||||
|
ConversionData& conv) {
|
||||||
std::unique_ptr<const Curve> cv(Curve::Convert(curve,conv));
|
std::unique_ptr<const Curve> cv(Curve::Convert(curve,conv));
|
||||||
if (!cv) {
|
if (!cv) {
|
||||||
IFCImporter::LogWarn("skipping unknown IfcCurve entity, type is ", curve.GetClassName());
|
IFCImporter::LogWarn("skipping unknown IfcCurve entity, type is ", curve.GetClassName());
|
||||||
|
@ -90,20 +90,23 @@ bool ProcessCurve(const Schema_2x3::IfcCurve& curve, TempMesh& meshout, Convers
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void ProcessClosedProfile(const Schema_2x3::IfcArbitraryClosedProfileDef& def, TempMesh& meshout, ConversionData& conv)
|
void ProcessClosedProfile(const Schema_2x3::IfcArbitraryClosedProfileDef& def,
|
||||||
{
|
TempMesh& meshout,
|
||||||
|
ConversionData& conv) {
|
||||||
ProcessCurve(def.OuterCurve,meshout,conv);
|
ProcessCurve(def.OuterCurve,meshout,conv);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void ProcessOpenProfile(const Schema_2x3::IfcArbitraryOpenProfileDef& def, TempMesh& meshout, ConversionData& conv)
|
void ProcessOpenProfile(const Schema_2x3::IfcArbitraryOpenProfileDef& def,
|
||||||
{
|
TempMesh& meshout,
|
||||||
|
ConversionData& conv) {
|
||||||
ProcessCurve(def.Curve,meshout,conv);
|
ProcessCurve(def.Curve,meshout,conv);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void ProcessParametrizedProfile(const Schema_2x3::IfcParameterizedProfileDef& def, TempMesh& meshout, ConversionData& conv)
|
void ProcessParametrizedProfile(const Schema_2x3::IfcParameterizedProfileDef& def,
|
||||||
{
|
TempMesh& meshout,
|
||||||
|
ConversionData& conv) {
|
||||||
if(const Schema_2x3::IfcRectangleProfileDef* const cprofile = def.ToPtr<Schema_2x3::IfcRectangleProfileDef>()) {
|
if(const Schema_2x3::IfcRectangleProfileDef* const cprofile = def.ToPtr<Schema_2x3::IfcRectangleProfileDef>()) {
|
||||||
const IfcFloat x = cprofile->XDim*0.5f, y = cprofile->YDim*0.5f;
|
const IfcFloat x = cprofile->XDim*0.5f, y = cprofile->YDim*0.5f;
|
||||||
|
|
||||||
|
@ -113,8 +116,7 @@ void ProcessParametrizedProfile(const Schema_2x3::IfcParameterizedProfileDef& de
|
||||||
meshout.mVerts.emplace_back(-x,-y, 0.f );
|
meshout.mVerts.emplace_back(-x,-y, 0.f );
|
||||||
meshout.mVerts.emplace_back( x,-y, 0.f );
|
meshout.mVerts.emplace_back( x,-y, 0.f );
|
||||||
meshout.mVertcnt.push_back(4);
|
meshout.mVertcnt.push_back(4);
|
||||||
}
|
} else if( const Schema_2x3::IfcCircleProfileDef* const circle = def.ToPtr<Schema_2x3::IfcCircleProfileDef>()) {
|
||||||
else if( const Schema_2x3::IfcCircleProfileDef* const circle = def.ToPtr<Schema_2x3::IfcCircleProfileDef>()) {
|
|
||||||
if(def.ToPtr<Schema_2x3::IfcCircleHollowProfileDef>()) {
|
if(def.ToPtr<Schema_2x3::IfcCircleHollowProfileDef>()) {
|
||||||
// TODO
|
// TODO
|
||||||
}
|
}
|
||||||
|
@ -129,8 +131,7 @@ void ProcessParametrizedProfile(const Schema_2x3::IfcParameterizedProfileDef& de
|
||||||
}
|
}
|
||||||
|
|
||||||
meshout.mVertcnt.push_back(static_cast<unsigned int>(segments));
|
meshout.mVertcnt.push_back(static_cast<unsigned int>(segments));
|
||||||
}
|
} else if( const Schema_2x3::IfcIShapeProfileDef* const ishape = def.ToPtr<Schema_2x3::IfcIShapeProfileDef>()) {
|
||||||
else if( const Schema_2x3::IfcIShapeProfileDef* const ishape = def.ToPtr<Schema_2x3::IfcIShapeProfileDef>()) {
|
|
||||||
// construct simplified IBeam shape
|
// construct simplified IBeam shape
|
||||||
const IfcFloat offset = (ishape->OverallWidth - ishape->WebThickness) / 2;
|
const IfcFloat offset = (ishape->OverallWidth - ishape->WebThickness) / 2;
|
||||||
const IfcFloat inner_height = ishape->OverallDepth - ishape->FlangeThickness * 2;
|
const IfcFloat inner_height = ishape->OverallDepth - ishape->FlangeThickness * 2;
|
||||||
|
@ -150,8 +151,7 @@ void ProcessParametrizedProfile(const Schema_2x3::IfcParameterizedProfileDef& de
|
||||||
meshout.mVerts.emplace_back(ishape->OverallWidth,0,0);
|
meshout.mVerts.emplace_back(ishape->OverallWidth,0,0);
|
||||||
|
|
||||||
meshout.mVertcnt.push_back(12);
|
meshout.mVertcnt.push_back(12);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
IFCImporter::LogWarn("skipping unknown IfcParameterizedProfileDef entity, type is ", def.GetClassName());
|
IFCImporter::LogWarn("skipping unknown IfcParameterizedProfileDef entity, type is ", def.GetClassName());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -162,18 +162,14 @@ void ProcessParametrizedProfile(const Schema_2x3::IfcParameterizedProfileDef& de
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
bool ProcessProfile(const Schema_2x3::IfcProfileDef& prof, TempMesh& meshout, ConversionData& conv)
|
bool ProcessProfile(const Schema_2x3::IfcProfileDef& prof, TempMesh& meshout, ConversionData& conv) {
|
||||||
{
|
|
||||||
if(const Schema_2x3::IfcArbitraryClosedProfileDef* const cprofile = prof.ToPtr<Schema_2x3::IfcArbitraryClosedProfileDef>()) {
|
if(const Schema_2x3::IfcArbitraryClosedProfileDef* const cprofile = prof.ToPtr<Schema_2x3::IfcArbitraryClosedProfileDef>()) {
|
||||||
ProcessClosedProfile(*cprofile,meshout,conv);
|
ProcessClosedProfile(*cprofile,meshout,conv);
|
||||||
}
|
} else if(const Schema_2x3::IfcArbitraryOpenProfileDef* const copen = prof.ToPtr<Schema_2x3::IfcArbitraryOpenProfileDef>()) {
|
||||||
else if(const Schema_2x3::IfcArbitraryOpenProfileDef* const copen = prof.ToPtr<Schema_2x3::IfcArbitraryOpenProfileDef>()) {
|
|
||||||
ProcessOpenProfile(*copen,meshout,conv);
|
ProcessOpenProfile(*copen,meshout,conv);
|
||||||
}
|
} else if(const Schema_2x3::IfcParameterizedProfileDef* const cparam = prof.ToPtr<Schema_2x3::IfcParameterizedProfileDef>()) {
|
||||||
else if(const Schema_2x3::IfcParameterizedProfileDef* const cparam = prof.ToPtr<Schema_2x3::IfcParameterizedProfileDef>()) {
|
|
||||||
ProcessParametrizedProfile(*cparam,meshout,conv);
|
ProcessParametrizedProfile(*cparam,meshout,conv);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
IFCImporter::LogWarn("skipping unknown IfcProfileDef entity, type is ", prof.GetClassName());
|
IFCImporter::LogWarn("skipping unknown IfcProfileDef entity, type is ", prof.GetClassName());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
|
||||||
|
|
||||||
Copyright (c) 2006-2022, assimp team
|
Copyright (c) 2006-2022, assimp team
|
||||||
|
|
||||||
|
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use of this software in source and binary forms,
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
@ -40,9 +39,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** @file IFCUtil.cpp
|
/// @file IFCUtil.cpp
|
||||||
* @brief Implementation of conversion routines for some common Ifc helper entities.
|
/// @brief Implementation of conversion routines for some common Ifc helper entities.
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef ASSIMP_BUILD_NO_IFC_IMPORTER
|
#ifndef ASSIMP_BUILD_NO_IFC_IMPORTER
|
||||||
|
|
||||||
|
@ -66,8 +64,7 @@ void TempOpening::Transform(const IfcMatrix4& mat) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
aiMesh* TempMesh::ToMesh()
|
aiMesh* TempMesh::ToMesh() {
|
||||||
{
|
|
||||||
ai_assert(mVerts.size() == std::accumulate(mVertcnt.begin(),mVertcnt.end(),size_t(0)));
|
ai_assert(mVerts.size() == std::accumulate(mVertcnt.begin(),mVertcnt.end(),size_t(0)));
|
||||||
|
|
||||||
if (mVerts.empty()) {
|
if (mVerts.empty()) {
|
||||||
|
@ -105,36 +102,31 @@ aiMesh* TempMesh::ToMesh()
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void TempMesh::Clear()
|
void TempMesh::Clear() {
|
||||||
{
|
|
||||||
mVerts.clear();
|
mVerts.clear();
|
||||||
mVertcnt.clear();
|
mVertcnt.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void TempMesh::Transform(const IfcMatrix4& mat)
|
void TempMesh::Transform(const IfcMatrix4& mat) {
|
||||||
{
|
|
||||||
for(IfcVector3& v : mVerts) {
|
for(IfcVector3& v : mVerts) {
|
||||||
v *= mat;
|
v *= mat;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------
|
||||||
IfcVector3 TempMesh::Center() const
|
IfcVector3 TempMesh::Center() const {
|
||||||
{
|
return mVerts.empty() ? IfcVector3(0.0f, 0.0f, 0.0f) : (std::accumulate(mVerts.begin(),mVerts.end(),IfcVector3()) / static_cast<IfcFloat>(mVerts.size()));
|
||||||
return (mVerts.size() == 0) ? IfcVector3(0.0f, 0.0f, 0.0f) : (std::accumulate(mVerts.begin(),mVerts.end(),IfcVector3()) / static_cast<IfcFloat>(mVerts.size()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void TempMesh::Append(const TempMesh& other)
|
void TempMesh::Append(const TempMesh& other) {
|
||||||
{
|
|
||||||
mVerts.insert(mVerts.end(),other.mVerts.begin(),other.mVerts.end());
|
mVerts.insert(mVerts.end(),other.mVerts.begin(),other.mVerts.end());
|
||||||
mVertcnt.insert(mVertcnt.end(),other.mVertcnt.begin(),other.mVertcnt.end());
|
mVertcnt.insert(mVertcnt.end(),other.mVertcnt.begin(),other.mVertcnt.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void TempMesh::RemoveDegenerates()
|
void TempMesh::RemoveDegenerates() {
|
||||||
{
|
|
||||||
// The strategy is simple: walk the mesh and compute normals using
|
// The strategy is simple: walk the mesh and compute normals using
|
||||||
// Newell's algorithm. The length of the normals gives the area
|
// Newell's algorithm. The length of the normals gives the area
|
||||||
// of the polygons, which is close to zero for lines.
|
// of the polygons, which is close to zero for lines.
|
||||||
|
@ -167,11 +159,9 @@ void TempMesh::RemoveDegenerates()
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
IfcVector3 TempMesh::ComputePolygonNormal(const IfcVector3* vtcs, size_t cnt, bool normalize)
|
IfcVector3 TempMesh::ComputePolygonNormal(const IfcVector3* vtcs, size_t cnt, bool normalize) {
|
||||||
{
|
|
||||||
std::vector<IfcFloat> temp((cnt+2)*3);
|
std::vector<IfcFloat> temp((cnt+2)*3);
|
||||||
for( size_t vofs = 0, i = 0; vofs < cnt; ++vofs )
|
for( size_t vofs = 0, i = 0; vofs < cnt; ++vofs ) {
|
||||||
{
|
|
||||||
const IfcVector3& v = vtcs[vofs];
|
const IfcVector3& v = vtcs[vofs];
|
||||||
temp[i++] = v.x;
|
temp[i++] = v.x;
|
||||||
temp[i++] = v.y;
|
temp[i++] = v.y;
|
||||||
|
@ -186,8 +176,7 @@ IfcVector3 TempMesh::ComputePolygonNormal(const IfcVector3* vtcs, size_t cnt, bo
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void TempMesh::ComputePolygonNormals(std::vector<IfcVector3>& normals,
|
void TempMesh::ComputePolygonNormals(std::vector<IfcVector3>& normals,
|
||||||
bool normalize,
|
bool normalize,
|
||||||
size_t ofs) const
|
size_t ofs) const {
|
||||||
{
|
|
||||||
size_t max_vcount = 0;
|
size_t max_vcount = 0;
|
||||||
std::vector<unsigned int>::const_iterator begin = mVertcnt.begin()+ofs, end = mVertcnt.end(), iit;
|
std::vector<unsigned int>::const_iterator begin = mVertcnt.begin()+ofs, end = mVertcnt.end(), iit;
|
||||||
for(iit = begin; iit != end; ++iit) {
|
for(iit = begin; iit != end; ++iit) {
|
||||||
|
@ -250,29 +239,27 @@ struct FindVector {
|
||||||
};
|
};
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void TempMesh::FixupFaceOrientation()
|
void TempMesh::FixupFaceOrientation() {
|
||||||
{
|
|
||||||
const IfcVector3 vavg = Center();
|
const IfcVector3 vavg = Center();
|
||||||
|
|
||||||
// create a list of start indices for all faces to allow random access to faces
|
// create a list of start indices for all faces to allow random access to faces
|
||||||
std::vector<size_t> faceStartIndices(mVertcnt.size());
|
std::vector<size_t> faceStartIndices(mVertcnt.size());
|
||||||
for( size_t i = 0, a = 0; a < mVertcnt.size(); i += mVertcnt[a], ++a )
|
for( size_t i = 0, a = 0; a < mVertcnt.size(); i += mVertcnt[a], ++a ) {
|
||||||
faceStartIndices[a] = i;
|
faceStartIndices[a] = i;
|
||||||
|
}
|
||||||
|
|
||||||
// list all faces on a vertex
|
// list all faces on a vertex
|
||||||
std::map<IfcVector3, std::vector<size_t>, CompareVector> facesByVertex;
|
std::map<IfcVector3, std::vector<size_t>, CompareVector> facesByVertex;
|
||||||
for( size_t a = 0; a < mVertcnt.size(); ++a )
|
for( size_t a = 0; a < mVertcnt.size(); ++a ) {
|
||||||
{
|
for( size_t b = 0; b < mVertcnt[a]; ++b ) {
|
||||||
for( size_t b = 0; b < mVertcnt[a]; ++b )
|
|
||||||
facesByVertex[mVerts[faceStartIndices[a] + b]].push_back(a);
|
facesByVertex[mVerts[faceStartIndices[a] + b]].push_back(a);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
// determine neighbourhood for all polys
|
// determine neighbourhood for all polys
|
||||||
std::vector<size_t> neighbour(mVerts.size(), SIZE_MAX);
|
std::vector<size_t> neighbour(mVerts.size(), SIZE_MAX);
|
||||||
std::vector<size_t> tempIntersect(10);
|
std::vector<size_t> tempIntersect(10);
|
||||||
for( size_t a = 0; a < mVertcnt.size(); ++a )
|
for( size_t a = 0; a < mVertcnt.size(); ++a ) {
|
||||||
{
|
for( size_t b = 0; b < mVertcnt[a]; ++b ) {
|
||||||
for( size_t b = 0; b < mVertcnt[a]; ++b )
|
|
||||||
{
|
|
||||||
size_t ib = faceStartIndices[a] + b, nib = faceStartIndices[a] + (b + 1) % mVertcnt[a];
|
size_t ib = faceStartIndices[a] + b, nib = faceStartIndices[a] + (b + 1) % mVertcnt[a];
|
||||||
const std::vector<size_t>& facesOnB = facesByVertex[mVerts[ib]];
|
const std::vector<size_t>& facesOnB = facesByVertex[mVerts[ib]];
|
||||||
const std::vector<size_t>& facesOnNB = facesByVertex[mVerts[nib]];
|
const std::vector<size_t>& facesOnNB = facesByVertex[mVerts[nib]];
|
||||||
|
@ -281,10 +268,12 @@ void TempMesh::FixupFaceOrientation()
|
||||||
std::vector<size_t>::iterator sectend = std::set_intersection(
|
std::vector<size_t>::iterator sectend = std::set_intersection(
|
||||||
facesOnB.begin(), facesOnB.end(), facesOnNB.begin(), facesOnNB.end(), sectstart);
|
facesOnB.begin(), facesOnB.end(), facesOnNB.begin(), facesOnNB.end(), sectstart);
|
||||||
|
|
||||||
if( std::distance(sectstart, sectend) != 2 )
|
if( std::distance(sectstart, sectend) != 2 ) {
|
||||||
continue;
|
continue;
|
||||||
if( *sectstart == a )
|
}
|
||||||
|
if( *sectstart == a ) {
|
||||||
++sectstart;
|
++sectstart;
|
||||||
|
}
|
||||||
neighbour[ib] = *sectstart;
|
neighbour[ib] = *sectstart;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -293,15 +282,14 @@ void TempMesh::FixupFaceOrientation()
|
||||||
// facing outwards. So we reverse this face to point outwards in relation to the center. Then we adapt neighbouring
|
// facing outwards. So we reverse this face to point outwards in relation to the center. Then we adapt neighbouring
|
||||||
// faces to have the same winding until all faces have been tested.
|
// faces to have the same winding until all faces have been tested.
|
||||||
std::vector<bool> faceDone(mVertcnt.size(), false);
|
std::vector<bool> faceDone(mVertcnt.size(), false);
|
||||||
while( std::count(faceDone.begin(), faceDone.end(), false) != 0 )
|
while( std::count(faceDone.begin(), faceDone.end(), false) != 0 ) {
|
||||||
{
|
|
||||||
// find the farthest of the remaining faces
|
// find the farthest of the remaining faces
|
||||||
size_t farthestIndex = SIZE_MAX;
|
size_t farthestIndex = SIZE_MAX;
|
||||||
IfcFloat farthestDistance = -1.0;
|
IfcFloat farthestDistance = -1.0;
|
||||||
for( size_t a = 0; a < mVertcnt.size(); ++a )
|
for( size_t a = 0; a < mVertcnt.size(); ++a ) {
|
||||||
{
|
if( faceDone[a] ) {
|
||||||
if( faceDone[a] )
|
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
IfcVector3 faceCenter = std::accumulate(mVerts.begin() + faceStartIndices[a],
|
IfcVector3 faceCenter = std::accumulate(mVerts.begin() + faceStartIndices[a],
|
||||||
mVerts.begin() + faceStartIndices[a] + mVertcnt[a], IfcVector3(0.0)) / IfcFloat(mVertcnt[a]);
|
mVerts.begin() + faceStartIndices[a] + mVertcnt[a], IfcVector3(0.0)) / IfcFloat(mVertcnt[a]);
|
||||||
IfcFloat dst = (faceCenter - vavg).SquareLength();
|
IfcFloat dst = (faceCenter - vavg).SquareLength();
|
||||||
|
@ -315,8 +303,7 @@ void TempMesh::FixupFaceOrientation()
|
||||||
/ IfcFloat(mVertcnt[farthestIndex]);
|
/ IfcFloat(mVertcnt[farthestIndex]);
|
||||||
// We accept a bit of negative orientation without reversing. In case of doubt, prefer the orientation given in
|
// We accept a bit of negative orientation without reversing. In case of doubt, prefer the orientation given in
|
||||||
// the file.
|
// the file.
|
||||||
if( (farthestNormal * (farthestCenter - vavg).Normalize()) < -0.4 )
|
if( (farthestNormal * (farthestCenter - vavg).Normalize()) < -0.4 ) {
|
||||||
{
|
|
||||||
size_t fsi = faceStartIndices[farthestIndex], fvc = mVertcnt[farthestIndex];
|
size_t fsi = faceStartIndices[farthestIndex], fvc = mVertcnt[farthestIndex];
|
||||||
std::reverse(mVerts.begin() + fsi, mVerts.begin() + fsi + fvc);
|
std::reverse(mVerts.begin() + fsi, mVerts.begin() + fsi + fvc);
|
||||||
std::reverse(neighbour.begin() + fsi, neighbour.begin() + fsi + fvc);
|
std::reverse(neighbour.begin() + fsi, neighbour.begin() + fsi + fvc);
|
||||||
|
@ -333,19 +320,18 @@ void TempMesh::FixupFaceOrientation()
|
||||||
todo.push_back(farthestIndex);
|
todo.push_back(farthestIndex);
|
||||||
|
|
||||||
// go over its neighbour faces recursively and adapt their winding order to match the farthest face
|
// go over its neighbour faces recursively and adapt their winding order to match the farthest face
|
||||||
while( !todo.empty() )
|
while( !todo.empty() ) {
|
||||||
{
|
|
||||||
size_t tdf = todo.back();
|
size_t tdf = todo.back();
|
||||||
size_t vsi = faceStartIndices[tdf], vc = mVertcnt[tdf];
|
size_t vsi = faceStartIndices[tdf], vc = mVertcnt[tdf];
|
||||||
todo.pop_back();
|
todo.pop_back();
|
||||||
|
|
||||||
// check its neighbours
|
// check its neighbours
|
||||||
for( size_t a = 0; a < vc; ++a )
|
for( size_t a = 0; a < vc; ++a ) {
|
||||||
{
|
|
||||||
// ignore neighbours if we already checked them
|
// ignore neighbours if we already checked them
|
||||||
size_t nbi = neighbour[vsi + a];
|
size_t nbi = neighbour[vsi + a];
|
||||||
if( nbi == SIZE_MAX || faceDone[nbi] )
|
if( nbi == SIZE_MAX || faceDone[nbi] ) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
const IfcVector3& vp = mVerts[vsi + a];
|
const IfcVector3& vp = mVerts[vsi + a];
|
||||||
size_t nbvsi = faceStartIndices[nbi], nbvc = mVertcnt[nbi];
|
size_t nbvsi = faceStartIndices[nbi], nbvc = mVertcnt[nbi];
|
||||||
|
@ -388,31 +374,7 @@ void TempMesh::RemoveAdjacentDuplicates() {
|
||||||
IfcVector3 vmin,vmax;
|
IfcVector3 vmin,vmax;
|
||||||
ArrayBounds(&*base, cnt ,vmin,vmax);
|
ArrayBounds(&*base, cnt ,vmin,vmax);
|
||||||
|
|
||||||
|
|
||||||
const IfcFloat epsilon = (vmax-vmin).SquareLength() / static_cast<IfcFloat>(1e9);
|
const IfcFloat epsilon = (vmax-vmin).SquareLength() / static_cast<IfcFloat>(1e9);
|
||||||
//const IfcFloat dotepsilon = 1e-9;
|
|
||||||
|
|
||||||
//// look for vertices that lie directly on the line between their predecessor and their
|
|
||||||
//// successor and replace them with either of them.
|
|
||||||
|
|
||||||
//for(size_t i = 0; i < cnt; ++i) {
|
|
||||||
// IfcVector3& v1 = *(base+i), &v0 = *(base+(i?i-1:cnt-1)), &v2 = *(base+(i+1)%cnt);
|
|
||||||
// const IfcVector3& d0 = (v1-v0), &d1 = (v2-v1);
|
|
||||||
// const IfcFloat l0 = d0.SquareLength(), l1 = d1.SquareLength();
|
|
||||||
// if (!l0 || !l1) {
|
|
||||||
// continue;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// const IfcFloat d = (d0/std::sqrt(l0))*(d1/std::sqrt(l1));
|
|
||||||
|
|
||||||
// if ( d >= 1.f-dotepsilon ) {
|
|
||||||
// v1 = v0;
|
|
||||||
// }
|
|
||||||
// else if ( d < -1.f+dotepsilon ) {
|
|
||||||
// v2 = v1;
|
|
||||||
// continue;
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
|
|
||||||
// drop any identical, adjacent vertices. this pass will collect the dropouts
|
// drop any identical, adjacent vertices. this pass will collect the dropouts
|
||||||
// of the previous pass as a side-effect.
|
// of the previous pass as a side-effect.
|
||||||
|
@ -440,78 +402,58 @@ void TempMesh::RemoveAdjacentDuplicates() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void TempMesh::Swap(TempMesh& other)
|
void TempMesh::Swap(TempMesh& other) {
|
||||||
{
|
|
||||||
mVertcnt.swap(other.mVertcnt);
|
mVertcnt.swap(other.mVertcnt);
|
||||||
mVerts.swap(other.mVerts);
|
mVerts.swap(other.mVerts);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
bool IsTrue(const ::Assimp::STEP::EXPRESS::BOOLEAN& in)
|
bool IsTrue(const ::Assimp::STEP::EXPRESS::BOOLEAN& in) {
|
||||||
{
|
|
||||||
return (std::string)in == "TRUE" || (std::string)in == "T";
|
return (std::string)in == "TRUE" || (std::string)in == "T";
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
IfcFloat ConvertSIPrefix(const std::string& prefix)
|
IfcFloat ConvertSIPrefix(const std::string& prefix) {
|
||||||
{
|
|
||||||
if (prefix == "EXA") {
|
if (prefix == "EXA") {
|
||||||
return 1e18f;
|
return 1e18f;
|
||||||
}
|
} else if (prefix == "PETA") {
|
||||||
else if (prefix == "PETA") {
|
|
||||||
return 1e15f;
|
return 1e15f;
|
||||||
}
|
} else if (prefix == "TERA") {
|
||||||
else if (prefix == "TERA") {
|
|
||||||
return 1e12f;
|
return 1e12f;
|
||||||
}
|
} else if (prefix == "GIGA") {
|
||||||
else if (prefix == "GIGA") {
|
|
||||||
return 1e9f;
|
return 1e9f;
|
||||||
}
|
} else if (prefix == "MEGA") {
|
||||||
else if (prefix == "MEGA") {
|
|
||||||
return 1e6f;
|
return 1e6f;
|
||||||
}
|
} else if (prefix == "KILO") {
|
||||||
else if (prefix == "KILO") {
|
|
||||||
return 1e3f;
|
return 1e3f;
|
||||||
}
|
} else if (prefix == "HECTO") {
|
||||||
else if (prefix == "HECTO") {
|
|
||||||
return 1e2f;
|
return 1e2f;
|
||||||
}
|
} else if (prefix == "DECA") {
|
||||||
else if (prefix == "DECA") {
|
|
||||||
return 1e-0f;
|
return 1e-0f;
|
||||||
}
|
} else if (prefix == "DECI") {
|
||||||
else if (prefix == "DECI") {
|
|
||||||
return 1e-1f;
|
return 1e-1f;
|
||||||
}
|
} else if (prefix == "CENTI") {
|
||||||
else if (prefix == "CENTI") {
|
|
||||||
return 1e-2f;
|
return 1e-2f;
|
||||||
}
|
} else if (prefix == "MILLI") {
|
||||||
else if (prefix == "MILLI") {
|
|
||||||
return 1e-3f;
|
return 1e-3f;
|
||||||
}
|
} else if (prefix == "MICRO") {
|
||||||
else if (prefix == "MICRO") {
|
|
||||||
return 1e-6f;
|
return 1e-6f;
|
||||||
}
|
} else if (prefix == "NANO") {
|
||||||
else if (prefix == "NANO") {
|
|
||||||
return 1e-9f;
|
return 1e-9f;
|
||||||
}
|
} else if (prefix == "PICO") {
|
||||||
else if (prefix == "PICO") {
|
|
||||||
return 1e-12f;
|
return 1e-12f;
|
||||||
}
|
} else if (prefix == "FEMTO") {
|
||||||
else if (prefix == "FEMTO") {
|
|
||||||
return 1e-15f;
|
return 1e-15f;
|
||||||
}
|
} else if (prefix == "ATTO") {
|
||||||
else if (prefix == "ATTO") {
|
|
||||||
return 1e-18f;
|
return 1e-18f;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
IFCImporter::LogError("Unrecognized SI prefix: ", prefix);
|
IFCImporter::LogError("Unrecognized SI prefix: ", prefix);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void ConvertColor(aiColor4D& out, const Schema_2x3::IfcColourRgb& in)
|
void ConvertColor(aiColor4D& out, const Schema_2x3::IfcColourRgb& in) {
|
||||||
{
|
|
||||||
out.r = static_cast<float>( in.Red );
|
out.r = static_cast<float>( in.Red );
|
||||||
out.g = static_cast<float>( in.Green );
|
out.g = static_cast<float>( in.Green );
|
||||||
out.b = static_cast<float>( in.Blue );
|
out.b = static_cast<float>( in.Blue );
|
||||||
|
@ -519,8 +461,10 @@ void ConvertColor(aiColor4D& out, const Schema_2x3::IfcColourRgb& in)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void ConvertColor(aiColor4D& out, const Schema_2x3::IfcColourOrFactor& in,ConversionData& conv,const aiColor4D* base)
|
void ConvertColor(aiColor4D& out,
|
||||||
{
|
const Schema_2x3::IfcColourOrFactor& in,
|
||||||
|
ConversionData& conv,
|
||||||
|
const aiColor4D* base) {
|
||||||
if (const ::Assimp::STEP::EXPRESS::REAL* const r = in.ToPtr<::Assimp::STEP::EXPRESS::REAL>()) {
|
if (const ::Assimp::STEP::EXPRESS::REAL* const r = in.ToPtr<::Assimp::STEP::EXPRESS::REAL>()) {
|
||||||
out.r = out.g = out.b = static_cast<float>(*r);
|
out.r = out.g = out.b = static_cast<float>(*r);
|
||||||
if(base) {
|
if(base) {
|
||||||
|
@ -528,20 +472,18 @@ void ConvertColor(aiColor4D& out, const Schema_2x3::IfcColourOrFactor& in,Conver
|
||||||
out.g *= static_cast<float>( base->g );
|
out.g *= static_cast<float>( base->g );
|
||||||
out.b *= static_cast<float>( base->b );
|
out.b *= static_cast<float>( base->b );
|
||||||
out.a = static_cast<float>( base->a );
|
out.a = static_cast<float>( base->a );
|
||||||
|
} else {
|
||||||
|
out.a = 1.0;
|
||||||
}
|
}
|
||||||
else out.a = 1.0;
|
} else if (const Schema_2x3::IfcColourRgb* const rgb = in.ResolveSelectPtr<Schema_2x3::IfcColourRgb>(conv.db)) {
|
||||||
}
|
|
||||||
else if (const Schema_2x3::IfcColourRgb* const rgb = in.ResolveSelectPtr<Schema_2x3::IfcColourRgb>(conv.db)) {
|
|
||||||
ConvertColor(out,*rgb);
|
ConvertColor(out,*rgb);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
IFCImporter::LogWarn("skipping unknown IfcColourOrFactor entity");
|
IFCImporter::LogWarn("skipping unknown IfcColourOrFactor entity");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void ConvertCartesianPoint(IfcVector3& out, const Schema_2x3::IfcCartesianPoint& in)
|
void ConvertCartesianPoint(IfcVector3& out, const Schema_2x3::IfcCartesianPoint& in) {
|
||||||
{
|
|
||||||
out = IfcVector3();
|
out = IfcVector3();
|
||||||
for(size_t i = 0; i < in.Coordinates.size(); ++i) {
|
for(size_t i = 0; i < in.Coordinates.size(); ++i) {
|
||||||
out[static_cast<unsigned int>(i)] = in.Coordinates[i];
|
out[static_cast<unsigned int>(i)] = in.Coordinates[i];
|
||||||
|
@ -549,15 +491,13 @@ void ConvertCartesianPoint(IfcVector3& out, const Schema_2x3::IfcCartesianPoint&
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void ConvertVector(IfcVector3& out, const Schema_2x3::IfcVector& in)
|
void ConvertVector(IfcVector3& out, const Schema_2x3::IfcVector& in) {
|
||||||
{
|
|
||||||
ConvertDirection(out,in.Orientation);
|
ConvertDirection(out,in.Orientation);
|
||||||
out *= in.Magnitude;
|
out *= in.Magnitude;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void ConvertDirection(IfcVector3& out, const Schema_2x3::IfcDirection& in)
|
void ConvertDirection(IfcVector3& out, const Schema_2x3::IfcDirection& in) {
|
||||||
{
|
|
||||||
out = IfcVector3();
|
out = IfcVector3();
|
||||||
for(size_t i = 0; i < in.DirectionRatios.size(); ++i) {
|
for(size_t i = 0; i < in.DirectionRatios.size(); ++i) {
|
||||||
out[static_cast<unsigned int>(i)] = in.DirectionRatios[i];
|
out[static_cast<unsigned int>(i)] = in.DirectionRatios[i];
|
||||||
|
@ -571,8 +511,7 @@ void ConvertDirection(IfcVector3& out, const Schema_2x3::IfcDirection& in)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void AssignMatrixAxes(IfcMatrix4& out, const IfcVector3& x, const IfcVector3& y, const IfcVector3& z)
|
void AssignMatrixAxes(IfcMatrix4& out, const IfcVector3& x, const IfcVector3& y, const IfcVector3& z) {
|
||||||
{
|
|
||||||
out.a1 = x.x;
|
out.a1 = x.x;
|
||||||
out.b1 = x.y;
|
out.b1 = x.y;
|
||||||
out.c1 = x.z;
|
out.c1 = x.z;
|
||||||
|
@ -587,8 +526,7 @@ void AssignMatrixAxes(IfcMatrix4& out, const IfcVector3& x, const IfcVector3& y,
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void ConvertAxisPlacement(IfcMatrix4& out, const Schema_2x3::IfcAxis2Placement3D& in)
|
void ConvertAxisPlacement(IfcMatrix4& out, const Schema_2x3::IfcAxis2Placement3D& in) {
|
||||||
{
|
|
||||||
IfcVector3 loc;
|
IfcVector3 loc;
|
||||||
ConvertCartesianPoint(loc,in.Location);
|
ConvertCartesianPoint(loc,in.Location);
|
||||||
|
|
||||||
|
@ -612,8 +550,7 @@ void ConvertAxisPlacement(IfcMatrix4& out, const Schema_2x3::IfcAxis2Placement3D
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void ConvertAxisPlacement(IfcMatrix4& out, const Schema_2x3::IfcAxis2Placement2D& in)
|
void ConvertAxisPlacement(IfcMatrix4& out, const Schema_2x3::IfcAxis2Placement2D& in) {
|
||||||
{
|
|
||||||
IfcVector3 loc;
|
IfcVector3 loc;
|
||||||
ConvertCartesianPoint(loc,in.Location);
|
ConvertCartesianPoint(loc,in.Location);
|
||||||
|
|
||||||
|
@ -629,34 +566,28 @@ void ConvertAxisPlacement(IfcMatrix4& out, const Schema_2x3::IfcAxis2Placement2D
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void ConvertAxisPlacement(IfcVector3& axis, IfcVector3& pos, const Schema_2x3::IfcAxis1Placement& in)
|
void ConvertAxisPlacement(IfcVector3& axis, IfcVector3& pos, const Schema_2x3::IfcAxis1Placement& in) {
|
||||||
{
|
|
||||||
ConvertCartesianPoint(pos,in.Location);
|
ConvertCartesianPoint(pos,in.Location);
|
||||||
if (in.Axis) {
|
if (in.Axis) {
|
||||||
ConvertDirection(axis,in.Axis.Get());
|
ConvertDirection(axis,in.Axis.Get());
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
axis = IfcVector3(0.f,0.f,1.f);
|
axis = IfcVector3(0.f,0.f,1.f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void ConvertAxisPlacement(IfcMatrix4& out, const Schema_2x3::IfcAxis2Placement& in, ConversionData& conv)
|
void ConvertAxisPlacement(IfcMatrix4& out, const Schema_2x3::IfcAxis2Placement& in, ConversionData& conv) {
|
||||||
{
|
|
||||||
if(const Schema_2x3::IfcAxis2Placement3D* pl3 = in.ResolveSelectPtr<Schema_2x3::IfcAxis2Placement3D>(conv.db)) {
|
if(const Schema_2x3::IfcAxis2Placement3D* pl3 = in.ResolveSelectPtr<Schema_2x3::IfcAxis2Placement3D>(conv.db)) {
|
||||||
ConvertAxisPlacement(out,*pl3);
|
ConvertAxisPlacement(out,*pl3);
|
||||||
}
|
} else if(const Schema_2x3::IfcAxis2Placement2D* pl2 = in.ResolveSelectPtr<Schema_2x3::IfcAxis2Placement2D>(conv.db)) {
|
||||||
else if(const Schema_2x3::IfcAxis2Placement2D* pl2 = in.ResolveSelectPtr<Schema_2x3::IfcAxis2Placement2D>(conv.db)) {
|
|
||||||
ConvertAxisPlacement(out,*pl2);
|
ConvertAxisPlacement(out,*pl2);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
IFCImporter::LogWarn("skipping unknown IfcAxis2Placement entity");
|
IFCImporter::LogWarn("skipping unknown IfcAxis2Placement entity");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void ConvertTransformOperator(IfcMatrix4& out, const Schema_2x3::IfcCartesianTransformationOperator& op)
|
void ConvertTransformOperator(IfcMatrix4& out, const Schema_2x3::IfcCartesianTransformationOperator& op) {
|
||||||
{
|
|
||||||
IfcVector3 loc;
|
IfcVector3 loc;
|
||||||
ConvertCartesianPoint(loc,op.LocalOrigin);
|
ConvertCartesianPoint(loc,op.LocalOrigin);
|
||||||
|
|
||||||
|
@ -677,14 +608,12 @@ void ConvertTransformOperator(IfcMatrix4& out, const Schema_2x3::IfcCartesianTra
|
||||||
IfcMatrix4::Translation(loc,locm);
|
IfcMatrix4::Translation(loc,locm);
|
||||||
AssignMatrixAxes(out,x,y,z);
|
AssignMatrixAxes(out,x,y,z);
|
||||||
|
|
||||||
|
|
||||||
IfcVector3 vscale;
|
IfcVector3 vscale;
|
||||||
if (const Schema_2x3::IfcCartesianTransformationOperator3DnonUniform* nuni = op.ToPtr<Schema_2x3::IfcCartesianTransformationOperator3DnonUniform>()) {
|
if (const Schema_2x3::IfcCartesianTransformationOperator3DnonUniform* nuni = op.ToPtr<Schema_2x3::IfcCartesianTransformationOperator3DnonUniform>()) {
|
||||||
vscale.x = nuni->Scale?op.Scale.Get():1.f;
|
vscale.x = nuni->Scale?op.Scale.Get():1.f;
|
||||||
vscale.y = nuni->Scale2?nuni->Scale2.Get():1.f;
|
vscale.y = nuni->Scale2?nuni->Scale2.Get():1.f;
|
||||||
vscale.z = nuni->Scale3?nuni->Scale3.Get():1.f;
|
vscale.z = nuni->Scale3?nuni->Scale3.Get():1.f;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
const IfcFloat sc = op.Scale?op.Scale.Get():1.f;
|
const IfcFloat sc = op.Scale?op.Scale.Get():1.f;
|
||||||
vscale = IfcVector3(sc,sc,sc);
|
vscale = IfcVector3(sc,sc,sc);
|
||||||
}
|
}
|
||||||
|
@ -695,8 +624,7 @@ void ConvertTransformOperator(IfcMatrix4& out, const Schema_2x3::IfcCartesianTra
|
||||||
out = locm * out * s;
|
out = locm * out * s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
} // ! IFC
|
} // ! IFC
|
||||||
} // ! Assimp
|
} // ! Assimp
|
||||||
|
|
||||||
#endif
|
#endif // ASSIMP_BUILD_NO_IFC_IMPORTER
|
||||||
|
|
|
@ -59,7 +59,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
// http://sauerbraten.org/iqm/
|
// http://sauerbraten.org/iqm/
|
||||||
// https://github.com/lsalzman/iqm
|
// https://github.com/lsalzman/iqm
|
||||||
|
|
||||||
|
|
||||||
inline void swap_block( uint32_t *block, size_t size ){
|
inline void swap_block( uint32_t *block, size_t size ){
|
||||||
(void)block; // suppress 'unreferenced formal parameter' MSVC warning
|
(void)block; // suppress 'unreferenced formal parameter' MSVC warning
|
||||||
size >>= 2;
|
size >>= 2;
|
||||||
|
@ -67,7 +66,7 @@ inline void swap_block( uint32_t *block, size_t size ){
|
||||||
AI_SWAP4( block[ i ] );
|
AI_SWAP4( block[ i ] );
|
||||||
}
|
}
|
||||||
|
|
||||||
static const aiImporterDesc desc = {
|
static constexpr aiImporterDesc desc = {
|
||||||
"Inter-Quake Model Importer",
|
"Inter-Quake Model Importer",
|
||||||
"",
|
"",
|
||||||
"",
|
"",
|
||||||
|
@ -100,13 +99,6 @@ bool IQMImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool c
|
||||||
if (!pIOHandler) {
|
if (!pIOHandler) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
* don't use CheckMagicToken because that checks with swapped bytes too, leading to false
|
|
||||||
* positives. This magic is not uint32_t, but char[4], so memcmp is the best way
|
|
||||||
|
|
||||||
const char* tokens[] = {"3DMO", "3dmo"};
|
|
||||||
return CheckMagicToken(pIOHandler,pFile,tokens,2,0,4);
|
|
||||||
*/
|
|
||||||
std::unique_ptr<IOStream> pStream(pIOHandler->Open(pFile, "rb"));
|
std::unique_ptr<IOStream> pStream(pIOHandler->Open(pFile, "rb"));
|
||||||
unsigned char data[15];
|
unsigned char data[15];
|
||||||
if (!pStream || 15 != pStream->Read(data, 1, 15)) {
|
if (!pStream || 15 != pStream->Read(data, 1, 15)) {
|
||||||
|
|
|
@ -66,7 +66,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
using namespace Assimp;
|
using namespace Assimp;
|
||||||
|
|
||||||
static const aiImporterDesc desc = {
|
static constexpr aiImporterDesc desc = {
|
||||||
"Irrlicht Scene Reader",
|
"Irrlicht Scene Reader",
|
||||||
"",
|
"",
|
||||||
"",
|
"",
|
||||||
|
@ -575,8 +575,8 @@ void SetupMapping(aiMaterial *mat, aiTextureMapping mode, const aiVector3D &axis
|
||||||
m->mSemantic = prop->mSemantic;
|
m->mSemantic = prop->mSemantic;
|
||||||
m->mType = aiPTI_Float;
|
m->mType = aiPTI_Float;
|
||||||
|
|
||||||
m->mDataLength = 12;
|
m->mDataLength = sizeof(aiVector3D);
|
||||||
m->mData = new char[12];
|
m->mData = new char[m->mDataLength];
|
||||||
*((aiVector3D *)m->mData) = axis;
|
*((aiVector3D *)m->mData) = axis;
|
||||||
p.push_back(m);
|
p.push_back(m);
|
||||||
}
|
}
|
||||||
|
@ -1234,7 +1234,10 @@ void IRRImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
|
||||||
// Parse the XML
|
// Parse the XML
|
||||||
// Find the scene root from document root.
|
// Find the scene root from document root.
|
||||||
const pugi::xml_node &sceneRoot = documentRoot.child("irr_scene");
|
const pugi::xml_node &sceneRoot = documentRoot.child("irr_scene");
|
||||||
if (!sceneRoot) throw new DeadlyImportError("IRR: <irr_scene> not found in file");
|
if (!sceneRoot) {
|
||||||
|
delete root;
|
||||||
|
throw new DeadlyImportError("IRR: <irr_scene> not found in file");
|
||||||
|
}
|
||||||
for (pugi::xml_node &child : sceneRoot.children()) {
|
for (pugi::xml_node &child : sceneRoot.children()) {
|
||||||
// XML elements are either nodes, animators, attributes, or materials
|
// XML elements are either nodes, animators, attributes, or materials
|
||||||
if (!ASSIMP_stricmp(child.name(), "node")) {
|
if (!ASSIMP_stricmp(child.name(), "node")) {
|
||||||
|
|
|
@ -56,7 +56,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
using namespace Assimp;
|
using namespace Assimp;
|
||||||
|
|
||||||
static const aiImporterDesc desc = {
|
static constexpr aiImporterDesc desc = {
|
||||||
"Irrlicht Mesh Reader",
|
"Irrlicht Mesh Reader",
|
||||||
"",
|
"",
|
||||||
"",
|
"",
|
||||||
|
|
|
@ -51,64 +51,56 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include "LWOLoader.h"
|
#include "LWOLoader.h"
|
||||||
using namespace Assimp;
|
using namespace Assimp;
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void LWOImporter::LoadLWOBFile()
|
void LWOImporter::LoadLWOBFile() {
|
||||||
{
|
|
||||||
LE_NCONST uint8_t* const end = mFileBuffer + fileSize;
|
LE_NCONST uint8_t* const end = mFileBuffer + fileSize;
|
||||||
bool running = true;
|
bool running = true;
|
||||||
while (running)
|
while (running) {
|
||||||
{
|
if (mFileBuffer + sizeof(IFF::ChunkHeader) > end)
|
||||||
if (mFileBuffer + sizeof(IFF::ChunkHeader) > end)break;
|
break;
|
||||||
const IFF::ChunkHeader head = IFF::LoadChunk(mFileBuffer);
|
const IFF::ChunkHeader head = IFF::LoadChunk(mFileBuffer);
|
||||||
|
|
||||||
if (mFileBuffer + head.length > end)
|
if (mFileBuffer + head.length > end) {
|
||||||
{
|
|
||||||
throw DeadlyImportError("LWOB: Invalid chunk length");
|
throw DeadlyImportError("LWOB: Invalid chunk length");
|
||||||
}
|
}
|
||||||
uint8_t* const next = mFileBuffer+head.length;
|
uint8_t* const next = mFileBuffer+head.length;
|
||||||
switch (head.type)
|
switch (head.type) {
|
||||||
{
|
|
||||||
// vertex list
|
// vertex list
|
||||||
case AI_LWO_PNTS:
|
case AI_LWO_PNTS: {
|
||||||
{
|
|
||||||
if (!mCurLayer->mTempPoints.empty())
|
if (!mCurLayer->mTempPoints.empty())
|
||||||
ASSIMP_LOG_WARN("LWO: PNTS chunk encountered twice");
|
ASSIMP_LOG_WARN("LWO: PNTS chunk encountered twice");
|
||||||
else LoadLWOPoints(head.length);
|
else
|
||||||
break;
|
LoadLWOPoints(head.length);
|
||||||
}
|
} break;
|
||||||
// face list
|
case AI_LWO_POLS: { // face list
|
||||||
case AI_LWO_POLS:
|
|
||||||
{
|
|
||||||
|
|
||||||
if (!mCurLayer->mFaces.empty())
|
if (!mCurLayer->mFaces.empty())
|
||||||
ASSIMP_LOG_WARN("LWO: POLS chunk encountered twice");
|
ASSIMP_LOG_WARN("LWO: POLS chunk encountered twice");
|
||||||
else LoadLWOBPolygons(head.length);
|
else
|
||||||
break;
|
LoadLWOBPolygons(head.length);
|
||||||
}
|
} break;
|
||||||
// list of tags
|
|
||||||
case AI_LWO_SRFS:
|
case AI_LWO_SRFS: // list of tags
|
||||||
{
|
{
|
||||||
if (!mTags->empty())
|
if (!mTags->empty())
|
||||||
ASSIMP_LOG_WARN("LWO: SRFS chunk encountered twice");
|
ASSIMP_LOG_WARN("LWO: SRFS chunk encountered twice");
|
||||||
else LoadLWOTags(head.length);
|
else
|
||||||
break;
|
LoadLWOTags(head.length);
|
||||||
}
|
} break;
|
||||||
|
|
||||||
// surface chunk
|
case AI_LWO_SURF: // surface chunk
|
||||||
case AI_LWO_SURF:
|
|
||||||
{
|
{
|
||||||
LoadLWOBSurface(head.length);
|
LoadLWOBSurface(head.length);
|
||||||
|
} break;
|
||||||
|
|
||||||
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
mFileBuffer = next;
|
mFileBuffer = next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void LWOImporter::LoadLWOBPolygons(unsigned int length)
|
void LWOImporter::LoadLWOBPolygons(unsigned int length) {
|
||||||
{
|
|
||||||
// first find out how many faces and vertices we'll finally need
|
// first find out how many faces and vertices we'll finally need
|
||||||
LE_NCONST uint16_t* const end = (LE_NCONST uint16_t*)(mFileBuffer+length);
|
LE_NCONST uint16_t* const end = (LE_NCONST uint16_t*)(mFileBuffer+length);
|
||||||
LE_NCONST uint16_t* cursor = (LE_NCONST uint16_t*)mFileBuffer;
|
LE_NCONST uint16_t* cursor = (LE_NCONST uint16_t*)mFileBuffer;
|
||||||
|
@ -123,8 +115,7 @@ void LWOImporter::LoadLWOBPolygons(unsigned int length)
|
||||||
CountVertsAndFacesLWOB(iNumVertices,iNumFaces,cursor,end);
|
CountVertsAndFacesLWOB(iNumVertices,iNumFaces,cursor,end);
|
||||||
|
|
||||||
// allocate the output array and copy face indices
|
// allocate the output array and copy face indices
|
||||||
if (iNumFaces)
|
if (iNumFaces) {
|
||||||
{
|
|
||||||
cursor = (LE_NCONST uint16_t*)mFileBuffer;
|
cursor = (LE_NCONST uint16_t*)mFileBuffer;
|
||||||
|
|
||||||
mCurLayer->mFaces.resize(iNumFaces);
|
mCurLayer->mFaces.resize(iNumFaces);
|
||||||
|
@ -135,10 +126,8 @@ void LWOImporter::LoadLWOBPolygons(unsigned int length)
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void LWOImporter::CountVertsAndFacesLWOB(unsigned int& verts, unsigned int& faces,
|
void LWOImporter::CountVertsAndFacesLWOB(unsigned int& verts, unsigned int& faces,
|
||||||
LE_NCONST uint16_t*& cursor, const uint16_t* const end, unsigned int max)
|
LE_NCONST uint16_t*& cursor, const uint16_t* const end, unsigned int max) {
|
||||||
{
|
while (cursor < end && max--) {
|
||||||
while (cursor < end && max--)
|
|
||||||
{
|
|
||||||
uint16_t numIndices;
|
uint16_t numIndices;
|
||||||
// must have 2 shorts left for numIndices and surface
|
// must have 2 shorts left for numIndices and surface
|
||||||
if (end - cursor < 2) {
|
if (end - cursor < 2) {
|
||||||
|
@ -154,8 +143,7 @@ void LWOImporter::CountVertsAndFacesLWOB(unsigned int& verts, unsigned int& face
|
||||||
cursor += numIndices;
|
cursor += numIndices;
|
||||||
int16_t surface;
|
int16_t surface;
|
||||||
::memcpy(&surface, cursor++, 2);
|
::memcpy(&surface, cursor++, 2);
|
||||||
if (surface < 0)
|
if (surface < 0) {
|
||||||
{
|
|
||||||
// there are detail polygons
|
// there are detail polygons
|
||||||
::memcpy(&numIndices, cursor++, 2);
|
::memcpy(&numIndices, cursor++, 2);
|
||||||
CountVertsAndFacesLWOB(verts,faces,cursor,end,numIndices);
|
CountVertsAndFacesLWOB(verts,faces,cursor,end,numIndices);
|
||||||
|
@ -167,18 +155,14 @@ void LWOImporter::CountVertsAndFacesLWOB(unsigned int& verts, unsigned int& face
|
||||||
void LWOImporter::CopyFaceIndicesLWOB(FaceList::iterator& it,
|
void LWOImporter::CopyFaceIndicesLWOB(FaceList::iterator& it,
|
||||||
LE_NCONST uint16_t*& cursor,
|
LE_NCONST uint16_t*& cursor,
|
||||||
const uint16_t* const end,
|
const uint16_t* const end,
|
||||||
unsigned int max)
|
unsigned int max) {
|
||||||
{
|
while (cursor < end && max--) {
|
||||||
while (cursor < end && max--)
|
|
||||||
{
|
|
||||||
LWO::Face& face = *it;++it;
|
LWO::Face& face = *it;++it;
|
||||||
uint16_t numIndices;
|
uint16_t numIndices;
|
||||||
::memcpy(&numIndices, cursor++, 2);
|
::memcpy(&numIndices, cursor++, 2);
|
||||||
face.mNumIndices = numIndices;
|
face.mNumIndices = numIndices;
|
||||||
if(face.mNumIndices)
|
if(face.mNumIndices) {
|
||||||
{
|
if (cursor + face.mNumIndices >= end) {
|
||||||
if (cursor + face.mNumIndices >= end)
|
|
||||||
{
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
face.mIndices = new unsigned int[face.mNumIndices];
|
face.mIndices = new unsigned int[face.mNumIndices];
|
||||||
|
@ -187,8 +171,7 @@ void LWOImporter::CopyFaceIndicesLWOB(FaceList::iterator& it,
|
||||||
uint16_t index;
|
uint16_t index;
|
||||||
::memcpy(&index, cursor++, 2);
|
::memcpy(&index, cursor++, 2);
|
||||||
mi = index;
|
mi = index;
|
||||||
if (mi > mCurLayer->mTempPoints.size())
|
if (mi > mCurLayer->mTempPoints.size()) {
|
||||||
{
|
|
||||||
ASSIMP_LOG_WARN("LWOB: face index is out of range");
|
ASSIMP_LOG_WARN("LWOB: face index is out of range");
|
||||||
mi = (unsigned int)mCurLayer->mTempPoints.size()-1;
|
mi = (unsigned int)mCurLayer->mTempPoints.size()-1;
|
||||||
}
|
}
|
||||||
|
@ -198,15 +181,13 @@ void LWOImporter::CopyFaceIndicesLWOB(FaceList::iterator& it,
|
||||||
}
|
}
|
||||||
int16_t surface;
|
int16_t surface;
|
||||||
::memcpy(&surface, cursor++, 2);
|
::memcpy(&surface, cursor++, 2);
|
||||||
if (surface < 0)
|
if (surface < 0) {
|
||||||
{
|
|
||||||
surface = -surface;
|
surface = -surface;
|
||||||
|
|
||||||
// there are detail polygons.
|
// there are detail polygons.
|
||||||
uint16_t numPolygons;
|
uint16_t numPolygons;
|
||||||
::memcpy(&numPolygons, cursor++, 2);
|
::memcpy(&numPolygons, cursor++, 2);
|
||||||
if (cursor < end)
|
if (cursor < end) {
|
||||||
{
|
|
||||||
CopyFaceIndicesLWOB(it,cursor,end,numPolygons);
|
CopyFaceIndicesLWOB(it,cursor,end,numPolygons);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -215,8 +196,7 @@ void LWOImporter::CopyFaceIndicesLWOB(FaceList::iterator& it,
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
LWO::Texture* LWOImporter::SetupNewTextureLWOB(LWO::TextureList& list,unsigned int size)
|
LWO::Texture* LWOImporter::SetupNewTextureLWOB(LWO::TextureList& list,unsigned int size) {
|
||||||
{
|
|
||||||
list.emplace_back();
|
list.emplace_back();
|
||||||
LWO::Texture* tex = &list.back();
|
LWO::Texture* tex = &list.back();
|
||||||
|
|
||||||
|
@ -224,8 +204,7 @@ LWO::Texture* LWOImporter::SetupNewTextureLWOB(LWO::TextureList& list,unsigned i
|
||||||
GetS0(type,size);
|
GetS0(type,size);
|
||||||
const char* s = type.c_str();
|
const char* s = type.c_str();
|
||||||
|
|
||||||
if(strstr(s, "Image Map"))
|
if(strstr(s, "Image Map")) {
|
||||||
{
|
|
||||||
// Determine mapping type
|
// Determine mapping type
|
||||||
if(strstr(s, "Planar"))
|
if(strstr(s, "Planar"))
|
||||||
tex->mapMode = LWO::Texture::Planar;
|
tex->mapMode = LWO::Texture::Planar;
|
||||||
|
@ -237,9 +216,7 @@ LWO::Texture* LWOImporter::SetupNewTextureLWOB(LWO::TextureList& list,unsigned i
|
||||||
tex->mapMode = LWO::Texture::Cubic;
|
tex->mapMode = LWO::Texture::Cubic;
|
||||||
else if(strstr(s, "Front"))
|
else if(strstr(s, "Front"))
|
||||||
tex->mapMode = LWO::Texture::FrontProjection;
|
tex->mapMode = LWO::Texture::FrontProjection;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
// procedural or gradient, not supported
|
// procedural or gradient, not supported
|
||||||
ASSIMP_LOG_ERROR("LWOB: Unsupported legacy texture: ", type);
|
ASSIMP_LOG_ERROR("LWOB: Unsupported legacy texture: ", type);
|
||||||
}
|
}
|
||||||
|
@ -248,8 +225,7 @@ LWO::Texture* LWOImporter::SetupNewTextureLWOB(LWO::TextureList& list,unsigned i
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void LWOImporter::LoadLWOBSurface(unsigned int size)
|
void LWOImporter::LoadLWOBSurface(unsigned int size) {
|
||||||
{
|
|
||||||
LE_NCONST uint8_t* const end = mFileBuffer + size;
|
LE_NCONST uint8_t* const end = mFileBuffer + size;
|
||||||
|
|
||||||
mSurfaces->push_back( LWO::Surface () );
|
mSurfaces->push_back( LWO::Surface () );
|
||||||
|
@ -277,8 +253,7 @@ void LWOImporter::LoadLWOBSurface(unsigned int size)
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t* const next = mFileBuffer+head.length;
|
uint8_t* const next = mFileBuffer+head.length;
|
||||||
switch (head.type)
|
switch (head.type) {
|
||||||
{
|
|
||||||
// diffuse color
|
// diffuse color
|
||||||
case AI_LWO_COLR:
|
case AI_LWO_COLR:
|
||||||
{
|
{
|
||||||
|
|
|
@ -63,7 +63,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
using namespace Assimp;
|
using namespace Assimp;
|
||||||
|
|
||||||
static const aiImporterDesc desc = {
|
static constexpr aiImporterDesc desc = {
|
||||||
"LightWave Scene Importer",
|
"LightWave Scene Importer",
|
||||||
"",
|
"",
|
||||||
"",
|
"",
|
||||||
|
@ -139,10 +139,6 @@ LWSImporter::LWSImporter() :
|
||||||
// nothing to do here
|
// nothing to do here
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
// Destructor, private as well
|
|
||||||
LWSImporter::~LWSImporter() = default;
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Returns whether the class can handle the format of the given file.
|
// Returns whether the class can handle the format of the given file.
|
||||||
bool LWSImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /*checkSig*/) const {
|
bool LWSImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /*checkSig*/) const {
|
||||||
|
|
|
@ -174,7 +174,7 @@ struct NodeDesc {
|
||||||
class LWSImporter : public BaseImporter {
|
class LWSImporter : public BaseImporter {
|
||||||
public:
|
public:
|
||||||
LWSImporter();
|
LWSImporter();
|
||||||
~LWSImporter() override;
|
~LWSImporter() override = default;
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
// Check whether we can read a specific file
|
// Check whether we can read a specific file
|
||||||
|
|
|
@ -85,7 +85,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
are listed in aiScene->mRootNode->children, but all without meshes
|
are listed in aiScene->mRootNode->children, but all without meshes
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static const aiImporterDesc desc = {
|
static constexpr aiImporterDesc desc = {
|
||||||
"Model 3D Importer",
|
"Model 3D Importer",
|
||||||
"",
|
"",
|
||||||
"",
|
"",
|
||||||
|
|
|
@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
|
||||||
|
|
||||||
Copyright (c) 2006-2022, assimp team
|
Copyright (c) 2006-2022, assimp team
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use of this software in source and binary forms,
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
@ -41,7 +39,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
---------------------------------------------------------------------------
|
---------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef ASSIMP_BUILD_NO_MD2_IMPORTER
|
#ifndef ASSIMP_BUILD_NO_MD2_IMPORTER
|
||||||
|
|
||||||
/** @file Implementation of the MD2 importer class */
|
/** @file Implementation of the MD2 importer class */
|
||||||
|
@ -65,7 +62,7 @@ using namespace Assimp::MD2;
|
||||||
# define ARRAYSIZE(_array) (int(sizeof(_array) / sizeof(_array[0])))
|
# define ARRAYSIZE(_array) (int(sizeof(_array) / sizeof(_array[0])))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static const aiImporterDesc desc = {
|
static constexpr aiImporterDesc desc = {
|
||||||
"Quake II Mesh Importer",
|
"Quake II Mesh Importer",
|
||||||
"",
|
"",
|
||||||
"",
|
"",
|
||||||
|
@ -79,7 +76,7 @@ static const aiImporterDesc desc = {
|
||||||
};
|
};
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Helper function to lookup a normal in Quake 2's precalculated table
|
// Helper function to lookup a normal in Quake 2's pre-calculated table
|
||||||
void MD2::LookupNormalIndex(uint8_t iNormalIndex,aiVector3D& vOut)
|
void MD2::LookupNormalIndex(uint8_t iNormalIndex,aiVector3D& vOut)
|
||||||
{
|
{
|
||||||
// make sure the normal index has a valid value
|
// make sure the normal index has a valid value
|
||||||
|
@ -100,10 +97,6 @@ MD2Importer::MD2Importer()
|
||||||
fileSize()
|
fileSize()
|
||||||
{}
|
{}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
// Destructor, private as well
|
|
||||||
MD2Importer::~MD2Importer() = default;
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Returns whether the class can handle the format of the given file.
|
// Returns whether the class can handle the format of the given file.
|
||||||
bool MD2Importer::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool /*checkSig*/) const
|
bool MD2Importer::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool /*checkSig*/) const
|
||||||
|
|
|
@ -63,7 +63,7 @@ using namespace MD2;
|
||||||
class MD2Importer : public BaseImporter {
|
class MD2Importer : public BaseImporter {
|
||||||
public:
|
public:
|
||||||
MD2Importer();
|
MD2Importer();
|
||||||
~MD2Importer() override;
|
~MD2Importer() override = default;
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Returns whether the class can handle the format of the given file.
|
/** Returns whether the class can handle the format of the given file.
|
||||||
|
|
|
@ -70,7 +70,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
using namespace Assimp;
|
using namespace Assimp;
|
||||||
|
|
||||||
static const aiImporterDesc desc = {
|
static constexpr aiImporterDesc desc = {
|
||||||
"Quake III Mesh Importer",
|
"Quake III Mesh Importer",
|
||||||
"",
|
"",
|
||||||
"",
|
"",
|
||||||
|
|
|
@ -64,7 +64,7 @@ using namespace Assimp;
|
||||||
// Minimum weight value. Weights inside [-n ... n] are ignored
|
// Minimum weight value. Weights inside [-n ... n] are ignored
|
||||||
#define AI_MD5_WEIGHT_EPSILON Math::getEpsilon<float>()
|
#define AI_MD5_WEIGHT_EPSILON Math::getEpsilon<float>()
|
||||||
|
|
||||||
static const aiImporterDesc desc = {
|
static constexpr aiImporterDesc desc = {
|
||||||
"Doom 3 / MD5 Mesh Importer",
|
"Doom 3 / MD5 Mesh Importer",
|
||||||
"",
|
"",
|
||||||
"",
|
"",
|
||||||
|
@ -92,10 +92,6 @@ MD5Importer::MD5Importer() :
|
||||||
// empty
|
// empty
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
// Destructor, private as well
|
|
||||||
MD5Importer::~MD5Importer() = default;
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Returns whether the class can handle the format of the given file.
|
// Returns whether the class can handle the format of the given file.
|
||||||
bool MD5Importer::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /*checkSig*/) const {
|
bool MD5Importer::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /*checkSig*/) const {
|
||||||
|
|
|
@ -65,7 +65,7 @@ using namespace Assimp::MD5;
|
||||||
class MD5Importer : public BaseImporter {
|
class MD5Importer : public BaseImporter {
|
||||||
public:
|
public:
|
||||||
MD5Importer();
|
MD5Importer();
|
||||||
~MD5Importer() override;
|
~MD5Importer() override = default;
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Returns whether the class can handle the format of the given file.
|
/** Returns whether the class can handle the format of the given file.
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
---------------------------------------------------------------------------
|
---------------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright (c) 2006-2022, assimp team
|
Copyright (c) 2006-2023, assimp team
|
||||||
|
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
|
@ -87,7 +87,7 @@ MD5Parser::MD5Parser(char *_buffer, unsigned int _fileSize) : buffer(_buffer), b
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Report error to the log stream
|
// Report error to the log stream
|
||||||
/*static*/ AI_WONT_RETURN void MD5Parser::ReportError(const char *error, unsigned int line) {
|
AI_WONT_RETURN void MD5Parser::ReportError(const char *error, unsigned int line) {
|
||||||
char szBuffer[1024];
|
char szBuffer[1024];
|
||||||
::ai_snprintf(szBuffer, 1024, "[MD5] Line %u: %s", line, error);
|
::ai_snprintf(szBuffer, 1024, "[MD5] Line %u: %s", line, error);
|
||||||
throw DeadlyImportError(szBuffer);
|
throw DeadlyImportError(szBuffer);
|
||||||
|
@ -95,7 +95,7 @@ MD5Parser::MD5Parser(char *_buffer, unsigned int _fileSize) : buffer(_buffer), b
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Report warning to the log stream
|
// Report warning to the log stream
|
||||||
/*static*/ void MD5Parser::ReportWarning(const char *warn, unsigned int line) {
|
void MD5Parser::ReportWarning(const char *warn, unsigned int line) {
|
||||||
char szBuffer[1024];
|
char szBuffer[1024];
|
||||||
::snprintf(szBuffer, sizeof(szBuffer), "[MD5] Line %u: %s", line, warn);
|
::snprintf(szBuffer, sizeof(szBuffer), "[MD5] Line %u: %s", line, warn);
|
||||||
ASSIMP_LOG_WARN(szBuffer);
|
ASSIMP_LOG_WARN(szBuffer);
|
||||||
|
@ -122,8 +122,8 @@ void MD5Parser::ParseHeader() {
|
||||||
// print the command line options to the console
|
// print the command line options to the console
|
||||||
// FIX: can break the log length limit, so we need to be careful
|
// FIX: can break the log length limit, so we need to be careful
|
||||||
char *sz = buffer;
|
char *sz = buffer;
|
||||||
while (!IsLineEnd(*buffer++))
|
while (!IsLineEnd(*buffer++));
|
||||||
;
|
|
||||||
ASSIMP_LOG_INFO(std::string(sz, std::min((uintptr_t)MAX_LOG_MESSAGE_LENGTH, (uintptr_t)(buffer - sz))));
|
ASSIMP_LOG_INFO(std::string(sz, std::min((uintptr_t)MAX_LOG_MESSAGE_LENGTH, (uintptr_t)(buffer - sz))));
|
||||||
SkipSpacesAndLineEnd();
|
SkipSpacesAndLineEnd();
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,8 +2,7 @@
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright (c) 2006-2022, assimp team
|
Copyright (c) 2006-2023, assimp team
|
||||||
|
|
||||||
|
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
|
@ -93,7 +92,7 @@ struct Section {
|
||||||
std::string mName;
|
std::string mName;
|
||||||
|
|
||||||
//! For global elements: the value of the element as string
|
//! For global elements: the value of the element as string
|
||||||
//! Iif !length() the section is not a global element
|
//! if !length() the section is not a global element
|
||||||
std::string mGlobalValue;
|
std::string mGlobalValue;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -349,7 +348,6 @@ public:
|
||||||
*/
|
*/
|
||||||
MD5Parser(char* buffer, unsigned int fileSize);
|
MD5Parser(char* buffer, unsigned int fileSize);
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Report a specific error message and throw an exception
|
/** Report a specific error message and throw an exception
|
||||||
* @param error Error message to be reported
|
* @param error Error message to be reported
|
||||||
|
@ -364,47 +362,47 @@ public:
|
||||||
*/
|
*/
|
||||||
static void ReportWarning(const char* warn, unsigned int line);
|
static void ReportWarning(const char* warn, unsigned int line);
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
/** Report a specific error
|
||||||
|
* @param error Error message to be reported
|
||||||
|
*/
|
||||||
AI_WONT_RETURN void ReportError (const char* error) AI_WONT_RETURN_SUFFIX;
|
AI_WONT_RETURN void ReportError (const char* error) AI_WONT_RETURN_SUFFIX;
|
||||||
|
|
||||||
void ReportWarning (const char* warn) {
|
// -------------------------------------------------------------------
|
||||||
return ReportWarning(warn, lineNumber);
|
/** Report a specific warning
|
||||||
}
|
* @param error Warn message to be reported
|
||||||
|
*/
|
||||||
|
void ReportWarning (const char* warn);
|
||||||
|
|
||||||
//! List of all sections which have been read
|
//! List of all sections which have been read
|
||||||
SectionList mSections;
|
SectionList mSections;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// -------------------------------------------------------------------
|
|
||||||
/** Parses a file section. The current file pointer must be outside
|
|
||||||
* of a section.
|
|
||||||
* @param out Receives the section data
|
|
||||||
* @return true if the end of the file has been reached
|
|
||||||
* @throws ImportErrorException if an error occurs
|
|
||||||
*/
|
|
||||||
bool ParseSection(Section& out);
|
bool ParseSection(Section& out);
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
|
||||||
/** Parses the file header
|
|
||||||
* @throws ImportErrorException if an error occurs
|
|
||||||
*/
|
|
||||||
void ParseHeader();
|
void ParseHeader();
|
||||||
|
|
||||||
bool SkipLine(const char* in, const char** out);
|
bool SkipLine(const char* in, const char** out);
|
||||||
bool SkipLine( );
|
bool SkipLine( );
|
||||||
bool SkipSpacesAndLineEnd( const char* in, const char** out);
|
bool SkipSpacesAndLineEnd( const char* in, const char** out);
|
||||||
bool SkipSpacesAndLineEnd();
|
bool SkipSpacesAndLineEnd();
|
||||||
bool SkipSpaces();
|
bool SkipSpaces();
|
||||||
|
|
||||||
|
private:
|
||||||
char* buffer;
|
char* buffer;
|
||||||
char* bufferEnd;
|
char* bufferEnd;
|
||||||
unsigned int fileSize;
|
unsigned int fileSize;
|
||||||
unsigned int lineNumber;
|
unsigned int lineNumber;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
inline void MD5Parser::ReportWarning (const char* warn) {
|
||||||
|
return ReportWarning(warn, lineNumber);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
inline void MD5Parser::ReportError(const char* error) {
|
inline void MD5Parser::ReportError(const char* error) {
|
||||||
ReportError(error, lineNumber);
|
ReportError(error, lineNumber);
|
||||||
}
|
}
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
inline bool MD5Parser::SkipLine(const char* in, const char** out) {
|
inline bool MD5Parser::SkipLine(const char* in, const char** out) {
|
||||||
++lineNumber;
|
++lineNumber;
|
||||||
|
@ -418,8 +416,12 @@ inline bool MD5Parser::SkipLine( ) {
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
inline bool MD5Parser::SkipSpacesAndLineEnd( const char* in, const char** out) {
|
inline bool MD5Parser::SkipSpacesAndLineEnd( const char* in, const char** out) {
|
||||||
bool bHad = false;
|
if (in == bufferEnd) {
|
||||||
bool running = true;
|
*out = in;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool bHad = false, running = true;
|
||||||
while (running) {
|
while (running) {
|
||||||
if( *in == '\r' || *in == '\n') {
|
if( *in == '\r' || *in == '\n') {
|
||||||
// we open files in binary mode, so there could be \r\n sequences ...
|
// we open files in binary mode, so there could be \r\n sequences ...
|
||||||
|
@ -427,9 +429,11 @@ inline bool MD5Parser::SkipSpacesAndLineEnd( const char* in, const char** out) {
|
||||||
bHad = true;
|
bHad = true;
|
||||||
++lineNumber;
|
++lineNumber;
|
||||||
}
|
}
|
||||||
|
} else if (*in == '\t' || *in == ' ') {
|
||||||
|
bHad = false;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
else if (*in == '\t' || *in == ' ')bHad = false;
|
|
||||||
else break;
|
|
||||||
++in;
|
++in;
|
||||||
if (in == bufferEnd) {
|
if (in == bufferEnd) {
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -60,7 +60,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
using namespace Assimp;
|
using namespace Assimp;
|
||||||
using namespace Assimp::MDC;
|
using namespace Assimp::MDC;
|
||||||
|
|
||||||
static const aiImporterDesc desc = {
|
static constexpr aiImporterDesc desc = {
|
||||||
"Return To Castle Wolfenstein Mesh Importer",
|
"Return To Castle Wolfenstein Mesh Importer",
|
||||||
"",
|
"",
|
||||||
"",
|
"",
|
||||||
|
@ -103,10 +103,6 @@ MDCImporter::MDCImporter() :
|
||||||
// empty
|
// empty
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
// Destructor, private as well
|
|
||||||
MDCImporter::~MDCImporter() = default;
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Returns whether the class can handle the format of the given file.
|
// Returns whether the class can handle the format of the given file.
|
||||||
bool MDCImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /*checkSig*/) const {
|
bool MDCImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /*checkSig*/) const {
|
||||||
|
|
|
@ -62,7 +62,7 @@ using namespace MDC;
|
||||||
class MDCImporter : public BaseImporter {
|
class MDCImporter : public BaseImporter {
|
||||||
public:
|
public:
|
||||||
MDCImporter();
|
MDCImporter();
|
||||||
~MDCImporter() override;
|
~MDCImporter() override = default;
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Returns whether the class can handle the format of the given file.
|
/** Returns whether the class can handle the format of the given file.
|
||||||
|
|
|
@ -65,7 +65,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
using namespace Assimp;
|
using namespace Assimp;
|
||||||
|
|
||||||
static const aiImporterDesc desc = {
|
static constexpr aiImporterDesc desc = {
|
||||||
"Quake Mesh / 3D GameStudio Mesh Importer",
|
"Quake Mesh / 3D GameStudio Mesh Importer",
|
||||||
"",
|
"",
|
||||||
"",
|
"",
|
||||||
|
@ -96,10 +96,6 @@ MDLImporter::MDLImporter() :
|
||||||
// empty
|
// empty
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
// Destructor, private as well
|
|
||||||
MDLImporter::~MDLImporter() = default;
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Returns whether the class can handle the format of the given file.
|
// Returns whether the class can handle the format of the given file.
|
||||||
bool MDLImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /*checkSig*/) const {
|
bool MDLImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /*checkSig*/) const {
|
||||||
|
|
|
@ -39,10 +39,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/// @file MDLLoader.h
|
||||||
/** @file MDLLoader.h
|
/// @brief Declaration of the loader for MDL files
|
||||||
* @brief Declaration of the loader for MDL files
|
|
||||||
*/
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#ifndef AI_MDLLOADER_H_INCLUDED
|
#ifndef AI_MDLLOADER_H_INCLUDED
|
||||||
#define AI_MDLLOADER_H_INCLUDED
|
#define AI_MDLLOADER_H_INCLUDED
|
||||||
|
@ -83,11 +81,10 @@ using namespace MDL;
|
||||||
* them all with a single 1000-line function-beast. However, it has been
|
* them all with a single 1000-line function-beast. However, it has been
|
||||||
* split into several code paths to make the code easier to read and maintain.
|
* split into several code paths to make the code easier to read and maintain.
|
||||||
*/
|
*/
|
||||||
class MDLImporter : public BaseImporter
|
class MDLImporter : public BaseImporter {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
MDLImporter();
|
MDLImporter();
|
||||||
~MDLImporter() override;
|
~MDLImporter() override = default;
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Returns whether the class can handle the format of the given file.
|
/** Returns whether the class can handle the format of the given file.
|
||||||
|
|
|
@ -123,9 +123,8 @@ aiColor4D MDLImporter::ReplaceTextureWithColor(const aiTexture *pcTexture) {
|
||||||
// Read a texture from a MDL3 file
|
// Read a texture from a MDL3 file
|
||||||
void MDLImporter::CreateTextureARGB8_3DGS_MDL3(const unsigned char *szData) {
|
void MDLImporter::CreateTextureARGB8_3DGS_MDL3(const unsigned char *szData) {
|
||||||
const MDL::Header *pcHeader = (const MDL::Header *)mBuffer; //the endianness is already corrected in the InternReadFile_3DGS_MDL345 function
|
const MDL::Header *pcHeader = (const MDL::Header *)mBuffer; //the endianness is already corrected in the InternReadFile_3DGS_MDL345 function
|
||||||
|
const size_t len = pcHeader->skinwidth * pcHeader->skinheight;
|
||||||
VALIDATE_FILE_SIZE(szData + pcHeader->skinwidth *
|
VALIDATE_FILE_SIZE(szData + len);
|
||||||
pcHeader->skinheight);
|
|
||||||
|
|
||||||
// allocate a new texture object
|
// allocate a new texture object
|
||||||
aiTexture *pcNew = new aiTexture();
|
aiTexture *pcNew = new aiTexture();
|
||||||
|
|
|
@ -57,7 +57,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
static const aiImporterDesc desc = { "MMD Importer",
|
static constexpr aiImporterDesc desc = { "MMD Importer",
|
||||||
"",
|
"",
|
||||||
"",
|
"",
|
||||||
"surfaces supported?",
|
"surfaces supported?",
|
||||||
|
@ -81,10 +81,6 @@ MMDImporter::MMDImporter() :
|
||||||
m_strAbsPath = io.getOsSeparator();
|
m_strAbsPath = io.getOsSeparator();
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
// Destructor.
|
|
||||||
MMDImporter::~MMDImporter() = default;
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Returns true, if file is an pmx file.
|
// Returns true, if file is an pmx file.
|
||||||
bool MMDImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler,
|
bool MMDImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler,
|
||||||
|
|
|
@ -50,46 +50,34 @@ struct aiMesh;
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
/// \class MMDImporter
|
/// @class MMDImporter
|
||||||
/// \brief Imports MMD a pmx/pmd/vmd file
|
/// @brief Imports MMD a pmx/pmd/vmd file
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
class MMDImporter : public BaseImporter {
|
class MMDImporter : public BaseImporter {
|
||||||
public:
|
public:
|
||||||
/// \brief Default constructor
|
/// @brief Default constructor
|
||||||
MMDImporter();
|
MMDImporter();
|
||||||
|
|
||||||
/// \brief Destructor
|
/// @brief Destructor
|
||||||
~MMDImporter() override;
|
~MMDImporter() override = default;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/// \brief Returns whether the class can handle the format of the given file.
|
/// @brief Returns whether the class can handle the format of the given file.
|
||||||
/// \remark See BaseImporter::CanRead() for details.
|
/// @remark See BaseImporter::CanRead() for details.
|
||||||
bool CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const override;
|
bool CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
//! \brief Appends the supported extension.
|
|
||||||
const aiImporterDesc* GetInfo() const override;
|
const aiImporterDesc* GetInfo() const override;
|
||||||
|
|
||||||
//! \brief File import implementation.
|
|
||||||
void InternReadFile(const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler) override;
|
void InternReadFile(const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler) override;
|
||||||
|
|
||||||
//! \brief Create the data from imported content.
|
|
||||||
void CreateDataFromImport(const pmx::PmxModel* pModel, aiScene* pScene);
|
void CreateDataFromImport(const pmx::PmxModel* pModel, aiScene* pScene);
|
||||||
|
|
||||||
//! \brief Create the mesh
|
|
||||||
aiMesh* CreateMesh(const pmx::PmxModel* pModel, const int indexStart, const int indexCount);
|
aiMesh* CreateMesh(const pmx::PmxModel* pModel, const int indexStart, const int indexCount);
|
||||||
|
|
||||||
//! \brief Create the material
|
|
||||||
aiMaterial* CreateMaterial(const pmx::PmxMaterial* pMat, const pmx::PmxModel* pModel);
|
aiMaterial* CreateMaterial(const pmx::PmxMaterial* pMat, const pmx::PmxModel* pModel);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
//! Data buffer
|
|
||||||
std::vector<char> m_Buffer;
|
std::vector<char> m_Buffer;
|
||||||
//! Absolute pathname of model in file system
|
|
||||||
std::string m_strAbsPath;
|
std::string m_strAbsPath;
|
||||||
};
|
};
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
} // Namespace Assimp
|
} // Namespace Assimp
|
||||||
|
|
||||||
|
|
|
@ -42,11 +42,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include "MMDPmxParser.h"
|
#include "MMDPmxParser.h"
|
||||||
#include <assimp/StringUtils.h>
|
#include <assimp/StringUtils.h>
|
||||||
#ifdef ASSIMP_USE_HUNTER
|
#include "utf8.h"
|
||||||
# include <utf8.h>
|
|
||||||
#else
|
|
||||||
# include "../contrib/utf8cpp/source/utf8.h"
|
|
||||||
#endif
|
|
||||||
#include <assimp/Exceptional.h>
|
#include <assimp/Exceptional.h>
|
||||||
|
|
||||||
namespace pmx
|
namespace pmx
|
||||||
|
@ -93,7 +89,7 @@ namespace pmx
|
||||||
{
|
{
|
||||||
return std::string();
|
return std::string();
|
||||||
}
|
}
|
||||||
buffer.reserve(size);
|
buffer.resize(size);
|
||||||
stream->read((char*) buffer.data(), size);
|
stream->read((char*) buffer.data(), size);
|
||||||
if (encoding == 0)
|
if (encoding == 0)
|
||||||
{
|
{
|
||||||
|
|
|
@ -60,7 +60,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
using namespace Assimp;
|
using namespace Assimp;
|
||||||
|
|
||||||
static const aiImporterDesc desc = {
|
static constexpr aiImporterDesc desc = {
|
||||||
"Milkshape 3D Importer",
|
"Milkshape 3D Importer",
|
||||||
"",
|
"",
|
||||||
"",
|
"",
|
||||||
|
@ -84,9 +84,6 @@ MS3DImporter::MS3DImporter()
|
||||||
: mScene()
|
: mScene()
|
||||||
{}
|
{}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
// Destructor, private as well
|
|
||||||
MS3DImporter::~MS3DImporter() = default;
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Returns whether the class can handle the format of the given file.
|
// Returns whether the class can handle the format of the given file.
|
||||||
bool MS3DImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool /*checkSig*/) const
|
bool MS3DImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool /*checkSig*/) const
|
||||||
|
|
|
@ -48,6 +48,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
#include <assimp/BaseImporter.h>
|
#include <assimp/BaseImporter.h>
|
||||||
#include <assimp/StreamReader.h>
|
#include <assimp/StreamReader.h>
|
||||||
|
|
||||||
struct aiNode;
|
struct aiNode;
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
|
@ -58,7 +59,7 @@ namespace Assimp {
|
||||||
class MS3DImporter : public BaseImporter {
|
class MS3DImporter : public BaseImporter {
|
||||||
public:
|
public:
|
||||||
MS3DImporter();
|
MS3DImporter();
|
||||||
~MS3DImporter() override;
|
~MS3DImporter() override = default;
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Returns whether the class can handle the format of the given file.
|
/** Returns whether the class can handle the format of the given file.
|
||||||
|
|
|
@ -43,8 +43,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
* Implementation of the NDO importer class.
|
* Implementation of the NDO importer class.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef ASSIMP_BUILD_NO_NDO_IMPORTER
|
#ifndef ASSIMP_BUILD_NO_NDO_IMPORTER
|
||||||
|
|
||||||
#include "NDOLoader.h"
|
#include "NDOLoader.h"
|
||||||
#include <assimp/DefaultLogger.hpp>
|
#include <assimp/DefaultLogger.hpp>
|
||||||
#include <assimp/IOSystem.hpp>
|
#include <assimp/IOSystem.hpp>
|
||||||
|
@ -56,7 +56,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
using namespace Assimp;
|
using namespace Assimp;
|
||||||
|
|
||||||
static const aiImporterDesc desc = {
|
static constexpr aiImporterDesc desc = {
|
||||||
"Nendo Mesh Importer",
|
"Nendo Mesh Importer",
|
||||||
"",
|
"",
|
||||||
"",
|
"",
|
||||||
|
@ -69,14 +69,6 @@ static const aiImporterDesc desc = {
|
||||||
"ndo"
|
"ndo"
|
||||||
};
|
};
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
// Constructor to be privately used by Importer
|
|
||||||
NDOImporter::NDOImporter() = default;
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
// Destructor, private as well
|
|
||||||
NDOImporter::~NDOImporter() = default;
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Returns whether the class can handle the format of the given file.
|
// Returns whether the class can handle the format of the given file.
|
||||||
bool NDOImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool /*checkSig*/) const
|
bool NDOImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool /*checkSig*/) const
|
||||||
|
|
|
@ -65,8 +65,8 @@ class Importer;
|
||||||
*/
|
*/
|
||||||
class NDOImporter : public BaseImporter {
|
class NDOImporter : public BaseImporter {
|
||||||
public:
|
public:
|
||||||
NDOImporter();
|
NDOImporter() = default;
|
||||||
~NDOImporter() override;
|
~NDOImporter() override = default;
|
||||||
|
|
||||||
//! Represents a single edge
|
//! Represents a single edge
|
||||||
struct Edge {
|
struct Edge {
|
||||||
|
|
|
@ -56,9 +56,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <assimp/IOSystem.hpp>
|
#include <assimp/IOSystem.hpp>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
using namespace Assimp;
|
namespace Assimp {
|
||||||
|
|
||||||
static const aiImporterDesc desc = {
|
static constexpr aiImporterDesc desc = {
|
||||||
"Neutral File Format Importer",
|
"Neutral File Format Importer",
|
||||||
"",
|
"",
|
||||||
"",
|
"",
|
||||||
|
@ -71,14 +71,6 @@ static const aiImporterDesc desc = {
|
||||||
"enff nff"
|
"enff nff"
|
||||||
};
|
};
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
// Constructor to be privately used by Importer
|
|
||||||
NFFImporter::NFFImporter() = default;
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
// Destructor, private as well
|
|
||||||
NFFImporter::~NFFImporter() = default;
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Returns whether the class can handle the format of the given file.
|
// Returns whether the class can handle the format of the given file.
|
||||||
bool NFFImporter::CanRead(const std::string & pFile, IOSystem * /*pIOHandler*/, bool /*checkSig*/) const {
|
bool NFFImporter::CanRead(const std::string & pFile, IOSystem * /*pIOHandler*/, bool /*checkSig*/) const {
|
||||||
|
@ -94,7 +86,7 @@ const aiImporterDesc *NFFImporter::GetInfo() const {
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
#define AI_NFF_PARSE_FLOAT(f) \
|
#define AI_NFF_PARSE_FLOAT(f) \
|
||||||
SkipSpaces(&sz); \
|
SkipSpaces(&sz); \
|
||||||
if (!::IsLineEnd(*sz)) sz = fast_atoreal_move<ai_real>(sz, (ai_real &)f);
|
if (!IsLineEnd(*sz)) sz = fast_atoreal_move<ai_real>(sz, (ai_real &)f);
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
#define AI_NFF_PARSE_TRIPLE(v) \
|
#define AI_NFF_PARSE_TRIPLE(v) \
|
||||||
|
@ -338,8 +330,8 @@ void NFFImporter::InternReadFile(const std::string &pFile,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// read the numbr of vertices
|
// read the number of vertices
|
||||||
unsigned int num = ::strtoul10(sz, &sz);
|
unsigned int num = strtoul10(sz, &sz);
|
||||||
|
|
||||||
// temporary storage
|
// temporary storage
|
||||||
std::vector<aiColor4D> tempColors;
|
std::vector<aiColor4D> tempColors;
|
||||||
|
@ -365,7 +357,7 @@ void NFFImporter::InternReadFile(const std::string &pFile,
|
||||||
// color definition
|
// color definition
|
||||||
if (TokenMatch(sz, "0x", 2)) {
|
if (TokenMatch(sz, "0x", 2)) {
|
||||||
hasColor = true;
|
hasColor = true;
|
||||||
unsigned int numIdx = ::strtoul16(sz, &sz);
|
unsigned int numIdx = strtoul16(sz, &sz);
|
||||||
aiColor4D clr;
|
aiColor4D clr;
|
||||||
clr.a = 1.f;
|
clr.a = 1.f;
|
||||||
|
|
||||||
|
@ -403,15 +395,16 @@ void NFFImporter::InternReadFile(const std::string &pFile,
|
||||||
}
|
}
|
||||||
|
|
||||||
AI_NFF2_GET_NEXT_TOKEN();
|
AI_NFF2_GET_NEXT_TOKEN();
|
||||||
if (!num) throw DeadlyImportError("NFF2: There are zero vertices");
|
if (!num)
|
||||||
num = ::strtoul10(sz, &sz);
|
throw DeadlyImportError("NFF2: There are zero vertices");
|
||||||
|
num = strtoul10(sz, &sz);
|
||||||
|
|
||||||
std::vector<unsigned int> tempIdx;
|
std::vector<unsigned int> tempIdx;
|
||||||
tempIdx.reserve(10);
|
tempIdx.reserve(10);
|
||||||
for (unsigned int i = 0; i < num; ++i) {
|
for (unsigned int i = 0; i < num; ++i) {
|
||||||
AI_NFF2_GET_NEXT_TOKEN();
|
AI_NFF2_GET_NEXT_TOKEN();
|
||||||
SkipSpaces(line, &sz);
|
SkipSpaces(line, &sz);
|
||||||
unsigned int numIdx = ::strtoul10(sz, &sz);
|
unsigned int numIdx = strtoul10(sz, &sz);
|
||||||
|
|
||||||
// read all faces indices
|
// read all faces indices
|
||||||
if (numIdx) {
|
if (numIdx) {
|
||||||
|
@ -421,7 +414,7 @@ void NFFImporter::InternReadFile(const std::string &pFile,
|
||||||
|
|
||||||
for (unsigned int a = 0; a < numIdx; ++a) {
|
for (unsigned int a = 0; a < numIdx; ++a) {
|
||||||
SkipSpaces(sz, &sz);
|
SkipSpaces(sz, &sz);
|
||||||
unsigned int m = ::strtoul10(sz, &sz);
|
unsigned int m = strtoul10(sz, &sz);
|
||||||
if (m >= (unsigned int)tempPositions.size()) {
|
if (m >= (unsigned int)tempPositions.size()) {
|
||||||
ASSIMP_LOG_ERROR("NFF2: Vertex index overflow");
|
ASSIMP_LOG_ERROR("NFF2: Vertex index overflow");
|
||||||
m = 0;
|
m = 0;
|
||||||
|
@ -446,7 +439,7 @@ void NFFImporter::InternReadFile(const std::string &pFile,
|
||||||
if (TokenMatch(sz, "0x", 2)) {
|
if (TokenMatch(sz, "0x", 2)) {
|
||||||
hasColor = true;
|
hasColor = true;
|
||||||
const char *sz2 = sz;
|
const char *sz2 = sz;
|
||||||
numIdx = ::strtoul16(sz, &sz);
|
numIdx = strtoul16(sz, &sz);
|
||||||
const unsigned int diff = (unsigned int)(sz - sz2);
|
const unsigned int diff = (unsigned int)(sz - sz2);
|
||||||
|
|
||||||
// 0xRRGGBB
|
// 0xRRGGBB
|
||||||
|
@ -518,7 +511,7 @@ void NFFImporter::InternReadFile(const std::string &pFile,
|
||||||
// Material ID?
|
// Material ID?
|
||||||
else if (!materialTable.empty() && TokenMatch(sz, "matid", 5)) {
|
else if (!materialTable.empty() && TokenMatch(sz, "matid", 5)) {
|
||||||
SkipSpaces(&sz);
|
SkipSpaces(&sz);
|
||||||
matIdx = ::strtoul10(sz, &sz);
|
matIdx = strtoul10(sz, &sz);
|
||||||
if (matIdx >= materialTable.size()) {
|
if (matIdx >= materialTable.size()) {
|
||||||
ASSIMP_LOG_ERROR("NFF2: Material index overflow.");
|
ASSIMP_LOG_ERROR("NFF2: Material index overflow.");
|
||||||
matIdx = 0;
|
matIdx = 0;
|
||||||
|
@ -1165,4 +1158,6 @@ void NFFImporter::InternReadFile(const std::string &pFile,
|
||||||
pScene->mRootNode = root;
|
pScene->mRootNode = root;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace Assimp
|
||||||
|
|
||||||
#endif // !! ASSIMP_BUILD_NO_NFF_IMPORTER
|
#endif // !! ASSIMP_BUILD_NO_NFF_IMPORTER
|
||||||
|
|
|
@ -63,8 +63,8 @@ namespace Assimp {
|
||||||
*/
|
*/
|
||||||
class NFFImporter : public BaseImporter {
|
class NFFImporter : public BaseImporter {
|
||||||
public:
|
public:
|
||||||
NFFImporter();
|
NFFImporter() = default;
|
||||||
~NFFImporter() override;
|
~NFFImporter() override = default;
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Returns whether the class can handle the format of the given file.
|
/** Returns whether the class can handle the format of the given file.
|
||||||
|
|
|
@ -43,7 +43,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
* @brief Implementation of the OFF importer class
|
* @brief Implementation of the OFF importer class
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef ASSIMP_BUILD_NO_OFF_IMPORTER
|
#ifndef ASSIMP_BUILD_NO_OFF_IMPORTER
|
||||||
|
|
||||||
// internal headers
|
// internal headers
|
||||||
|
@ -56,9 +55,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <assimp/DefaultLogger.hpp>
|
#include <assimp/DefaultLogger.hpp>
|
||||||
#include <assimp/importerdesc.h>
|
#include <assimp/importerdesc.h>
|
||||||
|
|
||||||
using namespace Assimp;
|
namespace Assimp {
|
||||||
|
|
||||||
static const aiImporterDesc desc = {
|
static constexpr aiImporterDesc desc = {
|
||||||
"OFF Importer",
|
"OFF Importer",
|
||||||
"",
|
"",
|
||||||
"",
|
"",
|
||||||
|
@ -71,29 +70,18 @@ static const aiImporterDesc desc = {
|
||||||
"off"
|
"off"
|
||||||
};
|
};
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
// Constructor to be privately used by Importer
|
|
||||||
OFFImporter::OFFImporter() = default;
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
// Destructor, private as well
|
|
||||||
OFFImporter::~OFFImporter() = default;
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Returns whether the class can handle the format of the given file.
|
// Returns whether the class can handle the format of the given file.
|
||||||
bool OFFImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool /*checkSig*/) const
|
bool OFFImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /*checkSig*/) const {
|
||||||
{
|
|
||||||
static const char *tokens[] = { "off" };
|
static const char *tokens[] = { "off" };
|
||||||
return SearchFileHeaderForToken(pIOHandler, pFile, tokens, AI_COUNT_OF(tokens), 3);
|
return SearchFileHeaderForToken(pIOHandler, pFile, tokens, AI_COUNT_OF(tokens), 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
const aiImporterDesc* OFFImporter::GetInfo () const
|
const aiImporterDesc *OFFImporter::GetInfo() const {
|
||||||
{
|
|
||||||
return &desc;
|
return &desc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// skip blank space, lines and comments
|
// skip blank space, lines and comments
|
||||||
static void NextToken(const char **car, const char *end) {
|
static void NextToken(const char **car, const char *end) {
|
||||||
SkipSpacesAndLineEnd(car);
|
SkipSpacesAndLineEnd(car);
|
||||||
|
@ -127,19 +115,24 @@ void OFFImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOS
|
||||||
NextToken(&car, end);
|
NextToken(&car, end);
|
||||||
|
|
||||||
if (car < end - 2 && car[0] == 'S' && car[1] == 'T') {
|
if (car < end - 2 && car[0] == 'S' && car[1] == 'T') {
|
||||||
hasTexCoord = true; car += 2;
|
hasTexCoord = true;
|
||||||
|
car += 2;
|
||||||
}
|
}
|
||||||
if (car < end - 1 && car[0] == 'C') {
|
if (car < end - 1 && car[0] == 'C') {
|
||||||
hasColors = true; car++;
|
hasColors = true;
|
||||||
|
car++;
|
||||||
}
|
}
|
||||||
if (car < end - 1 && car[0] == 'N') {
|
if (car < end - 1 && car[0] == 'N') {
|
||||||
hasNormals = true; car++;
|
hasNormals = true;
|
||||||
|
car++;
|
||||||
}
|
}
|
||||||
if (car < end - 1 && car[0] == '4') {
|
if (car < end - 1 && car[0] == '4') {
|
||||||
hasHomogenous = true; car++;
|
hasHomogenous = true;
|
||||||
|
car++;
|
||||||
}
|
}
|
||||||
if (car < end - 1 && car[0] == 'n') {
|
if (car < end - 1 && car[0] == 'n') {
|
||||||
hasDimension = true; car++;
|
hasDimension = true;
|
||||||
|
car++;
|
||||||
}
|
}
|
||||||
if (car < end - 3 && car[0] == 'O' && car[1] == 'F' && car[2] == 'F') {
|
if (car < end - 3 && car[0] == 'O' && car[1] == 'F' && car[2] == 'F') {
|
||||||
car += 3;
|
car += 3;
|
||||||
|
@ -162,8 +155,7 @@ void OFFImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOS
|
||||||
NextToken(&car, end);
|
NextToken(&car, end);
|
||||||
}
|
}
|
||||||
if (dimensions > 3) {
|
if (dimensions > 3) {
|
||||||
throw DeadlyImportError
|
throw DeadlyImportError("OFF: Number of vertex coordinates higher than 3 unsupported");
|
||||||
("OFF: Number of vertex coordinates higher than 3 unsupported");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NextToken(&car, end);
|
NextToken(&car, end);
|
||||||
|
@ -287,7 +279,8 @@ void OFFImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOS
|
||||||
throw DeadlyImportError("OFF: The number of faces in the header is incorrect");
|
throw DeadlyImportError("OFF: The number of faces in the header is incorrect");
|
||||||
}
|
}
|
||||||
unsigned int idx;
|
unsigned int idx;
|
||||||
sz = line; SkipSpaces(&sz);
|
sz = line;
|
||||||
|
SkipSpaces(&sz);
|
||||||
idx = strtoul10(sz, &sz);
|
idx = strtoul10(sz, &sz);
|
||||||
if (!idx || idx > 9) {
|
if (!idx || idx > 9) {
|
||||||
ASSIMP_LOG_ERROR("OFF: Faces with zero indices aren't allowed");
|
ASSIMP_LOG_ERROR("OFF: Faces with zero indices aren't allowed");
|
||||||
|
@ -330,4 +323,6 @@ void OFFImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOS
|
||||||
pcMat->AddProperty(&twosided, 1, AI_MATKEY_TWOSIDED);
|
pcMat->AddProperty(&twosided, 1, AI_MATKEY_TWOSIDED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace Assimp
|
||||||
|
|
||||||
#endif // !! ASSIMP_BUILD_NO_OFF_IMPORTER
|
#endif // !! ASSIMP_BUILD_NO_OFF_IMPORTER
|
||||||
|
|
|
@ -57,8 +57,8 @@ namespace Assimp {
|
||||||
*/
|
*/
|
||||||
class OFFImporter : public BaseImporter {
|
class OFFImporter : public BaseImporter {
|
||||||
public:
|
public:
|
||||||
OFFImporter();
|
OFFImporter() = default;
|
||||||
~OFFImporter() override;
|
~OFFImporter() override = default;
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Returns whether the class can handle the format of the given file.
|
/** Returns whether the class can handle the format of the given file.
|
||||||
|
|
|
@ -54,7 +54,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <assimp/ObjMaterial.h>
|
#include <assimp/ObjMaterial.h>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
static const aiImporterDesc desc = {
|
static constexpr aiImporterDesc desc = {
|
||||||
"Wavefront Object Importer",
|
"Wavefront Object Importer",
|
||||||
"",
|
"",
|
||||||
"",
|
"",
|
||||||
|
@ -78,7 +78,9 @@ using namespace std;
|
||||||
ObjFileImporter::ObjFileImporter() :
|
ObjFileImporter::ObjFileImporter() :
|
||||||
m_Buffer(),
|
m_Buffer(),
|
||||||
m_pRootObject(nullptr),
|
m_pRootObject(nullptr),
|
||||||
m_strAbsPath(std::string(1, DefaultIOSystem().getOsSeparator())) {}
|
m_strAbsPath(std::string(1, DefaultIOSystem().getOsSeparator())) {
|
||||||
|
// empty
|
||||||
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Destructor.
|
// Destructor.
|
||||||
|
@ -101,8 +103,13 @@ const aiImporterDesc *ObjFileImporter::GetInfo() const {
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Obj-file import implementation
|
// Obj-file import implementation
|
||||||
void ObjFileImporter::InternReadFile(const std::string &file, aiScene *pScene, IOSystem *pIOHandler) {
|
void ObjFileImporter::InternReadFile(const std::string &file, aiScene *pScene, IOSystem *pIOHandler) {
|
||||||
|
if (m_pRootObject != nullptr) {
|
||||||
|
delete m_pRootObject;
|
||||||
|
m_pRootObject = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
// Read file into memory
|
// Read file into memory
|
||||||
static const std::string mode = "rb";
|
static constexpr char mode[] = "rb";
|
||||||
auto streamCloser = [&](IOStream *pStream) {
|
auto streamCloser = [&](IOStream *pStream) {
|
||||||
pIOHandler->Close(pStream);
|
pIOHandler->Close(pStream);
|
||||||
};
|
};
|
||||||
|
|
|
@ -605,7 +605,8 @@ void ObjFileParser::getMaterialDesc() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (needsNewMesh(strName)) {
|
if (needsNewMesh(strName)) {
|
||||||
createMesh(strName);
|
auto newMeshName = m_pModel->mActiveGroup.empty() ? strName : m_pModel->mActiveGroup;
|
||||||
|
createMesh(newMeshName);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_pModel->mCurrentMesh->m_uiMaterialIndex = getMaterialIndex(strName);
|
m_pModel->mCurrentMesh->m_uiMaterialIndex = getMaterialIndex(strName);
|
||||||
|
|
|
@ -48,7 +48,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <assimp/Importer.hpp>
|
#include <assimp/Importer.hpp>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
static const aiImporterDesc desc = {
|
static constexpr aiImporterDesc desc = {
|
||||||
"Ogre3D Mesh Importer",
|
"Ogre3D Mesh Importer",
|
||||||
"",
|
"",
|
||||||
"",
|
"",
|
||||||
|
|
|
@ -52,7 +52,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <assimp/scene.h>
|
#include <assimp/scene.h>
|
||||||
#include <openddlparser/OpenDDLParser.h>
|
#include <openddlparser/OpenDDLParser.h>
|
||||||
|
|
||||||
static const aiImporterDesc desc = {
|
static constexpr aiImporterDesc desc = {
|
||||||
"Open Game Engine Exchange",
|
"Open Game Engine Exchange",
|
||||||
"",
|
"",
|
||||||
"",
|
"",
|
||||||
|
@ -66,42 +66,42 @@ static const aiImporterDesc desc = {
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace Grammar {
|
namespace Grammar {
|
||||||
static const char* MetricType = "Metric";
|
static constexpr char MetricType[] = "Metric";
|
||||||
static const char *Metric_DistanceType = "distance";
|
static constexpr char Metric_DistanceType[] = "distance";
|
||||||
static const char *Metric_AngleType = "angle";
|
static constexpr char Metric_AngleType[] = "angle";
|
||||||
static const char *Metric_TimeType = "time";
|
static constexpr char Metric_TimeType[] = "time";
|
||||||
static const char *Metric_UpType = "up";
|
static constexpr char Metric_UpType[] = "up";
|
||||||
static const char *NameType = "Name";
|
static constexpr char NameType[] = "Name";
|
||||||
static const char *ObjectRefType = "ObjectRef";
|
static constexpr char ObjectRefType[] = "ObjectRef";
|
||||||
static const char *MaterialRefType = "MaterialRef";
|
static constexpr char MaterialRefType[] = "MaterialRef";
|
||||||
static const char *MetricKeyType = "key";
|
static constexpr char MetricKeyType[] = "key";
|
||||||
static const char *GeometryNodeType = "GeometryNode";
|
static constexpr char GeometryNodeType[] = "GeometryNode";
|
||||||
static const char *CameraNodeType = "CameraNode";
|
static constexpr char CameraNodeType[] = "CameraNode";
|
||||||
static const char *LightNodeType = "LightNode";
|
static constexpr char LightNodeType[] = "LightNode";
|
||||||
static const char *GeometryObjectType = "GeometryObject";
|
static constexpr char GeometryObjectType[] = "GeometryObject";
|
||||||
static const char *CameraObjectType = "CameraObject";
|
static constexpr char CameraObjectType[] = "CameraObject";
|
||||||
static const char *LightObjectType = "LightObject";
|
static constexpr char LightObjectType[] = "LightObject";
|
||||||
static const char *TransformType = "Transform";
|
static constexpr char TransformType[] = "Transform";
|
||||||
static const char *MeshType = "Mesh";
|
static constexpr char MeshType[] = "Mesh";
|
||||||
static const char *VertexArrayType = "VertexArray";
|
static constexpr char VertexArrayType[] = "VertexArray";
|
||||||
static const char *IndexArrayType = "IndexArray";
|
static constexpr char IndexArrayType[] = "IndexArray";
|
||||||
static const char *MaterialType = "Material";
|
static constexpr char MaterialType[] = "Material";
|
||||||
static const char *ColorType = "Color";
|
static constexpr char ColorType[] = "Color";
|
||||||
static const char *ParamType = "Param";
|
static constexpr char ParamType[] = "Param";
|
||||||
static const char *TextureType = "Texture";
|
static constexpr char TextureType[] = "Texture";
|
||||||
static const char *AttenType = "Atten";
|
static constexpr char AttenType[] = "Atten";
|
||||||
|
|
||||||
static const char *DiffuseColorToken = "diffuse";
|
static constexpr char DiffuseColorToken[] = "diffuse";
|
||||||
static const char *SpecularColorToken = "specular";
|
static constexpr char SpecularColorToken[] = "specular";
|
||||||
static const char *EmissionColorToken = "emission";
|
static constexpr char EmissionColorToken[] = "emission";
|
||||||
|
|
||||||
static const char *DiffuseTextureToken = "diffuse";
|
static constexpr char DiffuseTextureToken[] = "diffuse";
|
||||||
static const char *DiffuseSpecularTextureToken = "specular";
|
static constexpr char DiffuseSpecularTextureToken[] = "specular";
|
||||||
static const char *SpecularPowerTextureToken = "specular_power";
|
static constexpr char SpecularPowerTextureToken[] = "specular_power";
|
||||||
static const char *EmissionTextureToken = "emission";
|
static constexpr char EmissionTextureToken[] = "emission";
|
||||||
static const char *OpacyTextureToken = "opacity";
|
static constexpr char OpacyTextureToken[] = "opacity";
|
||||||
static const char *TransparencyTextureToken = "transparency";
|
static constexpr char TransparencyTextureToken[] = "transparency";
|
||||||
static const char *NormalTextureToken = "normal";
|
static constexpr char NormalTextureToken[] = "normal";
|
||||||
|
|
||||||
enum TokenType {
|
enum TokenType {
|
||||||
NoneType = -1,
|
NoneType = -1,
|
||||||
|
@ -139,7 +139,7 @@ namespace Grammar {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int idx(-1);
|
int idx = -1;
|
||||||
for (size_t i = 0; i < 4; i++) {
|
for (size_t i = 0; i < 4; i++) {
|
||||||
if (ValidMetricToken[i] == token) {
|
if (ValidMetricToken[i] == token) {
|
||||||
idx = (int)i;
|
idx = (int)i;
|
||||||
|
|
|
@ -53,9 +53,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <assimp/IOSystem.hpp>
|
#include <assimp/IOSystem.hpp>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
using namespace ::Assimp;
|
namespace Assimp {
|
||||||
|
|
||||||
static const aiImporterDesc desc = {
|
static constexpr aiImporterDesc desc = {
|
||||||
"Stanford Polygon Library (PLY) Importer",
|
"Stanford Polygon Library (PLY) Importer",
|
||||||
"",
|
"",
|
||||||
"",
|
"",
|
||||||
|
@ -92,10 +92,6 @@ PLYImporter::PLYImporter() :
|
||||||
// empty
|
// empty
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
// Destructor, private as well
|
|
||||||
PLYImporter::~PLYImporter() = default;
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Returns whether the class can handle the format of the given file.
|
// Returns whether the class can handle the format of the given file.
|
||||||
bool PLYImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /*checkSig*/) const {
|
bool PLYImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /*checkSig*/) const {
|
||||||
|
@ -922,4 +918,6 @@ void PLYImporter::LoadMaterial(std::vector<aiMaterial *> *pvOut, std::string &de
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace Assimp
|
||||||
|
|
||||||
#endif // !! ASSIMP_BUILD_NO_PLY_IMPORTER
|
#endif // !! ASSIMP_BUILD_NO_PLY_IMPORTER
|
||||||
|
|
|
@ -65,7 +65,7 @@ using namespace PLY;
|
||||||
class PLYImporter : public BaseImporter {
|
class PLYImporter : public BaseImporter {
|
||||||
public:
|
public:
|
||||||
PLYImporter();
|
PLYImporter();
|
||||||
~PLYImporter() override;
|
~PLYImporter() override = default;
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Returns whether the class can handle the format of the given file.
|
/** Returns whether the class can handle the format of the given file.
|
||||||
|
|
|
@ -425,7 +425,8 @@ bool PLY::DOM::ParseHeader(IOStreamBuffer<char> &streamBuffer, std::vector<char>
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
// ignore unknown header elements
|
// ignore unknown header elements
|
||||||
streamBuffer.getNextLine(buffer);
|
if (!streamBuffer.getNextLine(buffer))
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -48,11 +48,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
#include <assimp/DefaultLogger.hpp>
|
#include <assimp/DefaultLogger.hpp>
|
||||||
|
|
||||||
#ifdef ASSIMP_BUILD_NO_OWN_ZLIB
|
#include "zlib.h"
|
||||||
#include <zlib.h>
|
|
||||||
#else
|
|
||||||
#include "../contrib/zlib/zlib.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <assimp/DefaultIOSystem.h>
|
#include <assimp/DefaultIOSystem.h>
|
||||||
#include <assimp/StringComparison.h>
|
#include <assimp/StringComparison.h>
|
||||||
|
@ -65,7 +61,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
static const aiImporterDesc desc = {
|
static constexpr aiImporterDesc desc = {
|
||||||
"Quake III BSP Importer",
|
"Quake III BSP Importer",
|
||||||
"",
|
"",
|
||||||
"",
|
"",
|
||||||
|
@ -146,7 +142,11 @@ Q3BSPFileImporter::Q3BSPFileImporter() :
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Destructor.
|
// Destructor.
|
||||||
Q3BSPFileImporter::~Q3BSPFileImporter() {
|
Q3BSPFileImporter::~Q3BSPFileImporter() {
|
||||||
// Clear face-to-material map
|
clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
void Q3BSPFileImporter::clear() {
|
||||||
for (FaceMap::iterator it = m_MaterialLookupMap.begin(); it != m_MaterialLookupMap.end(); ++it) {
|
for (FaceMap::iterator it = m_MaterialLookupMap.begin(); it != m_MaterialLookupMap.end(); ++it) {
|
||||||
const std::string &matName = it->first;
|
const std::string &matName = it->first;
|
||||||
if (!matName.empty()) {
|
if (!matName.empty()) {
|
||||||
|
@ -173,6 +173,7 @@ const aiImporterDesc *Q3BSPFileImporter::GetInfo() const {
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Import method.
|
// Import method.
|
||||||
void Q3BSPFileImporter::InternReadFile(const std::string &rFile, aiScene *scene, IOSystem *ioHandler) {
|
void Q3BSPFileImporter::InternReadFile(const std::string &rFile, aiScene *scene, IOSystem *ioHandler) {
|
||||||
|
clear();
|
||||||
ZipArchiveIOSystem Archive(ioHandler, rFile);
|
ZipArchiveIOSystem Archive(ioHandler, rFile);
|
||||||
if (!Archive.isOpen()) {
|
if (!Archive.isOpen()) {
|
||||||
throw DeadlyImportError("Failed to open file ", rFile, ".");
|
throw DeadlyImportError("Failed to open file ", rFile, ".");
|
||||||
|
@ -394,8 +395,11 @@ void Q3BSPFileImporter::createTriangleTopology(const Q3BSP::Q3BSPModel *pModel,
|
||||||
m_pCurrentFace->mIndices = new unsigned int[3];
|
m_pCurrentFace->mIndices = new unsigned int[3];
|
||||||
m_pCurrentFace->mIndices[idx] = vertIdx;
|
m_pCurrentFace->mIndices[idx] = vertIdx;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
m_pCurrentFace->mIndices[idx] = vertIdx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
pMesh->mVertices[vertIdx].Set(pVertex->vPosition.x, pVertex->vPosition.y, pVertex->vPosition.z);
|
pMesh->mVertices[vertIdx].Set(pVertex->vPosition.x, pVertex->vPosition.y, pVertex->vPosition.z);
|
||||||
pMesh->mNormals[vertIdx].Set(pVertex->vNormal.x, pVertex->vNormal.y, pVertex->vNormal.z);
|
pMesh->mNormals[vertIdx].Set(pVertex->vNormal.x, pVertex->vNormal.y, pVertex->vNormal.z);
|
||||||
|
|
||||||
|
|
|
@ -81,6 +81,7 @@ protected:
|
||||||
using FaceMapIt = std::map<std::string, std::vector<Q3BSP::sQ3BSPFace*>* >::iterator;
|
using FaceMapIt = std::map<std::string, std::vector<Q3BSP::sQ3BSPFace*>* >::iterator;
|
||||||
using FaceMapConstIt = std::map<std::string, std::vector<Q3BSP::sQ3BSPFace*>*>::const_iterator;
|
using FaceMapConstIt = std::map<std::string, std::vector<Q3BSP::sQ3BSPFace*>*>::const_iterator;
|
||||||
|
|
||||||
|
void clear();
|
||||||
const aiImporterDesc* GetInfo () const override;
|
const aiImporterDesc* GetInfo () const override;
|
||||||
void InternReadFile(const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler) override;
|
void InternReadFile(const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler) override;
|
||||||
void separateMapName( const std::string &rImportName, std::string &rArchiveName, std::string &rMapName );
|
void separateMapName( const std::string &rImportName, std::string &rArchiveName, std::string &rMapName );
|
||||||
|
|
|
@ -55,9 +55,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <assimp/DefaultLogger.hpp>
|
#include <assimp/DefaultLogger.hpp>
|
||||||
#include <assimp/IOSystem.hpp>
|
#include <assimp/IOSystem.hpp>
|
||||||
|
|
||||||
using namespace Assimp;
|
namespace Assimp {
|
||||||
|
|
||||||
static const aiImporterDesc desc = {
|
static constexpr aiImporterDesc desc = {
|
||||||
"Quick3D Importer",
|
"Quick3D Importer",
|
||||||
"",
|
"",
|
||||||
"",
|
"",
|
||||||
|
@ -237,7 +237,6 @@ void Q3DImporter::InternReadFile(const std::string &pFile,
|
||||||
if (minor > '0' && major == '3')
|
if (minor > '0' && major == '3')
|
||||||
stream.IncPtr(mesh.faces.size());
|
stream.IncPtr(mesh.faces.size());
|
||||||
}
|
}
|
||||||
// stream.IncPtr(4); // unknown value here
|
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
// materials chunk
|
// materials chunk
|
||||||
|
@ -275,8 +274,6 @@ void Q3DImporter::InternReadFile(const std::string &pFile,
|
||||||
// read the transparency
|
// read the transparency
|
||||||
mat.transparency = stream.GetF4();
|
mat.transparency = stream.GetF4();
|
||||||
|
|
||||||
// unknown value here
|
|
||||||
// stream.IncPtr(4);
|
|
||||||
// FIX: it could be the texture index ...
|
// FIX: it could be the texture index ...
|
||||||
mat.texIdx = (unsigned int)stream.GetI4();
|
mat.texIdx = (unsigned int)stream.GetI4();
|
||||||
}
|
}
|
||||||
|
@ -425,7 +422,8 @@ outer:
|
||||||
pScene->mMeshes = new aiMesh *[pScene->mNumMaterials];
|
pScene->mMeshes = new aiMesh *[pScene->mNumMaterials];
|
||||||
|
|
||||||
for (unsigned int i = 0, real = 0; i < (unsigned int)materials.size(); ++i) {
|
for (unsigned int i = 0, real = 0; i < (unsigned int)materials.size(); ++i) {
|
||||||
if (fidx[i].empty()) continue;
|
if (fidx[i].empty())
|
||||||
|
continue;
|
||||||
|
|
||||||
// Allocate a mesh and a material
|
// Allocate a mesh and a material
|
||||||
aiMesh *mesh = pScene->mMeshes[real] = new aiMesh();
|
aiMesh *mesh = pScene->mMeshes[real] = new aiMesh();
|
||||||
|
@ -548,14 +546,9 @@ outer:
|
||||||
// Now we need to attach the meshes to the root node of the scene
|
// Now we need to attach the meshes to the root node of the scene
|
||||||
pScene->mRootNode->mNumMeshes = pScene->mNumMeshes;
|
pScene->mRootNode->mNumMeshes = pScene->mNumMeshes;
|
||||||
pScene->mRootNode->mMeshes = new unsigned int[pScene->mNumMeshes];
|
pScene->mRootNode->mMeshes = new unsigned int[pScene->mNumMeshes];
|
||||||
for (unsigned int i = 0; i < pScene->mNumMeshes; ++i)
|
for (unsigned int i = 0; i < pScene->mNumMeshes; ++i) {
|
||||||
pScene->mRootNode->mMeshes[i] = i;
|
pScene->mRootNode->mMeshes[i] = i;
|
||||||
|
}
|
||||||
/*pScene->mRootNode->mTransformation *= aiMatrix4x4(
|
|
||||||
1.f, 0.f, 0.f, 0.f,
|
|
||||||
0.f, -1.f,0.f, 0.f,
|
|
||||||
0.f, 0.f, 1.f, 0.f,
|
|
||||||
0.f, 0.f, 0.f, 1.f);*/
|
|
||||||
|
|
||||||
// Add cameras and light sources to the scene root node
|
// Add cameras and light sources to the scene root node
|
||||||
pScene->mRootNode->mNumChildren = pScene->mNumLights + pScene->mNumCameras;
|
pScene->mRootNode->mNumChildren = pScene->mNumLights + pScene->mNumCameras;
|
||||||
|
@ -577,4 +570,6 @@ outer:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace Assimp
|
||||||
|
|
||||||
#endif // !! ASSIMP_BUILD_NO_Q3D_IMPORTER
|
#endif // !! ASSIMP_BUILD_NO_Q3D_IMPORTER
|
||||||
|
|
|
@ -55,9 +55,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <assimp/IOSystem.hpp>
|
#include <assimp/IOSystem.hpp>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
using namespace Assimp;
|
namespace Assimp {
|
||||||
|
|
||||||
static const aiImporterDesc desc = {
|
static constexpr aiImporterDesc desc = {
|
||||||
"Raw Importer",
|
"Raw Importer",
|
||||||
"",
|
"",
|
||||||
"",
|
"",
|
||||||
|
@ -70,14 +70,6 @@ static const aiImporterDesc desc = {
|
||||||
"raw"
|
"raw"
|
||||||
};
|
};
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
// Constructor to be privately used by Importer
|
|
||||||
RAWImporter::RAWImporter() = default;
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
// Destructor, private as well
|
|
||||||
RAWImporter::~RAWImporter() = default;
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Returns whether the class can handle the format of the given file.
|
// Returns whether the class can handle the format of the given file.
|
||||||
bool RAWImporter::CanRead(const std::string &filename, IOSystem * /*pIOHandler*/, bool /*checkSig*/) const {
|
bool RAWImporter::CanRead(const std::string &filename, IOSystem * /*pIOHandler*/, bool /*checkSig*/) const {
|
||||||
|
@ -295,4 +287,6 @@ void RAWImporter::InternReadFile(const std::string &pFile,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace Assimp
|
||||||
|
|
||||||
#endif // !! ASSIMP_BUILD_NO_RAW_IMPORTER
|
#endif // !! ASSIMP_BUILD_NO_RAW_IMPORTER
|
||||||
|
|
|
@ -57,8 +57,8 @@ namespace Assimp {
|
||||||
*/
|
*/
|
||||||
class RAWImporter : public BaseImporter {
|
class RAWImporter : public BaseImporter {
|
||||||
public:
|
public:
|
||||||
RAWImporter();
|
RAWImporter() = default;
|
||||||
~RAWImporter() override;
|
~RAWImporter() override = default;
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Returns whether the class can handle the format of the given file.
|
/** Returns whether the class can handle the format of the given file.
|
||||||
|
|
|
@ -56,11 +56,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <assimp/ByteSwapper.h>
|
#include <assimp/ByteSwapper.h>
|
||||||
#include <assimp/StreamReader.h>
|
#include <assimp/StreamReader.h>
|
||||||
#include <assimp/TinyFormatter.h>
|
#include <assimp/TinyFormatter.h>
|
||||||
#ifdef ASSIMP_USE_HUNTER
|
#include "utf8.h"
|
||||||
#include <utf8.h>
|
|
||||||
#else
|
|
||||||
#include "../contrib/utf8cpp/source/utf8.h"
|
|
||||||
#endif
|
|
||||||
#include <assimp/importerdesc.h>
|
#include <assimp/importerdesc.h>
|
||||||
#include <assimp/scene.h>
|
#include <assimp/scene.h>
|
||||||
#include <assimp/DefaultLogger.hpp>
|
#include <assimp/DefaultLogger.hpp>
|
||||||
|
@ -69,9 +65,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
using namespace Assimp;
|
namespace Assimp {
|
||||||
|
|
||||||
static const aiImporterDesc desc = {
|
static constexpr aiImporterDesc desc = {
|
||||||
"Silo SIB Importer",
|
"Silo SIB Importer",
|
||||||
"Richard Mitton (http://www.codersnotes.com/about)",
|
"Richard Mitton (http://www.codersnotes.com/about)",
|
||||||
"",
|
"",
|
||||||
|
@ -94,7 +90,7 @@ enum {
|
||||||
N
|
N
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::pair<uint32_t, uint32_t> SIBPair;
|
using SIBPair = std::pair<uint32_t, uint32_t>;
|
||||||
|
|
||||||
struct SIBEdge {
|
struct SIBEdge {
|
||||||
uint32_t faceA, faceB;
|
uint32_t faceA, faceB;
|
||||||
|
@ -199,15 +195,6 @@ static aiString ReadString(StreamReaderLE *stream, uint32_t numWChars) {
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
// Constructor to be privately used by Importer
|
|
||||||
SIBImporter::SIBImporter() = default;
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
// Destructor, private as well
|
|
||||||
SIBImporter::~SIBImporter() = default;
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Returns whether the class can handle the format of the given file.
|
// Returns whether the class can handle the format of the given file.
|
||||||
bool SIBImporter::CanRead(const std::string &filename, IOSystem * /*pIOHandler*/, bool /*checkSig*/) const {
|
bool SIBImporter::CanRead(const std::string &filename, IOSystem * /*pIOHandler*/, bool /*checkSig*/) const {
|
||||||
|
@ -882,4 +869,6 @@ void SIBImporter::InternReadFile(const std::string &pFile,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace Assimp
|
||||||
|
|
||||||
#endif // !! ASSIMP_BUILD_NO_SIB_IMPORTER
|
#endif // !! ASSIMP_BUILD_NO_SIB_IMPORTER
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue