!1978 功能:矩形灯切换配置可锁定长宽和批量修改灯光功能

pull/2001/MERGE
黄诗津 2 years ago committed by ChenX
parent c6f3359a1b
commit 04f1e79218

@ -0,0 +1,109 @@
import { app } from "../../ApplicationServices/Application";
import { EntitysUpdateWrap } from "../../Common/EntityUpdateWrap";
import { PointLight } from "../../DatabaseServices/Lights/PointLight";
import { RectAreaLight } from "../../DatabaseServices/Lights/RectAreaLight";
import { SpotLight } from "../../DatabaseServices/Lights/SpotLight";
import { Command } from "../../Editor/CommandMachine";
import { PromptStatus } from "../../Editor/PromptResult";
import { BoardModalType } from "../../UI/Components/Board/BoardModalType";
import { ModalState } from "../../UI/Components/Modal/ModalInterface";
import { IConfigStore } from "../../UI/Store/BoardStore";
import { LightConfigModel } from "../../UI/Store/RightPanelStore/LightConfigModel";
import { LightStore, PointLightStore, RectAreaLightStore, SpotLightStore } from "../../UI/Store/RightPanelStore/LightStore";
export class BatchModifyLights implements Command
{
async exec()
{
let lightType: BoardModalType;
let configStore: IConfigStore;
let enRes = await app.Editor.GetEntity({
Msg: "请选择第一个灯(需要修改的灯类型)",
NotNone: true,
Filter: { filterTypes: [RectAreaLight, SpotLight, PointLight] }
});
if (enRes.Status !== PromptStatus.OK) return;
let currentLight = enRes.Entity as RectAreaLight | SpotLight | PointLight;
app.Editor.SetSelection([currentLight]);
let lightStore = new LightStore().InitLightData(currentLight);
lightStore.IsDrawLight = true;
if (currentLight instanceof SpotLight)
{
lightType = BoardModalType.SpotLight;
configStore = SpotLightStore.GetInstance();
(configStore as SpotLightStore).lightStore = lightStore;
}
else if (currentLight instanceof RectAreaLight)
{
lightType = BoardModalType.RectAreaLight;
configStore = RectAreaLightStore.GetInstance();
(configStore as RectAreaLightStore).lightStore = lightStore;
}
else if (currentLight instanceof PointLight)
{
lightType = BoardModalType.PointLight;
configStore = PointLightStore.GetInstance();
(configStore as PointLightStore).lightStore = lightStore;
}
let ssRes = await app.Editor.GetSelection({
Msg: "请选择需要修改的灯",
Filter: { filterTypes: lightType === BoardModalType.RectAreaLight ? [RectAreaLight] : lightType === BoardModalType.SpotLight ? [SpotLight] : [PointLight] },
});
if (ssRes.Status !== PromptStatus.OK) return;
let lights = ssRes.SelectSet.SelectEntityList as (RectAreaLight | SpotLight | PointLight)[];
app.Editor.ModalManage.RenderModal(LightConfigModel,
{
store: lightStore,
lightType,
type: lightType + "Config",
configStore: configStore,
isNotModify: true,
}, { IsLightModal: true });
let state = await app.Editor.ModalManage.Wait();
if (state.Status !== ModalState.Ok) return;
EntitysUpdateWrap(lights, () =>
{
for (const light of lights)
{
light.Color = currentLight.Color;
light.Temperature = currentLight.Temperature;
light.Intensity = currentLight.Intensity;
light.IndirectLightingIntensity = currentLight.IndirectLightingIntensity;
light.SpecularScale = currentLight.SpecularScale;
light.ShowHelper = currentLight.ShowHelper;
if (currentLight instanceof RectAreaLight && light instanceof RectAreaLight)
{
light.Width = currentLight.Width;
light.Height = currentLight.Height;
light.BarnDoorAngle = currentLight.BarnDoorAngle;
light.BarnDoorLength = currentLight.BarnDoorLength;
light.AttenuationRadius = currentLight.AttenuationRadius;
light.CaseShadow = currentLight.CaseShadow;
}
else if (currentLight instanceof SpotLight && light instanceof SpotLight)
{
light.Angle = currentLight.Angle;
light.InnerConeAngle = currentLight.InnerConeAngle;
light.SoftSourceRadius = currentLight.SoftSourceRadius;
light.SourceLength = currentLight.SourceLength;
light.SourceRadius = currentLight.SourceRadius;
light.AttenuationRadius = currentLight.AttenuationRadius;
light.CaseShadow = currentLight.CaseShadow;
light.Update();
}
else if (currentLight instanceof PointLight && light instanceof PointLight)
{
light.SoftSourceRadius = currentLight.SoftSourceRadius;
light.SourceLength = currentLight.SourceLength;
light.SourceRadius = currentLight.SourceRadius;
}
}
});
}
}

