From d5d10bda2184a5f5d52f38eb8afbe3976b105c5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=92=D0=BB=D0=B0=D0=B4=D0=B8=D1=81=D0=BB=D0=B0=D0=B2=20?= =?UTF-8?q?=D0=A7=D0=B0=D0=BB=D1=8B=D0=B9?= Date: Tue, 7 Feb 2023 20:27:03 +0300 Subject: [PATCH] Slice workers and ViewCube camera type switch. Fixup other many functions --- README.md | 2 +- assets/defaultconfigs/Creality-LD-002H.json | 2 +- assets/defaultconfigs/Default Printer.json | 2 +- assets/defaultconfigs/Voxelab Proxima 6.json | 2 +- assets/workers/slice.worker.bundle.js | 2 +- src/main/main.ts | 83 ++++++--- src/main/preload.ts | 1 - .../Supports/Shared/SupportsGen.tsx | 2 +- .../ViewChange/LockLookAtCenterApp.tsx | 15 +- src/renderer/Main/Console/ConsoleApp.tsx | 32 +++- src/renderer/Main/Console/ConsoleStore.ts | 12 +- src/renderer/Main/Scene/SceneInitializer.ts | 6 - src/renderer/Main/Scene/SceneStore.ts | 2 +- src/renderer/Shared/Config.ts | 8 +- .../Shared/Helpers/OrientationHelper.js | 21 ++- src/renderer/Slicing/SlicingApp.tsx | 13 +- src/renderer/Slicing/SlicingStore.tsx | 170 ++++++++++-------- src/workers/slice.worker.ts | 24 ++- 18 files changed, 256 insertions(+), 143 deletions(-) diff --git a/README.md b/README.md index 78527f5..deb449e 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ ## About

- ProtoUV it's open-source slicer for a photopolymer 3d printers, written on TypeScript with base on Electron. Uses React, ThreeJs, ThreeJs, Electron, uvtools and many other deps. + ProtoUV it's open-source slicer for a photopolymer 3d printers, written on TypeScript with base on Electron. Uses React, ThreeJs, three-mesh-bvh, Electron, uvtools and many other deps.

