diff --git a/src/components/blender-controller.ts b/src/components/blender-controller.ts index f146829..231b704 100644 --- a/src/components/blender-controller.ts +++ b/src/components/blender-controller.ts @@ -2,11 +2,11 @@ import { blenderPath, blenderScriptPath, dataPath, templatePath } from "./paths" import {spawn} from "child_process"; import logger from "./logger"; import { setBlenderLoading, setBlenderStatus } from "./ui/menu"; -import { setLogNumber, setStatus } from "./ui/renderingSide"; +import { setLogNumber, setRenderDisplayProgress, setStatus } from "./ui/renderingSide"; import {imageLoading, imageLoaded} from "./ui/settingsSide"; -import { settingList } from "./settings"; +import { getLogList, getLogSize, settingList } from "./settings"; import isValid from "is-valid-path"; -import { sideSetRendering } from "../renderer"; +import { sideSetRendering, setProgress } from "../renderer"; import { ipcRenderer } from "electron"; const blenderStartString = [ @@ -26,9 +26,25 @@ let renderingPicture = false; let renderingVideo = false; let waitingForRender = false; +let logPortionList:number[] = []; +let currentLogPortion = 0; + +const estimatedRenderPortion = 0.97; +function setRenderProgress(log:number, init:boolean, frameCount:number, frame:number) { + let progress = 0; + if(init) { + progress = logPortionList[log-1] * (frame / frameCount * (1 - estimatedRenderPortion)) + currentLogPortion; + } else { + progress = logPortionList[log-1] * (frame / frameCount * estimatedRenderPortion + (1 - estimatedRenderPortion)) + currentLogPortion; + } + setProgress(progress); + setRenderDisplayProgress(parseFloat((progress*100).toFixed(2))); +} + function startBlender() { let frames = "0"; let lastFrame = "0"; + let log = "0"; blenderConsole.stdout.on('data', function(data) { const dataStr = data.toString(); @@ -52,6 +68,7 @@ function startBlender() { renderingVideo = false; setBlenderStatus("Restarting"); setBlenderLoading(true); + setProgress(); restartBlender(); } @@ -59,10 +76,12 @@ function startBlender() { frames = dataStr.split(":")[1]; renderingVideo = true; readyToAcceptCommand = false; + setRenderProgress(parseInt(log), true, 0, 0); } if(dataStr.includes("Fra:") && renderingVideo) { lastFrame = dataStr.split(":")[1].split(" ")[0]; setStatus("Rendering Frame " + lastFrame + "/" + frames); + setRenderProgress(parseInt(log), false, parseInt(frames), parseInt(lastFrame)); } if(dataStr.includes("Finished") && renderingVideo) { sideSetRendering(false); @@ -74,13 +93,19 @@ function startBlender() { } if(dataStr.includes("Init:") && renderingVideo) { setStatus("Initialize Frame " + dataStr.split(":")[1] + "/" + frames); + setRenderProgress(parseInt(log), true, parseInt(frames), parseInt(dataStr.split(":")[1])); } if(dataStr.includes("Lognr:") && renderingVideo) { - setLogNumber(dataStr.split(":")[1]); + log = dataStr.split(":")[1]; + if(log !== "1") { + currentLogPortion += logPortionList[parseInt(log)-2]; + } + setLogNumber(log); } if(dataStr.includes("Waiting for command")) { sideSetRendering(false); + setProgress(); if(renderingPicture) { imageLoaded(); @@ -140,6 +165,23 @@ function blender(command:blenderCmd) { } else if(!isValid(settingList.log)) { logger.warningMSG("Output path is invalid!"); } else { + currentLogPortion = 0; + + const logSizeList:number[] = []; + getLogList().forEach(function (value, index) { + logSizeList.push(getLogSize(index)); + }); + + let fullLogSize = 0; + for(let i = 0; i < logSizeList.length; i++) { + fullLogSize += logSizeList[i]; + } + + logPortionList = []; + logSizeList.forEach(function (value) { + logPortionList.push(value / fullLogSize); + }); + readyToAcceptCommand = false; renderingVideo = true; sideSetRendering(true); diff --git a/src/components/settings.ts b/src/components/settings.ts index e301578..626af49 100644 --- a/src/components/settings.ts +++ b/src/components/settings.ts @@ -94,8 +94,20 @@ function settingListLoadDefault() { }); } +function getLogList() { + return settingList.log.split("\"\""); +} + +function getLogSize(index:number) { + const logList = settingList.log.substring(1).slice(0, -1).split('""'); + + return fs.statSync(logList[index]).size; +} + export { updateSettings, settingListLoadDefault, settingList, + getLogList, + getLogSize } \ No newline at end of file diff --git a/src/components/ui/renderingSide.tsx b/src/components/ui/renderingSide.tsx index a1d63d8..fc803e7 100644 --- a/src/components/ui/renderingSide.tsx +++ b/src/components/ui/renderingSide.tsx @@ -1,21 +1,30 @@ import React, {useState} from "react"; -import { settingList } from "../settings"; +import { settingList, getLogList } from "../settings"; import openFolder from "../openFolder"; import { blenderCmd, blender } from "../blender-controller"; let setLogNumber:React.Dispatch>; let setStatus:React.Dispatch>; +let setRenderDisplayProgress:React.Dispatch>; function RenderingSide() { const [logNumber, setLogNumberInner] = useState("0"); setLogNumber = setLogNumberInner; const [status, setStatusInner] = useState("Idle"); setStatus = setStatusInner; + const [renderDisplayProgress, setRenderDisplayProgressInner] = useState(0); + setRenderDisplayProgress = setRenderDisplayProgressInner; return (
-

{"Log " + logNumber + "/" + String(settingList.log.split("\"\"").length)}

+

{"Log " + logNumber + "/" + getLogList().length}

{status}

+
+
+ +
@@ -25,5 +34,6 @@ function RenderingSide() { export default RenderingSide; export { setLogNumber, - setStatus + setStatus, + setRenderDisplayProgress }; \ No newline at end of file diff --git a/src/index.css b/src/index.css index b6179ba..aa4ecac 100644 --- a/src/index.css +++ b/src/index.css @@ -332,7 +332,6 @@ button:hover { border-top-left-radius: 18px; border-bottom-left-radius: 18px; font-weight: bolder; - text-shadow: #0d131e 1px 1px 1px; } #settingRow { @@ -373,4 +372,37 @@ button:hover { #winMinimize { margin-left: 5px; +} + +.progress { + height: 25px; + width: 100%; + background-color: #0d131e; + border-radius: 15px; + margin-bottom: 20px; + position: relative; + overflow: hidden; +} +.progress-done { + height: 100%; + background: repeating-linear-gradient( + -45deg, + #2196F3, + #2196F3 10px, + #0b6ab9 10px, + #0b6ab9 20px + ); + border-radius: 15px; + transition: width 1s; +} +.progress label { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + display: flex; + justify-content: center; + align-items: center; + font-size: large; } \ No newline at end of file diff --git a/src/index.ts b/src/index.ts index 345f3cd..c87f747 100644 --- a/src/index.ts +++ b/src/index.ts @@ -68,6 +68,9 @@ const createWindow = () => { }); mainWindow.setMenu(null); + if (process.env.NODE_ENV === 'development') { + mainWindow.webContents.openDevTools(); + } remoteInitialize(); remoteEnable(mainWindow.webContents); @@ -102,6 +105,10 @@ const createWindow = () => { } }); + ipcMain.on('setProgress', (event, arg) => { + mainWindow.setProgressBar(parseFloat(arg)); + }); + mainWindow.on('close', () => { mainWindow.webContents.send('closeApp'); }); diff --git a/src/renderer.tsx b/src/renderer.tsx index c9c41c3..ebfd2ab 100644 --- a/src/renderer.tsx +++ b/src/renderer.tsx @@ -7,6 +7,7 @@ import RenderingSide from "./components/ui/renderingSide"; import "./index.css"; import "./toggle-switchy.css"; import { startBlender } from "./components/blender-controller"; +import {ipcRenderer} from "electron"; enum Side { Main, @@ -50,9 +51,18 @@ function sideSetRendering(value:boolean) { } } } + +function setProgress(value?:number) { + if(value === undefined) { + ipcRenderer.send("setProgress", -1); + } else { + ipcRenderer.send("setProgress", value); + } +} export { openSide, Side, - sideSetRendering + sideSetRendering, + setProgress } \ No newline at end of file