thedworak / dfg_3dviewer

2 stars 2 forks source link

3D DFG Viewer

The module was primarily created for viewing 3D data as a Drupal extension for a WissKI based repository. During development it became also possible to use as a standalone version to be integrated with more environments. The Viewer is written in JavaScript, based on the three.js library for viewing 3D models and uses PHP/bash scripts for server-side operations. Supported 3D file formats: OBJ, DAE, FBX, PLY, IFC, STL, XYZ, JSON, 3DS, glTF. There is also a pre-configured complete workflow to handle more file formats and allow to render thumbnails for entries. If an uploaded file is saved in one of the compression-supported formats (obj, fbx, ply, dae, abc, blend, stl, wrl, x3d, glb, gltf), it is compressed on-the-fly and converted into GLB format and triggers automatic rendering (based on Blender utility).

Minimal Requirements

Screenshots

Functions and other features

Main view

Gallery Set

Gallery Preview Element

Gallery Preview Element 2

Tech Stack

Client: JavaScript, three.js, CSS, HTML, PHP, Drupal

Server: PHP, Drupal, bash, blender

The main part is located in the viewer directory and the main.js is responsible for delivering 3D content. The viewer at first imports all necessary three.js components:

import * as THREE from './build/three.module.js';
import { TWEEN } from './js/jsm/libs/tween.module.min.js';

import Stats from './js/jsm/libs/stats.module.js';

import { OrbitControls } from './js/jsm/controls/OrbitControls.js';
import { TransformControls } from './js/jsm/controls/TransformControls.js';
import { GUI } from './js/jsm/libs/lil-gui.module.min.js';
import { FBXLoader } from './js/jsm/loaders/FBXLoader.js';
import { DDSLoader } from './js/jsm/loaders/DDSLoader.js';
import { MTLLoader } from './js/jsm/loaders/MTLLoader.js';
import { OBJLoader } from './js/jsm/loaders/OBJLoader.js';
import { GLTFLoader } from './js/jsm/loaders/GLTFLoader.js';
import { DRACOLoader } from './js/jsm/loaders/DRACOLoader.js';
import { KTX2Loader } from './js/jsm/loaders/KTX2Loader.js';
import { MeshoptDecoder } from './js/jsm/libs/meshopt_decoder.module.js';
import { IFCLoader } from './js/jsm/loaders/IFCLoader.js';
import { PLYLoader } from './js/jsm/loaders/PLYLoader.js';
import { ColladaLoader } from './js/jsm/loaders/ColladaLoader.js';
import { STLLoader } from './js/jsm/loaders/STLLoader.js';
import { XYZLoader } from './js/jsm/loaders/XYZLoader.js'; 
import { TDSLoader } from './js/jsm/loaders/TDSLoader.js';
import { PCDLoader } from './js/jsm/loaders/PCDLoader.js';
import { FontLoader } from './js/jsm/loaders/FontLoader.js';
import { TextGeometry } from './js/jsm/geometries/TextGeometry.js';

Basic Viewer configuration

Then, basic configuration should be changed:

const CONFIG = {
    "domain": "https://3d-repository.hs-mainz.de",
    "metadataDomain": "https://3d-repository.hs-mainz.de",
    "container": "DFG_3DViewer",
    "galleryContainer": "block-bootstrap5-content",
    "galleryImageClass": "field--type-image",
    "basePath": "/modules/dfg_3dviewer/viewer",
    "entityIdUri": "/wisski/navigate/(.*)/view",
    "viewEntityPath": "/wisski/navigate/",
    "attributeId": "wisski_id",
    "lightweight": false
};

domain, metadataDomain - domains that deliver 3D content and metadata content respectively
container - container to attach to and will contain 3D content
galleryContainer - container with generated thumbnails
galleryImageClass - class for gallery 
basePath - relative path where this script is placed
entityIdUri - WissKI side URI that can deliver ID of the entity
attributeId - the ID name that container will be given
lightweight - use Viewer as simple version - mostly for usage as a standalone 3D viewer

3D DFG Viewer functions overview