diff --git a/assets/defaultconfigs/Creality-LD-002H.json b/assets/defaultconfigs/Creality-LD-002H.json index 5fcb151..ee959d7 100644 --- a/assets/defaultconfigs/Creality-LD-002H.json +++ b/assets/defaultconfigs/Creality-LD-002H.json @@ -21,7 +21,7 @@ { "Name": "Default", "ConnectionSphere": 0.4, - "Head": 0.35, + "Head": 0.3, "Body": 0.5, "Indent": 0.6, "Angle": 56, diff --git a/assets/defaultconfigs/Default Printer.json b/assets/defaultconfigs/Default Printer.json index 5fcb151..ee959d7 100644 --- a/assets/defaultconfigs/Default Printer.json +++ b/assets/defaultconfigs/Default Printer.json @@ -21,7 +21,7 @@ { "Name": "Default", "ConnectionSphere": 0.4, - "Head": 0.35, + "Head": 0.3, "Body": 0.5, "Indent": 0.6, "Angle": 56, diff --git a/assets/defaultconfigs/Voxelab Proxima 6.json b/assets/defaultconfigs/Voxelab Proxima 6.json index fbaa0ed..edfe855 100644 --- a/assets/defaultconfigs/Voxelab Proxima 6.json +++ b/assets/defaultconfigs/Voxelab Proxima 6.json @@ -21,7 +21,7 @@ { "Name": "Default", "ConnectionSphere": 0.4, - "Head": 0.35, + "Head": 0.3, "Body": 0.5, "Indent": 0.6, "Angle": 56, diff --git a/assets/workers/slice.worker.bundle.js b/assets/workers/slice.worker.bundle.js index cd69814..2a8d318 100644 --- a/assets/workers/slice.worker.bundle.js +++ b/assets/workers/slice.worker.bundle.js @@ -16,7 +16,7 @@ \*************************************/ /***/ (function(__unused_webpack_module, exports, __webpack_require__) { -eval("\r\nvar __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {\r\n if (k2 === undefined) k2 = k;\r\n var desc = Object.getOwnPropertyDescriptor(m, k);\r\n if (!desc || (\"get\" in desc ? !m.__esModule : desc.writable || desc.configurable)) {\r\n desc = { enumerable: true, get: function() { return m[k]; } };\r\n }\r\n Object.defineProperty(o, k2, desc);\r\n}) : (function(o, m, k, k2) {\r\n if (k2 === undefined) k2 = k;\r\n o[k2] = m[k];\r\n}));\r\nvar __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {\r\n Object.defineProperty(o, \"default\", { enumerable: true, value: v });\r\n}) : function(o, v) {\r\n o[\"default\"] = v;\r\n});\r\nvar __importStar = (this && this.__importStar) || function (mod) {\r\n if (mod && mod.__esModule) return mod;\r\n var result = {};\r\n if (mod != null) for (var k in mod) if (k !== \"default\" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\r\n __setModuleDefault(result, mod);\r\n return result;\r\n};\r\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\r\nconst THREE = __importStar(__webpack_require__(/*! three */ \"./node_modules/three/build/three.cjs\"));\r\nconst three_1 = __webpack_require__(/*! three */ \"./node_modules/three/build/three.cjs\");\r\nconst constants_1 = __webpack_require__(/*! three/src/constants */ \"./node_modules/three/src/constants.js\");\r\nconst three_mesh_bvh_1 = __webpack_require__(/*! three-mesh-bvh */ \"./node_modules/three-mesh-bvh/src/index.js\");\r\nconst scene = new three_1.Scene();\r\nconst reader = new FileReader();\r\nconst clippingPlaneMin = new three_1.Plane();\r\nconst clippingInnerColor = 0xFFFFFF;\r\nconst clippingPlaneMeshMin = new THREE.Mesh(new THREE.PlaneBufferGeometry(), new THREE.MeshBasicMaterial({\r\n color: clippingInnerColor, side: three_1.BackSide,\r\n transparent: true,\r\n stencilWrite: true,\r\n depthTest: true,\r\n depthWrite: true,\r\n depthFunc: constants_1.NotEqualDepth,\r\n reflectivity: 0,\r\n stencilRef: 0,\r\n stencilFunc: THREE.NotEqualStencilFunc,\r\n stencilFail: THREE.ReplaceStencilOp,\r\n stencilZFail: THREE.ReplaceStencilOp,\r\n stencilZPass: THREE.ReplaceStencilOp,\r\n}));\r\nclippingPlaneMeshMin.rotateX(Math.PI / 2);\r\nclippingPlaneMeshMin.renderOrder = 2;\r\nclippingPlaneMeshMin.scale.setScalar(1000000);\r\nonmessage = function (oEvent) {\r\n const data = oEvent.data;\r\n const loader = new three_1.ObjectLoader();\r\n const group = loader.parse(data.geometry);\r\n const sizeXZ = new three_1.Vector2(data.printer.Workspace.SizeX * 0.1, data.printer.Workspace.SizeY * 0.1);\r\n const stencilRenderer = new three_1.WebGLRenderer({\r\n canvas: data.canvas\r\n });\r\n stencilRenderer.localClippingEnabled = true;\r\n stencilRenderer.outputEncoding = constants_1.LinearEncoding;\r\n stencilRenderer.setClearColor(0x000000);\r\n stencilRenderer.setSize(data.printer.Resolution.X, data.printer.Resolution.Y, false);\r\n const sliceOrthographicCamera = new three_1.OrthographicCamera(sizeXZ.x / -2, sizeXZ.x / 2, sizeXZ.y / 2, sizeXZ.y / -2, 0.0001);\r\n const groupClipping = CreateClipping(group.children[0].geometry);\r\n scene.add(groupClipping.group);\r\n const updateClipping = (clippingPercent) => {\r\n const inverseMatrix = new three_1.Matrix4();\r\n const localPlane = new three_1.Plane();\r\n const tempLine = new three_1.Line3();\r\n const tempVector = new three_1.Vector3();\r\n const tempVector1 = new three_1.Vector3();\r\n const tempVector2 = new three_1.Vector3();\r\n const tempVector3 = new three_1.Vector3();\r\n clippingPlaneMeshMin.updateMatrixWorld(true);\r\n clippingPlaneMeshMin.position.setY(clippingPercent * data.gridSize.y);\r\n clippingPlaneMeshMin.updateMatrixWorld(true);\r\n clippingPlaneMin.applyMatrix4(clippingPlaneMeshMin.matrixWorld);\r\n clippingPlaneMeshMin.updateMatrixWorld(true);\r\n clippingPlaneMin.constant = clippingPercent * data.gridSize.y;\r\n clippingPlaneMin.normal.set(0, -1, 0);\r\n inverseMatrix.copy(groupClipping.colliderMesh.matrixWorld).invert();\r\n localPlane.copy(clippingPlaneMin).applyMatrix4(inverseMatrix);\r\n let index = 0;\r\n const posAttr = groupClipping.outlineLines.geometry.attributes.position;\r\n groupClipping.colliderBvh.shapecast({\r\n intersectsBounds: () => three_mesh_bvh_1.CONTAINED,\r\n intersectsTriangle: (tri) => {\r\n let count = 0;\r\n tempLine.start.copy(tri.a);\r\n tempLine.end.copy(tri.b);\r\n if (localPlane.intersectLine(tempLine, tempVector)) {\r\n posAttr.setXYZ(index, tempVector.x, tempVector.y, tempVector.z);\r\n index++;\r\n count++;\r\n }\r\n tempLine.start.copy(tri.b);\r\n tempLine.end.copy(tri.c);\r\n if (localPlane.intersectLine(tempLine, tempVector)) {\r\n posAttr.setXYZ(index, tempVector.x, tempVector.y, tempVector.z);\r\n count++;\r\n index++;\r\n }\r\n tempLine.start.copy(tri.c);\r\n tempLine.end.copy(tri.a);\r\n if (localPlane.intersectLine(tempLine, tempVector)) {\r\n posAttr.setXYZ(index, tempVector.x, tempVector.y, tempVector.z);\r\n count++;\r\n index++;\r\n }\r\n if (count === 3) {\r\n tempVector1.fromBufferAttribute(posAttr, index - 3);\r\n tempVector2.fromBufferAttribute(posAttr, index - 2);\r\n tempVector3.fromBufferAttribute(posAttr, index - 1);\r\n if (tempVector3.equals(tempVector1) || tempVector3.equals(tempVector2)) {\r\n count--;\r\n index--;\r\n }\r\n else if (tempVector1.equals(tempVector2)) {\r\n posAttr.setXYZ(index - 2, tempVector3.x, tempVector3.y, tempVector3.z);\r\n count--;\r\n index--;\r\n }\r\n }\r\n if (count !== 2) {\r\n index -= count;\r\n }\r\n },\r\n });\r\n groupClipping.outlineLines.geometry.setDrawRange(0, index);\r\n groupClipping.outlineLines.position.copy(clippingPlaneMin.normal).multiplyScalar(-0.00001);\r\n posAttr.needsUpdate = true;\r\n };\r\n const next = () => new Promise(resolve => {\r\n const layer = data.layers.shift();\r\n if (!layer) {\r\n postMessage({\r\n type: 1\r\n });\r\n resolve(true);\r\n return;\r\n }\r\n updateClipping(layer.percent);\r\n stencilRenderer.clearDepth();\r\n sliceOrthographicCamera.position.set(data.gridSize.x / 2, data.gridSize.y + 1, data.gridSize.z / 2);\r\n sliceOrthographicCamera.lookAt(data.gridSize.x / 2, 0, data.gridSize.z / 2);\r\n stencilRenderer.render(scene, sliceOrthographicCamera);\r\n data.canvas.convertToBlob().then((blob) => {\r\n reader.readAsDataURL(blob);\r\n reader.onloadend = function () {\r\n postMessage({\r\n type: 0,\r\n image: reader.result,\r\n layer: layer,\r\n reminder: data.layers.length\r\n });\r\n next().then(_ => {\r\n resolve(false);\r\n });\r\n };\r\n });\r\n });\r\n next().then();\r\n};\r\nconst material = new three_1.MeshLambertMaterial({ color: '#98de9c', side: three_1.DoubleSide,\r\n clippingPlanes: [clippingPlaneMin]\r\n});\r\nconst CreateClipping = (geometry) => {\r\n const frontSideModel = new three_1.Mesh(geometry);\r\n frontSideModel.updateMatrixWorld(true);\r\n const surfaceModel = frontSideModel.clone();\r\n surfaceModel.material = material;\r\n surfaceModel.material.transparent = true;\r\n surfaceModel.material.opacity = 0;\r\n surfaceModel.renderOrder = 1;\r\n const lineGeometry = new three_1.BufferGeometry();\r\n const linePosAttr = new three_1.BufferAttribute(new Float32Array(300000), 3, false);\r\n linePosAttr.setUsage(three_1.DynamicDrawUsage);\r\n lineGeometry.setAttribute('position', linePosAttr);\r\n const clippingLineMin = new three_1.LineSegments(lineGeometry, new three_1.LineBasicMaterial());\r\n clippingLineMin.material.color.set('#ffffff').convertSRGBToLinear();\r\n clippingLineMin.frustumCulled = false;\r\n clippingLineMin.renderOrder = 3;\r\n clippingLineMin.scale.copy(frontSideModel.scale);\r\n clippingLineMin.position.set(0, 0, 0);\r\n clippingLineMin.quaternion.identity();\r\n const matSet = new Set();\r\n const materialMap = new Map();\r\n frontSideModel.traverse((c) => {\r\n if (materialMap.has(c.material)) {\r\n c.material = materialMap.get(c.material);\r\n return;\r\n }\r\n matSet.add(c.material);\r\n const material = c.material.clone();\r\n material.roughness = 1.0;\r\n material.metalness = 0.1;\r\n material.side = three_1.FrontSide;\r\n material.stencilWrite = true;\r\n material.stencilFail = three_1.DecrementWrapStencilOp;\r\n material.stencilZFail = three_1.DecrementWrapStencilOp;\r\n material.stencilZPass = three_1.DecrementWrapStencilOp;\r\n material.depthWrite = false;\r\n material.depthTest = false;\r\n material.colorWrite = false;\r\n material.stencilWrite = true;\r\n material.stencilFunc = three_1.AlwaysStencilFunc;\r\n material.clippingPlanes = [clippingPlaneMin];\r\n materialMap.set(c.material, material);\r\n c.material = material;\r\n });\r\n materialMap.clear();\r\n const backSideModel = frontSideModel.clone();\r\n backSideModel.traverse((c) => {\r\n if (c.isMesh) {\r\n if (materialMap.has(c.material)) {\r\n c.material = materialMap.get(c.material);\r\n return;\r\n }\r\n const material = c.material.clone();\r\n material.side = three_1.BackSide;\r\n material.stencilFail = three_1.IncrementWrapStencilOp;\r\n material.stencilZFail = three_1.IncrementWrapStencilOp;\r\n material.stencilZPass = three_1.IncrementWrapStencilOp;\r\n material.depthWrite = false;\r\n material.depthTest = false;\r\n material.colorWrite = false;\r\n material.stencilWrite = true;\r\n material.clippingPlanes = [clippingPlaneMin];\r\n materialMap.set(c.material, material);\r\n c.material = material;\r\n }\r\n });\r\n const colliderBvh = new three_mesh_bvh_1.MeshBVH(frontSideModel.geometry, { maxLeafTris: 3 });\r\n frontSideModel.geometry.boundsTree = colliderBvh;\r\n const colliderMesh = new three_1.Mesh(frontSideModel.geometry, new three_1.MeshBasicMaterial({\r\n wireframe: true,\r\n transparent: true,\r\n opacity: 0.01,\r\n depthWrite: false,\r\n }));\r\n colliderMesh.renderOrder = 2;\r\n colliderMesh.position.copy(frontSideModel.position);\r\n colliderMesh.rotation.copy(frontSideModel.rotation);\r\n colliderMesh.scale.copy(frontSideModel.scale);\r\n const group = new three_1.Group();\r\n group.add(frontSideModel, backSideModel, surfaceModel, colliderMesh, clippingLineMin);\r\n group.children[3].visible = false;\r\n group.children[2].visible = false;\r\n return {\r\n group: group,\r\n colliderMesh: colliderMesh,\r\n outlineLines: clippingLineMin,\r\n colliderBvh: colliderBvh\r\n };\r\n};\r\n\n\n//# sourceURL=webpack://protouv/./src/workers/slice.worker.ts?"); +eval("\r\nvar __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {\r\n if (k2 === undefined) k2 = k;\r\n var desc = Object.getOwnPropertyDescriptor(m, k);\r\n if (!desc || (\"get\" in desc ? !m.__esModule : desc.writable || desc.configurable)) {\r\n desc = { enumerable: true, get: function() { return m[k]; } };\r\n }\r\n Object.defineProperty(o, k2, desc);\r\n}) : (function(o, m, k, k2) {\r\n if (k2 === undefined) k2 = k;\r\n o[k2] = m[k];\r\n}));\r\nvar __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {\r\n Object.defineProperty(o, \"default\", { enumerable: true, value: v });\r\n}) : function(o, v) {\r\n o[\"default\"] = v;\r\n});\r\nvar __importStar = (this && this.__importStar) || function (mod) {\r\n if (mod && mod.__esModule) return mod;\r\n var result = {};\r\n if (mod != null) for (var k in mod) if (k !== \"default\" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\r\n __setModuleDefault(result, mod);\r\n return result;\r\n};\r\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\r\nconst THREE = __importStar(__webpack_require__(/*! three */ \"./node_modules/three/build/three.cjs\"));\r\nconst three_1 = __webpack_require__(/*! three */ \"./node_modules/three/build/three.cjs\");\r\nconst constants_1 = __webpack_require__(/*! three/src/constants */ \"./node_modules/three/src/constants.js\");\r\nconst three_mesh_bvh_1 = __webpack_require__(/*! three-mesh-bvh */ \"./node_modules/three-mesh-bvh/src/index.js\");\r\nconst scene = new three_1.Scene();\r\nconst reader = new FileReader();\r\nconst clippingPlaneMin = new three_1.Plane();\r\nconst clippingInnerColor = 0xFFFFFF;\r\nconst clippingPlaneMeshMin = new THREE.Mesh(new THREE.PlaneBufferGeometry(), new THREE.MeshBasicMaterial({\r\n color: clippingInnerColor, side: three_1.BackSide,\r\n transparent: true,\r\n stencilWrite: true,\r\n depthTest: true,\r\n depthWrite: true,\r\n depthFunc: constants_1.NotEqualDepth,\r\n reflectivity: 0,\r\n stencilRef: 0,\r\n stencilFunc: THREE.NotEqualStencilFunc,\r\n stencilFail: THREE.ReplaceStencilOp,\r\n stencilZFail: THREE.ReplaceStencilOp,\r\n stencilZPass: THREE.ReplaceStencilOp,\r\n}));\r\nclippingPlaneMeshMin.rotateX(Math.PI / 2);\r\nclippingPlaneMeshMin.renderOrder = 2;\r\nscene.add(clippingPlaneMeshMin);\r\nclippingPlaneMeshMin.visible = true;\r\nclippingPlaneMeshMin.scale.setScalar(1000000);\r\nonmessage = function (oEvent) {\r\n const data = oEvent.data;\r\n const loader = new three_1.ObjectLoader();\r\n const group = loader.parse(data.geometry);\r\n const sizeXZ = new three_1.Vector2(data.printer.Workspace.SizeX * 0.1, data.printer.Workspace.SizeY * 0.1);\r\n const stencilRenderer = new three_1.WebGLRenderer({\r\n canvas: data.canvas\r\n });\r\n stencilRenderer.localClippingEnabled = true;\r\n stencilRenderer.outputEncoding = constants_1.LinearEncoding;\r\n stencilRenderer.setClearColor(0x000000);\r\n stencilRenderer.setSize(data.printer.Resolution.X, data.printer.Resolution.Y, false);\r\n const sliceOrthographicCamera = new three_1.OrthographicCamera(sizeXZ.x / -2, sizeXZ.x / 2, sizeXZ.y / 2, sizeXZ.y / -2, 0.0001);\r\n const groupClipping = CreateClipping(group.children[0].geometry);\r\n scene.add(groupClipping.group);\r\n const updateClipping = (clippingPercent) => {\r\n const inverseMatrix = new three_1.Matrix4();\r\n const localPlane = new three_1.Plane();\r\n const tempLine = new three_1.Line3();\r\n const tempVector = new three_1.Vector3();\r\n const tempVector1 = new three_1.Vector3();\r\n const tempVector2 = new three_1.Vector3();\r\n const tempVector3 = new three_1.Vector3();\r\n clippingPlaneMeshMin.updateMatrixWorld(true);\r\n clippingPlaneMeshMin.position.setY(clippingPercent * data.gridSize.y);\r\n clippingPlaneMeshMin.updateMatrixWorld(true);\r\n clippingPlaneMin.applyMatrix4(clippingPlaneMeshMin.matrixWorld);\r\n clippingPlaneMeshMin.updateMatrixWorld(true);\r\n clippingPlaneMin.constant = clippingPercent * data.gridSize.y;\r\n clippingPlaneMin.normal.set(0, -1, 0);\r\n inverseMatrix.copy(groupClipping.colliderMesh.matrixWorld).invert();\r\n localPlane.copy(clippingPlaneMin).applyMatrix4(inverseMatrix);\r\n let index = 0;\r\n const posAttr = groupClipping.outlineLines.geometry.attributes.position;\r\n groupClipping.colliderBvh.shapecast({\r\n intersectsBounds: () => three_mesh_bvh_1.CONTAINED,\r\n intersectsTriangle: (tri) => {\r\n let count = 0;\r\n tempLine.start.copy(tri.a);\r\n tempLine.end.copy(tri.b);\r\n if (localPlane.intersectLine(tempLine, tempVector)) {\r\n posAttr.setXYZ(index, tempVector.x, tempVector.y, tempVector.z);\r\n index++;\r\n count++;\r\n }\r\n tempLine.start.copy(tri.b);\r\n tempLine.end.copy(tri.c);\r\n if (localPlane.intersectLine(tempLine, tempVector)) {\r\n posAttr.setXYZ(index, tempVector.x, tempVector.y, tempVector.z);\r\n count++;\r\n index++;\r\n }\r\n tempLine.start.copy(tri.c);\r\n tempLine.end.copy(tri.a);\r\n if (localPlane.intersectLine(tempLine, tempVector)) {\r\n posAttr.setXYZ(index, tempVector.x, tempVector.y, tempVector.z);\r\n count++;\r\n index++;\r\n }\r\n if (count === 3) {\r\n tempVector1.fromBufferAttribute(posAttr, index - 3);\r\n tempVector2.fromBufferAttribute(posAttr, index - 2);\r\n tempVector3.fromBufferAttribute(posAttr, index - 1);\r\n if (tempVector3.equals(tempVector1) || tempVector3.equals(tempVector2)) {\r\n count--;\r\n index--;\r\n }\r\n else if (tempVector1.equals(tempVector2)) {\r\n posAttr.setXYZ(index - 2, tempVector3.x, tempVector3.y, tempVector3.z);\r\n count--;\r\n index--;\r\n }\r\n }\r\n if (count !== 2) {\r\n index -= count;\r\n }\r\n },\r\n });\r\n groupClipping.outlineLines.geometry.setDrawRange(0, index);\r\n groupClipping.outlineLines.position.copy(clippingPlaneMin.normal).multiplyScalar(-0.00001);\r\n posAttr.needsUpdate = true;\r\n };\r\n const next = () => new Promise(resolve => {\r\n const layer = data.layers.shift();\r\n if (!layer) {\r\n postMessage({\r\n type: 1\r\n });\r\n resolve(true);\r\n return;\r\n }\r\n updateClipping(layer.percent);\r\n stencilRenderer.clearDepth();\r\n sliceOrthographicCamera.position.set(data.gridSize.x / 2, data.gridSize.y + 1, data.gridSize.z / 2);\r\n sliceOrthographicCamera.lookAt(data.gridSize.x / 2, 0, data.gridSize.z / 2);\r\n stencilRenderer.render(scene, sliceOrthographicCamera);\r\n data.canvas.convertToBlob().then((blob) => {\r\n reader.readAsDataURL(blob);\r\n reader.onloadend = function () {\r\n postMessage({\r\n type: 0,\r\n image: reader.result,\r\n layer: layer,\r\n reminder: data.layers.length\r\n });\r\n next().then(_ => {\r\n resolve(false);\r\n });\r\n };\r\n });\r\n });\r\n next().then();\r\n};\r\nconst material = new three_1.MeshLambertMaterial({ color: '#98de9c', side: three_1.DoubleSide,\r\n clippingPlanes: [clippingPlaneMin]\r\n});\r\nconst CreateClipping = (geometry) => {\r\n const frontSideModel = new three_1.Mesh(geometry);\r\n frontSideModel.updateMatrixWorld(true);\r\n const surfaceModel = frontSideModel.clone();\r\n surfaceModel.material = material;\r\n surfaceModel.material.transparent = true;\r\n surfaceModel.material.opacity = 0;\r\n surfaceModel.renderOrder = 1;\r\n const lineGeometry = new three_1.BufferGeometry();\r\n const linePosAttr = new three_1.BufferAttribute(new Float32Array(300000), 3, false);\r\n linePosAttr.setUsage(three_1.DynamicDrawUsage);\r\n lineGeometry.setAttribute('position', linePosAttr);\r\n const clippingLineMin = new three_1.LineSegments(lineGeometry, new three_1.LineBasicMaterial());\r\n clippingLineMin.material.color.set('#ffffff').convertSRGBToLinear();\r\n clippingLineMin.frustumCulled = false;\r\n clippingLineMin.renderOrder = 3;\r\n clippingLineMin.scale.copy(frontSideModel.scale);\r\n clippingLineMin.position.set(0, 0, 0);\r\n clippingLineMin.quaternion.identity();\r\n const matSet = new Set();\r\n const materialMap = new Map();\r\n frontSideModel.traverse((c) => {\r\n if (materialMap.has(c.material)) {\r\n c.material = materialMap.get(c.material);\r\n return;\r\n }\r\n matSet.add(c.material);\r\n const material = c.material.clone();\r\n material.roughness = 1.0;\r\n material.metalness = 0.1;\r\n material.side = three_1.FrontSide;\r\n material.stencilWrite = true;\r\n material.stencilFail = three_1.DecrementWrapStencilOp;\r\n material.stencilZFail = three_1.DecrementWrapStencilOp;\r\n material.stencilZPass = three_1.DecrementWrapStencilOp;\r\n material.depthWrite = false;\r\n material.depthTest = false;\r\n material.colorWrite = false;\r\n material.stencilWrite = true;\r\n material.stencilFunc = three_1.AlwaysStencilFunc;\r\n material.clippingPlanes = [clippingPlaneMin];\r\n materialMap.set(c.material, material);\r\n c.material = material;\r\n });\r\n materialMap.clear();\r\n const backSideModel = frontSideModel.clone();\r\n backSideModel.traverse((c) => {\r\n if (c.isMesh) {\r\n if (materialMap.has(c.material)) {\r\n c.material = materialMap.get(c.material);\r\n return;\r\n }\r\n const material = c.material.clone();\r\n material.side = three_1.BackSide;\r\n material.stencilFail = three_1.IncrementWrapStencilOp;\r\n material.stencilZFail = three_1.IncrementWrapStencilOp;\r\n material.stencilZPass = three_1.IncrementWrapStencilOp;\r\n material.depthWrite = false;\r\n material.depthTest = false;\r\n material.colorWrite = false;\r\n material.stencilWrite = true;\r\n material.clippingPlanes = [clippingPlaneMin];\r\n materialMap.set(c.material, material);\r\n c.material = material;\r\n }\r\n });\r\n const colliderBvh = new three_mesh_bvh_1.MeshBVH(frontSideModel.geometry, { maxLeafTris: 3 });\r\n frontSideModel.geometry.boundsTree = colliderBvh;\r\n const colliderMesh = new three_1.Mesh(frontSideModel.geometry, new three_1.MeshBasicMaterial({\r\n wireframe: true,\r\n transparent: true,\r\n opacity: 0.01,\r\n depthWrite: false,\r\n }));\r\n colliderMesh.renderOrder = 2;\r\n colliderMesh.position.copy(frontSideModel.position);\r\n colliderMesh.rotation.copy(frontSideModel.rotation);\r\n colliderMesh.scale.copy(frontSideModel.scale);\r\n const group = new three_1.Group();\r\n group.add(frontSideModel, backSideModel, surfaceModel, colliderMesh, clippingLineMin);\r\n group.children[3].visible = false;\r\n group.children[2].visible = false;\r\n return {\r\n group: group,\r\n colliderMesh: colliderMesh,\r\n outlineLines: clippingLineMin,\r\n colliderBvh: colliderBvh\r\n };\r\n};\r\n\n\n//# sourceURL=webpack://protouv/./src/workers/slice.worker.ts?"); /***/ }), diff --git a/src/main/main.ts b/src/main/main.ts index 4d5e587..7dc19e6 100644 --- a/src/main/main.ts +++ b/src/main/main.ts @@ -11,15 +11,7 @@ const userData = electron.app.getPath('userData'); let mainWindow: BrowserWindow | null = null; let mainWindowIsFocused: boolean | undefined; -const workers = [] as BrowserWindow[]; -const RESOURCES_PATH = app.isPackaged - ? path.join((process as any).resourcesPath, 'assets') - : path.join(__dirname, '../../assets'); - -ipcMain.on('electron.assetsPath', (event: any) => { - event.returnValue = RESOURCES_PATH; -}); ipcMain.on('electron.userData', (event: any) => { event.returnValue = userData; }); @@ -50,10 +42,6 @@ ipcMain.on('electron.openFileDialog', (event: any) => { }); } }); -ipcMain.on('electron.isWorker', (_) => { - const worker = workers.find(x => _.sender === x.webContents); - _.returnValue = !!worker; -}); if (process.env.NODE_ENV === 'production') { // eslint-disable-next-line @typescript-eslint/no-var-requires @@ -91,10 +79,18 @@ const createWindow = async () => { await installExtensions(); } + const RESOURCES_PATH = app.isPackaged + ? path.join((process as any).resourcesPath, 'assets') + : path.join(__dirname, '../../assets'); + const getAssetPath = (...paths: string[]): string => { return path.join(RESOURCES_PATH, ...paths); }; + ipcMain.on('electron.assetsPath', (event: any) => { + event.returnValue = RESOURCES_PATH; + }); + mainWindow = new BrowserWindow({ show: false, width: 1200, @@ -115,6 +111,7 @@ const createWindow = async () => { }, titleBarStyle: 'hidden', }); + mainWindow.setMenu(null); mainWindow.loadURL(resolveHtmlPath('index.html')); @@ -143,6 +140,7 @@ const createWindow = async () => { }); } }); + mainWindow.on('closed', () => { mainWindow = null; }); @@ -153,24 +151,21 @@ const createWindow = async () => { return { action: 'deny' }; }); - ipcMain.on('prepare-to-slicing', (_) => { + ipcMain.on('prepare-to-slicing', () => { if (fs.existsSync(userData + '/slicing')) { fs.rmSync(userData + '/slicing', { recursive: true, force: true }); } - fs.mkdirSync(userData + '/slicing'); - - mainWindow?.webContents.send('prepare-to-slicing-ready'); + mainWindow?.webContents.send('prepare-to-slicing'); }); ipcMain.on('sliced-layer-save', (_, screenshot: string, path: string) => { fs.writeFileSync(userData + '/slicing/' + path, atob(screenshot), 'binary' ); }); - ipcMain.on('sliced-finalize-done', (_, + ipcMain.on('sliced-finalize', (_, gcode: string, pathToUVTools: string, encoder: string, extencion: string ) => { - try { fs.writeFileSync(userData + '/slicing/run.gcode', gcode); @@ -185,8 +180,13 @@ const createWindow = async () => { const _process = child(executablePath, parameters); - _process.stdout!.on('data', (data) => console.log(`stdout: ${data}`)); - _process.stderr!.on('data', (data) => console.error(`stderr: ${data}`)); + _process.stdout!.on('data', (data) => { + console.log(`stdout: ${data}`); + }); + + _process.stderr!.on('data', (data) => { + console.error(`stderr: ${data}`); + }); _process.on('close', (code) => { if (code === 1) { mainWindow?.webContents.send('sliced-finalize-result', 'done'); @@ -247,6 +247,46 @@ const createWindow = async () => { mainWindow?.webContents.send('sliced-finalize-result-save', 'finalize error: ' + e); } }); + + let workers: BrowserWindow[] = []; + + ipcMain.on('worker', (_, scene: string) => { + console.log(123); + const worker = new BrowserWindow({ + //show: false, + //titleBarStyle: 'hidden', + webPreferences: { + preload: app.isPackaged + ? path.join(__dirname, 'preload.js') + : path.join(__dirname, '../../.erb/dll/preload.js'), + webSecurity: false, + sandbox: false, + nodeIntegration: true, + devTools: isDebug, + nodeIntegrationInWorker: true, + nodeIntegrationInSubFrames: true + }, + titleBarStyle: 'hidden', + }); + console.log(scene); + worker.loadURL(resolveHtmlPath('index.html')); + worker.webContents.send('worker', scene); + workers.push(worker); + + const send = () => mainWindow?.webContents.send('worker-info', workers.length); + const interval = setInterval(() => { + send(); + if (!workers.length) { + clearInterval(interval); + } + }, 500); + + send(); + }); + ipcMain.on('worker-shutdown', (e) => { + workers = workers.filter(worker => worker.webContents !== e.sender); + e.sender.delete(); + }); }; /** @@ -261,7 +301,8 @@ app.on('window-all-closed', () => { } }); -app.whenReady() +app + .whenReady() .then(() => { createWindow(); app.on('activate', () => { diff --git a/src/main/preload.ts b/src/main/preload.ts index e693ac2..cba1bd1 100644 --- a/src/main/preload.ts +++ b/src/main/preload.ts @@ -14,7 +14,6 @@ const body = { userData: () => ipcRenderer.sendSync('electron.userData'), isDebug: () => ipcRenderer.sendSync('electron.isDebug'), assetsPath: () => ipcRenderer.sendSync('electron.assetsPath'), - isWorker: () => ipcRenderer.sendSync('electron.isWorker'), ipcRenderer: { ...ipcRenderer, send: (channel: any, ...args: any) => { diff --git a/src/renderer/Main/Components/ToolsRight/Supports/Shared/SupportsGen.tsx b/src/renderer/Main/Components/ToolsRight/Supports/Shared/SupportsGen.tsx index 68500a1..cf2f25b 100644 --- a/src/renderer/Main/Components/ToolsRight/Supports/Shared/SupportsGen.tsx +++ b/src/renderer/Main/Components/ToolsRight/Supports/Shared/SupportsGen.tsx @@ -111,7 +111,7 @@ const _supportCreator = ( const to = path[path.length-1].clone().setY(path[path.length-1].y + platformHeight); mesh1.add(createCylinder(material, from, to, to.distanceTo(from), platformWidth * 0.75, platformWidth).mesh); } - mesh1.add(createContactSphere(material, path[0], connectionSphere).mesh); + mesh1.add(createContactSphere(material, path[0], body).mesh); mesh1.add(createCylinder(material, path[0], to, to.distanceTo(path[0]), body, head).mesh); mesh1.add(createContactSphere(material, to, connectionSphere).mesh); diff --git a/src/renderer/Main/Components/ViewChange/LockLookAtCenterApp.tsx b/src/renderer/Main/Components/ViewChange/LockLookAtCenterApp.tsx index 537d5a7..2464716 100644 --- a/src/renderer/Main/Components/ViewChange/LockLookAtCenterApp.tsx +++ b/src/renderer/Main/Components/ViewChange/LockLookAtCenterApp.tsx @@ -1,21 +1,20 @@ import { IconButton, Tooltip } from '@mui/material'; import { MdCenterFocusStrong } from '@react-icons/all-files/md/MdCenterFocusStrong'; import { MdCenterFocusWeak } from '@react-icons/all-files/md/MdCenterFocusWeak'; -import { useState } from 'react'; +import { observer } from 'mobx-react'; import { AppStore } from '../../../AppStore'; import { config, saveConfig } from '../../../Shared/Config'; import { colors } from '../../../Shared/Config'; -export const LockLookAtCenterApp = () => { - const [isActive, setterIsActive] = useState(config.scene.isFixedCenter); +export const LockLookAtCenterApp = observer(() => { + AppStore.sceneStore.orbitControls.enablePan = !config.scene.isFixedCenter; - return { - config.scene.isFixedCenter = !isActive; - setterIsActive(config.scene.isFixedCenter); + config.scene.isFixedCenter = !config.scene.isFixedCenter; saveConfig(); AppStore.sceneStore.animate(); }} @@ -23,9 +22,9 @@ export const LockLookAtCenterApp = () => { AppStore.sceneStore.orbitControls.target.set(AppStore.sceneStore.gridSize.x / 2, 0, AppStore.sceneStore.gridSize.z / 2); AppStore.sceneStore.animate(); }}> - {isActive + {config.scene.isFixedCenter ? : } ; -}; +}); diff --git a/src/renderer/Main/Console/ConsoleApp.tsx b/src/renderer/Main/Console/ConsoleApp.tsx index dad9f3d..7701efc 100644 --- a/src/renderer/Main/Console/ConsoleApp.tsx +++ b/src/renderer/Main/Console/ConsoleApp.tsx @@ -1,6 +1,7 @@ import { Box, Fade, Typography } from '@mui/material'; import { observer } from 'mobx-react'; import { useState } from 'react'; +import { ConsoleColors } from './ConsoleStore'; import { AppStore } from '../../AppStore'; import { colors } from '../../Shared/Config'; import { linearGenerator } from '../../Shared/Libs/Tools'; @@ -23,7 +24,6 @@ export const ConsoleApp = observer((props: {mt?: string, mb?: string}) => { position: 'fixed', bottom: 0, overflow: 'hidden', - color: colors.typography.background, margin: Sizes.twelve, marginLeft: Sizes.twelve, marginBottom: Sizes.sum(Sizes.twentyFour, Sizes.eight), @@ -32,9 +32,33 @@ export const ConsoleApp = observer((props: {mt?: string, mb?: string}) => { pointerEvents: selectable ? 'unset' : 'none', ...props }}> - {AppStore.console.list.slice().reverse().map(x => - {x.time} {'>'} {x.text} - )} + {AppStore.console.list.slice().reverse().map(x => { + let color; + + switch (x.color) { + case ConsoleColors.Message: + color = colors.background.light; + break; + case ConsoleColors.Success: + color = colors.interact.success; + break; + case ConsoleColors.Error: + color = colors.interact.danger; + break; + } + + return + {x.time} {'>'} {x.text} + ; + })} ; }); diff --git a/src/renderer/Main/Console/ConsoleStore.ts b/src/renderer/Main/Console/ConsoleStore.ts index deb6a63..bcacb03 100644 --- a/src/renderer/Main/Console/ConsoleStore.ts +++ b/src/renderer/Main/Console/ConsoleStore.ts @@ -19,11 +19,12 @@ export class ConsoleStore { public list: Array<{ text: string; time: string; + color: ConsoleColors; }> = []; private timerHide?: NodeJS.Timeout; - public Add = (text: string) => { + public Add = (text: string, color: ConsoleColors = 0) => { const date = new Date() .toISOString() .replace(/T/, ' ') @@ -31,7 +32,8 @@ export class ConsoleStore { .split(' ')[1]; const log = { text: text.toLowerCase(), - time: date + time: date, + color: color }; if (this.timerHide) @@ -53,3 +55,9 @@ export class ConsoleStore { } }; } + +export enum ConsoleColors { + Message, + Success, + Error, +} diff --git a/src/renderer/Main/Scene/SceneInitializer.ts b/src/renderer/Main/Scene/SceneInitializer.ts index b01c56c..8c5b961 100644 --- a/src/renderer/Main/Scene/SceneInitializer.ts +++ b/src/renderer/Main/Scene/SceneInitializer.ts @@ -920,12 +920,6 @@ export class SceneInitializer extends SceneBase { if (this.activeCamera.position.y >= 0) { - // this.renderer.setSize( 333, 333 ); - // this.renderer.render( this.scene, this.activeCamera ); - // const screenshot = this.renderer.domElement.toDataURL('image/png'); - // console.log(screenshot); - // bridge.ipcRenderer.send('capture-page', screenshot.replace('data:image/png;base64,','') - // ); if (!this.clippingSceneWorking) { this.outlineEffectRenderer.renderOutline(this.scene, this.activeCamera); } diff --git a/src/renderer/Main/Scene/SceneStore.ts b/src/renderer/Main/Scene/SceneStore.ts index c67701e..4dde94c 100644 --- a/src/renderer/Main/Scene/SceneStore.ts +++ b/src/renderer/Main/Scene/SceneStore.ts @@ -32,7 +32,7 @@ export class SceneStore extends SceneInitializer { makeObservable(this); setTimeout(() => { - if (bridge.isDebug() && !bridge.isWorker()) + if (bridge.isDebug()) { AppStore.sceneStore.handleLoadFile('C:\\Users\\admin\\Downloads\\Old\\V7_Infinity_Cube_Hinge.stl'); } diff --git a/src/renderer/Shared/Config.ts b/src/renderer/Shared/Config.ts index e5fef65..58c20ab 100644 --- a/src/renderer/Shared/Config.ts +++ b/src/renderer/Shared/Config.ts @@ -1,3 +1,4 @@ +import { observable } from 'mobx'; import { Restore } from './Libs/Restore'; export const _default = { @@ -70,6 +71,9 @@ const storage = new Restore({ defaults: _default }); -export const saveConfig = () => storage.fullSave(); -export const config = storage.get('settings') as typeof _default.settings; +export const saveConfig = () => { + storage.data.settings = config; + storage.fullSave(); +}; +export const config = observable(storage.get('settings')) as typeof _default.settings; export const colors = (storage.get('settings') as typeof _default.settings).colors; diff --git a/src/renderer/Shared/Helpers/OrientationHelper.js b/src/renderer/Shared/Helpers/OrientationHelper.js index 801083b..82b0ed5 100644 --- a/src/renderer/Shared/Helpers/OrientationHelper.js +++ b/src/renderer/Shared/Helpers/OrientationHelper.js @@ -7,7 +7,7 @@ import { EventDispatcher, Group, Mesh, - MeshPhysicalMaterial, + MeshPhysicalMaterial, OrthographicCamera, PerspectiveCamera, Raycaster, RingGeometry, @@ -41,6 +41,7 @@ var OrientationHelper = function ( camera, controls, options, labels ) { cameraNear: 1, cameraFar: 1000, cameraDistance: 150, + cameraOrthographicZoom: 0.8, boxBackground: '#444', boxColor: '#fff', boxCanvasSide: 64, @@ -150,7 +151,23 @@ var OrientationHelper = function ( camera, controls, options, labels ) { scope._renderer.setSize( _options.width, _options.height ); scope._renderer.domElement.className = 'orientation-helper-scene ' + _options.className; - scope._camera = new PerspectiveCamera( _options.cameraFov, _options.width / _options.height, _options.cameraNear, _options.cameraFar ); + const isPerspective = camera instanceof PerspectiveCamera; + + scope._camera = isPerspective + ? new PerspectiveCamera( _options.cameraFov, _options.width / _options.height, _options.cameraNear, _options.cameraFar ) + : new OrthographicCamera( + _options.width / - 2, + _options.width / 2, + _options.height / 2, + _options.height / - 2, + 0.0001 + ); + + if (!isPerspective) + { + scope._camera.zoom = _options.cameraOrthographicZoom; + scope._camera.updateProjectionMatrix(); + } scope._raycaster = new Raycaster(); scope._raycaster.layers.enable( 1 ); diff --git a/src/renderer/Slicing/SlicingApp.tsx b/src/renderer/Slicing/SlicingApp.tsx index ffa2435..abc1f16 100644 --- a/src/renderer/Slicing/SlicingApp.tsx +++ b/src/renderer/Slicing/SlicingApp.tsx @@ -10,10 +10,8 @@ export const SlicingApp = observer(() => { const isSliced = AppStore.slice.sliceCount > AppStore.slice.sliceCountMax; return - {AppStore.slice.image !== '' && { right: '4px', gap: '4px' }}> - {!isSliced && + { config.saveAutomatically = !config.saveAutomatically; saveConfig(); }} sx={{ height: '36px', width: '36px', + marginRight: '2px' }}> - } + { }}> Cancel - {isSliced && <> + {isSliced && !AppStore.slice.isWorking && <> { return new Promise(resolve => { const worker = new Worker(bridge.assetsPath() + '/workers/slice.worker.bundle.js'); const canvas = new OffscreenCanvas(256, 256); - worker.onmessage = function (e) { + worker.onmessage = (e) => { + if (!_this.isWorking) + { + worker.terminate(); + resolve(true); + return; + } + switch (e.data.type) { case SliceWorkerResultType.SliceResult: @@ -125,12 +162,14 @@ export class SlicingStore { e.data.image.replace('data:image/png;base64,',''), (e.data.layer.i + 1)+'.png'); - if (reportStateCount >= reportStateCountMax) { - AppStore.instance.progressPercent = 1; - } - else { - AppStore.instance.progressPercent = (reportStateCount/reportStateCountMax); - } + runInAction(() => { + if (reportStateCount >= reportStateCountMax) { + AppStore.instance.progressPercent = 1; + } + else { + AppStore.instance.progressPercent = (reportStateCount/reportStateCountMax); + } + }); return; case SliceWorkerResultType.JobDone: worker.terminate(); @@ -171,58 +210,32 @@ export class SlicingStore { } }); - task.then(() => { - console.log('job done'); - }); - this.gcode += '\n\n;END_GCODE_BEGIN'; this.gcode += '\n' + AppStore.sceneStore.printer!.GCode.End .replace('*x', printer.Workspace.Height.toString()); this.gcode += '\n;END_GCODE_END'; - //this.finalize(false, false); + task.then(() => { + Log('slicing job done'); + if (this.isWorking) { + this.finalize(false, false); + } + }); }; public registrationReceivers = () => { const store = AppStore.sceneStore; - if (bridge.isWorker()) { - bridge.ipcRenderer.send('prepare-to-slicing-worker-ready'); - bridge.ipcRenderer.receive('prepare-to-slicing-worker-take-job', (json: string, workerJobs: { layer: number, percent: number }[]) => { - const obj = JSON.parse(json); - - console.log(obj, workerJobs); - - obj.sceneObjects.forEach((x: string) => { - const sceneObject = SceneObject.FromJson(x); - AppStore.sceneStore.objects.push(sceneObject); - AppStore.sceneStore.scene.add(sceneObject.mesh); - sceneObject.supports?.forEach(y => AppStore.sceneStore.scene.add(y)); - }); - - AppStore.sceneStore.setupPrinter(JSON.parse(obj.printer)); - AppStore.sceneStore.animate(true); - - //while (jobs.length > 0) - //{ - // const job = workerJobs.shift()!; - // this.image = AppStore.sceneStore.sliceLayer(job.percent, - // job.layer, SliceType.Normal); - //} - //bridge.ipcRenderer.send('sliced-layer-worker-done'); - }); - } - else { - bridge.ipcRenderer.receive('prepare-to-slicing-ready', () => { - this.reset(); - Log('prepare to slicing done!'); - this.isWorking = true; - const maxObjectsPoint = _.maxBy(store.objects, (x: SceneObject) => x.maxY.y); - const printer = AppStore.sceneStore.printer!; - this.sliceTo = Math.min(store.gridSize.y, maxObjectsPoint!.maxY.y); - this.sliceCountMax = Math.ceil(this.sliceTo / (printer.PrintSettings.LayerHeight * 0.1)); - this.sliceCount = 0; - this.gcode = `;fileName:${store.objects[0].name} + bridge.ipcRenderer.receive('prepare-to-slicing', () => { + this.reset(); + Log('prepare to slicing done!'); + this.isWorking = true; + const maxObjectsPoint = _.maxBy(store.objects, (x: SceneObject) => x.maxY.y); + const printer = AppStore.sceneStore.printer!; + this.sliceTo = Math.min(store.gridSize.y, maxObjectsPoint!.maxY.y); + this.sliceCountMax = Math.ceil(this.sliceTo / (printer.PrintSettings.LayerHeight * 0.1)); + this.sliceCount = 0; + this.gcode = `;fileName:${store.objects[0].name} ;machineType:${store.printer?.Name} ;estimatedPrintTime:${printer.PrintSettings.BottomExposureTime * printer.PrintSettings.BottomLayers + printer.PrintSettings.ExposureTime * this.sliceCountMax @@ -253,36 +266,35 @@ export class SlicingStore { ;bottomLayerLiftSpeed:${printer.PrintSettings.LiftingSpeed} ;bottomLightOffTime:0 ;lightOffTime:0`; - this.gcode += '\n\n;START_GCODE_BEGIN'; - this.gcode += '\n' + AppStore.sceneStore.printer!.GCode.Start; - this.gcode += '\n;START_GCODE_END'; - this.animate(); - Log('slice layers max: ' + this.sliceCountMax); - }); - bridge.ipcRenderer.receive('sliced-finalize-result-save', (error: string | null, success: string | null, filePath?: string) => { - if (error) { - Log(error); - } - if (success) { - config.pathToSave = filePath ?? config.pathToSave; - saveConfig(); - Log(success + ' to: ' + filePath); - AppStore.changeState(Pages.Main); - } - }); - bridge.ipcRenderer.receive('sliced-finalize-result', (error: string | null) => { - if (error) { - Log(error); - } + this.gcode += '\n\n;START_GCODE_BEGIN'; + this.gcode += '\n' + AppStore.sceneStore.printer!.GCode.Start; + this.gcode += '\n;START_GCODE_END'; + this.animate(); + Log('slice layers max: ' + this.sliceCountMax); + }); + bridge.ipcRenderer.receive('sliced-finalize-result-save', (error: string | null, success: string | null, filePath?: string) => { + if (error) { + Log(error, ConsoleColors.Error); + } + if (success) { + config.pathToSave = filePath ?? config.pathToSave; + saveConfig(); + Log(success + ' to: ' + filePath, ConsoleColors.Success); + AppStore.changeState(Pages.Main); + } + }); + bridge.ipcRenderer.receive('sliced-finalize-result', (error: string | null) => { + if (error && error !== 'done') { + Log(error, ConsoleColors.Error); + } - if (config.saveAutomatically) { - this.finalize(true, true); - } + if (config.saveAutomatically) { + this.finalize(true, true); + } - Log('slicing done!'); - this.isWorking = false; - }); - } + Log('slicing done!'); + this.isWorking = false; + }); }; } diff --git a/src/workers/slice.worker.ts b/src/workers/slice.worker.ts index ca7b3de..86b2798 100644 --- a/src/workers/slice.worker.ts +++ b/src/workers/slice.worker.ts @@ -1,14 +1,28 @@ import * as THREE from 'three'; import { AlwaysStencilFunc, - BackSide, BufferAttribute, BufferGeometry, DecrementWrapStencilOp, DoubleSide, DynamicDrawUsage, FrontSide, - Group, IncrementWrapStencilOp, Line3, LineBasicMaterial, LineSegments, Matrix4, - Mesh, MeshBasicMaterial, MeshLambertMaterial, + BackSide, + BufferAttribute, + BufferGeometry, + DecrementWrapStencilOp, + DoubleSide, + DynamicDrawUsage, + FrontSide, + Group, + IncrementWrapStencilOp, + Line3, + LineBasicMaterial, + LineSegments, + Matrix4, + Mesh, + MeshBasicMaterial, + MeshLambertMaterial, ObjectLoader, OrthographicCamera, Plane, Scene, - Vector2, Vector3, + Vector2, + Vector3, WebGLRenderer } from 'three'; import { LinearEncoding, NotEqualDepth } from 'three/src/constants'; @@ -37,6 +51,8 @@ const clippingPlaneMeshMin = new THREE.Mesh( new THREE.PlaneBufferGeometry(), clippingPlaneMeshMin.rotateX(Math.PI / 2); clippingPlaneMeshMin.renderOrder = 2; +scene.add(clippingPlaneMeshMin); +clippingPlaneMeshMin.visible = true; clippingPlaneMeshMin.scale.setScalar(1000000); onmessage = function (oEvent) {