diff --git a/src/Add-on/DropMaterialApply.ts b/src/Add-on/DropMaterialApply.ts index e3252759a..11f2d128e 100644 --- a/src/Add-on/DropMaterialApply.ts +++ b/src/Add-on/DropMaterialApply.ts @@ -38,7 +38,7 @@ export async function DropMaterialApply(pt: Vector3, getMtlFunction: () => Promi let mtl = await getMtlFunction(); if (!mtl) return; - ApplyMtlToSelectedObjs(mtl, selectObj, raycaster); + ApplyMtlToSelectedObjs(mtl, selectObj); }, "拽拖材质应用"); } } diff --git a/src/Common/ApplyMaterial.ts b/src/Common/ApplyMaterial.ts index 95b50764b..027c5f07f 100644 --- a/src/Common/ApplyMaterial.ts +++ b/src/Common/ApplyMaterial.ts @@ -2,8 +2,8 @@ import { Intent } from "@blueprintjs/core"; import { Curve, Intersection, Object3D, Raycaster } from "three"; import { app } from "../ApplicationServices/Application"; import { Board } from "../DatabaseServices/Entity/Board"; +import { CompositeEntity } from "../DatabaseServices/Entity/CompositeEntity"; import { Entity } from "../DatabaseServices/Entity/Entity"; -import { HardwareCompositeEntity } from "../DatabaseServices/Hardware/HardwareCompositeEntity"; import { PhysicalMaterialRecord } from "../DatabaseServices/PhysicalMaterialRecord"; import { BulkheadCeiling } from "../DatabaseServices/Room/Entity/Ceiling/BulkheadCeiling"; import { Text } from "../DatabaseServices/Text/Text"; @@ -11,7 +11,6 @@ import { CommandWrap } from "../Editor/CommandMachine"; import { Raycast } from "../Editor/PointPick"; import { userConfig } from "../Editor/UserConfig"; import { VisualSpaceBox } from "../Editor/VisualSpaceBox"; -import { RenderType } from "../GraphicsSystem/RenderType"; import { ApplyGoodInfo } from "../UI/Components/ApplyGoodInfo"; import { AppToaster } from "../UI/Components/Toaster"; import { CommandNames } from "./CommandNames"; @@ -94,38 +93,38 @@ export function ApplyMtlToSelectEntityList(material: PhysicalMaterialRecord, can app.Viewer.UpdateRender(); } +const GetEntFromComEntByRaycaster = (compositeEnt: CompositeEntity, raycaster: Raycaster, FilterTypes: any[] = []): Entity | undefined => +{ + let hwdEnts: Entity[] = []; + let en: Entity; + compositeEnt.Traverse((childrenEnt => + { + if (childrenEnt && childrenEnt !== compositeEnt && !childrenEnt.IsErase && !FilterTypes.some(T => childrenEnt instanceof T)) + hwdEnts.push(childrenEnt); + })); + + let objects = hwdEnts.map(childrenEnt => childrenEnt.GetDrawObjectFromRenderType(userConfig.RenderType)); + let intersection = Raycast(raycaster, objects, { filterErase: true }); + + let obj = intersection?.object; + if (obj) + { + let index = objects.findIndex(o => o === obj); + if (index !== -1 && hwdEnts[index]) + en = hwdEnts[index]; + } + return en; +}; + /** * 应用材质到射线相交处的面 * @param material 材质 * @param en 实体 * @param intersection 射线相交信息 + * @param raycaster 射线 */ export function ApplyPartMtlToInterFace(material: PhysicalMaterialRecord, en: Entity, intersection: Intersection, raycaster: Raycaster) { - if (en instanceof HardwareCompositeEntity) - { - let hwdEnts: Entity[] = []; - en.Traverse((childrenEnt => - { - if (childrenEnt && childrenEnt !== en && !childrenEnt.IsErase && !FilterTypes.some(T => childrenEnt instanceof T)) - hwdEnts.push(childrenEnt); - })); - - let objects = hwdEnts.map(childrenEnt => childrenEnt.GetDrawObjectFromRenderType(RenderType.Physical)); - let intersection = Raycast(raycaster, objects, { filterErase: true }); - - let obj = intersection?.object; - if (obj) - { - let index = objects.findIndex(o => o === obj); - if (index !== -1 && hwdEnts[index]) - { - en.WriteAllObjectRecord(); - en = hwdEnts[index]; - } - } - } - if (en.LockMaterial) { LockMtlToaster(1, true); @@ -134,6 +133,20 @@ export function ApplyPartMtlToInterFace(material: PhysicalMaterialRecord, en: En if (IsMeshMaterialEntity(en)) { + if (en instanceof CompositeEntity) + { + en = GetEntFromComEntByRaycaster(en, raycaster, FilterTypes); + if (!en) + { + console.log("发生未知错误,未能找到复合实体中的子实体"); + return; + } + if (en.LockMaterial) + { + LockMtlToaster(1, true); + return; + } + } if (en.IsMtlLockAtSlot(intersection.face.materialIndex)) LockMtlToaster(1, false, false, true); else @@ -151,7 +164,7 @@ export function ApplyPartMtlToInterFace(material: PhysicalMaterialRecord, en: En * @param {PhysicalMaterialRecord} material 材质 * @param {Object3D[]} selectedObj 选中的实体 */ -export function ApplyMtlToSelectedObjs(material: PhysicalMaterialRecord, selectedObj: Object3D[], raycaster: Raycaster) +export function ApplyMtlToSelectedObjs(material: PhysicalMaterialRecord, selectedObj: Object3D[]) { let meshMaterialCount = 0; const entMap = new Map(); @@ -166,30 +179,6 @@ export function ApplyMtlToSelectedObjs(material: PhysicalMaterialRecord, selecte if (entMap.get(en)) continue; entMap.set(en, true); - if (en instanceof HardwareCompositeEntity) - { - let hwdEnts: Entity[] = []; - en.Traverse((childrenEnt => - { - if (childrenEnt && !childrenEnt.IsErase && !FilterTypes.some(T => childrenEnt instanceof T)) - hwdEnts.push(childrenEnt); - })); - - let objects = hwdEnts.map(childrenEnt => childrenEnt.GetDrawObjectFromRenderType(RenderType.Physical)); - let intersection = Raycast(raycaster, objects, { filterErase: true }); - - let obj = intersection?.object; - if (obj) - { - let index = objects.findIndex(o => o === obj); - if (index !== -1 && hwdEnts[index]) - { - en.WriteAllObjectRecord(); - en = hwdEnts[index]; - } - } - } - if (en.LockMaterial) { hasEntMtlLocked = true; diff --git a/src/DatabaseServices/Entity/CompositeEntity.ts b/src/DatabaseServices/Entity/CompositeEntity.ts index 051dd5c68..c0ba60168 100644 --- a/src/DatabaseServices/Entity/CompositeEntity.ts +++ b/src/DatabaseServices/Entity/CompositeEntity.ts @@ -9,6 +9,8 @@ import { RenderType } from "../../GraphicsSystem/RenderType"; import { AutoRecord } from "../AutoRecord"; import { Factory } from "../CADFactory"; import { CADFiler } from "../CADFiler"; +import { ObjectId } from "../ObjectId"; +import { PhysicalMaterialRecord } from "../PhysicalMaterialRecord"; import { DragPointType } from "./DragPointType"; import { Entity } from "./Entity"; import { ExtrudeSolid } from "./Extrude"; @@ -168,6 +170,45 @@ export abstract class CompositeEntity extends Entity } } + SetAllMaterialAtSlot(mtl: ObjectId) + { + if (this.LockMaterial) + return; + this.WriteAllObjectRecord(); + this.Traverse(e => + { + if (e === this) + return; + e.SetAllMaterialAtSlot(mtl); + }); + + this.Update(UpdateDraw.Material); + } + + GetMtlLockedStatus() + { + let partMtlLocked = false; + let allMtlLocked = true; + this.Traverse(e => + { + if (e === this) + return; + const res = e.GetMtlLockedStatus(); + if (res.partMtlLocked) + { + partMtlLocked = true; + if (!res.allMtlLocked) + allMtlLocked = false; + } + else + allMtlLocked = false; + }); + return { + partMtlLocked, + allMtlLocked, + }; + } + UpdateDrawObjectMaterial(renderType: RenderType, obj: Object3D) { this.UpdateDrawObject(renderType, obj); diff --git a/src/UI/Components/MaterialExplorer.tsx b/src/UI/Components/MaterialExplorer.tsx index 18d081e71..4000e497b 100644 --- a/src/UI/Components/MaterialExplorer.tsx +++ b/src/UI/Components/MaterialExplorer.tsx @@ -18,7 +18,6 @@ import { SelectSetBase } from '../../Editor/SelectBase'; import { SelectBox } from '../../Editor/SelectBox'; import { SelectPick } from '../../Editor/SelectPick'; import { userConfig } from '../../Editor/UserConfig'; -import { RenderType } from '../../GraphicsSystem/RenderType'; import { userConfigStore } from '../Store/UserConfigStore'; import { Asset } from './Asset'; import { BoardModalType } from "./Board/BoardModalType"; @@ -95,7 +94,7 @@ export class MaterialExplorer extends React.Component<{ materialTable: MaterialT hwdEnts.push(childrenEnt); })); - let objects = hwdEnts.map(childrenEnt => childrenEnt.GetDrawObjectFromRenderType(RenderType.Physical)); + let objects = hwdEnts.map(childrenEnt => childrenEnt.GetDrawObjectFromRenderType(userConfig.RenderType)); if (ss instanceof SelectPick) {