FM/Assets/Test/v1.0/Render/RenderPrintingManager.cs

252 lines
8.6 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
using Cysharp.Threading.Tasks;
using HK;
using HK.FUJIFILM;
using UnityEngine;
public class RenderPrintingManager : MonoBehaviour
{
public static RenderPrintingManager Instance;
[SerializeField] Camera renderCam;
[SerializeField] Transform parent;
RenderPrintingManagerOption option;
// RenderPrintingManagerModelOption modelOption;
private RenderTexture rendtx;
string dirPath = Path.Combine(Application.dataPath, "TestPic");
public string FolderPath;
private bool isSaveFinished;
public bool IsSaveFinished => isSaveFinished;
private void Awake()
{
Instance = this;
var path = Path.Combine(Application.streamingAssetsPath, "PrintingSavePath.txt");
if (File.Exists(path) && !string.IsNullOrEmpty(File.ReadAllText(path)))
dirPath = File.ReadAllText(path);
if (!Directory.Exists(dirPath))
{
Directory.CreateDirectory(dirPath);
}
}
private void Update()
{
// if (Input.GetKeyDown(KeyCode.K))
// {
// StartCoroutine(WaitSavePreview());
// }
//
// if (Input.GetKeyDown(KeyCode.L))
// {
// StartCoroutine(WaitSavePrinting());
// }
}
public void StartRenderPrinting(GameObject preview, GameObject design,
Action<byte[], List<byte[]>, string, List<string>> callback = null)
{
isSaveFinished = false;
var i = PlayerPersistent.GetInt("OrderID");
FolderPath = Path.Combine(dirPath, $"OrderID_{i}_{DateTime.Now.Ticks}");
if (!Directory.Exists(FolderPath))
{
Directory.CreateDirectory(FolderPath);
}
previewData = new byte[] { };
printingDatas = new List<byte[]>();
previewName = "";
printingNames = new List<string>();
StartCoroutine(WaitSaveFinish(preview, design, callback));
}
byte[] previewData;
List<byte[]> printingDatas;
private string previewName;
private List<string> printingNames;
IEnumerator WaitSaveFinish(GameObject preview, GameObject design,
Action<byte[], List<byte[]>, string, List<string>> callback)
{
if (preview != null)
yield return StartCoroutine(WaitSavePreview(preview));
var designGo = GameObject.Instantiate(design, parent);
this.option = designGo.GetComponent<RenderPrintingManagerOption>();
option.GetComponent<RenderPrintingManagerOptionHelper>().ShowAllPrintings();
option.GetComponent<RenderPrintingManagerOptionHelper>().HideAllPrintings();
yield return null;
for (var i = 0; i < option.objectsToRender.Count; i++)
{
foreach (var t in option.objectsToRender)
{
t.gameObject.SetActive(false);
}
option.objectsToRender[i].gameObject.SetActive(true);
yield return StartCoroutine(WaitSavePrinting(designGo));
}
GameObject.Destroy(designGo);
callback?.Invoke(previewData, printingDatas, previewName, printingNames);
isSaveFinished = true;
}
IEnumerator WaitSavePreview(GameObject preview)
{
var previewGo = GameObject.Instantiate(preview, parent);
previewGo.GetComponent<RectTransform>().anchoredPosition = Vector2.zero;
var modelOption = previewGo.GetComponent<RenderPrintingManagerOption>();
modelOption.GetComponent<RenderPrintingManagerOptionHelper>().ShowAllPreviews();
modelOption.GetComponent<RenderPrintingManagerOptionHelper>().HideAllPreviews();
yield return null;
float smallerScale = Mathf.Max(modelOption.renderPreviewSize.x / 400f, modelOption.renderPreviewSize.y / 400f);
rendtx = new RenderTexture((int)(modelOption.renderPreviewSize.x / smallerScale),
(int)(modelOption.renderPreviewSize.y / smallerScale), 24,
RenderTextureFormat.ARGB32);
modelOption.pivot.transform.localScale = Vector3.one / smallerScale;
renderCam.targetTexture = rendtx;
yield return null;
Texture2D tex = ToTexture2D(rendtx);
var bytes = tex.EncodeToPNG();
var fileName = $"Preview - {DateTime.Now.Ticks}.png";
var path = Path.Combine(FolderPath, fileName);
previewName = fileName;
// yield return File.WriteAllBytesAsync(path, bytes);
bool isWriteDone = false;
Task.Run(() =>
{
// 后台线程:仅处理纯文件写入(无引擎资源操作)
File.WriteAllBytes(path, bytes);
// 标记完成线程安全因为bool是原子操作
isWriteDone = true;
});
// 主线程:等待后台线程完成(用循环+yield return null避免死等
while (!isWriteDone)
{
yield return null; // 每帧检查一次,不阻塞主线程
}
previewData = bytes;
Debug.Log("Preview finish");
rendtx.Release();
GameObject.Destroy(previewGo);
}
IEnumerator WaitSavePrinting(GameObject design)
{
option.pivot.GetComponent<RectTransform>().anchoredPosition = Vector2.zero;
option.pivot.transform.localScale = Vector3.one;
Vector2 printSize = option.renderPrintSize.x == 0 ? option.renderPreviewSize : option.renderPrintSize;
rendtx = new RenderTexture((int)printSize.x, (int)printSize.y, 24, RenderTextureFormat.ARGB32);
renderCam.targetTexture = rendtx;
yield return null;
Texture2D print_tex = ToTexture2D(rendtx);
// string uploadTmp = ;
yield return StartCoroutine(SpecialSaveImageFile(print_tex, "printing"));
// var fileInfo = new FileInfo(uploadTmp);
// var cutBG = fileInfo.Directory.FullName + $"cut bg {fileInfo.Name}";
// TODO:褪底功能
// yield return StartCoroutine(Wait(uploadTmp, cutBG));
// Debug.Log(cutBG);
Debug.Log("finish");
}
private IEnumerator SpecialSaveImageFile(Texture2D tex, string name)
{
byte[] bytes = tex.EncodeToPNG();
if (!Directory.Exists(FolderPath))
{
Directory.CreateDirectory(FolderPath);
}
Debug.Log(FolderPath);
var nowTicks = DateTime.Now.Ticks;
var fileName = $"printing-{nowTicks}.png";
string filePath = Path.Combine(FolderPath, fileName);
var changePpi = B83.Image.PNGTools.ChangePPI(bytes, 300, 300);
// File.WriteAllBytes(outputPath, changePpi);
yield return StartCoroutine(PngCompressor.CompressPngAndSetDpiAsync1(changePpi, filePath));
printingNames.Add(fileName);
printingDatas.Add(File.ReadAllBytes(filePath));
// string tmpPath = filePath;
// File.WriteAllBytes(tmpPath, B83.Image.PNGTools.ChangePPI(bytes, 300, 300));
// return tmpPath;
}
Texture2D ToTexture2D(RenderTexture rTex)
{
RenderTexture currentActiveRT = RenderTexture.active;
Texture2D tex = new Texture2D(rTex.width, rTex.height, TextureFormat.ARGB32, false);
RenderTexture.active = rTex;
tex.ReadPixels(new Rect(0, 0, rTex.width, rTex.height), 0, 0);
tex.Apply();
RenderTexture.active = currentActiveRT;
return tex;
}
IEnumerator WaitCutBG(string filePath, string transferPath)
{
string currentDirectory = Directory.GetCurrentDirectory();
string savePath = Path.Combine(currentDirectory, "temp");
if (!Directory.Exists(savePath))
{
Directory.CreateDirectory(savePath);
}
string fileName = "downloadedTexture.png";
string transferName = "transferTexture.png";
string path1 = Path.Combine(savePath, fileName);
File.Copy(filePath, path1, true);
string path2 = Path.Combine(savePath, transferName);
Debug.Log($"file path: {path1}");
Debug.Log($"transfer path: {path2}");
var startInfo = new System.Diagnostics.ProcessStartInfo
{
FileName = "python",
Arguments = $"cutbg.py \"{path1}\" \"{path2}\"",
RedirectStandardOutput = true,
RedirectStandardError = true,
UseShellExecute = false,
CreateNoWindow = true
};
System.Diagnostics.Process process = new System.Diagnostics.Process
{
StartInfo = startInfo
};
Debug.Log("Start");
process.Start();
process.WaitForExit();
// while (!process.HasExited)
// {
// yield return null;
// }
yield return null;
}
}