optimize geometry
This commit is contained in:
parent
d4b1398356
commit
00ae8600f0
1 changed files with 48 additions and 60 deletions
|
@ -32,17 +32,6 @@ class ThreeViewer extends React.PureComponent<Props, State> {
|
||||||
else reject();
|
else reject();
|
||||||
});
|
});
|
||||||
|
|
||||||
static createGeometry(data) {
|
|
||||||
const geometry = new THREE.Geometry();
|
|
||||||
geometry.fromBufferGeometry(data);
|
|
||||||
geometry.computeBoundingBox();
|
|
||||||
geometry.computeVertexNormals();
|
|
||||||
geometry.center();
|
|
||||||
geometry.rotateX(-Math.PI / 2);
|
|
||||||
geometry.lookAt(new THREE.Vector3(0, 0, 1));
|
|
||||||
return geometry;
|
|
||||||
}
|
|
||||||
|
|
||||||
static fitMeshToCamera(group) {
|
static fitMeshToCamera(group) {
|
||||||
const max = { x: 0, y: 0, z: 0 };
|
const max = { x: 0, y: 0, z: 0 };
|
||||||
const min = { x: 0, y: 0, z: 0 };
|
const min = { x: 0, y: 0, z: 0 };
|
||||||
|
@ -77,22 +66,11 @@ class ThreeViewer extends React.PureComponent<Props, State> {
|
||||||
|
|
||||||
constructor(props: Props) {
|
constructor(props: Props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
||||||
const { theme } = this.props;
|
const { theme } = this.props;
|
||||||
|
|
||||||
// Main container
|
|
||||||
this.viewer = React.createRef();
|
this.viewer = React.createRef();
|
||||||
|
|
||||||
this.guiContainer = React.createRef();
|
this.guiContainer = React.createRef();
|
||||||
|
// Object defualt color
|
||||||
// Object colors
|
this.materialColor = '#44b098';
|
||||||
this.materialColors = {
|
|
||||||
red: '#e74c3c',
|
|
||||||
blue: '#3498db',
|
|
||||||
green: '#44b098',
|
|
||||||
orange: '#f39c12',
|
|
||||||
};
|
|
||||||
|
|
||||||
// Viewer themes
|
// Viewer themes
|
||||||
this.themes = {
|
this.themes = {
|
||||||
dark: {
|
dark: {
|
||||||
|
@ -108,10 +86,8 @@ class ThreeViewer extends React.PureComponent<Props, State> {
|
||||||
centerLineColor: '#2F2F2F',
|
centerLineColor: '#2F2F2F',
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
// Select current theme
|
// Select current theme
|
||||||
this.theme = this.themes[theme] || this.themes.light;
|
this.theme = this.themes[theme] || this.themes.light;
|
||||||
|
|
||||||
// State
|
// State
|
||||||
this.state = {
|
this.state = {
|
||||||
error: null,
|
error: null,
|
||||||
|
@ -137,20 +113,22 @@ class ThreeViewer extends React.PureComponent<Props, State> {
|
||||||
componentWillUnmount() {
|
componentWillUnmount() {
|
||||||
// Remove event listeners
|
// Remove event listeners
|
||||||
window.removeEventListener('resize', this.handleResize, false);
|
window.removeEventListener('resize', this.handleResize, false);
|
||||||
|
|
||||||
// Free memory
|
// Free memory
|
||||||
if (this.renderer && this.mesh) {
|
if (this.renderer && this.mesh) {
|
||||||
// Debug
|
|
||||||
console.info('before', this.renderer.info.programs.length);
|
|
||||||
// Clean up group
|
// Clean up group
|
||||||
this.scene.remove(this.mesh);
|
this.scene.remove(this.mesh);
|
||||||
if (this.mesh.geometry) this.mesh.geometry.dispose();
|
if (this.mesh.geometry) this.mesh.geometry.dispose();
|
||||||
if (this.mesh.material) this.mesh.material.dispose();
|
if (this.mesh.material) this.mesh.material.dispose();
|
||||||
|
// Cleanup shared geometry
|
||||||
|
if (this.geometry) this.geometry.dispose();
|
||||||
|
if (this.bufferGeometry) this.bufferGeometry.dispose();
|
||||||
// Clean up shared material
|
// Clean up shared material
|
||||||
this.material.dispose();
|
if (this.material) this.material.dispose();
|
||||||
// Clean up grid
|
// Clean up grid
|
||||||
this.grid.material.dispose();
|
if (this.grid) {
|
||||||
this.grid.geometry.dispose();
|
this.grid.material.dispose();
|
||||||
|
this.grid.geometry.dispose();
|
||||||
|
}
|
||||||
// Clean up group items
|
// Clean up group items
|
||||||
this.mesh.traverse(child => {
|
this.mesh.traverse(child => {
|
||||||
if (child instanceof THREE.Mesh) {
|
if (child instanceof THREE.Mesh) {
|
||||||
|
@ -159,10 +137,10 @@ class ThreeViewer extends React.PureComponent<Props, State> {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
// It's unclear if we need this:
|
// It's unclear if we need this:
|
||||||
this.renderer.renderLists.dispose();
|
if (this.renderer) {
|
||||||
this.renderer.dispose();
|
this.renderer.renderLists.dispose();
|
||||||
// Debug
|
this.renderer.dispose();
|
||||||
console.info('after', this.renderer.info.programs.length);
|
}
|
||||||
// Stop animation
|
// Stop animation
|
||||||
cancelAnimationFrame(this.frameID);
|
cancelAnimationFrame(this.frameID);
|
||||||
// Destroy GUI Controls
|
// Destroy GUI Controls
|
||||||
|
@ -170,8 +148,10 @@ class ThreeViewer extends React.PureComponent<Props, State> {
|
||||||
// Empty objects
|
// Empty objects
|
||||||
this.grid = null;
|
this.grid = null;
|
||||||
this.mesh = null;
|
this.mesh = null;
|
||||||
this.material = null;
|
|
||||||
this.renderer = null;
|
this.renderer = null;
|
||||||
|
this.material = null;
|
||||||
|
this.geometry = null;
|
||||||
|
this.bufferGeometry = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -182,23 +162,20 @@ class ThreeViewer extends React.PureComponent<Props, State> {
|
||||||
|
|
||||||
createInterfaceControls() {
|
createInterfaceControls() {
|
||||||
if (this.guiContainer && this.mesh) {
|
if (this.guiContainer && this.mesh) {
|
||||||
this.gui = new dat.GUI({ autoPlace: false });
|
|
||||||
|
|
||||||
const { material } = this.mesh;
|
|
||||||
|
|
||||||
const config = {
|
const config = {
|
||||||
|
color: this.materialColor,
|
||||||
wireframe: false,
|
wireframe: false,
|
||||||
color: '#44b098',
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
this.gui = new dat.GUI({ autoPlace: false });
|
||||||
|
|
||||||
const colorPicker = this.gui.addColor(config, 'color');
|
const colorPicker = this.gui.addColor(config, 'color');
|
||||||
|
|
||||||
colorPicker.onChange(color => {
|
colorPicker.onChange(color => {
|
||||||
material.color.set(color);
|
this.material.color.set(color);
|
||||||
});
|
});
|
||||||
|
|
||||||
this.gui.add(material, 'wireframe').listen();
|
this.gui.add(this.material, 'wireframe').listen();
|
||||||
|
|
||||||
this.guiContainer.current.appendChild(this.gui.domElement);
|
this.guiContainer.current.appendChild(this.gui.domElement);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -217,6 +194,18 @@ class ThreeViewer extends React.PureComponent<Props, State> {
|
||||||
return controls;
|
return controls;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
createGeometry(data) {
|
||||||
|
this.bufferGeometry = data;
|
||||||
|
this.bufferGeometry.computeBoundingBox();
|
||||||
|
this.bufferGeometry.computeVertexNormals();
|
||||||
|
this.bufferGeometry.center();
|
||||||
|
this.bufferGeometry.rotateX(-Math.PI / 2);
|
||||||
|
this.bufferGeometry.lookAt(new THREE.Vector3(0, 0, 1));
|
||||||
|
// Get geometry from bufferGeometry
|
||||||
|
this.geometry = new THREE.Geometry().fromBufferGeometry(this.bufferGeometry);
|
||||||
|
this.geometry.mergeVertices();
|
||||||
|
}
|
||||||
|
|
||||||
startLoader() {
|
startLoader() {
|
||||||
const { source } = this.props;
|
const { source } = this.props;
|
||||||
|
|
||||||
|
@ -235,7 +224,6 @@ class ThreeViewer extends React.PureComponent<Props, State> {
|
||||||
|
|
||||||
handleReady = () => {
|
handleReady = () => {
|
||||||
this.setState({ isReady: true, isLoading: false });
|
this.setState({ isReady: true, isLoading: false });
|
||||||
|
|
||||||
// GUI
|
// GUI
|
||||||
this.createInterfaceControls();
|
this.createInterfaceControls();
|
||||||
};
|
};
|
||||||
|
@ -258,19 +246,17 @@ class ThreeViewer extends React.PureComponent<Props, State> {
|
||||||
}
|
}
|
||||||
|
|
||||||
renderStl(data) {
|
renderStl(data) {
|
||||||
const geometry = ThreeViewer.createGeometry(data);
|
this.createGeometry(data);
|
||||||
const group = new THREE.Mesh(geometry, this.material);
|
this.mesh = new THREE.Mesh(this.geometry, this.material);
|
||||||
// Assign name
|
this.mesh.name = 'model';
|
||||||
group.name = 'objectGroup';
|
this.scene.add(this.mesh);
|
||||||
this.scene.add(group);
|
this.transformGroup(this.mesh);
|
||||||
this.transformGroup(group);
|
|
||||||
this.mesh = group;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
renderObj(event) {
|
renderObj(event) {
|
||||||
const mesh = event.detail.loaderRootNode;
|
const mesh = event.detail.loaderRootNode;
|
||||||
const group = new THREE.Group();
|
this.mesh = new THREE.Group();
|
||||||
group.name = 'objGroup';
|
this.mesh.name = 'model';
|
||||||
|
|
||||||
// Assign new material
|
// Assign new material
|
||||||
mesh.traverse(child => {
|
mesh.traverse(child => {
|
||||||
|
@ -280,13 +266,15 @@ class ThreeViewer extends React.PureComponent<Props, State> {
|
||||||
geometry.fromBufferGeometry(child.geometry);
|
geometry.fromBufferGeometry(child.geometry);
|
||||||
// Create and regroup inner objects
|
// Create and regroup inner objects
|
||||||
const innerObj = new THREE.Mesh(geometry, this.material);
|
const innerObj = new THREE.Mesh(geometry, this.material);
|
||||||
group.add(innerObj);
|
this.mesh.add(innerObj);
|
||||||
|
// Clean up geometry
|
||||||
|
geometry.dispose();
|
||||||
|
child.geometry.dispose();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
this.scene.add(group);
|
this.scene.add(this.mesh);
|
||||||
this.transformGroup(group);
|
this.transformGroup(this.mesh);
|
||||||
this.mesh = group;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
renderModel(fileType, parsedData) {
|
renderModel(fileType, parsedData) {
|
||||||
|
@ -338,7 +326,7 @@ class ThreeViewer extends React.PureComponent<Props, State> {
|
||||||
});
|
});
|
||||||
|
|
||||||
// Set material color
|
// Set material color
|
||||||
this.material.color.set(this.materialColors.green);
|
this.material.color.set(this.materialColor);
|
||||||
|
|
||||||
// Load file and render mesh
|
// Load file and render mesh
|
||||||
this.startLoader();
|
this.startLoader();
|
||||||
|
|
Loading…
Add table
Reference in a new issue