!3022 修复: 1、删除模型材质相关bug 2、优化fbx材质相关功能3、材质动作:全部材质被锁定或者有实体材质锁,则不修改材质

pull/3032/MERGE
zc 1 month ago committed by 林三
parent e52521a7ab
commit c1d84a41c2

@ -209,8 +209,32 @@ export abstract class CompositeEntity extends Entity
};
}
GetPhyMtlRecords()
{
const materials: PhysicalMaterialRecord[] = [];
this.Traverse(e =>
{
if (e === this)
return;
const res = e.GetPhyMtlRecords();
if (res.length)
arrayPushArray(materials, res);
});
return materials;
}
UpdateDrawObjectMaterial(renderType: RenderType, obj: Object3D)
{
this.Traverse(e =>
{
if (e === this)
return;
let o = e.GetDrawObjectFromRenderType(renderType);
e.UpdateDrawObjectMaterial(renderType, o);
});
this.UpdateDrawObject(renderType, obj);
}

@ -138,6 +138,8 @@ export class Entity extends CADObject
if (materialId.Object.Db !== this.Db)
throw "程序内部错误!设置材质错误:不同图纸间材质";
}
const _obj = this._MaterialId?.Object;
if (_obj?.IsMaterialLock) return;
this.WriteAllObjectRecord();
this._MaterialId = materialId;
@ -145,7 +147,12 @@ export class Entity extends CADObject
this.UpdateDrawObjectMaterial(type, obj);
}
get Material() { return this._MaterialId; }
get Material()
{
if (this._MaterialId?.IsErase)
return;
return this._MaterialId;
}
GetMaterialSlots() { }
@ -173,6 +180,14 @@ export class Entity extends CADObject
};
}
GetPhyMtlRecords(): PhysicalMaterialRecord[]
{
const mtl = this.Material;
if (mtl?.Object)
return [mtl.Object];
return [];
}
get HasLayer() { return this._Layer?.Object !== undefined; }
get Layer(): ObjectId<LayerTableRecord>
@ -631,8 +646,9 @@ export class Entity extends CADObject
protected get MeshMaterial(): Material | Material[]
{
if (this._MaterialId && this._MaterialId.Object)
return (<PhysicalMaterialRecord>this._MaterialId.Object).Material as MeshStandardMaterial;
const mtlId = this._MaterialId;
if (!mtlId?.IsErase && mtlId?.Object)
return mtlId.Object.Material as MeshStandardMaterial;
return HostApplicationServices.DefaultMeshMaterial;
}

