You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
WebCAD/src/Common/SerializeMaterial.ts

307 lines
8.4 KiB

import pako from "pako";
import { Color, Matrix4, Scene, Vector2, Vector3 } from "three";
import { Purge } from "../Add-on/Purge";
import { app } from "../ApplicationServices/Application";
import { HostApplicationServices } from "../ApplicationServices/HostApplicationServices";
import { ExtrudeHole } from "../DatabaseServices/3DSolid/ExtrudeHole";
import { CADFiler } from "../DatabaseServices/CADFiler";
import { Database } from "../DatabaseServices/Database";
import { Entity } from "../DatabaseServices/Entity/Entity";
import { Polyline } from "../DatabaseServices/Entity/Polyline";
import { PhysicalMaterialRecord } from "../DatabaseServices/PhysicalMaterialRecord";
import { TemplateParam } from "../DatabaseServices/Template/Param/TemplateParam";
import { TemplateRecord } from "../DatabaseServices/Template/TemplateRecord";
import { AsVector2 } from "../Geometry/GeUtils";
import { RenderType } from "../GraphicsSystem/RenderType";
import { userConfig } from './../Editor/UserConfig';
import { DisposeThreeObj } from "./Dispose";
import { uploadLogo } from "./Request";
import { DuplicateRecordCloning } from "./Status";
import { AAType } from "./SystemEnum";
export function MaterialOut(material: PhysicalMaterialRecord): string
{
let db = new Database();
db.WblockCloneObejcts(
[material],
db.MaterialTable,
new Map(),
DuplicateRecordCloning.Ignore
);
return JSON.stringify(db.FileWrite().Data);
}
export function MaterialIn(fileData: Object[]): PhysicalMaterialRecord
{
let f = new CADFiler(fileData);
let db = new Database().FileRead(f);
db.hm.Enable = false;
return db.MaterialTable.Symbols.entries().next().value[1];
}
export function TemplateOut(template: TemplateRecord, tempDb = new Database(false, false, true))
{
template = template.Root;
let idMap = new Map();
tempDb.WblockCloneObejcts([template], tempDb.TemplateTable, idMap, DuplicateRecordCloning.Ignore);
Purge(tempDb);
let scs = template.GetTemplateRealitySpaceCS();
let scsInv = new Matrix4().getInverse(scs);
for (let en of tempDb.ModelSpace.Entitys)
en.ApplyMatrix(scsInv);
for (let l of tempDb.Lights.Entitys)
if (l.Id.Index > 99)
l.ApplyMatrix(scsInv);
return JSON.stringify(tempDb.FileWrite().Data);
}
export function TemplateIn(fileData: Object[]): TemplateRecord
{
let f = new CADFiler(fileData);
let db = new Database(false, false, true).FileRead(f);
return db.TemplateTable.Objects[0].Root;
}
export function TemplateParamsOut(params: TemplateParam[])
{
let dataList = [];
for (let par of params)
{
let filer = new CADFiler();
par.WriteFile(filer);
dataList.push(filer.Data);
}
return JSON.stringify(dataList);
}
export function TemplateParamsIn(paramsData: Object[][])
{
let pars: TemplateParam[] = [];
for (let data of paramsData)
{
let file = new CADFiler(data);
let par = new TemplateParam();
par.ReadFile(file);
pars.push(par);
}
return pars;
}
/**反序列化材质并加入图纸*/
export function MaterialInAndAppendAppData(fileData: Object[], name?: string): PhysicalMaterialRecord
{
let mtl = MaterialIn(fileData) as PhysicalMaterialRecord;
if (name)
mtl.Name = name;
return app.Database.WblockCloneObejcts(
[mtl],
app.Database.MaterialTable,
new Map(),
DuplicateRecordCloning.Rename
)[0] as PhysicalMaterialRecord;
}
export function deflate(data: string)
{
let binaryString = pako.deflate(data, { to: "string" });
let base64 = btoa(binaryString);
return base64;
}
export function inflate(base64: string)
{
let binaryString = atob(base64);
let data = pako.inflate(binaryString, { to: "string" });
return data;
}
export function dataURItoBlob(dataURI: string)
{
// convert base64 to raw binary data held in a string
// doesn't handle URLEncoded DataURIs - see SO answer #6850276 for code that does this
var byteString = atob(dataURI.split(',')[1]);
// separate out the mime component
var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];
// write the bytes of the string to an ArrayBuffer
var ab = new ArrayBuffer(byteString.length);
// create a view into the buffer
var ia = new Uint8Array(ab);
// set the bytes of the buffer to the correct values
for (var i = 0; i < byteString.length; i++)
{
ia[i] = byteString.charCodeAt(i);
}
// write the ArrayBuffer to a blob, and you're done
var blob = new Blob([ab], { type: mimeString });
return blob;
}
export function toplineFileIn(json: string)
{
let data = JSON.parse(json);
let f = new CADFiler(data);
let pl = new Polyline();
pl.ReadFile(f);
return pl;
}
export function getPolylineSVG(en: Polyline)
{
let pl = en.Clone();
pl.OCS = new Matrix4();
//Y镜像
for (let d of pl.LineData)
{
d.pt.y = -d.pt.y;
d.bul = -d.bul;
}
let box = pl.BoundingBox;
let size = box.getSize(new Vector3());
let maxEdgeLength = Math.max(size.x, size.y);
let m = AsVector2(pl.BoundingBox.min);//移动到0点
let scale = 90 / maxEdgeLength;//缩放到90,避免图形和边缘重合
let m2 = new Vector2((100 - scale * size.x) / 2, (100 - scale * size.y) / 2);//居中移动
for (let d of pl.LineData)
{
d.pt.sub(m);//移动到0
d.pt.multiplyScalar(scale);
d.pt.add(m2);//居中
}
return pl.SVG;
}
/**
* 获取当前图纸的缩略图(预览图)
*/
export function GetCurrentViewPreViewImage(restore = true, isBase64 = false): Blob | string
{
//生成预览图
app.Viewer.OnSize(400, 400);
app.Viewer.Render();
let url = app.Viewer.Renderer.domElement.toDataURL(isBase64 ? "image/png" : "image/jpeg");
if (restore)
{
app.Viewer.OnSize();
app.Viewer.Render();
}
if (isBase64)
return url;
return dataURItoBlob(url);
}
export function ExtrudeDrillFileIn(data: any[])
{
let f = new CADFiler(data);
let en = new ExtrudeHole();
en.ReadFile(f);
return en;
}
//返回logo url
export async function GetEntitysLogo(ens: Entity[], isConceptual = false, dir = new Vector3(1, 1, -1), isBase64 = false)
{
//备份视图
let sceneBak = app.Viewer.Scene;
let renderTypeBak: RenderType;
let clearColorBak: Color;
if (isConceptual)
{
renderTypeBak = userConfig.RenderType;
HostApplicationServices._renderType = RenderType.Conceptual;
clearColorBak = app.Viewer.Renderer.getClearColor().clone();
app.Viewer.Renderer.setClearColor(new Color());
}
let aabak = app.Viewer.AAType;
let f = new CADFiler();
app.Viewer.CameraCtrl.WriteFile(f);
//设置视图
app.Viewer.Scene = new Scene();
app.Viewer._AAType = AAType.SMAA;
app.Viewer.CameraCtrl.LookAt(dir);
//绘制
for (let e of ens)
app.Viewer.Scene.add(e.DrawObject);
app.Viewer.ZoomAll(false);
let blob = GetCurrentViewPreViewImage(false, isBase64);
//还原视图
[app.Viewer.Scene, sceneBak] = [sceneBak, app.Viewer.Scene];
if (isConceptual)
{
HostApplicationServices._renderType = renderTypeBak;
app.Viewer.Renderer.setClearColor(clearColorBak);
}
app.Viewer._AAType = aabak;
f.Reset();
app.Viewer.CameraCtrl.ReadFile(f);
app.Viewer.OnSize();
DisposeThreeObj(sceneBak);
if (isBase64)
return blob;
//上传
let logo = await uploadLogo(blob as Blob);
return logo;
}
export function GroupOut(ens: Entity[])
{
let file = new CADFiler();
file.Write(ens.length);
for (let e of ens)
{
file.WriteObject(e);
}
return JSON.stringify(file.Data);
}
export function GroupFileIn(fileData: Object[]): Entity[]
{
let f = new CADFiler(fileData);
let count = f.Read();
let ens: Entity[] = [];
for (let i = 0; i < count; i++)
{
let en = f.ReadObject() as Entity;
ens.push(en);
}
return ens;
}
export function EntitysOut(ens: Entity[], callback?: (en) => void)
{
let dataList = [];
for (let en of ens)
{
let vf = new CADFiler();
if (callback)
callback(en);
en.WriteFile(vf);
dataList.push(vf.Data);
}
return JSON.stringify(dataList);
}
export function EntitysIn(datalist: any[])
{
let ens: Entity[] = [];
for (let data of datalist)
ens.push(ExtrudeDrillFileIn(data));
return ens;
}