Introduce VRML format (.wrl and .x3dv) 3D model support (#5857)
- Introduce VRML format (.wrl and .x3dv) 3D model support - Add samples --------- Co-authored-by: Steve M <praktique-tellypresence@yahoo.com> Co-authored-by: Kim Kulling <kimkulling@users.noreply.github.com>
2
.gitignore
vendored
@@ -122,5 +122,7 @@ tools/assimp_qt_viewer/ui_mainwindow.h
|
|||||||
generated/*
|
generated/*
|
||||||
|
|
||||||
# 3rd party cloned repos/tarballs etc
|
# 3rd party cloned repos/tarballs etc
|
||||||
|
# meshlab repo, automatically cloned via CMake (to gain 2 source files for VRML file format conversion)
|
||||||
|
contrib/meshlab/autoclone
|
||||||
# tinyusdz repo, automatically cloned via CMake
|
# tinyusdz repo, automatically cloned via CMake
|
||||||
contrib/tinyusdz/autoclone
|
contrib/tinyusdz/autoclone
|
||||||
|
|||||||
@@ -40,12 +40,47 @@ SET(CMAKE_POLICY_DEFAULT_CMP0092 NEW)
|
|||||||
|
|
||||||
CMAKE_MINIMUM_REQUIRED( VERSION 3.22 )
|
CMAKE_MINIMUM_REQUIRED( VERSION 3.22 )
|
||||||
|
|
||||||
|
#================================================================================#
|
||||||
|
# Model formats not enabled by default
|
||||||
|
#
|
||||||
|
# 3rd party projects may not adhere to strict standards enforced by assimp,
|
||||||
|
# in which case those formats must be opt-in; otherwise the 3rd party code
|
||||||
|
# would fail assimp CI checks
|
||||||
|
#================================================================================#
|
||||||
|
# M3D format import support (assimp integration no longer supported by M3D format author)
|
||||||
|
# User may override these in their CMake script to provide M3D import/export support
|
||||||
|
# (M3D importer/exporter was disabled for assimp release 5.1 or later)
|
||||||
|
option(ASSIMP_BUILD_M3D_IMPORTER "Enable M3D file import" off)
|
||||||
|
option(ASSIMP_BUILD_M3D_EXPORTER "Enable M3D file export" off)
|
||||||
|
|
||||||
# Experimental USD importer: disabled, need to opt-in
|
# Experimental USD importer: disabled, need to opt-in
|
||||||
# Note: assimp github PR automatic checks will fail the PR due to compiler warnings in
|
# Note: assimp github PR automatic checks will fail the PR due to compiler warnings in
|
||||||
# the external, 3rd party tinyusdz code which isn't technically part of the PR since it's
|
# the external, 3rd party tinyusdz code which isn't technically part of the PR since it's
|
||||||
# auto-cloned during build; so MUST disable the feature or the PR will be rejected
|
# auto-cloned during build; so MUST disable the feature or the PR will be rejected
|
||||||
option(ASSIMP_BUILD_USD_IMPORTER "Enable USD file import" off)
|
option(ASSIMP_BUILD_USD_IMPORTER "Enable USD file import" off)
|
||||||
option(ASSIMP_BUILD_USD_VERBOSE_LOGS "Enable verbose USD import debug logging" off)
|
option(ASSIMP_BUILD_USD_VERBOSE_LOGS "Enable verbose USD import debug logging" off)
|
||||||
|
|
||||||
|
# VRML (.wrl/.x3dv) file import support by leveraging X3D importer and 3rd party file
|
||||||
|
# format converter to convert .wrl/.x3dv files to X3D-compatible .xml
|
||||||
|
# (Need to make this opt-in because 3rd party code triggers lots of CI code quality warnings)
|
||||||
|
option(ASSIMP_BUILD_VRML_IMPORTER "Enable VRML (.wrl/.x3dv) file import" off)
|
||||||
|
#--------------------------------------------------------------------------------#
|
||||||
|
# Internal impl for optional model formats
|
||||||
|
#--------------------------------------------------------------------------------#
|
||||||
|
# Internal/private M3D logic
|
||||||
|
if (NOT ASSIMP_BUILD_M3D_IMPORTER)
|
||||||
|
ADD_DEFINITIONS( -DASSIMP_BUILD_NO_M3D_IMPORTER)
|
||||||
|
endif () # if (not ASSIMP_BUILD_M3D_IMPORTER)
|
||||||
|
if (NOT ASSIMP_BUILD_M3D_EXPORTER)
|
||||||
|
ADD_DEFINITIONS( -DASSIMP_BUILD_NO_M3D_EXPORTER)
|
||||||
|
endif () # if (not ASSIMP_BUILD_M3D_EXPORTER)
|
||||||
|
|
||||||
|
# Internal/private VRML logic
|
||||||
|
if (NOT ASSIMP_BUILD_VRML_IMPORTER)
|
||||||
|
ADD_DEFINITIONS( -DASSIMP_BUILD_NO_VRML_IMPORTER)
|
||||||
|
endif () # if (not ASSIMP_BUILD_VRML_IMPORTER)
|
||||||
|
#================================================================================#
|
||||||
|
|
||||||
option(ASSIMP_BUILD_USE_CCACHE "Use ccache to speed up compilation." on)
|
option(ASSIMP_BUILD_USE_CCACHE "Use ccache to speed up compilation." on)
|
||||||
|
|
||||||
if(ASSIMP_BUILD_USE_CCACHE)
|
if(ASSIMP_BUILD_USE_CCACHE)
|
||||||
@@ -56,19 +91,6 @@ if(ASSIMP_BUILD_USE_CCACHE)
|
|||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# User may override these in their CMake script to provide M3D import/export support
|
|
||||||
# (M3D importer/exporter was disabled for assimp release 5.1 or later)
|
|
||||||
option(ASSIMP_BUILD_M3D_IMPORTER "Enable M3D file import" off)
|
|
||||||
option(ASSIMP_BUILD_M3D_EXPORTER "Enable M3D file export" off)
|
|
||||||
|
|
||||||
# Internal/private M3D logic
|
|
||||||
if (NOT ASSIMP_BUILD_M3D_IMPORTER)
|
|
||||||
ADD_DEFINITIONS( -DASSIMP_BUILD_NO_M3D_IMPORTER)
|
|
||||||
endif () # if (not ASSIMP_BUILD_M3D_IMPORTER)
|
|
||||||
if (NOT ASSIMP_BUILD_M3D_EXPORTER)
|
|
||||||
ADD_DEFINITIONS( -DASSIMP_BUILD_NO_M3D_EXPORTER)
|
|
||||||
endif () # if (not ASSIMP_BUILD_M3D_EXPORTER)
|
|
||||||
|
|
||||||
# Toggles the use of the hunter package manager
|
# Toggles the use of the hunter package manager
|
||||||
option(ASSIMP_HUNTER_ENABLED "Enable Hunter package manager support" OFF)
|
option(ASSIMP_HUNTER_ENABLED "Enable Hunter package manager support" OFF)
|
||||||
|
|
||||||
|
|||||||
21
code/AssetLib/VRML/README.md
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
# WRL/X3DV to X3D file format converter
|
||||||
|
|
||||||
|
## VRML and X3D 3D model formats background
|
||||||
|
"VRML" 3D model files use either `VRML97` (`.wrl`) or "Classic VRML" (`.x3dv`)
|
||||||
|
file formats.
|
||||||
|
|
||||||
|
The X3D model specification was introduced after these formats, as a superset of both WRL and X3DV.
|
||||||
|
While X3D can understand the _content_ of WRL/X3DV files, it can't directly parse them because
|
||||||
|
X3D uses `.xml` files, rather than `VRML97` or "Classic VRML" format.
|
||||||
|
|
||||||
|
But, if a converter is available to migrate just the file format (preserving the content), so that
|
||||||
|
the `.wrl`/`.x3dv` files can be converted to an X3D-compatible `.xml` file, then the X3D importer
|
||||||
|
will be able to load the resulting model file.
|
||||||
|
|
||||||
|
## How this code is used
|
||||||
|
The sole purpose of `Parser`/`Scanner` (adopted from the `meshlab` project) is to take a
|
||||||
|
`VRML97` (`.wrl`) or "Classic VRML" (`.x3dv`) file as input, and convert to an X3D `.xml` file.
|
||||||
|
That's it.
|
||||||
|
|
||||||
|
By passing the converted in-memory `.xml` file content to the `X3DImporter`, the `.wrl` or `x3dv`
|
||||||
|
model can be loaded via assimp.
|
||||||
103
code/AssetLib/VRML/VrmlConverter.cpp
Normal file
@@ -0,0 +1,103 @@
|
|||||||
|
/*
|
||||||
|
Open Asset Import Library (assimp)
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
|
Copyright (c) 2006-2024, assimp team
|
||||||
|
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
with or without modification, are permitted provided that the
|
||||||
|
following conditions are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above
|
||||||
|
copyright notice, this list of conditions and the
|
||||||
|
following disclaimer.
|
||||||
|
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
copyright notice, this list of conditions and the
|
||||||
|
following disclaimer in the documentation and/or other
|
||||||
|
materials provided with the distribution.
|
||||||
|
|
||||||
|
* Neither the name of the assimp team, nor the names of its
|
||||||
|
contributors may be used to endorse or promote products
|
||||||
|
derived from this software without specific prior
|
||||||
|
written permission of the assimp team.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
/// \file VrmlImporter.cpp
|
||||||
|
/// \brief Convert VRML-formatted (.wrl, .x3dv) files to X3D .xml format
|
||||||
|
/// \date 2024
|
||||||
|
/// \author tellypresence
|
||||||
|
|
||||||
|
#ifndef ASSIMP_BUILD_NO_X3D_IMPORTER
|
||||||
|
|
||||||
|
#include <memory> // std::unique_ptr
|
||||||
|
#include "VrmlConverter.hpp"
|
||||||
|
|
||||||
|
namespace Assimp {
|
||||||
|
|
||||||
|
bool isFileWrlVrml97Ext(const std::string &pFile) {
|
||||||
|
size_t pos = pFile.find_last_of('.');
|
||||||
|
if (pos == std::string::npos) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
std::string ext = pFile.substr(pos + 1);
|
||||||
|
if (ext.size() != 3) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return (ext[0] == 'w' || ext[0] == 'W') && (ext[1] == 'r' || ext[1] == 'R') && (ext[2] == 'l' || ext[2] == 'L');
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isFileX3dvClassicVrmlExt(const std::string &pFile) {
|
||||||
|
size_t pos = pFile.find_last_of('.');
|
||||||
|
if (pos == std::string::npos) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
std::string ext = pFile.substr(pos + 1);
|
||||||
|
if (ext.size() != 4) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return (ext[0] == 'x' || ext[0] == 'X') && (ext[1] == '3') && (ext[2] == 'd' || ext[2] == 'D') && (ext[3] == 'v' || ext[3] == 'V');
|
||||||
|
}
|
||||||
|
|
||||||
|
#if !defined(ASSIMP_BUILD_NO_VRML_IMPORTER)
|
||||||
|
static VrmlTranslator::Scanner createScanner(const std::string &pFile) {
|
||||||
|
std::unique_ptr<wchar_t[]> wide_stringPtr{ new wchar_t[ pFile.length() + 1 ] };
|
||||||
|
std::copy(pFile.begin(), pFile.end(), wide_stringPtr.get());
|
||||||
|
wide_stringPtr[ pFile.length() ] = 0;
|
||||||
|
|
||||||
|
return VrmlTranslator::Scanner(wide_stringPtr.get());
|
||||||
|
} // wide_stringPtr auto-deleted when leaving scope
|
||||||
|
#endif // #if !defined(ASSIMP_BUILD_NO_VRML_IMPORTER)
|
||||||
|
|
||||||
|
std::stringstream ConvertVrmlFileToX3dXmlFile(const std::string &pFile) {
|
||||||
|
std::stringstream ss;
|
||||||
|
if (isFileWrlVrml97Ext(pFile) || isFileX3dvClassicVrmlExt(pFile)) {
|
||||||
|
#if !defined(ASSIMP_BUILD_NO_VRML_IMPORTER)
|
||||||
|
VrmlTranslator::Scanner scanner = createScanner(pFile);
|
||||||
|
VrmlTranslator::Parser parser(&scanner);
|
||||||
|
parser.Parse();
|
||||||
|
ss.str("");
|
||||||
|
parser.doc_.save(ss);
|
||||||
|
#endif // #if !defined(ASSIMP_BUILD_NO_VRML_IMPORTER)
|
||||||
|
}
|
||||||
|
return ss;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Assimp
|
||||||
|
|
||||||
|
#endif // !ASSIMP_BUILD_NO_X3D_IMPORTER
|
||||||
57
code/AssetLib/VRML/VrmlConverter.hpp
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
/*
|
||||||
|
Open Asset Import Library (assimp)
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
|
Copyright (c) 2006-2024, assimp team
|
||||||
|
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
with or without modification, are permitted provided that the
|
||||||
|
following conditions are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above
|
||||||
|
copyright notice, this list of conditions and the
|
||||||
|
following disclaimer.
|
||||||
|
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
copyright notice, this list of conditions and the
|
||||||
|
following disclaimer in the documentation and/or other
|
||||||
|
materials provided with the distribution.
|
||||||
|
|
||||||
|
* Neither the name of the assimp team, nor the names of its
|
||||||
|
contributors may be used to endorse or promote products
|
||||||
|
derived from this software without specific prior
|
||||||
|
written permission of the assimp team.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <sstream>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#if !defined(ASSIMP_BUILD_NO_VRML_IMPORTER)
|
||||||
|
#include "contrib/meshlab/autoclone/meshlab_repo-src/src/meshlabplugins/io_x3d/vrml/Parser.h"
|
||||||
|
#endif // #if !defined(ASSIMP_BUILD_NO_VRML_IMPORTER)
|
||||||
|
|
||||||
|
namespace Assimp {
|
||||||
|
|
||||||
|
bool isFileWrlVrml97Ext(const std::string &pFile);
|
||||||
|
bool isFileX3dvClassicVrmlExt(const std::string &pFile);
|
||||||
|
|
||||||
|
std::stringstream ConvertVrmlFileToX3dXmlFile(const std::string &pFile);
|
||||||
|
} // namespace Assimp
|
||||||
@@ -45,6 +45,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
|
|
||||||
#ifndef ASSIMP_BUILD_NO_X3D_IMPORTER
|
#ifndef ASSIMP_BUILD_NO_X3D_IMPORTER
|
||||||
|
|
||||||
|
#include "AssetLib/VRML/VrmlConverter.hpp"
|
||||||
#include "X3DImporter.hpp"
|
#include "X3DImporter.hpp"
|
||||||
#include "X3DImporter_Macro.hpp"
|
#include "X3DImporter_Macro.hpp"
|
||||||
|
|
||||||
@@ -54,11 +55,19 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#include <iterator>
|
#include <iterator>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
|
#if defined(ASSIMP_BUILD_NO_VRML_IMPORTER)
|
||||||
|
#define X3D_FORMATS_DESCR_STR "Extensible 3D(X3D, X3DB) Importer"
|
||||||
|
#define X3D_FORMATS_EXTENSIONS_STR "x3d x3db"
|
||||||
|
#else
|
||||||
|
#define X3D_FORMATS_DESCR_STR "VRML(WRL, X3DV) and Extensible 3D(X3D, X3DB) Importer"
|
||||||
|
#define X3D_FORMATS_EXTENSIONS_STR "wrl x3d x3db x3dv"
|
||||||
|
#endif // #if defined(ASSIMP_BUILD_NO_VRML_IMPORTER)
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
|
|
||||||
/// Constant which holds the importer description
|
/// Constant which holds the importer description
|
||||||
const aiImporterDesc X3DImporter::Description = {
|
const aiImporterDesc X3DImporter::Description = {
|
||||||
"Extensible 3D(X3D) Importer",
|
X3D_FORMATS_DESCR_STR,
|
||||||
"smalcom",
|
"smalcom",
|
||||||
"",
|
"",
|
||||||
"See documentation in source code. Chapter: Limitations.",
|
"See documentation in source code. Chapter: Limitations.",
|
||||||
@@ -67,7 +76,7 @@ const aiImporterDesc X3DImporter::Description = {
|
|||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
"x3d x3db"
|
X3D_FORMATS_EXTENSIONS_STR
|
||||||
};
|
};
|
||||||
|
|
||||||
bool X3DImporter::isNodeEmpty(XmlNode &node) {
|
bool X3DImporter::isNodeEmpty(XmlNode &node) {
|
||||||
@@ -215,7 +224,19 @@ void X3DImporter::ParseFile(const std::string &file, IOSystem *pIOHandler) {
|
|||||||
if (!theParser.parse(fileStream.get())) {
|
if (!theParser.parse(fileStream.get())) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
ParseFile(theParser);
|
||||||
|
}
|
||||||
|
|
||||||
|
void X3DImporter::ParseFile(std::istream &myIstream) {
|
||||||
|
XmlParser theParser;
|
||||||
|
if (!theParser.parse(myIstream)) {
|
||||||
|
LogInfo("ParseFile(): ERROR: failed to convert VRML istream to xml");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ParseFile(theParser);
|
||||||
|
}
|
||||||
|
|
||||||
|
void X3DImporter::ParseFile(XmlParser &theParser) {
|
||||||
XmlNode *node = theParser.findNode("X3D");
|
XmlNode *node = theParser.findNode("X3D");
|
||||||
if (nullptr == node) {
|
if (nullptr == node) {
|
||||||
return;
|
return;
|
||||||
@@ -246,9 +267,13 @@ void X3DImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
|
|||||||
mpIOHandler = pIOHandler;
|
mpIOHandler = pIOHandler;
|
||||||
|
|
||||||
Clear();
|
Clear();
|
||||||
std::shared_ptr<IOStream> stream(pIOHandler->Open(pFile, "rb"));
|
std::stringstream ss = ConvertVrmlFileToX3dXmlFile(pFile);
|
||||||
if (!stream) {
|
const bool isReadFromMem{ ss.str().length() > 0 };
|
||||||
throw DeadlyImportError("Could not open file for reading");
|
if (!isReadFromMem) {
|
||||||
|
std::shared_ptr<IOStream> stream(pIOHandler->Open(pFile, "rb"));
|
||||||
|
if (!stream) {
|
||||||
|
throw DeadlyImportError("Could not open file for reading");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
std::string::size_type slashPos = pFile.find_last_of("\\/");
|
std::string::size_type slashPos = pFile.find_last_of("\\/");
|
||||||
|
|
||||||
@@ -257,9 +282,13 @@ void X3DImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
|
|||||||
pScene->mRootNode->mParent = nullptr;
|
pScene->mRootNode->mParent = nullptr;
|
||||||
pScene->mFlags |= AI_SCENE_FLAGS_ALLOW_SHARED;
|
pScene->mFlags |= AI_SCENE_FLAGS_ALLOW_SHARED;
|
||||||
|
|
||||||
pIOHandler->PushDirectory(slashPos == std::string::npos ? std::string() : pFile.substr(0, slashPos + 1));
|
if (isReadFromMem) {
|
||||||
ParseFile(pFile, pIOHandler);
|
ParseFile(ss);
|
||||||
pIOHandler->PopDirectory();
|
} else {
|
||||||
|
pIOHandler->PushDirectory(slashPos == std::string::npos ? std::string() : pFile.substr(0, slashPos + 1));
|
||||||
|
ParseFile(pFile, pIOHandler);
|
||||||
|
pIOHandler->PopDirectory();
|
||||||
|
}
|
||||||
|
|
||||||
//search for root node element
|
//search for root node element
|
||||||
|
|
||||||
|
|||||||
@@ -275,7 +275,9 @@ public:
|
|||||||
/// Also exception can be thrown if trouble will found.
|
/// Also exception can be thrown if trouble will found.
|
||||||
/// \param [in] pFile - name of file to be parsed.
|
/// \param [in] pFile - name of file to be parsed.
|
||||||
/// \param [in] pIOHandler - pointer to IO helper object.
|
/// \param [in] pIOHandler - pointer to IO helper object.
|
||||||
void ParseFile(const std::string &pFile, IOSystem *pIOHandler);
|
void ParseFile(const std::string &file, IOSystem *pIOHandler);
|
||||||
|
void ParseFile(std::istream &myIstream);
|
||||||
|
void ParseFile(XmlParser &theParser);
|
||||||
bool CanRead(const std::string &pFile, IOSystem *pIOHandler, bool pCheckSig) const;
|
bool CanRead(const std::string &pFile, IOSystem *pIOHandler, bool pCheckSig) const;
|
||||||
void InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler);
|
void InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler);
|
||||||
const aiImporterDesc *GetInfo() const;
|
const aiImporterDesc *GetInfo() const;
|
||||||
|
|||||||
@@ -864,6 +864,7 @@ ADD_ASSIMP_IMPORTER( X3D
|
|||||||
AssetLib/X3D/X3DGeoHelper.h
|
AssetLib/X3D/X3DGeoHelper.h
|
||||||
AssetLib/X3D/X3DXmlHelper.cpp
|
AssetLib/X3D/X3DXmlHelper.cpp
|
||||||
AssetLib/X3D/X3DXmlHelper.h
|
AssetLib/X3D/X3DXmlHelper.h
|
||||||
|
AssetLib/VRML/VrmlConverter.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
ADD_ASSIMP_IMPORTER( GLTF
|
ADD_ASSIMP_IMPORTER( GLTF
|
||||||
@@ -930,6 +931,69 @@ SET( Extra_SRCS
|
|||||||
)
|
)
|
||||||
SOURCE_GROUP( Extra FILES ${Extra_SRCS})
|
SOURCE_GROUP( Extra FILES ${Extra_SRCS})
|
||||||
|
|
||||||
|
# VRML (.wrl/.x3dv) support
|
||||||
|
IF (ASSIMP_BUILD_VRML_IMPORTER)
|
||||||
|
# Note: ALWAYS specify a git commit hash (or tag) instead of a branch name; using a branch name
|
||||||
|
# can lead to non-deterministic (unpredictable) results since the code is potentially in flux
|
||||||
|
# "main" branch, 18 Nov 2024
|
||||||
|
set(Meshlab_GIT_TAG "ad55b47a9b0700e7b427db6db287bb3a39aa31e7")
|
||||||
|
message("****")
|
||||||
|
message("\n\n**** Cloning meshlab repo, git tag ${Meshlab_GIT_TAG}\n\n")
|
||||||
|
|
||||||
|
# Use CMAKE_CURRENT_SOURCE_DIR which provides assimp-local path (CMAKE_SOURCE_DIR is
|
||||||
|
# relative to top-level/main project)
|
||||||
|
set(Meshlab_BASE_ABSPATH "${CMAKE_CURRENT_SOURCE_DIR}/../contrib/meshlab")
|
||||||
|
|
||||||
|
# Note: Depending on user's OS, build environment etc it may be necessary to change line endings of
|
||||||
|
# "patches/meshlab.patch" file from CRLF to LF in order for patch operation to succeed
|
||||||
|
# Patch required to
|
||||||
|
# - replace QtXml w/pugixml
|
||||||
|
# - disable meshlab cmake scripts to prevent breaking assimp build
|
||||||
|
# - address compiler warnings to avoid breaking build for users who wisely treat warnings-as-errors
|
||||||
|
set(Meshlab_PATCH_CMD git apply ${Meshlab_BASE_ABSPATH}/patches/meshlab.patch)
|
||||||
|
|
||||||
|
# Note: cloning entire meshlab repo is wasteful since we require literally only two source files.
|
||||||
|
# There is a technique using "git archive" e.g.
|
||||||
|
# execute_process(
|
||||||
|
# COMMAND git archive --remote=${Meshlab_GIT_REPO} ${Meshlab_GIT_TAG} <files> | \
|
||||||
|
# tar -x -C ${Meshlab_BASE_ABSPATH}
|
||||||
|
# RESULT_VARIABLE result
|
||||||
|
# )
|
||||||
|
# But this doesn't work with git "https" protocol so not a viable solution
|
||||||
|
|
||||||
|
# Note: CMake's "FetchContent" (which executes at configure time) is much better for this use case
|
||||||
|
# than "ExternalProject" (which executes at build time); we just want to clone a repo and
|
||||||
|
# block (wait) as long as necessary until cloning is complete, so we immediately have full
|
||||||
|
# access to the cloned source files
|
||||||
|
include(FetchContent)
|
||||||
|
set(Meshlab_REPO_ABSPATH "${Meshlab_BASE_ABSPATH}/autoclone")
|
||||||
|
# Only want to clone once (on Android, using SOURCE_DIR will clone per-ABI (x86, x86_64 etc))
|
||||||
|
set(FETCHCONTENT_BASE_DIR ${Meshlab_REPO_ABSPATH})
|
||||||
|
set(FETCHCONTENT_QUIET on) # Turn off to troubleshoot repo clone problems
|
||||||
|
set(FETCHCONTENT_UPDATES_DISCONNECTED on) # Prevent other ABIs from re-cloning/re-patching etc
|
||||||
|
set(Meshlab_GIT_REPO "https://github.com/cnr-isti-vclab/meshlab")
|
||||||
|
FetchContent_Declare(
|
||||||
|
meshlab_repo
|
||||||
|
GIT_REPOSITORY ${Meshlab_GIT_REPO}
|
||||||
|
GIT_TAG ${Meshlab_GIT_TAG}
|
||||||
|
PATCH_COMMAND ${Meshlab_PATCH_CMD}
|
||||||
|
)
|
||||||
|
FetchContent_MakeAvailable(meshlab_repo)
|
||||||
|
message("**** Finished cloning meshlab repo")
|
||||||
|
message("****")
|
||||||
|
set(Meshlab_SRC_ABSPATH "${Meshlab_REPO_ABSPATH}/meshlab_repo-src/src/meshlabplugins/io_x3d/vrml")
|
||||||
|
set(Meshlab_SRCS
|
||||||
|
${Meshlab_SRC_ABSPATH}/Parser.cpp
|
||||||
|
${Meshlab_SRC_ABSPATH}/Scanner.cpp
|
||||||
|
)
|
||||||
|
set(Meshlab_INCLUDE_DIRS "${Meshlab_SRC_ABSPATH}")
|
||||||
|
INCLUDE_DIRECTORIES(${Meshlab_INCLUDE_DIRS})
|
||||||
|
MESSAGE(STATUS "VRML enabled")
|
||||||
|
ELSE() # IF (ASSIMP_BUILD_VRML_IMPORTER)
|
||||||
|
set(Meshlab_SRCS "")
|
||||||
|
MESSAGE(STATUS "VRML disabled")
|
||||||
|
ENDIF() # IF (ASSIMP_BUILD_VRML_IMPORTER)
|
||||||
|
|
||||||
# USD/USDA/USDC/USDZ support
|
# USD/USDA/USDC/USDZ support
|
||||||
# tinyusdz
|
# tinyusdz
|
||||||
IF (ASSIMP_BUILD_USD_IMPORTER)
|
IF (ASSIMP_BUILD_USD_IMPORTER)
|
||||||
@@ -1297,6 +1361,7 @@ SET( assimp_src
|
|||||||
${openddl_parser_SRCS}
|
${openddl_parser_SRCS}
|
||||||
${open3dgc_SRCS}
|
${open3dgc_SRCS}
|
||||||
${ziplib_SRCS}
|
${ziplib_SRCS}
|
||||||
|
${Meshlab_SRCS}
|
||||||
${Tinyusdz_SRCS}
|
${Tinyusdz_SRCS}
|
||||||
${Tinyusdz_DEP_SOURCES}
|
${Tinyusdz_DEP_SOURCES}
|
||||||
${Pugixml_SRCS}
|
${Pugixml_SRCS}
|
||||||
|
|||||||
11
contrib/meshlab/README.md
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
# meshlab
|
||||||
|
Meshlab project cloned in entirety but only using two files: "Parser" and "Scanner" in order to
|
||||||
|
reformat .wrl/.x3dv files as .xml
|
||||||
|
|
||||||
|
## Automatic repo clone
|
||||||
|
Meshlab repo is automatically cloned. Users who haven't opted-in to VRML support
|
||||||
|
won't be burdened with the extra download volume.
|
||||||
|
|
||||||
|
To update the git commit hash pulled down, modify `Meshlab_GIT_TAG` in file
|
||||||
|
`code/CMakeLists.txt`; it is not expected that the sole files of interest "Parser" and "Scanner"
|
||||||
|
will change frequently, if at all, going forward
|
||||||
14
contrib/meshlab/patches/README.md
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
# meshlab patch
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
Depending on user's OS, build environment etc it may be necessary to change line endings of
|
||||||
|
`patches/meshlab.patch` file from `CRLF` to `LF` in order for patch operation to succeed
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
"Parser" based on QtXml, need to change to use pugixml
|
||||||
|
|
||||||
|
## pugixml notes
|
||||||
|
Note that it isn't possible to add an unattached pugixml Node object, modify it, then
|
||||||
|
add it to the tree later; the node needs to be attached somewhere in the tree on instantiation
|
||||||
|
(even if it's a temporary at root level to be removed when finished) before populating, adding
|
||||||
|
children etc.
|
||||||
1191
contrib/meshlab/patches/meshlab.patch
Normal file
@@ -5,7 +5,7 @@
|
|||||||
tinyusdz repo is automatically cloned. Users who haven't opted-in to USD support
|
tinyusdz repo is automatically cloned. Users who haven't opted-in to USD support
|
||||||
won't be burdened with the extra download volume.
|
won't be burdened with the extra download volume.
|
||||||
|
|
||||||
To update te git commit hash pulled down, modify `TINYUSDZ_GIT_TAG` in file
|
To update the git commit hash pulled down, modify `TINYUSDZ_GIT_TAG` in file
|
||||||
`code/CMakeLists.txt`
|
`code/CMakeLists.txt`
|
||||||
|
|
||||||
## Notes
|
## Notes
|
||||||
|
|||||||
@@ -50,6 +50,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#include "IOStream.hpp"
|
#include "IOStream.hpp"
|
||||||
|
|
||||||
#include <pugixml.hpp>
|
#include <pugixml.hpp>
|
||||||
|
#include <istream>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
@@ -128,6 +129,11 @@ public:
|
|||||||
/// @return true, if the parsing was successful, false if not.
|
/// @return true, if the parsing was successful, false if not.
|
||||||
bool parse(IOStream *stream);
|
bool parse(IOStream *stream);
|
||||||
|
|
||||||
|
/// @brief Will parse an xml-file from a stringstream.
|
||||||
|
/// @param[in] str The input istream (note: not "const" to match pugixml param)
|
||||||
|
/// @return true, if the parsing was successful, false if not.
|
||||||
|
bool parse(std::istream &inStream);
|
||||||
|
|
||||||
/// @brief Will return true if a root node is there.
|
/// @brief Will return true if a root node is there.
|
||||||
/// @return true in case of an existing root.
|
/// @return true in case of an existing root.
|
||||||
bool hasRoot() const;
|
bool hasRoot() const;
|
||||||
@@ -311,7 +317,23 @@ bool TXmlParser<TNodeType>::parse(IOStream *stream) {
|
|||||||
mDoc = new pugi::xml_document();
|
mDoc = new pugi::xml_document();
|
||||||
// load_string assumes native encoding (aka always utf-8 per build options)
|
// load_string assumes native encoding (aka always utf-8 per build options)
|
||||||
//pugi::xml_parse_result parse_result = mDoc->load_string(&mData[0], pugi::parse_full);
|
//pugi::xml_parse_result parse_result = mDoc->load_string(&mData[0], pugi::parse_full);
|
||||||
pugi::xml_parse_result parse_result = mDoc->load_buffer(&mData[0], mData.size(), pugi::parse_full);
|
pugi::xml_parse_result parse_result = mDoc->load_buffer(&mData[0], mData.size(), pugi::parse_full);
|
||||||
|
if (parse_result.status == pugi::status_ok) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
ASSIMP_LOG_DEBUG("Error while parse xml.", std::string(parse_result.description()), " @ ", parse_result.offset);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class TNodeType>
|
||||||
|
bool TXmlParser<TNodeType>::parse(std::istream &inStream) {
|
||||||
|
if (hasRoot()) {
|
||||||
|
clear();
|
||||||
|
}
|
||||||
|
mDoc = new pugi::xml_document();
|
||||||
|
pugi::xml_parse_result parse_result = mDoc->load(inStream);
|
||||||
if (parse_result.status == pugi::status_ok) {
|
if (parse_result.status == pugi::status_ok) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
87
test/models/WRL/HelloWorld.wrl
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
#VRML V2.0 utf8
|
||||||
|
# X3D-to-VRML-97 XSL translation autogenerated by X3dToVrml97.xslt
|
||||||
|
# https://www.web3d.org/x3d/content/X3dToVrml97.xslt
|
||||||
|
# Generated using XSLT processor: Saxonica
|
||||||
|
|
||||||
|
# [X3D] VRML V3.3 utf8
|
||||||
|
# PROFILE Immersive
|
||||||
|
# [X3D] version=3.3
|
||||||
|
# [X3D] noNamespaceSchemaLocation=https://www.web3d.org/specifications/x3d-3.3.xsd
|
||||||
|
# [head]
|
||||||
|
|
||||||
|
# Alternate encodings: VRML97, X3D ClassicVRML Encoding, X3D Compressed Binary Encoding (CBE), X3DOM, JSON
|
||||||
|
# META "title" "HelloWorld.x3d"
|
||||||
|
# META "description" "Simple X3D model example: Hello World!"
|
||||||
|
# META "created" "30 October 2000"
|
||||||
|
# META "modified" "9 July 2023"
|
||||||
|
# META "creator" "Don Brutzman"
|
||||||
|
# META "Image" "HelloWorld.tall.png"
|
||||||
|
# META "reference" "https://en.wikipedia.org/wiki/Hello_world"
|
||||||
|
# META "reference" "https://en.wikipedia.org/wiki/Hello#.22Hello.2C_World.22_computer_program"
|
||||||
|
# META "reference" "https://en.wikipedia.org/wiki/\"Hello,_World!\"_program"
|
||||||
|
# META "reference" "https://en.wikibooks.org/w/index.php?title=Computer_Programming/Hello_world"
|
||||||
|
# META "reference" "https://www.HelloWorldExample.net"
|
||||||
|
# META "reference" "https://www.web3d.org"
|
||||||
|
# META "reference" "https://www.web3d.org/realtime-3d/news/internationalization-x3d"
|
||||||
|
# META "reference" "https://www.web3d.org/x3d/content/examples/HelloWorld.x3d"
|
||||||
|
# META "reference" "https://www.web3d.org/x3d/content/examples/X3dForAdvancedModeling/HelloWorldScenes/HelloWorld.x3d"
|
||||||
|
# META "identifier" "https://www.web3d.org/x3d/content/examples/X3dForWebAuthors/Chapter01TechnicalOverview/HelloWorld.x3d"
|
||||||
|
# META "license" "https://www.web3d.org/x3d/content/examples/license.html"
|
||||||
|
# META "generator" "X3D-Edit 4.0, https://savage.nps.edu/X3D-Edit"
|
||||||
|
# META "reference" "HelloWorld.wrl"
|
||||||
|
# META "reference" "HelloWorld.x3dv"
|
||||||
|
# META "reference" "HelloWorld.x3db"
|
||||||
|
# META "reference" "HelloWorld.xhtml"
|
||||||
|
# META "reference" "HelloWorld.json"
|
||||||
|
|
||||||
|
# [Scene] ========== ========== ==========
|
||||||
|
|
||||||
|
NavigationInfo { type [ "EXAMINE" "ANY" ] } ### Default X3D NavigationInfo
|
||||||
|
|
||||||
|
# Example scene to illustrate X3D nodes and fields (XML elements and attributes)
|
||||||
|
WorldInfo {
|
||||||
|
info [ "Example scene to illustrate a simple X3D model" ]
|
||||||
|
title "Hello World!"
|
||||||
|
}
|
||||||
|
Group {
|
||||||
|
children [
|
||||||
|
DEF ViewUpClose Viewpoint {
|
||||||
|
centerOfRotation 0 -1 0
|
||||||
|
description "Hello world!"
|
||||||
|
position 0 -1 7
|
||||||
|
}
|
||||||
|
Transform {
|
||||||
|
rotation 0 1 0 3
|
||||||
|
children [
|
||||||
|
Shape {
|
||||||
|
geometry Sphere {
|
||||||
|
}
|
||||||
|
appearance Appearance {
|
||||||
|
material DEF MaterialOffWhite Material {
|
||||||
|
diffuseColor 0.980392 0.976471 0.964706
|
||||||
|
}
|
||||||
|
texture DEF ImageCloudlessEarth ImageTexture {
|
||||||
|
url [ "earth-topo.png" "earth-topo.jpg" "earth-topo-small.gif" "https://www.web3d.org/x3d/content/examples/Basic/earth-topo.png" "https://www.web3d.org/x3d/content/examples/Basic/earth-topo.jpg" "https://www.web3d.org/x3d/content/examples/Basic/earth-topo-small.gif" ]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
Transform {
|
||||||
|
translation 0 -2 0
|
||||||
|
children [
|
||||||
|
Shape {
|
||||||
|
geometry DEF TextMessage Text {
|
||||||
|
string [ "Hello" "world!" ]
|
||||||
|
fontStyle FontStyle {
|
||||||
|
justify [ "MIDDLE" "MIDDLE" ]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
appearance Appearance {
|
||||||
|
material USE MaterialOffWhite
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
6
test/models/WRL/README.md
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
# WRL models
|
||||||
|
|
||||||
|
X3D is a modern superset of the old (VRML) WRL format
|
||||||
|
|
||||||
|
# HelloWorld.wrl
|
||||||
|
Downloaded from [HelloWorld.wrl](http://www.web3d.org/x3d/content/examples/HelloWorld.wrl)
|
||||||
BIN
test/models/WRL/earth-topo.png
Normal file
|
After Width: | Height: | Size: 100 KiB |
4
test/models/WRL/ref/README.md
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
# WRL 3D model reference images
|
||||||
|
|
||||||
|
## HelloWorld.wrl
|
||||||
|
<img alt="HelloWorld.wrl" src="screenshots/HelloWorld_wrl.png" width=180 />
|
||||||
BIN
test/models/WRL/ref/screenshots/HelloWorld_wrl.png
Normal file
|
After Width: | Height: | Size: 802 KiB |
57
test/models/X3D/HelloWorld.x3d
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE X3D PUBLIC "ISO//Web3D//DTD X3D 3.3//EN" "https://www.web3d.org/specifications/x3d-3.3.dtd">
|
||||||
|
<X3D profile='Immersive' version='3.3' xmlns:xsd='http://www.w3.org/2001/XMLSchema-instance' xsd:noNamespaceSchemaLocation='https://www.web3d.org/specifications/x3d-3.3.xsd'>
|
||||||
|
<head>
|
||||||
|
<!-- Alternate encodings: VRML97, X3D ClassicVRML Encoding, X3D Compressed Binary Encoding (CBE), X3DOM, JSON -->
|
||||||
|
<meta content='HelloWorld.x3d' name='title'/>
|
||||||
|
<meta content='Simple X3D model example: Hello World!' name='description'/>
|
||||||
|
<meta content='30 October 2000' name='created'/>
|
||||||
|
<meta content='9 July 2023' name='modified'/>
|
||||||
|
<meta content='Don Brutzman' name='creator'/>
|
||||||
|
<meta content='HelloWorld.tall.png' name='Image'/>
|
||||||
|
<meta content='https://en.wikipedia.org/wiki/Hello_world' name='reference'/>
|
||||||
|
<meta content='https://en.wikipedia.org/wiki/Hello#.22Hello.2C_World.22_computer_program' name='reference'/>
|
||||||
|
<meta content='https://en.wikipedia.org/wiki/"Hello,_World!"_program' name='reference'/>
|
||||||
|
<meta content='https://en.wikibooks.org/w/index.php?title=Computer_Programming/Hello_world' name='reference'/>
|
||||||
|
<meta content='https://www.HelloWorldExample.net' name='reference'/>
|
||||||
|
<meta content='https://www.web3d.org' name='reference'/>
|
||||||
|
<meta content='https://www.web3d.org/realtime-3d/news/internationalization-x3d' name='reference'/>
|
||||||
|
<meta content='https://www.web3d.org/x3d/content/examples/HelloWorld.x3d' name='reference'/>
|
||||||
|
<meta content='https://www.web3d.org/x3d/content/examples/X3dForAdvancedModeling/HelloWorldScenes/HelloWorld.x3d' name='reference'/>
|
||||||
|
<meta content='https://www.web3d.org/x3d/content/examples/X3dForWebAuthors/Chapter01TechnicalOverview/HelloWorld.x3d' name='identifier'/>
|
||||||
|
<meta content='https://www.web3d.org/x3d/content/examples/license.html' name='license'/>
|
||||||
|
<meta content='X3D-Edit 4.0, https://savage.nps.edu/X3D-Edit' name='generator'/>
|
||||||
|
<meta content='HelloWorld.wrl' name='reference'/>
|
||||||
|
<meta content='HelloWorld.x3dv' name='reference'/>
|
||||||
|
<meta content='HelloWorld.x3db' name='reference'/>
|
||||||
|
<meta content='HelloWorld.xhtml' name='reference'/>
|
||||||
|
<meta content='HelloWorld.json' name='reference'/>
|
||||||
|
</head>
|
||||||
|
<Scene>
|
||||||
|
<!-- Example scene to illustrate X3D nodes and fields (XML elements and attributes) -->
|
||||||
|
<WorldInfo info='"Example scene to illustrate a simple X3D model"' title='Hello World!'/>
|
||||||
|
<Group>
|
||||||
|
<Viewpoint DEF='ViewUpClose' centerOfRotation='0 -1 0' description='Hello world!' position='0 -1 7'/>
|
||||||
|
<Transform rotation='0 1 0 3'>
|
||||||
|
<Shape>
|
||||||
|
<Sphere/>
|
||||||
|
<Appearance>
|
||||||
|
<!-- https://htmlcolorcodes.com/colors/off-white -->
|
||||||
|
<Material DEF='MaterialOffWhite' diffuseColor='0.980392 0.976471 0.964706'/>
|
||||||
|
<ImageTexture DEF='ImageCloudlessEarth' url='"earth-topo.png" "earth-topo.jpg" "earth-topo-small.gif" "https://www.web3d.org/x3d/content/examples/Basic/earth-topo.png" "https://www.web3d.org/x3d/content/examples/Basic/earth-topo.jpg" "https://www.web3d.org/x3d/content/examples/Basic/earth-topo-small.gif"'/>
|
||||||
|
</Appearance>
|
||||||
|
</Shape>
|
||||||
|
</Transform>
|
||||||
|
<Transform translation='0 -2 0'>
|
||||||
|
<Shape>
|
||||||
|
<Text DEF='TextMessage' string='"Hello" "world!"'>
|
||||||
|
<FontStyle justify='"MIDDLE" "MIDDLE"'/>
|
||||||
|
</Text>
|
||||||
|
<Appearance>
|
||||||
|
<Material USE='MaterialOffWhite'/>
|
||||||
|
</Appearance>
|
||||||
|
</Shape>
|
||||||
|
</Transform>
|
||||||
|
</Group>
|
||||||
|
</Scene>
|
||||||
|
</X3D>
|
||||||
4
test/models/X3D/README.md
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
# X3D models
|
||||||
|
|
||||||
|
# HelloWorld.x3d
|
||||||
|
Downloaded from [HelloWorld.x3d](http://www.web3d.org/x3d/content/examples/HelloWorld.x3d)
|
||||||
BIN
test/models/X3D/earth-topo.png
Normal file
|
After Width: | Height: | Size: 100 KiB |
@@ -12,3 +12,6 @@ ComputerKeyboard as of 1 Dec 2021 git commit `1614934`, using pugi xml parsing,
|
|||||||
missing meshes and obvious artifacts:
|
missing meshes and obvious artifacts:
|
||||||
|
|
||||||
<img alt="ComputerKeyboard.x3d (pugi xml)" src="screenshots/ComputerKeyboard_x3d_pugi_xml.png" width=320 />
|
<img alt="ComputerKeyboard.x3d (pugi xml)" src="screenshots/ComputerKeyboard_x3d_pugi_xml.png" width=320 />
|
||||||
|
|
||||||
|
## HelloWorld.x3d
|
||||||
|
<img alt="HelloWorld.x3d" src="screenshots/HelloWorld_x3d.png" width=180 />
|
||||||
|
|||||||
BIN
test/models/X3D/ref/screenshots/HelloWorld_x3d.png
Normal file
|
After Width: | Height: | Size: 929 KiB |
BIN
test/models/X3DB/HelloWorld.x3db
Normal file
6
test/models/X3DB/README.md
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
# X3DB models
|
||||||
|
|
||||||
|
X3DB models are compressed X3D models
|
||||||
|
|
||||||
|
# HelloWorld.x3db
|
||||||
|
Downloaded from [HelloWorld.x3db](http://www.web3d.org/x3d/content/examples/HelloWorld.x3db)
|
||||||
BIN
test/models/X3DB/earth-topo.png
Normal file
|
After Width: | Height: | Size: 100 KiB |
86
test/models/X3DV/HelloWorld.x3dv
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
#X3D V3.3 utf8
|
||||||
|
# X3D-to-ClassicVRML XSL translation autogenerated by X3dToVrml97.xslt
|
||||||
|
# https://www.web3d.org/x3d/content/X3dToVrml97.xslt
|
||||||
|
# Generated using XSLT processor: Saxonica
|
||||||
|
|
||||||
|
PROFILE Immersive
|
||||||
|
# [X3D] version=3.3
|
||||||
|
# [X3D] noNamespaceSchemaLocation=https://www.web3d.org/specifications/x3d-3.3.xsd
|
||||||
|
# [head]
|
||||||
|
|
||||||
|
# Alternate encodings: VRML97, X3D ClassicVRML Encoding, X3D Compressed Binary Encoding (CBE), X3DOM, JSON
|
||||||
|
META "title" "HelloWorld.x3d"
|
||||||
|
META "description" "Simple X3D model example: Hello World!"
|
||||||
|
META "created" "30 October 2000"
|
||||||
|
META "modified" "9 July 2023"
|
||||||
|
META "creator" "Don Brutzman"
|
||||||
|
META "Image" "HelloWorld.tall.png"
|
||||||
|
META "reference" "https://en.wikipedia.org/wiki/Hello_world"
|
||||||
|
META "reference" "https://en.wikipedia.org/wiki/Hello#.22Hello.2C_World.22_computer_program"
|
||||||
|
META "reference" "https://en.wikipedia.org/wiki/\"Hello,_World!\"_program"
|
||||||
|
META "reference" "https://en.wikibooks.org/w/index.php?title=Computer_Programming/Hello_world"
|
||||||
|
META "reference" "https://www.HelloWorldExample.net"
|
||||||
|
META "reference" "https://www.web3d.org"
|
||||||
|
META "reference" "https://www.web3d.org/realtime-3d/news/internationalization-x3d"
|
||||||
|
META "reference" "https://www.web3d.org/x3d/content/examples/HelloWorld.x3d"
|
||||||
|
META "reference" "https://www.web3d.org/x3d/content/examples/X3dForAdvancedModeling/HelloWorldScenes/HelloWorld.x3d"
|
||||||
|
META "identifier" "https://www.web3d.org/x3d/content/examples/X3dForWebAuthors/Chapter01TechnicalOverview/HelloWorld.x3d"
|
||||||
|
META "license" "https://www.web3d.org/x3d/content/examples/license.html"
|
||||||
|
META "generator" "X3D-Edit 4.0, https://savage.nps.edu/X3D-Edit"
|
||||||
|
META "reference" "HelloWorld.wrl"
|
||||||
|
META "reference" "HelloWorld.x3dv"
|
||||||
|
META "reference" "HelloWorld.x3db"
|
||||||
|
META "reference" "HelloWorld.xhtml"
|
||||||
|
META "reference" "HelloWorld.json"
|
||||||
|
|
||||||
|
# [Scene] ========== ========== ==========
|
||||||
|
|
||||||
|
NavigationInfo { type [ "EXAMINE" "ANY" ] } ### Default X3D NavigationInfo
|
||||||
|
|
||||||
|
# Example scene to illustrate X3D nodes and fields (XML elements and attributes)
|
||||||
|
WorldInfo {
|
||||||
|
info [ "Example scene to illustrate a simple X3D model" ]
|
||||||
|
title "Hello World!"
|
||||||
|
}
|
||||||
|
Group {
|
||||||
|
children [
|
||||||
|
DEF ViewUpClose Viewpoint {
|
||||||
|
centerOfRotation 0 -1 0
|
||||||
|
description "Hello world!"
|
||||||
|
position 0 -1 7
|
||||||
|
}
|
||||||
|
Transform {
|
||||||
|
rotation 0 1 0 3
|
||||||
|
children [
|
||||||
|
Shape {
|
||||||
|
geometry Sphere {
|
||||||
|
}
|
||||||
|
appearance Appearance {
|
||||||
|
material DEF MaterialOffWhite Material {
|
||||||
|
diffuseColor 0.980392 0.976471 0.964706
|
||||||
|
}
|
||||||
|
texture DEF ImageCloudlessEarth ImageTexture {
|
||||||
|
url [ "earth-topo.png" "earth-topo.jpg" "earth-topo-small.gif" "https://www.web3d.org/x3d/content/examples/Basic/earth-topo.png" "https://www.web3d.org/x3d/content/examples/Basic/earth-topo.jpg" "https://www.web3d.org/x3d/content/examples/Basic/earth-topo-small.gif" ]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
Transform {
|
||||||
|
translation 0 -2 0
|
||||||
|
children [
|
||||||
|
Shape {
|
||||||
|
geometry DEF TextMessage Text {
|
||||||
|
string [ "Hello" "world!" ]
|
||||||
|
fontStyle FontStyle {
|
||||||
|
justify [ "MIDDLE" "MIDDLE" ]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
appearance Appearance {
|
||||||
|
material USE MaterialOffWhite
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
6
test/models/X3DV/README.md
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
# X3DV models
|
||||||
|
|
||||||
|
X3DV models are as simple WRL (VRML) models with the version number upgraded from `2` to `3`
|
||||||
|
|
||||||
|
# HelloWorld.x3dv
|
||||||
|
Downloaded from [HelloWorld.x3dv](http://www.web3d.org/x3d/content/examples/HelloWorld.x3dv)
|
||||||
BIN
test/models/X3DV/earth-topo.png
Normal file
|
After Width: | Height: | Size: 100 KiB |
4
test/models/X3DV/ref/README.md
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
# X3DV 3D model reference images
|
||||||
|
|
||||||
|
## HelloWorld.x3dv
|
||||||
|
<img alt="HelloWorld.x3dv" src="screenshots/HelloWorld_x3dv.png" width=180 />
|
||||||
BIN
test/models/X3DV/ref/screenshots/HelloWorld_x3dv.png
Normal file
|
After Width: | Height: | Size: 918 KiB |