@ -28,7 +28,7 @@ export class DrawPointLight implements Command
type: BoardModalType.PointLight + "Config",
configStore: configStore,
isNotModify: true,
});
}, { IsLightModal: true });
setTimeout(() =>
{

@ -73,7 +73,7 @@ export class DrawRectAreaLight implements Command
type: BoardModalType.RectAreaLight + "Config",
configStore: configStore,
isNotModify: true
});
}, { IsLightModal: true });
setTimeout(() =>
{

@ -30,7 +30,7 @@ export class DrawSpotLight implements Command
type: BoardModalType.SpotLight + "Config",
configStore: configStore,
isNotModify: true
});
}, { IsLightModal: true });
setTimeout(() =>
{
@ -97,7 +97,7 @@ export class DrawSpotLight2 implements Command
type: BoardModalType.SpotLight + "Config",
configStore: configStore,
isNotModify: true
});
}, { IsLightModal: true });
setTimeout(() =>
{

@ -76,6 +76,7 @@ export enum CommandNames
SpotLight = "SPOTLIGHT",
SpotLight2 = "SPOTLIGHT2",
RectLight = "RECTLIGHT",
BatchModifyLights = "BATCHMODIFYLIGHTS",
Divide = "DIVIDE",
Point = "POINT",
AlignDim = "ALGINDIMEN",

@ -74,7 +74,7 @@ export class Light extends Entity
set Color(color: Color)
{
this.WriteAllObjectRecord();
this._LightColor = color;
this._LightColor.set(color);
this.Update();
}
get ShowHelper()

@ -89,6 +89,7 @@ import { DrawEllipse } from "../Add-on/DrawEllipse";
import { DrawExtrude } from "../Add-on/DrawExtrude";
import { DrawFloor } from "../Add-on/DrawFloor";
import { DrawGripStretch } from "../Add-on/DrawGripStretch";
import { BatchModifyLights } from "../Add-on/DrawLight/BatchModifyLights";
import { DrawPointLight } from "../Add-on/DrawLight/DrawPointLight";
import { DrawRectAreaLight } from "../Add-on/DrawLight/DrawRectAreaLight";
import { DrawSpotLight, DrawSpotLight2 } from "../Add-on/DrawLight/DrawSpotLight";
@ -428,6 +429,7 @@ export function registerCommand()
commandMachine.RegisterCommand(CommandNames.SpotLight, new DrawSpotLight());
commandMachine.RegisterCommand(CommandNames.SpotLight2, new DrawSpotLight2());
commandMachine.RegisterCommand(CommandNames.RectLight, new DrawRectAreaLight());
commandMachine.RegisterCommand(CommandNames.BatchModifyLights, new BatchModifyLights());
commandMachine.RegisterCommand("ptcopy", new Command_CopyPoint());

@ -84,7 +84,7 @@ export class DbClickManager extends Singleton
if (pickEnt instanceof Light)
{
const width = 500;
const height = 500;
const height = 600;
let lightStore = LightStore.GetInstance();
lightStore.IsDrawLight = false;
lightStore.InitLightData(pickEnt);
@ -102,16 +102,19 @@ export class DbClickManager extends Singleton
{
lightType = BoardModalType.SpotLight;
configStore = SpotLightStore.GetInstance();
(configStore as SpotLightStore).lightStore = lightStore;
}
else if (pickEnt instanceof RectAreaLight)
{
lightType = BoardModalType.RectAreaLight;
configStore = RectAreaLightStore.GetInstance();
(configStore as RectAreaLightStore).lightStore = lightStore;
}
else if (pickEnt instanceof PointLight)
{
lightType = BoardModalType.PointLight;
configStore = PointLightStore.GetInstance();
(configStore as PointLightStore).lightStore = lightStore;
}
let p = app.Viewer.WorldToScreen(pickEnt.Position);
let left = Math.min(p.x + app.Viewer.canvasContainer.offsetLeft + 10, window.innerWidth - width);
@ -120,7 +123,7 @@ export class DbClickManager extends Singleton
CADModal.ModalOldPosition.top = `${top > 0 ? top : 0}px`;
app.Editor.ModalManage.RenderModeless(LightConfigModel,
{ store: lightStore, configStore, lightType, type: "lightModel" }, { position: ModalPosition.Old });
{ store: lightStore, configStore, lightType, type: "lightModel" }, { position: ModalPosition.Old, IsLightModal: true });
}
else if (pickEnt instanceof Text || pickEnt instanceof RoomRegion)
{

@ -972,6 +972,16 @@ export const CommandList: ICommand[] = [
// enName: "Rectangular light",
chDes: "均匀的矩形面光源",
},
{
// icon: IconEnum.RectLight,
typeId: "dg",
link: `#`,
defaultCustom: "BML",
command: CommandNames.BatchModifyLights,
type: "灯光",
chName: "批量修改灯光",
chDes: "批量修改灯光属性",
},
//排钻命令
{

@ -94,7 +94,7 @@ export class CADModal
}
Render<T extends AnyObject>(Component: React.ComponentType<T>, props: T, option: IModalProps = {})
{
const { canMinimize = true, resizable = false, position = ModalPosition.Center, isModal = false, isMax = false, canForceMax = false } = option;
const { canMinimize = true, resizable = false, position = ModalPosition.Center, isModal = false, isMax = false, canForceMax = false, IsLightModal = false } = option;
let key = props?.type ?? GetCompoentObjectIdString(Component);
//校验Key
@ -181,6 +181,7 @@ export class CADModal
this.canResize = resizable;
this.canMinimize = canMinimize;
this.IsModal = isModal;
this.IsLightModal = IsLightModal;
this.SetPosition(position);
this._canForceMax = canForceMax;
this.container.focus();

@ -37,7 +37,8 @@ export interface IModalProps
root?: CADModal;
/**可以在命令执行中放大 */
canForceMax?: boolean;
/**是否为灯光模板 */
IsLightModal?: boolean;
minWidth?: number;
minHeight?: number;
}

@ -1063,14 +1063,14 @@ img {
}
#SpotLightModel {
width : 300px;
width : 310px;
font-size: 13px;
.bp3-dialog-body {
padding: 5px;
.bp3-control.bp3-switch.bp3-align-right {
padding-left : 14px;
padding-left : 24px;
padding-right: 47px;
}
@ -1081,16 +1081,25 @@ img {
input {
width : 100px;
height : 27px;
margin-left: 10px;
}
.bp3-label {
float : left;
width : 56px;
width : 76px;
margin-top: 5px;
text-align: center;
}
.bp3-label .bp3-popover-wrapper{
margin: 0;
width: 16px;
height: 16px;
.checkbox{
margin: 0 0 0 5px;
}
}
.bp3-form-group {
margin: 0;
}
@ -1108,7 +1117,7 @@ img {
.bp3-input {
width : 100px;
height : 27px;
margin-left: 10px;
margin-left: 0;
text-indent: 18px;
}
}
@ -1119,7 +1128,7 @@ img {
.bp3-input {
height : 27px;
width : 50px;
margin-left: 10px;
margin-left: 0;
padding : 10px;
}
}
@ -1136,7 +1145,7 @@ img {
height : auto;
position : absolute;
margin-top : 5px;
margin-left: 130px;
margin-left: 140px;
.bp3-slider-axis {
display: none;
@ -1157,7 +1166,7 @@ img {
}
.bp3-dialog-footer {
padding : 7px 10px 7px 10px;
padding : 7px 10px 7px 15px;
border-top : 1px solid #dddddd;
background-color: white;
}

@ -1,4 +1,4 @@
import { Alignment, Button, Classes, FormGroup, Icon, InputGroup, Intent, Label, NumericInput, Popover, PopoverPosition, Position, Slider, Switch, Tooltip, UL } from "@blueprintjs/core";
import { Alignment, Button, Checkbox, Classes, FormGroup, Icon, InputGroup, Intent, Label, NumericInput, Popover, PopoverPosition, Position, Slider, Switch, Tooltip, UL } from "@blueprintjs/core";
import { observable } from "mobx";
import { observer } from "mobx-react";
import React from "react";
@ -25,7 +25,7 @@ import { Config_ModalType, UserConfig } from "../../Components/Board/UserConfig"
import { ModalState } from "../../Components/Modal/ModalInterface";
import { AppToaster } from "../../Components/Toaster";
import { IConfigStore } from "../BoardStore";
import { LightStore } from "./LightStore";
import { LightStore, RectAreaLightStore } from "./LightStore";
@observer
export class LightConfigModel extends React.Component<{ store: LightStore; configStore: IConfigStore; lightType: BoardModalType; isNotModify?: boolean; type: string; }, {}>
@ -49,11 +49,9 @@ export class LightConfigModel extends React.Component<{ store: LightStore; confi
e.stopPropagation();
})
);
setTimeout(() => { app.Editor.ModalManage.CurrentModal.IsLightModal = true; }, 0);
}
componentWillUnmount()
{
app.Editor.ModalManage.CurrentModal.IsLightModal = false;
for (let f of this.removeFuncs)
f();
this.removeFuncs.length = 0;
@ -127,25 +125,22 @@ export class LightConfigModel extends React.Component<{ store: LightStore; confi
/>
</div>
<div className={Classes.DIALOG_BODY}>
{
<div style={{ height: 25 }}>
<Switch
checked={lightData.ShowHelper}
label="显示灯光助手"
onChange={e =>
{
if (!this.props.isNotModify)
CommandWrap(() =>
{
light.ShowHelper = !light.ShowHelper;
}, "灯光助手显示/隐藏");
lightData.ShowHelper = !lightData.ShowHelper;
}}
alignIndicator={Alignment.RIGHT}
/>
</div>
}
<div style={{ height: 25 }}>
<Switch
checked={lightData.ShowHelper}
label="显示灯光助手"
onChange={e =>
{
if (!this.props.isNotModify)
CommandWrap(() =>
{
light.ShowHelper = !light.ShowHelper;
}, "灯光助手显示/隐藏");
lightData.ShowHelper = !lightData.ShowHelper;
}}
alignIndicator={Alignment.RIGHT}
/>
</div>
<div style={{ height: 25 }}>
<Switch
checked={lightData.CaseShadow}
@ -163,12 +158,13 @@ export class LightConfigModel extends React.Component<{ store: LightStore; confi
/>
</div>
{
(this.props.lightType === BoardModalType.PointLight) || <div>
(this.props.lightType === BoardModalType.PointLight) ||
<div>
<div>
<Label style={{ float: "left" }}>:</Label>
<input
className={Classes.INPUT}
style={{ height: 27, marginLeft: 10 }}
style={{ height: 27 }}
value={this._Target}
disabled
/>
@ -208,7 +204,7 @@ export class LightConfigModel extends React.Component<{ store: LightStore; confi
<div className="pos">
<input
className={Classes.INPUT}
style={{ height: 27, marginLeft: 10 }}
style={{ height: 27 }}
value={this._Position}
disabled
/>
@ -285,6 +281,7 @@ export class LightConfigModel extends React.Component<{ store: LightStore; confi
<InputGroup
value={lightData.Color.toUpperCase()}
small
readOnly
leftIcon={
<Icon
icon='stop'
@ -302,6 +299,7 @@ export class LightConfigModel extends React.Component<{ store: LightStore; confi
onClose={(e) => { e.preventDefault(); }}
>
<InputGroup
readOnly
value={this.props.store.lightData.Temperature.toString() + 'K'}
/>
<div className='sun-colortemp'>
@ -365,43 +363,53 @@ export class LightConfigModel extends React.Component<{ store: LightStore; confi
let max: number = 200;
let min: number = 0;
let isFloat: boolean = false; //stepsize 是否为0.1
let scale: number = 1;
let noLim: boolean = false;
switch (k)
{
case "Intensity":
max = 2000;
max = 200;
scale = 10;
break;
case "IndirectLightingIntensity":
max = 6;
scale = 1;
break;
case "Angle":
case "InnerConeAngle":
case "BarnDoorAngle":
max = 90;
scale = 1;
break;
case "SpecularScale":
max = 1;
isFloat = true;
scale = 1;
break;
case "SourceLength":
max = 1000;
max = 100;
scale = 10;
break;
case "SourceRadius":
case "SoftSourceRadius":
max = 300;
scale = 1;
break;
case "AttenuationRadius":
min = 10;
max = 1000;
min = 1;
max = 100;
scale = 10;
break;
case "Width":
case "Height":
min = 1;
max = 5000;
max = 50;
noLim = true;
scale = 100;
break;
case "BarnDoorLength":
max = 100;
scale = 1;
break;
default:
break;
@ -412,6 +420,7 @@ export class LightConfigModel extends React.Component<{ store: LightStore; confi
store={this.props.store}
max={max}
min={min}
scale={scale}
isFloat={isFloat}
noLim={noLim}
isNotModify={this.props.isNotModify}
@ -450,7 +459,7 @@ export class LightConfigModel extends React.Component<{ store: LightStore; confi
}
@observer
export class InputAndSlider extends React.Component<{ pars: string[], store: LightStore; max: number; isFloat: boolean; min: number; noLim: boolean; isNotModify: boolean; }, {}>
export class InputAndSlider extends React.Component<{ pars: string[], store: LightStore; max: number; isFloat: boolean; min: number; scale: number; noLim: boolean; isNotModify: boolean; }, {}>
{
OldData: number = 0;
private coolTime = new CoolDownTime;
@ -561,13 +570,40 @@ export class InputAndSlider extends React.Component<{ pars: string[], store: Lig
render()
{
let store = this.props.store;
let rectStore = RectAreaLightStore.GetInstance();
return (
<FormGroup>
<div className='light'>
<Label style={{ float: "left", width: 56, marginTop: 5 }}>{this.props.pars[1]}:</Label>
<div className='inputslider'>
{
["Height", "Width"].includes(this.props.pars[0]) ?
<Label style={{ float: "left", width: 76, marginTop: 5, display: "flex" }}>
{
<Tooltip
content={`${this.props.pars[0] === "Width" ? "宽度" : "长度"}锁定`}
>
<Checkbox
className="checkbox"
checked={this.props.pars[0] === "Width" ? rectStore.isLockWidth : rectStore.isLockHeight}
onChange={() =>
{
if (this.props.pars[0] === "Width")
rectStore.isLockWidth = !rectStore.isLockWidth;
else
rectStore.isLockHeight = !rectStore.isLockHeight;
}}
/>
</Tooltip>
}
<div style={{ position: "absolute", left: 28 }}>{this.props.pars[1]}:</div>
</Label> :
<Label style={{ float: "left", width: 76, marginTop: 5 }}>
{this.props.pars[1]}:
</Label>
}
<NumericInput
min={this.props.min}
max={this.props.noLim ? 10e6 : this.props.max}
min={this.props.min * this.props.scale}
max={this.props.noLim ? 10e6 : this.props.max * this.props.scale}
buttonPosition={"none"}
value={this.props.store.lightData[this.props.pars[0]]}
allowNumericCharactersOnly
@ -600,7 +636,7 @@ export class InputAndSlider extends React.Component<{ pars: string[], store: Lig
}
if (this.props.store.lightData[this.props.pars[0]] < this.props.min)
{
if (this.OldData === this.props.store.currentSelectEnt[this.props.pars[0]])
if (this.OldData = this.props.store.currentSelectEnt[this.props.pars[0]])
{
this.props.store.lightData[this.props.pars[0]] = this.props.store.currentSelectEnt[this.props.pars[0]];
return;
@ -625,9 +661,10 @@ export class InputAndSlider extends React.Component<{ pars: string[], store: Lig
min={this.props.min}
max={this.props.max}
stepSize={this.props.isFloat ? 0.1 : 1}
value={parseFloat(this.props.store.lightData[this.props.pars[0]]) >= this.props.max ? this.props.max : parseFloat(this.props.store.lightData[this.props.pars[0]])}
value={parseFloat(store.lightData[this.props.pars[0]]) / this.props.scale > this.props.max ? this.props.max : parseFloat(store.lightData[this.props.pars[0]]) / this.props.scale}
onChange={(e) =>
{
e = e * this.props.scale;
let coolTime = new CoolDownTime;
coolTime.Debounce(() =>
{

@ -90,9 +90,9 @@ export class LightStore implements IConfigStore
@observable ShowSunLight = true;
@observable ShowHemiLight = true;
@observable ShowExposure = true;
@observable currentSelectEnt: Light = undefined;
@observable title = "";
@observable pars: [string, string][] = [];
currentSelectEnt: Light = undefined;
title = "";
pars: [string, string][] = [];
@observable lightData: LightModalState = {};
@observable ambientLightData = {
Color: "#" + app.Database.AmbientLight.Color.getHexString(),
@ -226,6 +226,7 @@ export class LightStore implements IConfigStore
Object.assign(this.lightData, newState);
this.currentSelectEnt = light;
}
return this;
}
private WatchLightEvent()
@ -469,6 +470,8 @@ export class RectAreaLightStore implements IConfigStore
@observable m_Option: RectAreaLightOption = { ...DefaultRectAreaLightOption };
@observable configsNames: string[] = [];
lightStore: LightStore;
@observable isLockWidth: boolean = false;
@observable isLockHeight: boolean = false;
InitOption()
{
Object.assign(this.m_Option, DefaultRectAreaLightOption);
@ -516,8 +519,10 @@ export class RectAreaLightStore implements IConfigStore
lightStore.lightData.AttenuationRadius = cof.option.AttenuationRadius.toString();
lightStore.lightData.CaseShadow = cof.option.CaseShadow;
lightStore.lightData.ShowHelper = cof.option.ShowHelper;
lightStore.lightData.Height = cof.option.Height.toString();
lightStore.lightData.Width = cof.option.Width.toString();
if (!this.isLockHeight)
lightStore.lightData.Height = cof.option.Height.toString();
if (!this.isLockWidth)
lightStore.lightData.Width = cof.option.Width.toString();
let rectAreaLight = lightStore.currentSelectEnt as RectAreaLight;
if (!lightStore.IsDrawLight)
{
@ -543,8 +548,10 @@ export class RectAreaLightStore implements IConfigStore
rectAreaLight.Temperature = cof.option.temperature;
rectAreaLight.IndirectLightingIntensity = cof.option.IndirectLightingIntensity;
rectAreaLight.SpecularScale = cof.option.SpecularScale;
rectAreaLight.Width = cof.option.Width;
rectAreaLight.Height = cof.option.Height;
if (!this.isLockWidth)
rectAreaLight.Width = cof.option.Width;
if (!this.isLockHeight)
rectAreaLight.Height = cof.option.Height;
rectAreaLight.BarnDoorAngle = cof.option.BarnDoorAngle;
rectAreaLight.BarnDoorLength = cof.option.BarnDoorLength;
rectAreaLight.AttenuationRadius = cof.option.AttenuationRadius;

Loading…
Cancel
Save