@ -109,12 +109,7 @@ export class EntityFbx extends Entity
return true;
const curMtl = this._OverWriteMaterial.get(slotIndex);
if (curMtl)
{
if (curMtl?.Object?.IsMaterialLock)
return true;
}
else if (this.Material?.Object?.IsMaterialLock)
if (curMtl?.Object?.IsMaterialLock)
return true;
return false;
}
@ -136,18 +131,33 @@ export class EntityFbx extends Entity
{
if (this.LockMaterial)
return;
this.WriteAllObjectRecord();
for (const [k, v] of this._OverWriteMaterial)
this.DrawObject.traverse(o =>
{
if (v?.Object?.IsMaterialLock)
continue;
this._OverWriteMaterial.set(k, mtl);
}
if (this.Material?.Object?.IsMaterialLock)
return;
if (o instanceof Mesh)
{
if (Array.isArray(o.material))
{
for (let i = 0; i < o.material.length; i++)
{
const curMtl = this._OverWriteMaterial.get(i);
if (curMtl?.Object?.IsMaterialLock)
continue;
this.Material = mtl;
this.WriteAllObjectRecord();
this._OverWriteMaterial.set(i, mtl);
}
}
else
{
const curMtl = this._OverWriteMaterial.get(0);
if (!curMtl?.Object?.IsMaterialLock)
{
this.WriteAllObjectRecord();
this._OverWriteMaterial.set(0, mtl);
}
}
}
});
this.Update(UpdateDraw.Material);
}
@ -187,6 +197,46 @@ export class EntityFbx extends Entity
};
}
private _GetValidOWMtlRecord(index: number): PhysicalMaterialRecord | undefined
{
const obj = this._OverWriteMaterial.get(index)?.Object;
if (obj && !obj.IsErase)
return obj;
return undefined;
}
// 注意不含默认的fbx材质record
GetPhyMtlRecords()
{
const materials: PhysicalMaterialRecord[] = [];
this.DrawObject.traverse(o =>
{
if (o instanceof Mesh)
{
if (Array.isArray(o.material))
{
let allUseOW = true;
for (let i = 0; i < o.material.length; i++)
{
const curMtl = this._GetValidOWMtlRecord(i);
if (curMtl)
materials.push(curMtl);
else
allUseOW = false;
}
}
else
{
const curMtl = this._GetValidOWMtlRecord(0);
if (curMtl)
materials.push(curMtl);
}
}
});
return materials;
}
newObject: Group;
//通过二进制数组生成fbx模型
@ -267,6 +317,14 @@ export class EntityFbx extends Entity
return this;
}
private _GetValidOWMtl(index: number): MeshPhysicalMaterial | undefined
{
const obj = this._OverWriteMaterial.get(index)?.Object;
const owMtl = !obj?.IsErase && obj?.Material;
if (!owMtl) return;
return owMtl;
}
//del_exp_start
InitDrawObject(renderType: RenderType = RenderType.Wireframe)
{
@ -277,11 +335,11 @@ export class EntityFbx extends Entity
const GetMaterial = (m: MeshPhongMaterial, index?: number) =>
{
let overMtl = this._OverWriteMaterial.get(index);
if (overMtl?.Object?.Material)
return overMtl.Object.Material;
const owMtl = this._GetValidOWMtl(index);
if (owMtl)
return owMtl;
else
return this.MeshMaterial ?? GetDefultFBXMaterial();
return GetDefultFBXMaterial();
};
if (this.newObject)
@ -442,7 +500,7 @@ export class EntityFbx extends Entity
{
for (let i = 0; i < o.material.length; i++)
{
const mtl = this._OverWriteMaterial.get(i)?.Object?.Material ?? this.MeshMaterial as MeshPhysicalMaterial;
const mtl = this._GetValidOWMtl(i);
if (mtl)
{
o.material[i] = mtl;
@ -461,7 +519,7 @@ export class EntityFbx extends Entity
}
else
{
const mtl = this._OverWriteMaterial.get(0)?.Object?.Material ?? this.MeshMaterial as MeshPhysicalMaterial;
const mtl = this._GetValidOWMtl(0);
if (mtl)
o.material = mtl;
else

@ -272,6 +272,41 @@ export class EntityRef extends Entity
};
}
private _GetValidOWMtlRecord(index: number): PhysicalMaterialRecord | undefined
{
const obj = this._OverWriteMaterial.get(index)?.Object;
if (obj && !obj.IsErase)
return obj;
return undefined;
}
GetPhyMtlRecords()
{
const materials: PhysicalMaterialRecord[] = [];
this.DrawObject.traverse(o =>
{
if (o instanceof Mesh)
{
if (Array.isArray(o.material))
{
for (let i = 0; i < o.material.length; i++)
{
const curMtl = this._GetValidOWMtlRecord(i);
if (curMtl)
materials.push(curMtl);
}
}
else
{
const curMtl = this._GetValidOWMtlRecord(0);
if (curMtl)
materials.push(curMtl);
}
}
});
return materials;
}
//del_exp_start
async FetchBox()
{
@ -392,9 +427,9 @@ export class EntityRef extends Entity
const GenMaterial = (mtl: MeshPhongMaterial, index?: number) =>
{
let overMtl = this._OverWriteMaterial.get(index);
if (overMtl?.Object?.Material)
return overMtl.Object.Material;
const owMtl = this._GetValidOWMtl(index);
if (owMtl)
return owMtl;
let p = this.mtlpromiseCache.get(mtl.name);
if (p) return p;
@ -476,6 +511,14 @@ export class EntityRef extends Entity
newObject.updateMatrixWorld(false);//保证更新位置
}
private _GetValidOWMtl(index: number): MeshPhysicalMaterial | undefined
{
const obj = this._OverWriteMaterial.get(index)?.Object;
const owMtl = !obj?.IsErase && obj?.Material;
if (!owMtl) return;
return owMtl;
}
UpdateDrawObjectMaterial(renderType: RenderType, obj: Object3D)
{
obj.traverse(o =>
@ -486,8 +529,8 @@ export class EntityRef extends Entity
{
for (let i = 0; i < o.material.length; i++)
{
let mtl = this._OverWriteMaterial.get(i)?.Object?.Material;
if (mtl)
const mtl = this._GetValidOWMtl(i);
if (mtl) // 没有被删除 并且有材质
{
o.material[i] = mtl;
if (mtl.transparent)
@ -522,7 +565,7 @@ export class EntityRef extends Entity
}
else
{
let mtl = this._OverWriteMaterial.get(0)?.Object?.Material;
const mtl = this._GetValidOWMtl(0);
if (mtl)
o.material = mtl;
else

@ -244,7 +244,7 @@ export class PhysicalMaterialRecord extends MaterialTableRecord
}
get IsMaterialLock()
{
return this._isMaterialLock;
return !this.IsErase && this._isMaterialLock;
}
set IsMaterialLock(v)
{

@ -85,8 +85,9 @@ export class BulkheadCeiling extends RoomBase
get MeshMaterial(): Material
{
if (this._MaterialId && this._MaterialId.Object)
return (<PhysicalMaterialRecord>this._MaterialId.Object).Material;
const mtl = this._MaterialId;
if (!mtl?.IsErase && mtl?.Object)
return mtl.Object.Material;
return HostApplicationServices.DefaultBulkheadCeilingMaterial;
}

@ -2,7 +2,6 @@ import { MeshStandardMaterial } from "three";
import { HostApplicationServices } from "../../../../ApplicationServices/HostApplicationServices";
import { Factory } from "../../../CADFactory";
import { CADFiler } from "../../../CADFiler";
import { PhysicalMaterialRecord } from "../../../PhysicalMaterialRecord";
import { RoomFlatBase } from "./RoomFlatBase";
@ -30,8 +29,9 @@ export class RoomFlatFloor extends RoomFlatBase
protected get MeshMaterial()
{
if (this._MaterialId && this._MaterialId.Object)
return (<PhysicalMaterialRecord>this._MaterialId.Object).Material as MeshStandardMaterial;
const mtl = this._MaterialId;
if (!mtl?.IsErase && mtl?.Object)
return mtl.Object.Material as MeshStandardMaterial;
return HostApplicationServices.DefaultFloorMaterial ?? HostApplicationServices.DefaultMeshMaterial;
}
}

@ -3,7 +3,6 @@ import { HostApplicationServices } from "../../../../ApplicationServices/HostApp
import { arrayPushArray } from "../../../../Common/ArrayExt";
import { AsVector3 } from "../../../../Geometry/GeUtils";
import { Factory } from "../../../CADFactory";
import { PhysicalMaterialRecord } from "../../../PhysicalMaterialRecord";
import { RoomFlatBase, UpdateTempPolyline } from "./RoomFlatBase";
@ -65,8 +64,9 @@ export class RoomFlatTop extends RoomFlatBase
protected get MeshMaterial()
{
if (this._MaterialId && this._MaterialId.Object)
return (<PhysicalMaterialRecord>this._MaterialId.Object).Material as MeshStandardMaterial;
const mtl = this._MaterialId;
if (!mtl?.IsErase && mtl?.Object)
return mtl.Object.Material as MeshStandardMaterial;
return HostApplicationServices.DefaultWallMaterial ?? HostApplicationServices.DefaultMeshMaterial;
}
}

@ -1,4 +1,4 @@
import { Color, Face3, Geometry, InstancedInterleavedBuffer, InterleavedBufferAttribute, LineSegments, Material, Matrix3, Mesh, MeshStandardMaterial, Object3D, ShapeUtils, Vector2, Vector3 } from "three";
import { Color, Face3, Geometry, InstancedInterleavedBuffer, InterleavedBufferAttribute, LineSegments, Material, Matrix3, Mesh, MeshPhysicalMaterial, MeshStandardMaterial, Object3D, ShapeUtils, Vector2, Vector3 } from "three";
import { Line2 } from "three/examples/jsm/lines/Line2";
import { LineGeometry } from "three/examples/jsm/lines/LineGeometry";
import { HostApplicationServices } from "../../../../../ApplicationServices/HostApplicationServices";
@ -512,7 +512,12 @@ export class RoomHolePolyline extends RoomHoleBase
super.Material = materialId;
}
get Material() { return this._MaterialId; }
get Material()
{
if (this._MaterialId?.IsErase)
return;
return this._MaterialId;
}
private _OverWriteMaterial = new Map<number, ObjectId<PhysicalMaterialRecord>>();//section index -> materialId
@ -590,11 +595,37 @@ export class RoomHolePolyline extends RoomHoleBase
};
}
GetPhyMtlRecords()
{
const materials: PhysicalMaterialRecord[] = [];
for (const [, v] of this._OverWriteMaterial)
{
if (!v?.IsErase && v?.Object)
materials.push(v.Object);
}
const meshSize = this.MeshMaterial.length;
if (this._OverWriteMaterial.size !== meshSize && super.Material?.Object)
materials.push(super.Material.Object);
return materials;
}
private _GetValidOWMtl(index: number): MeshPhysicalMaterial | undefined
{
const obj = this.OverWriteMaterial.get(index)?.Object;
const owMtl = !obj?.IsErase && obj?.Material;
if (!owMtl) return;
return owMtl;
}
protected get MeshMaterial(): Material[]
{
let defaultMtl: Material;
if (this._MaterialId && this._MaterialId.Object)
defaultMtl = (<PhysicalMaterialRecord>this._MaterialId.Object).Material as MeshStandardMaterial;
const mtlId = this._MaterialId;
if (!mtlId?.IsErase && mtlId?.Object)
defaultMtl = mtlId.Object.Material as MeshStandardMaterial;
else
defaultMtl = HostApplicationServices.DefaultWallMaterial ?? HostApplicationServices.DefaultMeshMaterial;
@ -603,7 +634,7 @@ export class RoomHolePolyline extends RoomHoleBase
if (this.LidCurves)
for (let c of this.LidCurves)
{
materials.push(this._OverWriteMaterial.get(materialIndex)?.Object.Material ?? defaultMtl);
materials.push(this._GetValidOWMtl(materialIndex) ?? defaultMtl);
materialIndex++;
}
@ -611,8 +642,8 @@ export class RoomHolePolyline extends RoomHoleBase
{
for (let r of this.LidCurves)
{
materials.push(this._OverWriteMaterial.get(materialIndex)?.Object.Material ?? defaultMtl);
materials.push(this._OverWriteMaterial.get(materialIndex + 1)?.Object.Material ?? defaultMtl);//地板?
materials.push(this._GetValidOWMtl(materialIndex) ?? defaultMtl);
materials.push(this._GetValidOWMtl(materialIndex + 1) ?? defaultMtl);//地板?
materialIndex += 2;;
}
}

@ -1,4 +1,4 @@
import { Material, Mesh, MeshStandardMaterial, Object3D, Line as TLine } from "three";
import { Material, Mesh, MeshPhysicalMaterial, MeshStandardMaterial, Object3D, Line as TLine } from "three";
import { HostApplicationServices } from "../../../../ApplicationServices/HostApplicationServices";
import { ColorMaterial } from "../../../../Common/ColorPalette";
import { UpdateDraw } from "../../../../Common/Status";
@ -188,13 +188,39 @@ export abstract class RoomWallBase extends RoomBase
};
}
GetPhyMtlRecords()
{
const materials: PhysicalMaterialRecord[] = [];
for (const [, v] of this.OverWriteMaterial)
{
if (!v?.IsErase && v?.Object)
materials.push(v?.Object);
}
const meshSize = this.MeshMaterials.length;
if (this.OverWriteMaterial.size !== meshSize && super.Material?.Object)
materials.push(super.Material.Object);
return materials;
}
protected get MeshMaterial()
{
if (this._MaterialId && this._MaterialId.Object)
return this._MaterialId.Object.Material as MeshStandardMaterial;
const mtlId = this._MaterialId;
if (!mtlId?.IsErase && mtlId?.Object)
return mtlId.Object.Material as MeshStandardMaterial;
return HostApplicationServices.DefaultWallMaterial ?? HostApplicationServices.DefaultMeshMaterial;
}
private _GetValidOWMtl(index: number): MeshPhysicalMaterial | undefined
{
const obj = this.OverWriteMaterial.get(index)?.Object;
const owMtl = !obj?.IsErase && obj?.Material;
if (!owMtl) return;
return owMtl;
}
get MeshMaterials(): Material[]
{
let defaultMtl = this.MeshMaterial;
@ -210,7 +236,7 @@ export abstract class RoomWallBase extends RoomBase
if (c[CURVE_FACE_TYPE_KEY] === WallFaceType.Outside)
continue;
materials.push(this.OverWriteMaterial.get(materialIndex)?.Object.Material ?? defaultMtl);
materials.push(this._GetValidOWMtl(materialIndex) ?? defaultMtl);
materialIndex++;
//这里不使用1
if (materialIndex === 1)
@ -227,9 +253,9 @@ export abstract class RoomWallBase extends RoomBase
if (this.Region)
{
materials.push(this.OverWriteMaterial.get(materialIndex)?.Object.Material ?? defaultMtl);
materials.push(this._GetValidOWMtl(materialIndex) ?? defaultMtl);
if (HostApplicationServices.DrawWallBottomFace)
materials.push(this.OverWriteMaterial.get(materialIndex + 1)?.Object.Material ?? defaultMtl);
materials.push(this._GetValidOWMtl(materialIndex + 1) ?? defaultMtl);
}
return materials;

@ -63,6 +63,8 @@ export class MaterialTable extends SymbolTable
Remove(record: PhysicalMaterialRecord)
{
this.WriteAllObjectRecord();
record.Erase();
return super.Remove(record);
}

@ -32,10 +32,10 @@ export class TemplateMaterialAction extends TemplateAction
let en = id.Object;
if (this.ApplyGoodInfo && en instanceof Board)
ApplyGoodInfo(en, this.parent.MaterialValue);
if (en.GetMtlLockedStatus().partMtlLocked || en.LockMaterial)
const lockStatus = en.GetMtlLockedStatus();
if (lockStatus.partMtlLocked || lockStatus.allMtlLocked || en.LockMaterial)
hasMaterialLock = true;
else
if (!(lockStatus.allMtlLocked || en.LockMaterial)) // 如果全部材质被锁定或者有实体材质锁,则不修改
en.SetAllMaterialAtSlot(this.parent.MaterialValue.Id);
}
@ -70,10 +70,10 @@ export class TemplateMaterialAction extends TemplateAction
if (this.ApplyGoodInfo && subE instanceof Board)
ApplyGoodInfo(subE, this.parent.MaterialValue);
if (subE.GetMtlLockedStatus().partMtlLocked || subE.LockMaterial)
const lockStatus = subE.GetMtlLockedStatus();
if (lockStatus.partMtlLocked || lockStatus.allMtlLocked || subE.LockMaterial)
hasMaterialLock = true;
else
if (!(lockStatus.allMtlLocked || subE.LockMaterial)) // 如果全部材质被锁定或者有实体材质锁,则不修改
subE.SetAllMaterialAtSlot(this.parent.MaterialValue.Id);
}
}

