1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-10 18:51:21 +03:00

0032525: Data Exchange, RWGltf_CafReader - support KHR_draco_mesh_compression

Added new optional dependency - Draco library.
RWGltf_GltfJsonParser now detects KHR_draco_mesh_compression extension,
marks accessor being compressed and redirects to compressed buffer view.
RWGltf_TriangulationReader now handles decoding of buffer view compressed using Draco.

env.bat template for genproj has been modified to allow specifying dedicated folders
with debug versions of libraries (CSF_OPT_LIB64D / CSF_OPT_BIN64D) within custom.bat.
Removed unused CSF_FREETYPE from TKOpenGl.
This commit is contained in:
kgv 2021-08-10 20:35:14 +03:00 committed by bugmaster
parent aeef9e2c13
commit d9d75a845f
20 changed files with 415 additions and 28 deletions

View File

@ -370,6 +370,7 @@ set (USE_FREEIMAGE OFF CACHE BOOL "${USE_FREEIMAGE_DESCR}")
set (USE_FFMPEG OFF CACHE BOOL "${USE_FFMPEG_DESCR}") set (USE_FFMPEG OFF CACHE BOOL "${USE_FFMPEG_DESCR}")
set (USE_OPENVR OFF CACHE BOOL "${USE_OPENVR_DESCR}") set (USE_OPENVR OFF CACHE BOOL "${USE_OPENVR_DESCR}")
set (USE_RAPIDJSON OFF CACHE BOOL "${USE_RAPIDJSON_DESCR}") set (USE_RAPIDJSON OFF CACHE BOOL "${USE_RAPIDJSON_DESCR}")
set (USE_DRACO OFF CACHE BOOL "${USE_DRACO_DESCR}")
set (USE_TBB OFF CACHE BOOL "${USE_TBB_DESCR}") set (USE_TBB OFF CACHE BOOL "${USE_TBB_DESCR}")
set (USE_EIGEN OFF CACHE BOOL "${USE_EIGEN_DESCR}") set (USE_EIGEN OFF CACHE BOOL "${USE_EIGEN_DESCR}")
@ -716,6 +717,24 @@ else()
OCCT_CHECK_AND_UNSET ("INSTALL_RAPIDJSON") OCCT_CHECK_AND_UNSET ("INSTALL_RAPIDJSON")
endif() endif()
# Draco library
# search for CSF_Draco variable in EXTERNLIB of each being used toolkit
OCCT_IS_PRODUCT_REQUIRED (CSF_Draco CAN_USE_DRACO)
if (CAN_USE_DRACO)
if (USE_DRACO)
add_definitions (-DHAVE_DRACO)
OCCT_INCLUDE_CMAKE_FILE ("adm/cmake/draco")
else()
OCCT_CHECK_AND_UNSET_GROUP ("3RDPARTY_DRACO")
OCCT_CHECK_AND_UNSET ("INSTALL_DRACO")
endif()
else()
OCCT_CHECK_AND_UNSET ("USE_DRACO")
OCCT_CHECK_AND_UNSET_GROUP ("3RDPARTY_DRACO")
OCCT_CHECK_AND_UNSET ("INSTALL_DRACO")
endif()
# EIGEN # EIGEN
if (CAN_USE_EIGEN) if (CAN_USE_EIGEN)
if (USE_EIGEN) if (USE_EIGEN)

4
adm/cmake/draco.cmake Normal file
View File

@ -0,0 +1,4 @@
# Draco - a library for a lossy vertex data compression, used as extension to glTF format.
# https://github.com/google/draco
THIRDPARTY_PRODUCT("DRACO" "draco/compression/decode.h" "CSF_Draco" "")

View File

@ -75,6 +75,13 @@ if (USE_TK)
endif() endif()
endif() endif()
# Draco
if (USE_DRACO)
set (CSF_Draco "draco")
else()
set (CSF_Draco)
endif()
if (WIN32) if (WIN32)
set (CSF_advapi32 "advapi32.lib") set (CSF_advapi32 "advapi32.lib")
set (CSF_gdi32 "gdi32.lib") set (CSF_gdi32 "gdi32.lib")

View File