createClippingPlaneGroup(geometry, plane, renderOrder) - creates group of planes for clipping 3D (available via GUI controller)
showToast (_str) - shows information about current operations
addTextWatermark (_text, _scale) - adds watermark
addTextPoint (_text, _scale, _point) - adds text at given point
selectObjectHierarchy (_id) - selects object from hierarchy
fetchMetadata (_object, _type) - fetches metadata about object
recreateBoundingBox (object) - creates new bounding box
setupObject (_object, _light, _data, _controls) - setups basic properties for object, lights, camera and controls
invertHexColor(hexTripletColor) - inverts color in hex
setupClippingPlanes (_geometry, _size, _distance) - setups clipping planes for given geometry
fitCameraToCenteredObject (camera, object, offset, orbitControls, _fit)- setups camera view centered to given object
buildGallery() - builds gallery of thumbnails
render() - main function for rendering
setupCamera (_object, _camera, _light, _data, _controls) - setups camera according to object properties
distanceBetweenPoints(pointA, pointB) - calculates distance between two given points
distanceBetweenPointsVector(vector) - calculates distance of given vector
vectorBetweenPoints (pointA, pointB) - creates vector between two given points
halfwayBetweenPoints(pointA, pointB) - calculates halfway between two given points
interpolateDistanceBetweenPoints(pointA, vector, length, scalar) - calculates distance from given point, with vector and it’s length
pickFaces(_id) - picks face with given id

buildRuler(_id) - creates ruler for measurement geometry
onWindowResize() - handler for window resize
addWissKIMetadata(label, value) - adds metadata fetched from WissKI repository
truncateString(str, n) - truncates given string with n length
getProxyPath(url) - gets proxy path from given url
expandMetadata () - expands metadata
fullscreen() - handler for fullscreen mode
exitFullscreenHandler() - handler for fullscreen exit
appendMetadata (metadataContent, canvasText, metadataContainer, container) - appends metadata to given container
fetchSettings (path, basename, filename, object, camera, light, controls, orgExtension, extension) - fetches settings for object
onError = function (_event) - error loading handler
onErrorMTL = function (_event) - MTL error loading handler
onProgress = function (xhr) - loading progress handler
setupMaterials (_object) - setups materials of an object
getMaterialByID (_object, _uuid) - gets material with given ID
traverseMesh (object) - traverses mesh to get more detailed info
loadModel (path, basename, filename, extension, orgExtension) - main function for loading object
animate() - main animation funcion
onPointerDown(e) - mouse down click handler
onPointerUp(e)- mouse up click handler
onPointerMove(e)- mouse move handler
changeScale()- changes scale of an object (available via GUI controller)
calculateObjectScale() - calculates object scale
changeLightRotation() - changes light rotation (available via GUI controller)
takeScreenshot()- takes screenshot for thumbnail rendering\
mainLoadModel (_ext)- main function for loading objects
init() - main function that inits workflow

Viewer overview

Server side scripts

Backend overview|500

Main workflow is divided into two automatic parts:

Scripts needed there are placed under scripts and php directory.

After uploading 3D model into repository there are triggered following steps:

This step is performed inside scripts/convert.sh bash script. Script defaults (need to be changed if used in different environment):

BLENDER_PATH=''

#Defaults:
COMPRESSION=false
COMPRESSION_LEVEL=3
GLTF="gltf"
FORCE="false"
isOutput=false
IS_ARCHIVE=false
SPATH="/var/www/html/3drepository/modules/dfg_3dviewer"

Functions used during this step:

Minimal effort setup for 3D DFG Viewer

<!doctype html>
<html>
    <head>
        <title>Three.js 3D-DFG-Viewer</title>
        <link rel="stylesheet" href="https://github.com/thedworak/dfg_3dviewer/blob/main/3D-DFG-Viewer/css/spinner.css">
        <link rel="stylesheet" href="https://github.com/thedworak/dfg_3dviewer/blob/main/3D-DFG-Viewer/css/main.css">
    </head>
    <body>
        <script type="module" src="https://github.com/thedworak/dfg_3dviewer/raw/main/3D-DFG-Viewer/main/jquery-3.6.0.min.js"></script>
        <script src="https://github.com/thedworak/dfg_3dviewer/raw/main/3D-DFG-Viewer/main/toastify.js"></script>
        <script src="https://github.com/thedworak/dfg_3dviewer/raw/main/3D-DFG-Viewer/main/spinner/main.js"></script>
        <script type="module" src="https://github.com/thedworak/dfg_3dviewer/raw/main/3D-DFG-Viewer/main/main.js"></script>
        <div id="DFG_3DViewer" 3d="your_model_name"></div>
    </body>
</html>

Documentation

Documentation

Features