@ -10,6 +10,7 @@ import { IsMeshMaterialEntity } from '../../Common/IsMeshMaterialEntity';
import { Post, PostJson, RequestStatus } from '../../Common/Request';
import { MaterialOut, deflate } from '../../Common/SerializeMaterial';
import { Sleep } from '../../Common/Sleep';
import { UpdateDraw } from '../../Common/Status';
import { Intent } from '../../Common/Toaster';
import { Board } from '../../DatabaseServices/Entity/Board';
import { Entity } from '../../DatabaseServices/Entity/Entity';
@ -302,7 +303,16 @@ export class Asset extends React.Component<AssetProps, {}>
_HandleDelete = async () =>
{
let hasUsed = app.Database.ModelSpace.Entitys.some(e => (!e.IsErase && (e.Material?.Object ?? app.Database.DefaultMaterial) === this.props.material));
const mtl = this.props.material;
let hasUsed = app.Database.ModelSpace.Entitys.some(e =>
{
if (e.IsErase) return false;
if (!IsMeshMaterialEntity(e)) return false;
const allMtl = e.GetPhyMtlRecords() || [];
if (allMtl.includes(mtl))
return true;
});
let res = await AppConfirm.show({
intent: hasUsed ? Intent.DANGER : Intent.WARNING,
@ -312,10 +322,10 @@ export class Asset extends React.Component<AssetProps, {}>
CommandWrap(() =>
{
let brs = this._GetUseCurMtlEntitys();
let allEnt = this._GetUseCurMtlEntitys();
app.Database.MaterialTable.Remove(this.props.material as PhysicalMaterialRecord);
for (let br of brs)
br.Material = undefined;//回归默认
for (let en of allEnt)
en.Update(UpdateDraw.Material);
}, "删除材质");
};
@ -324,17 +334,17 @@ export class Asset extends React.Component<AssetProps, {}>
*/
_GetUseCurMtlEntitys()
{
let ents: Entity[] = [];
const ents: Entity[] = [];
const mtl = this.props.material;
for (let e of app.Database.ModelSpace.Entitys)
{
if (e.IsErase) continue;
if (!IsMeshMaterialEntity(e)) continue;
let mtl = e.Material?.Object as PhysicalMaterialRecord ?? app.Database.DefaultMaterial;
if (mtl === this.props.material)
const allMtl = e.GetPhyMtlRecords() || [];
if (allMtl.includes(mtl))
ents.push(e);
}

Loading…
Cancel
Save