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