@ -176,6 +176,9 @@ set (USE_RAPIDJSON_DESCR
"Indicates whether RapidJSON product should be used in OCCT DataExchange "Indicates whether RapidJSON product should be used in OCCT DataExchange
module for support of JSON-based formats like glTF") module for support of JSON-based formats like glTF")
set (USE_DRACO_DESCR
"Indicates whether Draco mesh decoding library should be used by glTF reader")
set (USE_EGL_DESCR set (USE_EGL_DESCR
"Indicates whether EGL should be used in OCCT visualization "Indicates whether EGL should be used in OCCT visualization
module instead of conventional OpenGL context creation APIs") module instead of conventional OpenGL context creation APIs")

View File

@ -227,6 +227,10 @@ proc wokdep:gui:UpdateList {} {
if { "$::HAVE_RAPIDJSON" == "true" } { if { "$::HAVE_RAPIDJSON" == "true" } {
wokdep:SearchRapidJson anIncErrs anLib32Errs anLib64Errs anBin32Errs anBin64Errs wokdep:SearchRapidJson anIncErrs anLib32Errs anLib64Errs anBin32Errs anBin64Errs
} }
if { "$::HAVE_DRACO" == "true" } {
set aDummy {}
wokdep:SearchStandardLibrary anIncErrs anLib32Errs anLib64Errs aDummy aDummy "draco" "draco/compression/decode.h" "draco" {"draco"}
}
if {"$::BUILD_Inspector" == "true" } { if {"$::BUILD_Inspector" == "true" } {
set ::CHECK_QT "true" set ::CHECK_QT "true"
@ -495,6 +499,8 @@ ttk::label .myFrame.myChecks.myFFmpegLbl -text "Use FFmpeg"
#ttk::label .myFrame.myChecks.myOpenClLbl -text "Use OpenCL" #ttk::label .myFrame.myChecks.myOpenClLbl -text "Use OpenCL"
checkbutton .myFrame.myChecks.myRapidJsonCheck -offvalue "false" -onvalue "true" -variable HAVE_RAPIDJSON -command wokdep:gui:UpdateList checkbutton .myFrame.myChecks.myRapidJsonCheck -offvalue "false" -onvalue "true" -variable HAVE_RAPIDJSON -command wokdep:gui:UpdateList
ttk::label .myFrame.myChecks.myRapidJsonLbl -text "Use RapidJSON" ttk::label .myFrame.myChecks.myRapidJsonLbl -text "Use RapidJSON"
checkbutton .myFrame.myChecks.myDracoCheck -offvalue "false" -onvalue "true" -variable HAVE_DRACO -command wokdep:gui:UpdateList
ttk::label .myFrame.myChecks.myDracoLbl -text "Use Draco"
checkbutton .myFrame.myChecks.myXLibCheck -offvalue "false" -onvalue "true" -variable HAVE_XLIB checkbutton .myFrame.myChecks.myXLibCheck -offvalue "false" -onvalue "true" -variable HAVE_XLIB
ttk::label .myFrame.myChecks.myXLibLbl -text "Use X11 for windows drawing" ttk::label .myFrame.myChecks.myXLibLbl -text "Use X11 for windows drawing"
@ -627,8 +633,9 @@ grid .myFrame.myChecks.myQtLbl -row $aCheckRowIter -column 13 -sticky w
incr aCheckRowIter incr aCheckRowIter
grid .myFrame.myChecks.myFImageCheck -row $aCheckRowIter -column 0 -sticky e grid .myFrame.myChecks.myFImageCheck -row $aCheckRowIter -column 0 -sticky e
grid .myFrame.myChecks.myFImageLbl -row $aCheckRowIter -column 1 -sticky w grid .myFrame.myChecks.myFImageLbl -row $aCheckRowIter -column 1 -sticky w
grid .myFrame.myChecks.myTbbCheck -row $aCheckRowIter -column 2 -sticky e grid .myFrame.myChecks.myDracoCheck -row $aCheckRowIter -column 2 -sticky e
grid .myFrame.myChecks.myTbbLbl -row $aCheckRowIter -column 3 -sticky w grid .myFrame.myChecks.myDracoLbl -row $aCheckRowIter -column 3 -sticky w
if { "$::tcl_platform(platform)" == "windows" } { if { "$::tcl_platform(platform)" == "windows" } {
grid .myFrame.myChecks.myD3dCheck -row $aCheckRowIter -column 4 -sticky e grid .myFrame.myChecks.myD3dCheck -row $aCheckRowIter -column 4 -sticky e
grid .myFrame.myChecks.myD3dLbl -row $aCheckRowIter -column 5 -sticky w grid .myFrame.myChecks.myD3dLbl -row $aCheckRowIter -column 5 -sticky w
@ -658,6 +665,11 @@ if { "$::tcl_platform(platform)" == "windows" } {
incr aCheckRowIter incr aCheckRowIter
grid .myFrame.myChecks.myTbbCheck -row $aCheckRowIter -column 12 -sticky e
grid .myFrame.myChecks.myTbbLbl -row $aCheckRowIter -column 13 -sticky w
incr aCheckRowIter
# Additional headers search paths # Additional headers search paths
grid .myFrame.myIncLbl -row $aRowIter -column 0 -columnspan 10 -sticky w grid .myFrame.myIncLbl -row $aRowIter -column 0 -columnspan 10 -sticky w
incr aRowIter incr aRowIter

View File

@ -68,7 +68,10 @@ if { [info exists ::env(SHORTCUT_HEADERS)] } {
} }
# fetch environment variables (e.g. set by custom.sh or custom.bat) and set them as tcl variables with the same name # fetch environment variables (e.g. set by custom.sh or custom.bat) and set them as tcl variables with the same name
set THE_ENV_VARIABLES {HAVE_TK HAVE_FREETYPE HAVE_FREEIMAGE HAVE_FFMPEG HAVE_TBB HAVE_GLES2 HAVE_D3D HAVE_VTK HAVE_ZLIB HAVE_LIBLZMA HAVE_E57 HAVE_RAPIDJSON HAVE_OPENVR HAVE_OPENCL CHECK_QT4 CHECK_JDK HAVE_XLIB HAVE_RelWithDebInfo BUILD_Inspector} set THE_ENV_VARIABLES { HAVE_TK HAVE_FREETYPE HAVE_FREEIMAGE HAVE_FFMPEG HAVE_TBB HAVE_GLES2 HAVE_D3D HAVE_VTK \
HAVE_ZLIB HAVE_LIBLZMA HAVE_E57 HAVE_RAPIDJSON HAVE_DRACO HAVE_OPENVR HAVE_OPENCL \
CHECK_QT4 CHECK_JDK HAVE_XLIB \
HAVE_RelWithDebInfo BUILD_Inspector }
foreach anEnvIter $THE_ENV_VARIABLES { set ${anEnvIter} "false" } foreach anEnvIter $THE_ENV_VARIABLES { set ${anEnvIter} "false" }
set HAVE_TK "true" set HAVE_TK "true"
set HAVE_FREETYPE "true" set HAVE_FREETYPE "true"

View File

@ -1447,6 +1447,9 @@ proc osutils:csfList { theOS theCsfLibsMap theCsfFrmsMap theRelease} {
if { "$::HAVE_LIBLZMA" == "true" } { if { "$::HAVE_LIBLZMA" == "true" } {
set aLibsMap(CSF_LIBLZMA) "liblzma" set aLibsMap(CSF_LIBLZMA) "liblzma"
} }
if { "$::HAVE_DRACO" == "true" } {
set aLibsMap(CSF_Draco) "draco"
}
if { "$::HAVE_OPENVR" == "true" } { if { "$::HAVE_OPENVR" == "true" } {
set aLibsMap(CSF_OpenVR) "openvr_api" set aLibsMap(CSF_OpenVR) "openvr_api"
} }

View File

@ -27,6 +27,7 @@ set "HAVE_D3D=false"
set "HAVE_ZLIB=false" set "HAVE_ZLIB=false"
set "HAVE_LIBLZMA=false" set "HAVE_LIBLZMA=false"
set "HAVE_RAPIDJSON=false" set "HAVE_RAPIDJSON=false"
set "HAVE_DRACO=false"
set "HAVE_OPENVR=false" set "HAVE_OPENVR=false"
set "HAVE_E57=false" set "HAVE_E57=false"
set "CSF_OPT_INC=" set "CSF_OPT_INC="
@ -34,6 +35,14 @@ set "CSF_OPT_LIB32="
set "CSF_OPT_LIB64=" set "CSF_OPT_LIB64="
set "CSF_OPT_BIN32=" set "CSF_OPT_BIN32="
set "CSF_OPT_BIN64=" set "CSF_OPT_BIN64="
set "CSF_OPT_LIB32D="
set "CSF_OPT_LIB64D="
set "CSF_OPT_BIN32D="
set "CSF_OPT_BIN64D="
set "CSF_OPT_LIB32I="
set "CSF_OPT_LIB64I="
set "CSF_OPT_BIN32I="
set "CSF_OPT_BIN64I="
set "CSF_DEFINES=%CSF_DEFINES_EXTRA%" set "CSF_DEFINES=%CSF_DEFINES_EXTRA%"
if not ["%CASROOT%"] == [""] if exist "%SCRIPTROOT%\%CASROOT%" set "CASROOT=%SCRIPTROOT%\%CASROOT%" if not ["%CASROOT%"] == [""] if exist "%SCRIPTROOT%\%CASROOT%" set "CASROOT=%SCRIPTROOT%\%CASROOT%"
@ -170,14 +179,14 @@ if /I "%VCFMT%" == "vc9" (
exit /B exit /B
) )
set "CSF_OPT_LIB32D=%CSF_OPT_LIB32%" if ["%CSF_OPT_LIB32D%"] == [""] set "CSF_OPT_LIB32D=%CSF_OPT_LIB32%"
set "CSF_OPT_LIB64D=%CSF_OPT_LIB64%" if ["%CSF_OPT_LIB64D%"] == [""] set "CSF_OPT_LIB64D=%CSF_OPT_LIB64%"
set "CSF_OPT_BIN32D=%CSF_OPT_BIN32%" if ["%CSF_OPT_BIN32D%"] == [""] set "CSF_OPT_BIN32D=%CSF_OPT_BIN32%"
set "CSF_OPT_BIN64D=%CSF_OPT_BIN64%" if ["%CSF_OPT_BIN64D%"] == [""] set "CSF_OPT_BIN64D=%CSF_OPT_BIN64%"
set "CSF_OPT_LIB32I=%CSF_OPT_LIB32%" if ["%CSF_OPT_LIB32I%"] == [""] set "CSF_OPT_LIB32I=%CSF_OPT_LIB32%"
set "CSF_OPT_LIB64I=%CSF_OPT_LIB64%" if ["%CSF_OPT_LIB64I%"] == [""] set "CSF_OPT_LIB64I=%CSF_OPT_LIB64%"
set "CSF_OPT_BIN32I=%CSF_OPT_BIN32%" if ["%CSF_OPT_BIN32I%"] == [""] set "CSF_OPT_BIN32I=%CSF_OPT_BIN32%"
set "CSF_OPT_BIN64I=%CSF_OPT_BIN64%" if ["%CSF_OPT_BIN64I%"] == [""] set "CSF_OPT_BIN64I=%CSF_OPT_BIN64%"
rem ----- Optional 3rd-parties should be enabled by HAVE macros ----- rem ----- Optional 3rd-parties should be enabled by HAVE macros -----
set "CSF_OPT_CMPL=" set "CSF_OPT_CMPL="
@ -194,6 +203,7 @@ if ["%HAVE_D3D%"] == ["true"] set "PRODUCTS_DEFINES=%PRODUCTS_DEFINES% -DH
if ["%HAVE_ZLIB%"] == ["true"] set "PRODUCTS_DEFINES=%PRODUCTS_DEFINES% -DHAVE_ZLIB" & set "CSF_DEFINES=HAVE_ZLIB;%CSF_DEFINES%" if ["%HAVE_ZLIB%"] == ["true"] set "PRODUCTS_DEFINES=%PRODUCTS_DEFINES% -DHAVE_ZLIB" & set "CSF_DEFINES=HAVE_ZLIB;%CSF_DEFINES%"
if ["%HAVE_LIBLZMA%"] == ["true"] set "PRODUCTS_DEFINES=%PRODUCTS_DEFINES% -DHAVE_LIBLZMA" & set "CSF_DEFINES=HAVE_LIBLZMA;%CSF_DEFINES%" if ["%HAVE_LIBLZMA%"] == ["true"] set "PRODUCTS_DEFINES=%PRODUCTS_DEFINES% -DHAVE_LIBLZMA" & set "CSF_DEFINES=HAVE_LIBLZMA;%CSF_DEFINES%"
if ["%HAVE_RAPIDJSON%"] == ["true"] set "PRODUCTS_DEFINES=%PRODUCTS_DEFINES% -DHAVE_RAPIDJSON" & set "CSF_DEFINES=HAVE_RAPIDJSON;%CSF_DEFINES%" if ["%HAVE_RAPIDJSON%"] == ["true"] set "PRODUCTS_DEFINES=%PRODUCTS_DEFINES% -DHAVE_RAPIDJSON" & set "CSF_DEFINES=HAVE_RAPIDJSON;%CSF_DEFINES%"
if ["%HAVE_DRACO%"] == ["true"] set "PRODUCTS_DEFINES=%PRODUCTS_DEFINES% -DHAVE_DRACO" & set "CSF_DEFINES=HAVE_DRACO;%CSF_DEFINES%"
if ["%HAVE_OPENVR%"] == ["true"] set "PRODUCTS_DEFINES=%PRODUCTS_DEFINES% -DHAVE_OPENVR" & set "CSF_DEFINES=HAVE_OPENVR;%CSF_DEFINES%" if ["%HAVE_OPENVR%"] == ["true"] set "PRODUCTS_DEFINES=%PRODUCTS_DEFINES% -DHAVE_OPENVR" & set "CSF_DEFINES=HAVE_OPENVR;%CSF_DEFINES%"
if ["%HAVE_E57%"] == ["true"] set "PRODUCTS_DEFINES=%PRODUCTS_DEFINES% -DHAVE_E57" & set "CSF_DEFINES=HAVE_E57;%CSF_DEFINES%" if ["%HAVE_E57%"] == ["true"] set "PRODUCTS_DEFINES=%PRODUCTS_DEFINES% -DHAVE_E57" & set "CSF_DEFINES=HAVE_E57;%CSF_DEFINES%"

View File

@ -20,6 +20,7 @@ export HAVE_GLES2="false";
export HAVE_ZLIB="false"; export HAVE_ZLIB="false";
export HAVE_LIBLZMA="false"; export HAVE_LIBLZMA="false";
export HAVE_RAPIDJSON="false"; export HAVE_RAPIDJSON="false";
export HAVE_DRACO="false";
export HAVE_OPENVR="false"; export HAVE_OPENVR="false";
export HAVE_E57="false"; export HAVE_E57="false";
export HAVE_XLIB="true"; export HAVE_XLIB="true";
@ -115,6 +116,7 @@ if [ "$HAVE_VTK" == "true" ]; then export CSF_OPT_CMPL="${CSF_OPT_CMPL} -D
if [ "$HAVE_ZLIB" == "true" ]; then export CSF_OPT_CMPL="${CSF_OPT_CMPL} -DHAVE_ZLIB"; fi if [ "$HAVE_ZLIB" == "true" ]; then export CSF_OPT_CMPL="${CSF_OPT_CMPL} -DHAVE_ZLIB"; fi
if [ "$HAVE_LIBLZMA" == "true" ]; then export CSF_OPT_CMPL="${CSF_OPT_CMPL} -DHAVE_LIBLZMA"; fi if [ "$HAVE_LIBLZMA" == "true" ]; then export CSF_OPT_CMPL="${CSF_OPT_CMPL} -DHAVE_LIBLZMA"; fi
if [ "$HAVE_RAPIDJSON" == "true" ]; then export CSF_OPT_CMPL="${CSF_OPT_CMPL} -DHAVE_RAPIDJSON"; fi if [ "$HAVE_RAPIDJSON" == "true" ]; then export CSF_OPT_CMPL="${CSF_OPT_CMPL} -DHAVE_RAPIDJSON"; fi
if [ "$HAVE_DRACO" == "true" ]; then export CSF_OPT_CMPL="${CSF_OPT_CMPL} -DHAVE_DRACO"; fi
if [ "$HAVE_OPENVR" == "true" ]; then export CSF_OPT_CMPL="${CSF_OPT_CMPL} -DHAVE_OPENVR"; fi if [ "$HAVE_OPENVR" == "true" ]; then export CSF_OPT_CMPL="${CSF_OPT_CMPL} -DHAVE_OPENVR"; fi
if [ "$HAVE_E57" == "true" ]; then export CSF_OPT_CMPL="${CSF_OPT_CMPL} -DHAVE_E57"; fi if [ "$HAVE_E57" == "true" ]; then export CSF_OPT_CMPL="${CSF_OPT_CMPL} -DHAVE_E57"; fi
if [ "$HAVE_XLIB" == "true" ]; then export CSF_OPT_CMPL="${CSF_OPT_CMPL} -DHAVE_XLIB"; fi if [ "$HAVE_XLIB" == "true" ]; then export CSF_OPT_CMPL="${CSF_OPT_CMPL} -DHAVE_XLIB"; fi

View File

@ -370,6 +370,7 @@ https://www.opencascade.com/content/3rd-party-components
| VTK 6.1+ | https://www.vtk.org/download/ | Visualization | Optional (VTK integration) | | VTK 6.1+ | https://www.vtk.org/download/ | Visualization | Optional (VTK integration) |
| Flex 2.6.4+ and Bison 3.7.1+ | https://sourceforge.net/projects/winflexbison/ | Data Exchange | Optional (update of STEP and ExprIntrp parsers) | | Flex 2.6.4+ and Bison 3.7.1+ | https://sourceforge.net/projects/winflexbison/ | Data Exchange | Optional (update of STEP and ExprIntrp parsers) |
| RapidJSON 1.1+ | https://rapidjson.org/ | Data Exchange | Optional (reading glTF files) | | RapidJSON 1.1+ | https://rapidjson.org/ | Data Exchange | Optional (reading glTF files) |
| Draco 1.4.1+ | https://github.com/google/draco | Data Exchange | Optional (reading compressed glTF files) |
| Tcl/Tk 8.6.3+ <br> or ActiveTcl 8.6 | https://www.tcl.tk/software/tcltk/download.html <br> https://www.activestate.com/activetcl/downloads | DRAW Test Harness | Required | | Tcl/Tk 8.6.3+ <br> or ActiveTcl 8.6 | https://www.tcl.tk/software/tcltk/download.html <br> https://www.activestate.com/activetcl/downloads | DRAW Test Harness | Required |
| Qt Desktop: Qt 4.8.6+ <br> Android: Qt 5.3.2+ | https://www.qt.io/download/ | Samples and demos | Optional (Qt samples) | | Qt Desktop: Qt 4.8.6+ <br> Android: Qt 5.3.2+ | https://www.qt.io/download/ | Samples and demos | Optional (Qt samples) |
| Doxygen 1.8.5+ | https://www.doxygen.nl/download.html | Documentation | Required | | Doxygen 1.8.5+ | https://www.doxygen.nl/download.html | Documentation | Required |
@ -642,6 +643,10 @@ on this tool.
**RapidJSON** is an Open Source JSON parser and generator for C++. **RapidJSON** is an Open Source JSON parser and generator for C++.
RapidJSON is optionally used by OCCT for reading glTF files (https://rapidjson.org/). RapidJSON is optionally used by OCCT for reading glTF files (https://rapidjson.org/).
**Draco** is an Open Source JSON parser and generator for C++.
Draco is optionally used by OCCT for reading glTF files using KHR_draco_mesh_compression extension (https://github.com/google/draco).
Draco is available under Apache 2.0 license.
**DejaVu** fonts are a font family based on the Vera Fonts under a permissive license (MIT-like, https://dejavu-fonts.github.io/License.html). **DejaVu** fonts are a font family based on the Vera Fonts under a permissive license (MIT-like, https://dejavu-fonts.github.io/License.html).
DejaVu Sans (basic Latin sub-set) is used by OCCT as fallback font when no system font is available. DejaVu Sans (basic Latin sub-set) is used by OCCT as fallback font when no system font is available.

View File

@ -389,6 +389,11 @@ static Standard_Integer dversion(Draw_Interpretor& di, Standard_Integer, const c
#else #else
di << "RapidJSON disabled\n"; di << "RapidJSON disabled\n";
#endif #endif
#ifdef HAVE_DRACO
di << "Draco enabled (HAVE_DRACO)\n";
#else
di << "Draco disabled\n";
#endif
#ifdef HAVE_VTK #ifdef HAVE_VTK
di << "VTK enabled (HAVE_VTK)\n"; di << "VTK enabled (HAVE_VTK)\n";
#else #else

View File

@ -33,6 +33,7 @@ public:
RWGltf_GltfAccessorLayout Type; //!< layout type RWGltf_GltfAccessorLayout Type; //!< layout type
RWGltf_GltfAccessorCompType ComponentType; //!< component type RWGltf_GltfAccessorCompType ComponentType; //!< component type
Graphic3d_BndBox3d BndBox; //!< bounding box Graphic3d_BndBox3d BndBox; //!< bounding box
bool IsCompressed; //!< flag indicating KHR_draco_mesh_compression
//! Empty constructor. //! Empty constructor.
RWGltf_GltfAccessor() RWGltf_GltfAccessor()
@ -41,7 +42,8 @@ public:
Count (0), Count (0),
ByteStride (0), ByteStride (0),
Type (RWGltf_GltfAccessorLayout_UNKNOWN), Type (RWGltf_GltfAccessorLayout_UNKNOWN),
ComponentType (RWGltf_GltfAccessorCompType_UNKNOWN) {} ComponentType (RWGltf_GltfAccessorCompType_UNKNOWN),
IsCompressed (false) {}
}; };

View File

@ -35,8 +35,9 @@
namespace namespace
{ {
//! Material extension. //! Material extension.
const char THE_KHR_materials_common[] = "KHR_materials_common"; static const char THE_KHR_materials_common[] = "KHR_materials_common";
const char THE_KHR_binary_glTF[] = "KHR_binary_glTF"; static const char THE_KHR_binary_glTF[] = "KHR_binary_glTF";
static const char THE_KHR_draco_mesh_compression[] = "KHR_draco_mesh_compression";
//! Data buffer referring to a portion of another buffer. //! Data buffer referring to a portion of another buffer.
class RWGltf_SubBuffer : public NCollection_Buffer class RWGltf_SubBuffer : public NCollection_Buffer
@ -1404,6 +1405,14 @@ bool RWGltf_GltfJsonParser::gltfParsePrimArray (const Handle(RWGltf_GltfLatePrim
const RWGltf_JsonValue* anIndices = findObjectMember (thePrimArray, "indices"); const RWGltf_JsonValue* anIndices = findObjectMember (thePrimArray, "indices");
const RWGltf_JsonValue* aMaterial = findObjectMember (thePrimArray, "material"); const RWGltf_JsonValue* aMaterial = findObjectMember (thePrimArray, "material");
const RWGltf_JsonValue* aModeVal = findObjectMember (thePrimArray, "mode"); const RWGltf_JsonValue* aModeVal = findObjectMember (thePrimArray, "mode");
const RWGltf_JsonValue* anExtVal = findObjectMember (thePrimArray, "extensions");
const RWGltf_JsonValue* aDracoVal = anExtVal != NULL
? findObjectMember (*anExtVal, THE_KHR_draco_mesh_compression)
: NULL;
const RWGltf_JsonValue* aDracoBuf = aDracoVal != NULL
? findObjectMember (*aDracoVal, "bufferView")
: NULL;
RWGltf_GltfPrimitiveMode aMode = RWGltf_GltfPrimitiveMode_Triangles; RWGltf_GltfPrimitiveMode aMode = RWGltf_GltfPrimitiveMode_Triangles;
if (anAttribs == NULL if (anAttribs == NULL
|| !anAttribs->IsObject()) || !anAttribs->IsObject())
@ -1473,7 +1482,7 @@ bool RWGltf_GltfJsonParser::gltfParsePrimArray (const Handle(RWGltf_GltfLatePrim
reportGltfError ("Primitive array attribute accessor key '" + anAttribId + "' points to non-existing object."); reportGltfError ("Primitive array attribute accessor key '" + anAttribId + "' points to non-existing object.");
return false; return false;
} }
else if (!gltfParseAccessor (theMeshData, anAttribId, *anAccessor, aType)) else if (!gltfParseAccessor (theMeshData, anAttribId, *anAccessor, aType, aDracoBuf))
{ {
return false; return false;
} }
@ -1498,7 +1507,7 @@ bool RWGltf_GltfJsonParser::gltfParsePrimArray (const Handle(RWGltf_GltfLatePrim
reportGltfError ("Primitive array indices accessor key '" + anIndicesId + "' points to non-existing object."); reportGltfError ("Primitive array indices accessor key '" + anIndicesId + "' points to non-existing object.");
return false; return false;
} }
else if (!gltfParseAccessor (theMeshData, anIndicesId, *anAccessor, RWGltf_GltfArrayType_Indices)) else if (!gltfParseAccessor (theMeshData, anIndicesId, *anAccessor, RWGltf_GltfArrayType_Indices, aDracoBuf))
{ {
return false; return false;
} }
@ -1518,12 +1527,17 @@ bool RWGltf_GltfJsonParser::gltfParsePrimArray (const Handle(RWGltf_GltfLatePrim
bool RWGltf_GltfJsonParser::gltfParseAccessor (const Handle(RWGltf_GltfLatePrimitiveArray)& theMeshData, bool RWGltf_GltfJsonParser::gltfParseAccessor (const Handle(RWGltf_GltfLatePrimitiveArray)& theMeshData,
const TCollection_AsciiString& theName, const TCollection_AsciiString& theName,
const RWGltf_JsonValue& theAccessor, const RWGltf_JsonValue& theAccessor,
const RWGltf_GltfArrayType theType) const RWGltf_GltfArrayType theType,
const RWGltf_JsonValue* theCompBuffView)
{ {
RWGltf_GltfAccessor aStruct; RWGltf_GltfAccessor aStruct;
const RWGltf_JsonValue* aTypeStr = findObjectMember (theAccessor, "type"); const RWGltf_JsonValue* aTypeStr = findObjectMember (theAccessor, "type");
const RWGltf_JsonValue* aBufferViewName = findObjectMember (theAccessor, "bufferView"); const RWGltf_JsonValue* aBufferViewName = theCompBuffView == NULL
const RWGltf_JsonValue* aByteOffset = findObjectMember (theAccessor, "byteOffset"); ? findObjectMember (theAccessor, "bufferView")
: theCompBuffView;
const RWGltf_JsonValue* aByteOffset = theCompBuffView == NULL
? findObjectMember (theAccessor, "byteOffset")
: 0;
const RWGltf_JsonValue* aByteStride = findObjectMember (theAccessor, "byteStride"); // byteStride was part of bufferView in glTF 1.0 const RWGltf_JsonValue* aByteStride = findObjectMember (theAccessor, "byteStride"); // byteStride was part of bufferView in glTF 1.0
const RWGltf_JsonValue* aCompType = findObjectMember (theAccessor, "componentType"); const RWGltf_JsonValue* aCompType = findObjectMember (theAccessor, "componentType");
const RWGltf_JsonValue* aCount = findObjectMember (theAccessor, "count"); const RWGltf_JsonValue* aCount = findObjectMember (theAccessor, "count");
@ -1534,6 +1548,7 @@ bool RWGltf_GltfJsonParser::gltfParseAccessor (const Handle(RWGltf_GltfLatePrimi
return false; return false;
} }
aStruct.Type = RWGltf_GltfParseAccessorType (aTypeStr->GetString()); aStruct.Type = RWGltf_GltfParseAccessorType (aTypeStr->GetString());
aStruct.IsCompressed = theCompBuffView != NULL;
if (aStruct.Type == RWGltf_GltfAccessorLayout_UNKNOWN) if (aStruct.Type == RWGltf_GltfAccessorLayout_UNKNOWN)
{ {
reportGltfError ("Accessor '" + theName + "' has invalid type."); reportGltfError ("Accessor '" + theName + "' has invalid type.");
@ -1767,6 +1782,7 @@ bool RWGltf_GltfJsonParser::gltfParseBuffer (const Handle(RWGltf_GltfLatePrimiti
aData.Accessor = theAccessor; aData.Accessor = theAccessor;
aData.Accessor.ByteStride = aByteStride; aData.Accessor.ByteStride = aByteStride;
aData.StreamOffset = anOffset; aData.StreamOffset = anOffset;
aData.StreamLength = theView.ByteLength;
aData.StreamUri = myFilePath; aData.StreamUri = myFilePath;
return true; return true;
} }
@ -1785,6 +1801,7 @@ bool RWGltf_GltfJsonParser::gltfParseBuffer (const Handle(RWGltf_GltfLatePrimiti
aData.Accessor = theAccessor; aData.Accessor = theAccessor;
aData.Accessor.ByteStride = aByteStride; aData.Accessor.ByteStride = aByteStride;
aData.StreamOffset = anOffset; aData.StreamOffset = anOffset;
aData.StreamLength = 0;
if (!myDecodedBuffers.Find (theName, aData.StreamData)) if (!myDecodedBuffers.Find (theName, aData.StreamData))
{ {
// it is better decoding in multiple threads // it is better decoding in multiple threads
@ -1819,6 +1836,7 @@ bool RWGltf_GltfJsonParser::gltfParseBuffer (const Handle(RWGltf_GltfLatePrimiti
aData.Accessor = theAccessor; aData.Accessor = theAccessor;
aData.Accessor.ByteStride = aByteStride; aData.Accessor.ByteStride = aByteStride;
aData.StreamOffset = anOffset; aData.StreamOffset = anOffset;
aData.StreamLength = theView.ByteLength;
aData.StreamUri = myFolder + anUri; aData.StreamUri = myFolder + anUri;
if (myExternalFiles != NULL) if (myExternalFiles != NULL)
{ {

View File

@ -196,7 +196,8 @@ protected:
Standard_EXPORT bool gltfParseAccessor (const Handle(RWGltf_GltfLatePrimitiveArray)& theMeshData, Standard_EXPORT bool gltfParseAccessor (const Handle(RWGltf_GltfLatePrimitiveArray)& theMeshData,
const TCollection_AsciiString& theName, const TCollection_AsciiString& theName,
const RWGltf_JsonValue& theAccessor, const RWGltf_JsonValue& theAccessor,
const RWGltf_GltfArrayType theType); const RWGltf_GltfArrayType theType,
const RWGltf_JsonValue* theCompBuffView);
//! Parse buffer view. //! Parse buffer view.
Standard_EXPORT bool gltfParseBufferView (const Handle(RWGltf_GltfLatePrimitiveArray)& theMeshData, Standard_EXPORT bool gltfParseBufferView (const Handle(RWGltf_GltfLatePrimitiveArray)& theMeshData,

View File

@ -78,7 +78,7 @@ public:
//! Add primitive array data element. //! Add primitive array data element.
Standard_EXPORT RWGltf_GltfPrimArrayData& AddPrimArrayData (RWGltf_GltfArrayType theType); Standard_EXPORT RWGltf_GltfPrimArrayData& AddPrimArrayData (RWGltf_GltfArrayType theType);
//! Return TRUE if there is deferred storege and some triangulation data //! Return TRUE if there is deferred storage and some triangulation data
//! that can be loaded using LoadDeferredData(). //! that can be loaded using LoadDeferredData().
virtual Standard_Boolean HasDeferredData() const Standard_OVERRIDE virtual Standard_Boolean HasDeferredData() const Standard_OVERRIDE
{ {

View File

@ -27,15 +27,16 @@ public:
Handle(NCollection_Buffer) StreamData; Handle(NCollection_Buffer) StreamData;
TCollection_AsciiString StreamUri; TCollection_AsciiString StreamUri;
int64_t StreamOffset; int64_t StreamOffset;
int64_t StreamLength;
RWGltf_GltfAccessor Accessor; RWGltf_GltfAccessor Accessor;
RWGltf_GltfArrayType Type; RWGltf_GltfArrayType Type;
RWGltf_GltfPrimArrayData() RWGltf_GltfPrimArrayData()
: StreamOffset (0), Type (RWGltf_GltfArrayType_UNKNOWN) {} : StreamOffset (0), StreamLength (0), Type (RWGltf_GltfArrayType_UNKNOWN) {}
RWGltf_GltfPrimArrayData (RWGltf_GltfArrayType theType) RWGltf_GltfPrimArrayData (RWGltf_GltfArrayType theType)
: StreamOffset (0), Type (theType) {} : StreamOffset (0), StreamLength (0), Type (theType) {}
}; };
#endif // _RWGltf_GltfPrimArrayData_HeaderFile #endif // _RWGltf_GltfPrimArrayData_HeaderFile

View File

@ -21,11 +21,63 @@
#include <Standard_ArrayStreamBuffer.hxx> #include <Standard_ArrayStreamBuffer.hxx>
#include <Standard_ReadBuffer.hxx> #include <Standard_ReadBuffer.hxx>
#ifdef HAVE_DRACO
#include <draco/compression/decode.h>
#endif
namespace namespace
{ {
static const Standard_Integer THE_LOWER_TRI_INDEX = 1; static const Standard_Integer THE_LOWER_TRI_INDEX = 1;
static const Standard_Integer THE_LOWER_NODE_INDEX = 1; static const Standard_Integer THE_LOWER_NODE_INDEX = 1;
static const Standard_ShortReal THE_NORMAL_PREC2 = 0.001f; static const Standard_ShortReal THE_NORMAL_PREC2 = 0.001f;
#ifdef HAVE_DRACO
//! Return array type from Draco attribute type.
static RWGltf_GltfArrayType arrayTypeFromDraco (draco::GeometryAttribute::Type theType)
{
switch (theType)
{
case draco::GeometryAttribute::POSITION: return RWGltf_GltfArrayType_Position;
case draco::GeometryAttribute::NORMAL: return RWGltf_GltfArrayType_Normal;
case draco::GeometryAttribute::COLOR: return RWGltf_GltfArrayType_Color;
case draco::GeometryAttribute::TEX_COORD: return RWGltf_GltfArrayType_TCoord0;
default: return RWGltf_GltfArrayType_UNKNOWN;
}
}
//! Return layout from Draco number of components.
static RWGltf_GltfAccessorLayout layoutFromDraco (int8_t theNbComps)
{
switch (theNbComps)
{
case 1: return RWGltf_GltfAccessorLayout_Scalar;
case 2: return RWGltf_GltfAccessorLayout_Vec2;
case 3: return RWGltf_GltfAccessorLayout_Vec3;
case 4: return RWGltf_GltfAccessorLayout_Vec4;
}
return RWGltf_GltfAccessorLayout_UNKNOWN;
}
//! Return component type from Draco data type.
static RWGltf_GltfAccessorCompType compTypeFromDraco (draco::DataType theType)
{
switch (theType)
{
case draco::DT_INT8: return RWGltf_GltfAccessorCompType_Int8;
case draco::DT_UINT8: return RWGltf_GltfAccessorCompType_UInt8;
case draco::DT_INT16: return RWGltf_GltfAccessorCompType_Int16;
case draco::DT_UINT16: return RWGltf_GltfAccessorCompType_UInt16;
case draco::DT_INT32:
case draco::DT_UINT32: return RWGltf_GltfAccessorCompType_UInt32;
//case draco::DT_INT64:
//case draco::DT_UINT64:
case draco::DT_FLOAT32: return RWGltf_GltfAccessorCompType_Float32;
//case draco::DT_FLOAT64:
//case draco::DT_BOOL:
default: return RWGltf_GltfAccessorCompType_UNKNOWN;
}
}
#endif
} }
IMPLEMENT_STANDARD_RTTIEXT(RWGltf_TriangulationReader, RWMesh_TriangulationReader) IMPLEMENT_STANDARD_RTTIEXT(RWGltf_TriangulationReader, RWMesh_TriangulationReader)
@ -104,9 +156,10 @@ bool RWGltf_TriangulationReader::readFileData (const Handle(RWGltf_GltfLatePrimi
(theGltfData.StreamUri, std::ios::in | std::ios::binary, theGltfData.StreamOffset); (theGltfData.StreamUri, std::ios::in | std::ios::binary, theGltfData.StreamOffset);
if (aSharedStream.get() == NULL) if (aSharedStream.get() == NULL)
{ {
reportError (TCollection_AsciiString("Buffer '") + theSourceGltfMesh->Id() + "refers to invalid file '" + theGltfData.StreamUri + "'."); reportError (TCollection_AsciiString("Buffer '") + theSourceGltfMesh->Id() + "' refers to invalid file '" + theGltfData.StreamUri + "'.");
return false; return false;
} }
if (!readBuffer (theSourceGltfMesh, theDestMesh, *aSharedStream.get(), theGltfData.Accessor, theGltfData.Type)) if (!readBuffer (theSourceGltfMesh, theDestMesh, *aSharedStream.get(), theGltfData.Accessor, theGltfData.Type))
{ {
return false; return false;
@ -149,6 +202,218 @@ bool RWGltf_TriangulationReader::loadStreamData (const Handle(RWMesh_Triangulati
return wasLoaded; return wasLoaded;
} }
// =======================================================================
// function : readDracoBuffer
// purpose :
// =======================================================================
bool RWGltf_TriangulationReader::readDracoBuffer (const Handle(RWGltf_GltfLatePrimitiveArray)& theSourceGltfMesh,
const RWGltf_GltfPrimArrayData& theGltfData,
const Handle(Poly_Triangulation)& theDestMesh,
const Handle(OSD_FileSystem)& theFileSystem) const
{
const TCollection_AsciiString& aName = theSourceGltfMesh->Id();
const Handle(OSD_FileSystem)& aFileSystem = !theFileSystem.IsNull() ? theFileSystem : OSD_FileSystem::DefaultFileSystem();
opencascade::std::shared_ptr<std::istream> aSharedStream = aFileSystem->OpenIStream (theGltfData.StreamUri, std::ios::in | std::ios::binary, theGltfData.StreamOffset);
if (aSharedStream.get() == NULL)
{
reportError (TCollection_AsciiString("Buffer '") + aName + "' refers to invalid file '" + theGltfData.StreamUri + "'.");
return false;
}
#ifdef HAVE_DRACO
std::vector<char> aReadData;
aReadData.resize (theGltfData.StreamLength);
aSharedStream->read (aReadData.data(), (std::streamsize )theGltfData.StreamLength);
if (!aSharedStream->good())
{
reportError (TCollection_AsciiString("Buffer '") + aName + "' refers to file that cannot be read '" + theGltfData.StreamUri + "'.");
return false;
}
draco::DecoderBuffer aDracoBuf;
aDracoBuf.Init (aReadData.data(), aReadData.size());
draco::Decoder aDracoDecoder;
draco::StatusOr<std::unique_ptr<draco::Mesh>> aDracoStat = aDracoDecoder.DecodeMeshFromBuffer (&aDracoBuf);
if (!aDracoStat.ok() || aDracoStat.value().get() == NULL)
{
reportError (TCollection_AsciiString("Buffer '") + aName + "' refers to Draco data that cannot be decoded '" + theGltfData.StreamUri + "'.");
return false;
}
const Standard_Integer aNbNodes = (Standard_Integer )aDracoStat.value()->num_points();
const Standard_Integer aNbTris = (Standard_Integer )aDracoStat.value()->num_faces();
if (aNbNodes < 0)
{
reportError (TCollection_AsciiString ("Buffer '") + aName + "' defines an empty array.");
return false;
}
if ((int64_t )aDracoStat.value()->num_points() > std::numeric_limits<Standard_Integer>::max())
{
reportError (TCollection_AsciiString ("Buffer '") + aName + "' defines too big array.");
return false;
}
if (!setNbPositionNodes (theDestMesh, aNbNodes))
{
return false;
}
if (aNbTris > 0
&& !setNbTriangles (theDestMesh, aNbTris))
{
return false;
}
// copy vertex attributes
for (int32_t anAttrIter = 0; anAttrIter < aDracoStat.value()->num_attributes(); ++anAttrIter)
{
const draco::PointAttribute* anAttrib = aDracoStat.value()->attribute (anAttrIter);
const RWGltf_GltfArrayType aWrapType = arrayTypeFromDraco(anAttrib->attribute_type());
const RWGltf_GltfAccessorLayout aWrapLayout = layoutFromDraco (anAttrib->num_components());
const RWGltf_GltfAccessorCompType aWrapCompType = compTypeFromDraco (anAttrib->data_type());
switch (aWrapType)
{
case RWGltf_GltfArrayType_Position:
{
if (aWrapCompType != RWGltf_GltfAccessorCompType_Float32
|| aWrapLayout != RWGltf_GltfAccessorLayout_Vec3)
{
reportError (TCollection_AsciiString ("Buffer '") + aName + "' has unsupported position data type.");
return false;
}
for (Standard_Integer aVertIter = 0; aVertIter < aNbNodes; ++aVertIter)
{
const Graphic3d_Vec3* aVec3 = reinterpret_cast<const Graphic3d_Vec3* >(anAttrib->GetAddressOfMappedIndex (draco::PointIndex (aVertIter)));
if (aVec3 == NULL)
{
reportError (TCollection_AsciiString ("Buffer '") + aName + "' reading error.");
return false;
}
gp_Pnt anXYZ (aVec3->x(), aVec3->y(), aVec3->z());
myCoordSysConverter.TransformPosition (anXYZ.ChangeCoord());
setNodePosition (theDestMesh, THE_LOWER_NODE_INDEX + aVertIter, anXYZ);
}
}
case RWGltf_GltfArrayType_Normal:
{
if (aWrapCompType != RWGltf_GltfAccessorCompType_Float32
|| aWrapLayout != RWGltf_GltfAccessorLayout_Vec3)
{
Message::SendTrace (TCollection_AsciiString() + "Vertex normals in unsupported format have been skipped while reading glTF triangulation '" + aName + "'");
break;
}
if (!setNbNormalNodes (theDestMesh, aNbNodes))
{
return false;
}
for (Standard_Integer aVertIter = 0; aVertIter < aNbNodes; ++aVertIter)
{
const Graphic3d_Vec3* aVec3 = reinterpret_cast<const Graphic3d_Vec3* >(anAttrib->GetAddressOfMappedIndex (draco::PointIndex (aVertIter)));
if (aVec3 == NULL)
{
reportError (TCollection_AsciiString ("Buffer '") + aName + "' reading error.");
return false;
}
if (aVec3->SquareModulus() >= THE_NORMAL_PREC2)
{
Graphic3d_Vec3 aVec3Copy = *aVec3;
myCoordSysConverter.TransformNormal (aVec3Copy);
setNodeNormal (theDestMesh, THE_LOWER_NODE_INDEX + aVertIter, aVec3Copy);
}
else
{
setNodeNormal (theDestMesh, THE_LOWER_NODE_INDEX + aVertIter, gp_Vec3f(0.0, 0.0, 1.0));
}
}
break;
}
case RWGltf_GltfArrayType_TCoord0:
{
if (aWrapCompType != RWGltf_GltfAccessorCompType_Float32
|| aWrapLayout != RWGltf_GltfAccessorLayout_Vec2)
{
Message::SendTrace (TCollection_AsciiString() + "Vertex UV coordinates in unsupported format have been skipped while reading glTF triangulation '" + aName + "'");
break;
}
if (!setNbUVNodes (theDestMesh, aNbNodes))
{
return false;
}
for (int aVertIter = 0; aVertIter < aNbNodes; ++aVertIter)
{
const Graphic3d_Vec2* aVec2 = reinterpret_cast<const Graphic3d_Vec2* >(anAttrib->GetAddressOfMappedIndex (draco::PointIndex (aVertIter)));
if (aVec2 == NULL)
{
reportError (TCollection_AsciiString ("Buffer '") + aName + "' reading error.");
return false;
}
// Y should be flipped (relative to image layout used by OCCT)
float aTexY = 1.0f - aVec2->y();
setNodeUV (theDestMesh, THE_LOWER_NODE_INDEX + aVertIter, gp_Pnt2d (aVec2->x(), aTexY));
}
break;
}
default:
{
break;
}
}
}
// copy triangles
Standard_Integer aLastTriIndex = 0;
for (Standard_Integer aFaceIter = 0; aFaceIter < aNbTris; ++aFaceIter)
{
const draco::Mesh::Face& aFace = aDracoStat.value()->face (draco::FaceIndex (aFaceIter));
Poly_Triangle aVec3;
aVec3.ChangeValue (1) = THE_LOWER_NODE_INDEX + aFace[0].value();
aVec3.ChangeValue (2) = THE_LOWER_NODE_INDEX + aFace[1].value();
aVec3.ChangeValue (3) = THE_LOWER_NODE_INDEX + aFace[2].value();
const Standard_Integer wasSet = setTriangle (theDestMesh, THE_LOWER_TRI_INDEX + aLastTriIndex, aVec3);
if (!wasSet)
{
reportError (TCollection_AsciiString ("Buffer '") + aName + "' refers to invalid indices.");
}
if (wasSet > 0)
{
++aLastTriIndex;
}
}
const Standard_Integer aNbDegenerate = aNbTris - aLastTriIndex;
if (aNbDegenerate > 0)
{
if (aNbDegenerate == aNbTris)
{
Message::SendWarning (TCollection_AsciiString("Buffer '") + aName + "' has been skipped (all elements are degenerative in)");
return false;
}
theSourceGltfMesh->ChangeDegeneratedTriNb() += aNbDegenerate;
if (myLoadingStatistic == NULL && myToPrintDebugMessages)
{
Message::SendTrace (TCollection_AsciiString() + aNbDegenerate
+ " degenerate triangles have been skipped while reading glTF triangulation '" + aName + "'");
}
if (!setNbTriangles (theDestMesh, aLastTriIndex, true))
{
return false;
}
}
return true;
#else
(void )theDestMesh;
reportError (TCollection_AsciiString ("Buffer '") + aName + "' refers to unsupported compressed data.");
return false;
#endif
}
// ======================================================================= // =======================================================================
// function : load // function : load
// purpose : // purpose :
@ -164,22 +429,39 @@ bool RWGltf_TriangulationReader::load (const Handle(RWMesh_TriangulationSource)&
return false; return false;
} }
bool hasCompressed = false;
for (NCollection_Sequence<RWGltf_GltfPrimArrayData>::Iterator aDataIter (aSourceGltfMesh->Data()); aDataIter.More(); aDataIter.Next()) for (NCollection_Sequence<RWGltf_GltfPrimArrayData>::Iterator aDataIter (aSourceGltfMesh->Data()); aDataIter.More(); aDataIter.Next())
{ {
const RWGltf_GltfPrimArrayData& aData = aDataIter.Value(); const RWGltf_GltfPrimArrayData& aData = aDataIter.Value();
const TCollection_AsciiString& aName = aSourceGltfMesh->Id();
if (!aData.StreamData.IsNull()) if (!aData.StreamData.IsNull())
{ {
Message::SendWarning (TCollection_AsciiString("Buffer '") + aSourceGltfMesh->Id() + Message::SendWarning (TCollection_AsciiString("Buffer '") + aName +
"' contains stream data that cannot be loaded during deferred data loading."); "' contains stream data that cannot be loaded during deferred data loading.");
continue; continue;
} }
else if (aData.StreamUri.IsEmpty()) else if (aData.StreamUri.IsEmpty())
{ {
reportError (TCollection_AsciiString ("Buffer '") + aSourceGltfMesh->Id() + "' does not define uri."); reportError (TCollection_AsciiString ("Buffer '") + aName + "' does not define uri.");
return false; return false;
} }
if (!readFileData (aSourceGltfMesh, aData, theDestMesh, theFileSystem)) if (aData.Accessor.IsCompressed)
{
if (hasCompressed)
{
// already decoded (compressed stream defines all attributes at once)
continue;
}
if (!readDracoBuffer (aSourceGltfMesh, aData, theDestMesh, theFileSystem))
{
return false;
}
// keep decoding - there are might be uncompressed attributes in addition to compressed
hasCompressed = true;
}
else if (!readFileData (aSourceGltfMesh, aData, theDestMesh, theFileSystem))
{ {
return false; return false;
} }

View File

@ -97,6 +97,16 @@ protected:
const RWGltf_GltfAccessor& theAccessor, const RWGltf_GltfAccessor& theAccessor,
RWGltf_GltfArrayType theType) const; RWGltf_GltfArrayType theType) const;
//! Reads primitive array from file data compressed in Draco format.
//! @param theSourceGltfMesh source glTF triangulation
//! @param theGltfData primitive array element (Uri of file stream should not be empty)
//! @param theDestMesh triangulation to be modified
//! @param theFileSystem shared file system to read from
Standard_EXPORT virtual bool readDracoBuffer (const Handle(RWGltf_GltfLatePrimitiveArray)& theSourceGltfMesh,
const RWGltf_GltfPrimArrayData& theGltfData,
const Handle(Poly_Triangulation)& theDestMesh,
const Handle(OSD_FileSystem)& theFileSystem) const;
protected: protected:
Handle(Poly_Triangulation) myTriangulation; Handle(Poly_Triangulation) myTriangulation;

View File

@ -2,7 +2,6 @@ TKernel
TKService TKService
TKMath TKMath
CSF_TBB CSF_TBB
CSF_FREETYPE
CSF_OpenGlLibs CSF_OpenGlLibs
CSF_user32 CSF_user32
CSF_gdi32 CSF_gdi32

View File

@ -8,3 +8,4 @@ TKBRep
TKG3d TKG3d
TKService TKService
CSF_RapidJSON CSF_RapidJSON
CSF_Draco