update three-viewer
fix model position and scale fix obj loader
This commit is contained in:
parent
f0e364243e
commit
f0035fda0a
5 changed files with 98 additions and 58 deletions
|
@ -4,6 +4,7 @@ import LoadingScreen from 'component/common/loading-screen';
|
|||
// ThreeJS
|
||||
import * as THREE from './internal/three';
|
||||
import detectWebGL from './internal/detector';
|
||||
import ThreeGrid from './internal/grid';
|
||||
import ThreeScene from './internal/scene';
|
||||
import ThreeLoader from './internal/loader';
|
||||
import ThreeRenderer from './internal/renderer';
|
||||
|
@ -77,6 +78,12 @@ class ThreeViewer extends React.PureComponent<Props> {
|
|||
window.removeEventListener('resize', this.handleResize, false);
|
||||
}
|
||||
|
||||
transformGroup(group) {
|
||||
this.fitMeshToCamera(group);
|
||||
this.createWireFrame(group);
|
||||
this.updateControlsTarget(group.position);
|
||||
}
|
||||
|
||||
createOrbitControls(camera, canvas) {
|
||||
const { autoRotate } = this.props;
|
||||
const controls = new THREE.OrbitControls(camera, canvas);
|
||||
|
@ -87,6 +94,7 @@ class ThreeViewer extends React.PureComponent<Props> {
|
|||
controls.minDistance = 1;
|
||||
controls.maxDistance = 50;
|
||||
controls.autoRotate = autoRotate;
|
||||
controls.enablePan = false;
|
||||
return controls;
|
||||
}
|
||||
|
||||
|
@ -114,32 +122,6 @@ class ThreeViewer extends React.PureComponent<Props> {
|
|||
group.add(this.wireframe);
|
||||
}
|
||||
|
||||
createMesh(geometry) {
|
||||
const material = new THREE.MeshPhongMaterial({
|
||||
opacity: 1,
|
||||
transparent: true,
|
||||
depthWrite: true,
|
||||
vertexColors: THREE.FaceColors,
|
||||
// Positive value pushes polygon further away
|
||||
polygonOffsetFactor: 1,
|
||||
polygonOffsetUnits: 1,
|
||||
});
|
||||
|
||||
// Set material color
|
||||
material.color.set(this.materialColors.green);
|
||||
|
||||
const mesh = new THREE.Mesh(geometry, material);
|
||||
|
||||
// Assign name
|
||||
mesh.name = 'objectGroup';
|
||||
|
||||
this.scene.add(mesh);
|
||||
this.fitMeshToCamera(mesh);
|
||||
this.createWireFrame(mesh);
|
||||
this.updateControlsTarget(mesh.position);
|
||||
return mesh;
|
||||
}
|
||||
|
||||
toggleWireFrame(show = false) {
|
||||
this.wireframe.opacity = show ? 1 : 0;
|
||||
this.mesh.material.opacity = show ? 0 : 1;
|
||||
|
@ -151,7 +133,7 @@ class ThreeViewer extends React.PureComponent<Props> {
|
|||
|
||||
group.traverse(child => {
|
||||
if (child instanceof THREE.Mesh) {
|
||||
const box = new THREE.Box3().setFromObject(group);
|
||||
const box = new THREE.Box3().setFromObject(child);
|
||||
// Max
|
||||
max.x = box.max.x > max.x ? box.max.x : max.x;
|
||||
max.y = box.max.y > max.y ? box.max.y : max.y;
|
||||
|
@ -165,12 +147,18 @@ class ThreeViewer extends React.PureComponent<Props> {
|
|||
|
||||
const meshY = Math.abs(max.y - min.y);
|
||||
const meshX = Math.abs(max.x - min.x);
|
||||
const scaleFactor = 15 / Math.max(meshX, meshY);
|
||||
|
||||
const scaleFactor = 10 / Math.max(meshX, meshY);
|
||||
|
||||
group.scale.set(scaleFactor, scaleFactor, scaleFactor);
|
||||
group.position.setY((meshY / 2) * scaleFactor);
|
||||
|
||||
// Reset object position
|
||||
const box = new THREE.Box3().setFromObject(group);
|
||||
box.getCenter(group.position);
|
||||
|
||||
group.position.multiplyScalar(-1);
|
||||
group.position.setY((meshY * scaleFactor) / 2);
|
||||
group.position.setY(group.position.y + meshY * scaleFactor);
|
||||
}
|
||||
|
||||
startLoader() {
|
||||
|
@ -217,12 +205,52 @@ class ThreeViewer extends React.PureComponent<Props> {
|
|||
this.controls.update();
|
||||
}
|
||||
|
||||
renderModel(fileType, data) {
|
||||
renderStl(data) {
|
||||
const geometry = this.createGeometry(data);
|
||||
this.mesh = this.createMesh(geometry);
|
||||
const group = new THREE.Mesh(geometry, this.material);
|
||||
// Assign name
|
||||
group.name = 'objectGroup';
|
||||
this.scene.add(group);
|
||||
this.transformGroup(group);
|
||||
this.mesh = group;
|
||||
}
|
||||
|
||||
renderObj(event) {
|
||||
const mesh = event.detail.loaderRootNode;
|
||||
const group = new THREE.Group();
|
||||
group.name = 'objGroup';
|
||||
|
||||
// Assign new material
|
||||
mesh.traverse(child => {
|
||||
if (child instanceof THREE.Mesh) {
|
||||
// Get geometry from child
|
||||
const geometry = new THREE.Geometry();
|
||||
geometry.fromBufferGeometry(child.geometry);
|
||||
// Create and regroup inner objects
|
||||
const innerObj = new THREE.Mesh(geometry, this.material);
|
||||
group.add(innerObj);
|
||||
}
|
||||
});
|
||||
|
||||
this.scene.add(group);
|
||||
this.transformGroup(group);
|
||||
this.mesh = group;
|
||||
}
|
||||
|
||||
renderModel(fileType, parsedData) {
|
||||
const renderTypes = {
|
||||
stl: data => this.renderStl(data),
|
||||
obj: data => this.renderObj(data),
|
||||
};
|
||||
|
||||
if (renderTypes[fileType]) {
|
||||
renderTypes[fileType](parsedData);
|
||||
}
|
||||
}
|
||||
|
||||
renderScene() {
|
||||
const { gridColor, centerLineColor } = this.theme;
|
||||
|
||||
this.renderer = ThreeRenderer({
|
||||
antialias: true,
|
||||
shadowMap: true,
|
||||
|
@ -230,20 +258,40 @@ class ThreeViewer extends React.PureComponent<Props> {
|
|||
|
||||
this.scene = ThreeScene({
|
||||
showFog: true,
|
||||
showGrid: true,
|
||||
...this.theme,
|
||||
});
|
||||
|
||||
const viewer = this.viewer.current;
|
||||
const canvas = this.renderer.domElement;
|
||||
const { offsetWidth: width, offsetHeight: height } = viewer;
|
||||
|
||||
// Grid
|
||||
this.grid = ThreeGrid({ size: 100, gridColor, centerLineColor });
|
||||
this.scene.add(this.grid);
|
||||
|
||||
// Camera
|
||||
this.camera = new THREE.PerspectiveCamera(80, width / height, 0.1, 1000);
|
||||
this.camera.position.set(-9.5, 14, 11);
|
||||
|
||||
// Controls
|
||||
this.controls = this.createOrbitControls(this.camera, canvas);
|
||||
|
||||
// Set viewer size
|
||||
this.renderer.setSize(width, height);
|
||||
|
||||
// Create model material
|
||||
this.material = new THREE.MeshPhongMaterial({
|
||||
opacity: 1,
|
||||
transparent: true,
|
||||
// depthWrite: true,
|
||||
vertexColors: THREE.FaceColors,
|
||||
// Positive value pushes polygon further away
|
||||
// polygonOffsetFactor: 1,
|
||||
// polygonOffsetUnits: 1,
|
||||
});
|
||||
// Set material color
|
||||
this.material.color.set(this.materialColors.green);
|
||||
|
||||
// Load file and render mesh
|
||||
this.startLoader();
|
||||
|
||||
|
|
13
src/renderer/component/viewers/threeViewer/internal/grid.js
Normal file
13
src/renderer/component/viewers/threeViewer/internal/grid.js
Normal file
|
@ -0,0 +1,13 @@
|
|||
import { GridHelper, Color } from './three';
|
||||
|
||||
const ThreeGrid = ({ size, gridColor, centerLineColor }) => {
|
||||
const divisions = size / 2;
|
||||
const grid = new GridHelper(size, divisions, new Color(centerLineColor), new Color(gridColor));
|
||||
|
||||
grid.material.opacity = 0.4;
|
||||
grid.material.transparent = true;
|
||||
|
||||
return grid;
|
||||
};
|
||||
|
||||
export default ThreeGrid;
|
|
@ -1,4 +1,4 @@
|
|||
import { LoadingManager, STLLoader, OBJLoader } from './three';
|
||||
import { LoadingManager, STLLoader, OBJLoader2 } from './three';
|
||||
|
||||
const Manager = ({ onLoad, onStart, onError }) => {
|
||||
const manager = new LoadingManager();
|
||||
|
@ -12,7 +12,7 @@ const Manager = ({ onLoad, onStart, onError }) => {
|
|||
const Loader = (fileType, manager) => {
|
||||
const fileTypes = {
|
||||
stl: () => new STLLoader(manager),
|
||||
obj: () => new OBJLoader(manager),
|
||||
obj: () => new OBJLoader2(manager),
|
||||
};
|
||||
return fileTypes[fileType] ? fileTypes[fileType]() : null;
|
||||
};
|
||||
|
|
|
@ -1,18 +1,5 @@
|
|||
import * as THREE from './three';
|
||||
|
||||
const addGrid = (scene, { gridColor, centerLineColor, size }) => {
|
||||
const divisions = size / 2;
|
||||
const grid = new THREE.GridHelper(
|
||||
size,
|
||||
divisions,
|
||||
new THREE.Color(centerLineColor),
|
||||
new THREE.Color(gridColor)
|
||||
);
|
||||
grid.material.opacity = 0.4;
|
||||
grid.material.transparent = true;
|
||||
scene.add(grid);
|
||||
};
|
||||
|
||||
const addLights = (scene, color, groundColor) => {
|
||||
// Light color
|
||||
const lightColor = new THREE.Color(color);
|
||||
|
@ -30,7 +17,7 @@ const addLights = (scene, color, groundColor) => {
|
|||
scene.add(shadowLight);
|
||||
};
|
||||
|
||||
const Scene = ({ backgroundColor, groundColor, showFog, showGrid, gridColor, centerLineColor }) => {
|
||||
const Scene = ({ backgroundColor, groundColor, showFog }) => {
|
||||
// Convert color
|
||||
const bgColor = new THREE.Color(backgroundColor);
|
||||
// New scene
|
||||
|
@ -39,17 +26,8 @@ const Scene = ({ backgroundColor, groundColor, showFog, showGrid, gridColor, cen
|
|||
scene.background = bgColor;
|
||||
// Fog effect
|
||||
scene.fog = showFog === true ? new THREE.Fog(bgColor, 1, 95) : null;
|
||||
// Add grid
|
||||
if (showGrid) {
|
||||
addGrid(scene, {
|
||||
size: 100,
|
||||
gridColor,
|
||||
centerLineColor,
|
||||
});
|
||||
}
|
||||
// Add basic lights
|
||||
addLights(scene, '#FFFFFF', groundColor);
|
||||
|
||||
// Return new three scene
|
||||
return scene;
|
||||
};
|
||||
|
|
|
@ -4,7 +4,8 @@ import * as THREE from 'three';
|
|||
// Fix: https://github.com/mrdoob/three.js/issues/9562#issuecomment-383390251
|
||||
global.THREE = THREE;
|
||||
require('three/examples/js/controls/OrbitControls');
|
||||
require('three/examples/js/loaders/OBJLoader');
|
||||
require('three/examples/js/loaders/LoaderSupport');
|
||||
require('three/examples/js/loaders/OBJLoader2');
|
||||
require('three/examples/js/loaders/STLLoader');
|
||||
|
||||
module.exports = global.THREE;
|
||||
|
|
Loading…
Reference in a new issue