!2337 新增:吊顶新增可设置高度、增加线条偏移距离、支持非闭合线条

pull/2744/head
林三 5 months ago committed by ChenX
parent efdc70f1ec
commit cbabf6989e

@ -1,4 +1,4 @@
import { BufferAttribute, BufferGeometry, Float32BufferAttribute, InstancedInterleavedBuffer, InterleavedBufferAttribute, Intersection, LineSegments, Material, Mesh, Object3D, ShapeBufferGeometry, Vector3 } from "three"; import { BufferAttribute, BufferGeometry, Float32BufferAttribute, InstancedInterleavedBuffer, InterleavedBufferAttribute, Intersection, LineSegments, Material, Mesh, Object3D, ShapeBufferGeometry, Vector2, Vector3 } from "three";
import { Line2 } from "three/examples/jsm/lines/Line2"; import { Line2 } from "three/examples/jsm/lines/Line2";
import { LineGeometry } from "three/examples/jsm/lines/LineGeometry"; import { LineGeometry } from "three/examples/jsm/lines/LineGeometry";
import { HostApplicationServices } from "../../../../ApplicationServices/HostApplicationServices"; import { HostApplicationServices } from "../../../../ApplicationServices/HostApplicationServices";
@ -14,7 +14,7 @@ import { Factory } from "../../../CADFactory";
import { CADFiler } from "../../../CADFiler"; import { CADFiler } from "../../../CADFiler";
import { Contour } from "../../../Contour"; import { Contour } from "../../../Contour";
import { Curve } from "../../../Entity/Curve"; import { Curve } from "../../../Entity/Curve";
import { Polyline } from "../../../Entity/Polyline"; import { Polyline, PolylineProps } from "../../../Entity/Polyline";
import { ObjectId } from "../../../ObjectId"; import { ObjectId } from "../../../ObjectId";
import { PhysicalMaterialRecord } from "../../../PhysicalMaterialRecord"; import { PhysicalMaterialRecord } from "../../../PhysicalMaterialRecord";
import { Shape } from "../../../Shape"; import { Shape } from "../../../Shape";
@ -39,6 +39,8 @@ export interface BulkheadCeiling_ContourData
ContourId: number; //截面轮廓ID ContourId: number; //截面轮廓ID
ShapeMaterialSlotData: number[]; ShapeMaterialSlotData: number[];
OverWriteMaterial?: Map<number, ObjectId<PhysicalMaterialRecord>>;//替代材质 OverWriteMaterial?: Map<number, ObjectId<PhysicalMaterialRecord>>;//替代材质
Deviation: number; //线条上下偏移量
Height: number; //吊顶高度
} }
/** /**
@ -62,7 +64,7 @@ export class BulkheadCeiling extends RoomBase
this.Update(); this.Update();
} }
private _Height = 300;//吊顶高度 private _Height = 0;//吊顶高度
get Height() get Height()
{ {
@ -137,7 +139,7 @@ export class BulkheadCeiling extends RoomBase
contours.push(contourNode); contours.push(contourNode);
contour_data_Map.set(contourNode, con_data); contour_data_Map.set(contourNode, con_data);
} }
ContourTreeNode.ParseContourTree(contours); ContourTreeNode.ParseContourTree(contours, true);
//#endregion //#endregion
let faceGeoms: BufferGeometry[] = []; let faceGeoms: BufferGeometry[] = [];
@ -154,18 +156,29 @@ export class BulkheadCeiling extends RoomBase
if (contourNode.parent && contour_data_Map.get(contourNode.parent).ContourType === BulkheadCeiling_ContourType.Land)//上级也是岛 不需要在绘制平面了 if (contourNode.parent && contour_data_Map.get(contourNode.parent).ContourType === BulkheadCeiling_ContourType.Land)//上级也是岛 不需要在绘制平面了
continue; continue;
if (contourNode.children.length)
con_data.Height = 0;
let holes: Contour[] = []; let holes: Contour[] = [];
for (let chiNode of contourNode.children) for (let chiNode of contourNode.children)
{ {
let chi_con_data = contour_data_Map.get(chiNode); let chi_con_data = contour_data_Map.get(chiNode);
if (chi_con_data.ContourType === BulkheadCeiling_ContourType.Hole) if (chi_con_data.ContourType === BulkheadCeiling_ContourType.Hole)
{
holes.push(chiNode.contour.Clone()); holes.push(chiNode.contour.Clone());
let height = chi_con_data.Height;
if (height > con_data.Height)
con_data.Height = height;
}
} }
let shape = new Shape(contourNode.contour, holes); let shape = new Shape(contourNode.contour, holes);
let geom = new ShapeBufferGeometry(shape.Shape, 30); let geom = new ShapeBufferGeometry(shape.Shape, 30);
geom.applyMatrix4(shape.Outline.Curve.OCSNoClone); //应用高度
let mat = shape.Outline.Curve.OCS.multiply(shape.Outline.Curve.OCS.setPosition(new Vector3(0, 0, - con_data.Height)));
geom.applyMatrix4(mat);
{ {
const indices = Array.from(geom.getIndex().array); const indices = Array.from(geom.getIndex().array);
@ -198,12 +211,16 @@ export class BulkheadCeiling extends RoomBase
for (; i < this._ContourData.length; i++) for (; i < this._ContourData.length; i++)
{ {
let contour = this._ContourData[i].Contour; let contour = this._ContourData[i].Contour;
let path = this._ContourData[i].Path.Clone();
if (contour) if (contour)
{ {
let path = this._ContourData[i].Path; //范样上下偏移
let mat = this.OCS.clone().setPosition(0, 0, this._ContourData[i].Deviation - this._ContourData[i].Height);
path.ApplyMatrix(mat);
if (this._ContourData[i].ContourType === BulkheadCeiling_ContourType.Hole) if (this._ContourData[i].ContourType === BulkheadCeiling_ContourType.Hole)
path = path.Clone().Reverse(); path = path.Reverse();
let sweepGeo = new SweepGeometry(contour, path, this._ContourData[i].ShapeMaterialSlotData); let sweepGeo = new SweepGeometry(contour, path, this._ContourData[i].ShapeMaterialSlotData);
@ -219,6 +236,31 @@ export class BulkheadCeiling extends RoomBase
sweepGeo.edgePts = undefined; sweepGeo.edgePts = undefined;
} }
else
{
//给岛增加围栏 20 * height
if (this._ContourData[i].ContourType === BulkheadCeiling_ContourType.Land && i !== 0)
{
let height = this._ContourData[i].Height;
if (equaln(height, 0)) continue;
let mat = this.OCS.clone().setPosition(0, 0, -height);
path.ApplyMatrix(mat);
const lineData: PolylineProps[] = [
{ bul: 0, pt: new Vector2(0, 0) },
{ bul: 0, pt: new Vector2(-20, 0) },
{ bul: 0, pt: new Vector2(-20, height) },
{ bul: 0, pt: new Vector2(0, height) },
{ bul: 0, pt: new Vector2(0, 0) }
];
let contour = new Polyline(lineData);
let sweepGeo = new SweepGeometry(contour, path, [undefined]);
this._GemoIdMap.set(sweepGeo.id, i);
this._MeshGeometry.push(sweepGeo);
}
}
} }
this._FaceGeometry = BufferGeometryUtils.MergeBufferGeometries(faceGeoms); this._FaceGeometry = BufferGeometryUtils.MergeBufferGeometries(faceGeoms);
@ -227,7 +269,6 @@ export class BulkheadCeiling extends RoomBase
return this._MeshGeometry; return this._MeshGeometry;
} }
//
get MeshGeometry2() get MeshGeometry2()
{ {
this.MeshGeometry;//TODO: 避免重复构造 this.MeshGeometry;//TODO: 避免重复构造
@ -248,6 +289,7 @@ export class BulkheadCeiling extends RoomBase
let geo = BufferGeometryUtils.MergeBufferGeometries(geos, true); let geo = BufferGeometryUtils.MergeBufferGeometries(geos, true);
return geo; return geo;
} }
get Materials2() get Materials2()
{ {
let materials: Material[] = [this.MeshMaterial as Material];//所有的材质 let materials: Material[] = [this.MeshMaterial as Material];//所有的材质
@ -440,8 +482,9 @@ export class BulkheadCeiling extends RoomBase
GetGripPoints(): Array<Vector3> GetGripPoints(): Array<Vector3>
{ {
let pts = []; let pts = [];
let mat = this.OCS.multiply(this.OCS.setPosition(new Vector3(0, 0, -this._Height)));
for (let data of this._ContourData) for (let data of this._ContourData)
pts.push(...data.Path.Clone().ApplyMatrix(this.OCSNoClone).GetGripPoints()); pts.push(...data.Path.Clone().ApplyMatrix(mat).GetGripPoints());
return pts; return pts;
} }
@ -517,6 +560,8 @@ export class BulkheadCeiling extends RoomBase
ContourId: null, ContourId: null,
ShapeMaterialSlotData: [], ShapeMaterialSlotData: [],
OverWriteMaterial: null, OverWriteMaterial: null,
Deviation: null,
Height: null
}; };
data.ContourType = file.Read(); data.ContourType = file.Read();
@ -524,6 +569,8 @@ export class BulkheadCeiling extends RoomBase
data.ContourId = file.Read(); data.ContourId = file.Read();
data.Path = file.ReadObject(); data.Path = file.ReadObject();
data.SweepShapeTempalteId = file.ReadObjectId() as ObjectId<TemplateRecord>; data.SweepShapeTempalteId = file.ReadObjectId() as ObjectId<TemplateRecord>;
data.Deviation = ver > 1 ? file.Read() : 0;
data.Height = ver > 1 ? file.Read() : 0;
//覆盖材质 //覆盖材质
let overwriteMtlSize = file.Read() as number; let overwriteMtlSize = file.Read() as number;
@ -555,7 +602,7 @@ export class BulkheadCeiling extends RoomBase
//对象将自身数据写入到文件. //对象将自身数据写入到文件.
override WriteFile(file: CADFiler) override WriteFile(file: CADFiler)
{ {
file.Write(1); file.Write(2);
super.WriteFile(file); super.WriteFile(file);
file.Write(this.ContourData.length); file.Write(this.ContourData.length);
@ -567,6 +614,8 @@ export class BulkheadCeiling extends RoomBase
file.Write(data.ContourId); file.Write(data.ContourId);
file.WriteObject(data.Path); file.WriteObject(data.Path);
file.WriteObjectId(data.SweepShapeTempalteId); file.WriteObjectId(data.SweepShapeTempalteId);
file.Write(data.Deviation);
file.Write(data.Height);
//覆盖材质 //覆盖材质
if (data.OverWriteMaterial) if (data.OverWriteMaterial)
@ -594,5 +643,5 @@ export class BulkheadCeiling extends RoomBase
file.WriteObjectId(this.RelativeRoomFlatTop); file.WriteObjectId(this.RelativeRoomFlatTop);
} }
//#endregion //#endregionq
} }

@ -1071,7 +1071,8 @@ export const DefaultShareBoardInfConfigurationOption: ShareBoardInfConfiguration
Object.freeze(DefaultShareBoardInfConfigurationOption); Object.freeze(DefaultShareBoardInfConfigurationOption);
export const DefaultBulkheadCeilingOption: BulkheadCeilingOption = { export const DefaultBulkheadCeilingOption: BulkheadCeilingOption = {
Item: [] Item: [],
Height: 300
}; };
Object.freeze(DefaultBulkheadCeilingOption); Object.freeze(DefaultBulkheadCeilingOption);

@ -285,7 +285,7 @@ export class ContourTreeNode
} }
} }
static ParseContourTree(contourNodes: ContourTreeNode[]): void static ParseContourTree(contourNodes: ContourTreeNode[], ignoreInCurve = false): void
{ {
if (contourNodes.length < 2) return; if (contourNodes.length < 2) return;
@ -312,7 +312,7 @@ export class ContourTreeNode
let node2 = contourNodes[id]; let node2 = contourNodes[id];
if (node2.parent === node1 || node2.area < node1.area) continue;//避免自己的儿子成为自己的父亲 if (node2.parent === node1 || node2.area < node1.area) continue;//避免自己的儿子成为自己的父亲
if (node2.contour.Curve.PtInCurve(p)) if (node2.contour.Curve.PtInCurve(p) || ignoreInCurve)
{ {
node1.SetParent(node2); node1.SetParent(node2);
break; break;

@ -1,6 +1,8 @@
#BulkheadCeilingConfig { #BulkheadCeilingConfig,
#OperRoomFlatTop
{
.bp3-dialog-body { .bp3-dialog-body {
width : 430px; width : 480px;
min-height : 495px; min-height : 495px;
padding : 10px; padding : 10px;
overflow : auto; overflow : auto;
@ -20,6 +22,10 @@
:last-child { :last-child {
border-radius: 0px 5px 0px 0px; border-radius: 0px 5px 0px 0px;
} }
:nth-last-child(2)
{
border-right: 0;
}
.bp3-label { .bp3-label {
line-height: 2rem; line-height: 2rem;
@ -51,12 +57,16 @@
} }
&>:nth-child(2) { &>:nth-child(2) {
width : 70px; width : 80px;
border-right: 0px border-right: 0px
} }
&>:last-child { &>:nth-child(3) {
width: 100%; width : 95%;
}
&>:nth-child(4) {
width : 80px;
} }
.bp3-html-select { .bp3-html-select {
@ -171,6 +181,10 @@
justify-content: center; justify-content: center;
} }
:nth-child(3) {
border-right: 0;
}
.backgroudColor { .backgroudColor {
height: 28px; height: 28px;
width : 100%; width : 100%;

@ -1,4 +1,4 @@
import { Button, Classes, Icon, Label } from "@blueprintjs/core"; import { Button, Classes, Icon } from "@blueprintjs/core";
import { observable } from "mobx"; import { observable } from "mobx";
import { observer } from "mobx-react"; import { observer } from "mobx-react";
import React from "react"; import React from "react";
@ -13,21 +13,15 @@ import { PhysicalMaterialRecord } from "../../../DatabaseServices/PhysicalMateri
import { TEMPLATE_SELECT_ID } from "../../../DatabaseServices/Room/Entity/Wall/Hole/Window/DrawWindowPanel"; import { TEMPLATE_SELECT_ID } from "../../../DatabaseServices/Room/Entity/Wall/Hole/Window/DrawWindowPanel";
import { GetCeilingContourDate, HeadCeilingInfoStore, NONE_CONTOUR_ID } from "../../Store/HeadCeilingStore/HeadCeilingInfoStore"; import { GetCeilingContourDate, HeadCeilingInfoStore, NONE_CONTOUR_ID } from "../../Store/HeadCeilingStore/HeadCeilingInfoStore";
import { HeadCeilingProfileMaterialStore, NONE_MATERIAL_ID } from "../../Store/HeadCeilingStore/HeadCeilingMaterialStore"; import { HeadCeilingProfileMaterialStore, NONE_MATERIAL_ID } from "../../Store/HeadCeilingStore/HeadCeilingMaterialStore";
import { BulkheadCeilingOption, BulkheadCeilingProfileMaterialOption } from "../../Store/OptionInterface/BulkheadCeilingOption"; import { BulkheadCeilingOption, BulkheadCeilingProfileMaterialOption, Display } from "../../Store/OptionInterface/BulkheadCeilingOption";
import { BoardModalType } from "../Board/BoardModalType"; import { BoardModalType } from "../Board/BoardModalType";
import { Config_ModalType, UserConfigComponent } from "../Board/UserConfigComponent"; import { Config_ModalType, UserConfigComponent } from "../Board/UserConfigComponent";
import { ModalState } from "../Modal/ModalInterface"; import { ModalState } from "../Modal/ModalInterface";
import { OnlySelectPanelStore } from "../OnlySelectManage/OnlySelectPanelStore"; import { OnlySelectPanelStore } from "../OnlySelectManage/OnlySelectPanelStore";
import { OnlySelectManagePanel } from "../OnlySelectManage/SelectManagePanel"; import { OnlySelectManagePanel } from "../OnlySelectManage/SelectManagePanel";
import { GetMtlJson } from "../SourceManage/MaterialList"; import { GetMtlJson } from "../SourceManage/MaterialList";
import { CeilingInfoModifyParam } from "../ToolBar/ModifyModel/CeilingInfoModifyParam";
import './HeadCeiling.less'; import './HeadCeiling.less';
import { HeadCeilingInfoItem } from "./HeadCeilingInfoItem";
export enum Display
{
Block = "block",
None = "none",
}
interface HeadCeilingInfoConfigPanelProps interface HeadCeilingInfoConfigPanelProps
{ {
@ -73,7 +67,6 @@ export class HeadCeilingInfoConfigPanel extends React.Component<HeadCeilingInfoC
this._CameraStateContainer.style.display = Display.None; this._CameraStateContainer.style.display = Display.None;
ReactDOM.render(<OnlySelectManagePanel ReactDOM.render(<OnlySelectManagePanel
dataStore={this.props.store}
selectStore={this._SelectStore} selectStore={this._SelectStore}
directoryId={this.props.directoryId} directoryId={this.props.directoryId}
setDisplay={this._OpenSelectTemplate} setDisplay={this._OpenSelectTemplate}
@ -153,12 +146,12 @@ export class HeadCeilingInfoConfigPanel extends React.Component<HeadCeilingInfoC
if (contour_id) if (contour_id)
{ {
let date = await GetCeilingContourDate(contour_id); let data = await GetCeilingContourDate(contour_id);
if (date) if (data)
{ {
contour.id = parseInt(contour_id); contour.id = parseInt(contour_id);
contour.name = date.toplines.name; contour.name = data.toplines.name;
contour.logo = date.toplines.logo; contour.logo = data.toplines.logo;
} }
} }
else else
@ -193,6 +186,7 @@ export class HeadCeilingInfoConfigPanel extends React.Component<HeadCeilingInfoC
render() render()
{ {
const store = this.props.store;
return ( return (
<div id="BulkheadCeilingConfig" className={Classes.DIALOG_CONTAINER}> <div id="BulkheadCeilingConfig" className={Classes.DIALOG_CONTAINER}>
<div className={Classes.DIALOG} > <div className={Classes.DIALOG} >
@ -213,30 +207,17 @@ export class HeadCeilingInfoConfigPanel extends React.Component<HeadCeilingInfoC
/> />
</div> </div>
<div className={Classes.DIALOG_BODY}> <div className={Classes.DIALOG_BODY}>
<ul> <CeilingInfoModifyParam
<li className="firstLi"> store={store}
<Label></Label> openSelectTemplate={this._OpenSelectTemplate}
<Label>/</Label> selectStore={this._SelectStore}
<Label></Label> configType={this.props.configType}
</li> />
{
this.props.store.m_Option.Item.map((item, index) =>
{
return <HeadCeilingInfoItem
item={item}
display={this._OpenSelectTemplate}
itemIndex={index}
selectStore={this._SelectStore}
configType={this.props.configType}
/>;
})
}
</ul>
</div> </div>
<div className={Classes.DIALOG_FOOTER} style={{ display: "unset" }}> <div className={Classes.DIALOG_FOOTER} style={{ display: "unset" }}>
<div className={Classes.DIALOG_FOOTER_ACTIONS}> <div className={Classes.DIALOG_FOOTER_ACTIONS}>
<div className="foot_left"> <div className="foot_left">
<UserConfigComponent store={this.props.store} type={this.props.configType} configType={Config_ModalType.UserConfigModal} isNotUpdateStore={this.props.isNotUpdateStore} /> <UserConfigComponent store={store} type={this.props.configType} configType={Config_ModalType.UserConfigModal} isNotUpdateStore={this.props.isNotUpdateStore} />
</div> </div>
</div> </div>
</div> </div>

@ -4,18 +4,18 @@ import React from "react";
import { ColorMaterial } from "../../../Common/ColorPalette"; import { ColorMaterial } from "../../../Common/ColorPalette";
import { BulkheadCeiling_ContourType } from "../../../DatabaseServices/Room/Entity/Ceiling/BulkheadCeiling"; import { BulkheadCeiling_ContourType } from "../../../DatabaseServices/Room/Entity/Ceiling/BulkheadCeiling";
import { ICeilingProfileMaterialItem } from "../../Store/HeadCeilingStore/HeadCeilingMaterialStore"; import { ICeilingProfileMaterialItem } from "../../Store/HeadCeilingStore/HeadCeilingMaterialStore";
import { ICeilingItem } from "../../Store/OptionInterface/BulkheadCeilingOption"; import { Display, ICeilingItem } from "../../Store/OptionInterface/BulkheadCeilingOption";
import { BoardModalType } from "../Board/BoardModalType"; import { BoardModalType } from "../Board/BoardModalType";
import { INumericInput } from "../INumericInput";
import { OnlySelectPanelStore } from "../OnlySelectManage/OnlySelectPanelStore"; import { OnlySelectPanelStore } from "../OnlySelectManage/OnlySelectPanelStore";
import './HeadCeiling.less'; import './HeadCeiling.less';
import { Display } from "./HeadCeilingInfoConfigPanel";
interface ItemPorps interface ItemPorps
{ {
item: ICeilingItem | ICeilingProfileMaterialItem; item: ICeilingItem | ICeilingProfileMaterialItem;
itemIndex: number; itemIndex: number;
selectStore: OnlySelectPanelStore; selectStore: OnlySelectPanelStore;
configType: BoardModalType; configType?: BoardModalType;
display: (display: Display) => void; display: (display: Display) => void;
} }
@ -90,6 +90,19 @@ export class HeadCeilingInfoItem extends React.Component<ItemPorps, {}>
}} }}
/> />
</div> </div>
{
!this._IsMaterial &&
< div className="itemContour bp3-label">
<INumericInput
style={{ width: 50, height: 27, marginLeft: 10 }}
value={item.example.deviation}
float={1}
onBlur={(e) => { item.example.deviation = parseFloat(e.currentTarget.value); }}
tooltip={false}
canNull={false}
/>
</div>
}
</li> </li>
); );
} }

@ -73,7 +73,7 @@ export class INumericInput extends React.Component<INumericInputProps, {}>
} }
if (isNaN(num) || num < this._Value_Min || num > this._Value_Max) if (isNaN(num) || num < this._Value_Min || num > this._Value_Max)
{ {
this._isPopoverOpen = true; 3; this._isPopoverOpen = true;
return; return;
} }
if (num >= this._Value_Min && num < this._Value_Max && value === num + ".") if (num >= this._Value_Min && num < this._Value_Max && value === num + ".")
@ -107,7 +107,7 @@ export class INumericInput extends React.Component<INumericInputProps, {}>
this._Value = FixedNotZero(e.currentTarget.value, this._Float); this._Value = FixedNotZero(e.currentTarget.value, this._Float);
if (!this._Value) if (!this._Value)
{ {
this._Value = this._CanNull ? "" : this._Value_Min.toString(); this._Value = this._CanNull ? "" : (this.props.min ?? 0).toString();
e.currentTarget.value = this._Value; e.currentTarget.value = this._Value;
} }
if (this.props.onBlur) if (this.props.onBlur)

@ -3,9 +3,7 @@ import { observer } from 'mobx-react';
import * as React from 'react'; import * as React from 'react';
import { MaterialUrls, ToplineUrls } from '../../../Common/HostUrl'; import { MaterialUrls, ToplineUrls } from '../../../Common/HostUrl';
import { DirectoryId } from '../../../Common/Request'; import { DirectoryId } from '../../../Common/Request';
import { HeadCeilingInfoStore } from '../../Store/HeadCeilingStore/HeadCeilingInfoStore'; import { Display } from '../../Store/OptionInterface/BulkheadCeilingOption';
import { HeadCeilingProfileMaterialStore } from '../../Store/HeadCeilingStore/HeadCeilingMaterialStore';
import { Display } from '../HeadCeiling/HeadCeilingInfoConfigPanel';
import { ModalState } from '../Modal/ModalInterface'; import { ModalState } from '../Modal/ModalInterface';
import { OnlySelectDataList } from './OnlySelectDataList'; import { OnlySelectDataList } from './OnlySelectDataList';
import { OnlySelectDataManage } from './OnlySelectManage'; import { OnlySelectDataManage } from './OnlySelectManage';
@ -15,7 +13,6 @@ interface IDataListProps
{ {
directoryId: DirectoryId; directoryId: DirectoryId;
setDisplay: (display: Display) => void; setDisplay: (display: Display) => void;
dataStore: HeadCeilingInfoStore | HeadCeilingProfileMaterialStore;
selectStore: OnlySelectPanelStore; selectStore: OnlySelectPanelStore;
dispaly: Display; dispaly: Display;
return: (status: ModalState) => void; return: (status: ModalState) => void;

@ -0,0 +1,146 @@
import { observable } from "mobx";
import { observer } from "mobx-react";
import React from "react";
import ReactDOM from "react-dom";
import { begin } from "xaop";
import { app } from "../../../../ApplicationServices/Application";
import { KeyBoard } from "../../../../Common/KeyEnum";
import { DirectoryId } from "../../../../Common/Request";
import { BulkheadCeiling } from "../../../../DatabaseServices/Room/Entity/Ceiling/BulkheadCeiling";
import { TEMPLATE_SELECT_ID } from "../../../../DatabaseServices/Room/Entity/Wall/Hole/Window/DrawWindowPanel";
import { GetCeilingContourDate, HeadCeilingInfoStore } from "../../../Store/HeadCeilingStore/HeadCeilingInfoStore";
import { ModalState } from "../../Modal/ModalInterface";
import { OnlySelectPanelStore } from "../../OnlySelectManage/OnlySelectPanelStore";
import { OnlySelectManagePanel } from "../../OnlySelectManage/SelectManagePanel";
import { CeilingInfoModifyParam } from "./CeilingInfoModifyParam";
enum Display
{
Block = "block",
None = "none",
}
interface CeilingInfoModifyPanelProp
{
headCeilingEnt: BulkheadCeiling;
headCeilingInfoStore: HeadCeilingInfoStore;
}
@observer
export class CeilingInfoModifyPanel extends React.Component<CeilingInfoModifyPanelProp, {}>
{
@observable _Display = Display.None;
_Event: Function;
_CameraStateContainer: HTMLElement;
_SelectStore: OnlySelectPanelStore = OnlySelectPanelStore.GetSingleInstance(); //独立的材质选择Store
constructor(props)
{
super(props);
this.props.headCeilingInfoStore.InitItemsForBulkheadCeiling(this.props.headCeilingEnt);
//选择材质的UI放在 #modal 里有效居中
this._CameraStateContainer = document.createElement('div');
this._CameraStateContainer.id = TEMPLATE_SELECT_ID;
this._CameraStateContainer.style.zIndex = "35";
document.getElementById('modal').appendChild(this._CameraStateContainer);
if (window.screen.width <= 1450)
this._CameraStateContainer.style.left = '120px';
else
this._CameraStateContainer.style.left = `calc(50vw - 500px)`;
if (window.screen.height <= 750)
this._CameraStateContainer.style.top = `0px`;
else
this._CameraStateContainer.style.top = `calc(50vh - 395px)`;
this._CameraStateContainer.style.display = Display.None;
ReactDOM.render(<OnlySelectManagePanel
selectStore={this._SelectStore}
directoryId={DirectoryId.CeilingContour}
setDisplay={this._OpenSelectTemplate}
dispaly={this._Display}
return={this._Return}
/>, this._CameraStateContainer);
}
componentDidMount()
{
this._Event = begin(app.Editor.ModalManage, app.Editor.ModalManage.OnKeyDown, (e: KeyboardEvent) =>
{
if (e.keyCode === KeyBoard.Escape)
{
if (this._CameraStateContainer.style.display === Display.Block)
{
this._OpenSelectTemplate(Display.None);
e.preventDefault();
e.stopPropagation();
return;
}
}
});
}
componentWillUnmount()
{
this._Event();
this._Event = null;
document.getElementById('modal').removeChild(this._CameraStateContainer);
this._CameraStateContainer = undefined;
}
_Return = async (status: ModalState) =>
{
if (status === ModalState.Ok)
{
let contour_id = "";
this._SelectStore.currentSelectId.forEach((e) => { contour_id = e; });
let item = this.props.headCeilingInfoStore.m_Option.Item[this._SelectStore.itemIndex];
if (contour_id)
{
let data = await GetCeilingContourDate(contour_id);
if (data)
{
item.example.id = parseInt(contour_id);
item.example.name = data.toplines.name;
item.example.logo = data.toplines.logo;
}
}
else
{
item.example.id = 0;
item.example.name = "";
item.example.logo = "";
}
}
};
//开关选择材质的面板
_OpenSelectTemplate = (style: Display) =>
{
if (style === Display.Block)
{
this._SelectStore.Clear();
app.Editor.ModalManage.stopKeyDownEvent = true;
}
this._CameraStateContainer.style.display = style;
this._Display = style;
};
render()
{
return (
<CeilingInfoModifyParam
store={this.props.headCeilingInfoStore}
openSelectTemplate={this._OpenSelectTemplate}
selectStore={this._SelectStore}
/>
);
}
}

@ -0,0 +1,60 @@
import { Label } from "@blueprintjs/core";
import { observer } from "mobx-react";
import React from "react";
import { HeadCeilingInfoStore } from "../../../Store/HeadCeilingStore/HeadCeilingInfoStore";
import { HeadCeilingProfileMaterialStore } from "../../../Store/HeadCeilingStore/HeadCeilingMaterialStore";
import { Display } from "../../../Store/OptionInterface/BulkheadCeilingOption";
import { BoardModalType } from "../../Board/BoardModalType";
import { HeadCeilingInfoItem } from "../../HeadCeiling/HeadCeilingInfoItem";
import { OnlySelectPanelStore } from "../../OnlySelectManage/OnlySelectPanelStore";
interface ItemPorps
{
store: HeadCeilingInfoStore | HeadCeilingProfileMaterialStore;
openSelectTemplate: (display: Display) => void;
selectStore: OnlySelectPanelStore;
configType?: BoardModalType;
}
@observer
export class CeilingInfoModifyParam extends React.Component<ItemPorps, {}>
{
render()
{
const { store } = this.props;
const isHeadCeilingInfo = store instanceof HeadCeilingInfoStore;
return (
<div>
<ul>
<li className="firstLi">
<Label></Label>
<Label>/</Label>
{
isHeadCeilingInfo ?
<Label></Label>
:
<Label></Label>
}
{
isHeadCeilingInfo &&
<Label></Label>
}
</li>
{
store.m_Option.Item.map((item, index) =>
{
return <HeadCeilingInfoItem
item={item}
display={this.props.openSelectTemplate}
itemIndex={index}
selectStore={this.props.selectStore}
configType={this.props.configType}
/>;
})
}
</ul>
</div>
);
}
}

@ -306,11 +306,38 @@
#OperRoomFlatTop{ #OperRoomFlatTop{
.bp3-dialog-body{ .bp3-dialog-body{
height : 70px; width : auto;
width : 200px; padding : 10px 10px 10px 10px;
display : flex; min-height : unset;
align-items : center; overflow : unset;
border-radius : 5px; max-height : unset;
justify-content: space-evenly; border-radius : 0 0 5px 5px;
ul{
width : 450px;
max-height: 350px;
overflow : auto;
}
.apply_button{
height : 70px;
display : flex;
align-items : center;
border-radius : 5px;
justify-content: space-between;
.button_left{
margin : 15px;
display : flex;
button{
margin: 0 5px;
}
}
.button_right{
margin-right: 25px;
}
}
} }
} }

@ -6,6 +6,7 @@ import { SelectExtrudeContour, selectOutlinePosition } from "../../../../Add-on/
import { ViewChange } from "../../../../Add-on/ViewChange"; import { ViewChange } from "../../../../Add-on/ViewChange";
import { app } from "../../../../ApplicationServices/Application"; import { app } from "../../../../ApplicationServices/Application";
import { HostApplicationServices } from "../../../../ApplicationServices/HostApplicationServices"; import { HostApplicationServices } from "../../../../ApplicationServices/HostApplicationServices";
import { EntityUpdateWrap } from "../../../../Common/EntityUpdateWrap";
import { MaterialUrls } from "../../../../Common/HostUrl"; import { MaterialUrls } from "../../../../Common/HostUrl";
import { NormalMatrix } from "../../../../Common/Matrix4Utils"; import { NormalMatrix } from "../../../../Common/Matrix4Utils";
import { DirectoryId, PostJson, RequestStatus } from "../../../../Common/Request"; import { DirectoryId, PostJson, RequestStatus } from "../../../../Common/Request";
@ -15,12 +16,13 @@ import { inflateBase64 } from "../../../../Common/inflate";
import { CADFiler } from "../../../../DatabaseServices/CADFiler"; import { CADFiler } from "../../../../DatabaseServices/CADFiler";
import { Contour } from "../../../../DatabaseServices/Contour"; import { Contour } from "../../../../DatabaseServices/Contour";
import { Database } from "../../../../DatabaseServices/Database"; import { Database } from "../../../../DatabaseServices/Database";
import { Circle } from "../../../../DatabaseServices/Entity/Circle";
import { Curve } from "../../../../DatabaseServices/Entity/Curve"; import { Curve } from "../../../../DatabaseServices/Entity/Curve";
import { Polyline } from "../../../../DatabaseServices/Entity/Polyline"; import { Polyline } from "../../../../DatabaseServices/Entity/Polyline";
import { DefaultParamMap, SetMaterialParams } from "../../../../DatabaseServices/IMaterialDefaultParam"; import { DefaultParamMap, SetMaterialParams } from "../../../../DatabaseServices/IMaterialDefaultParam";
import { ObjectId } from "../../../../DatabaseServices/ObjectId"; import { ObjectId } from "../../../../DatabaseServices/ObjectId";
import { PhysicalMaterialRecord } from "../../../../DatabaseServices/PhysicalMaterialRecord"; import { PhysicalMaterialRecord } from "../../../../DatabaseServices/PhysicalMaterialRecord";
import { BulkheadCeiling, BulkheadCeiling_ContourType } from "../../../../DatabaseServices/Room/Entity/Ceiling/BulkheadCeiling"; import { BulkheadCeiling, BulkheadCeiling_ContourData, BulkheadCeiling_ContourType } from "../../../../DatabaseServices/Room/Entity/Ceiling/BulkheadCeiling";
import { BulkheadCeilingShapeTemplateExtendData } from "../../../../DatabaseServices/Room/Entity/Ceiling/BulkheadCeilingShapeExtendData"; import { BulkheadCeilingShapeTemplateExtendData } from "../../../../DatabaseServices/Room/Entity/Ceiling/BulkheadCeilingShapeExtendData";
import { RoomFlatTop } from "../../../../DatabaseServices/Room/Entity/Flat/RoomFlatTop"; import { RoomFlatTop } from "../../../../DatabaseServices/Room/Entity/Flat/RoomFlatTop";
import { CommandWrap } from "../../../../Editor/CommandMachine"; import { CommandWrap } from "../../../../Editor/CommandMachine";
@ -35,6 +37,7 @@ import { DialogUserConfig } from "../../Board/UserConfigComponent";
import { HeadCeilingInfoConfigPanel } from "../../HeadCeiling/HeadCeilingInfoConfigPanel"; import { HeadCeilingInfoConfigPanel } from "../../HeadCeiling/HeadCeilingInfoConfigPanel";
import { ModalPosition } from "../../Modal/ModalInterface"; import { ModalPosition } from "../../Modal/ModalInterface";
import { AppToaster } from "../../Toaster"; import { AppToaster } from "../../Toaster";
import { CeilingInfoModifyPanel } from "./CeilingInfoModifyPanel";
import './ModifyModel.less'; import './ModifyModel.less';
interface RoomBaseParamsProps interface RoomBaseParamsProps
@ -53,6 +56,8 @@ interface ContourData
@observer @observer
export default class RoomFlatTopParams extends Component<RoomBaseParamsProps, {}> export default class RoomFlatTopParams extends Component<RoomBaseParamsProps, {}>
{ {
_HeadCeilingInfoStore: HeadCeilingInfoStore = new HeadCeilingInfoStore();
//获取吊顶地面面材质 默认乳胶漆 //获取吊顶地面面材质 默认乳胶漆
SetBulkCeilingFaceDefaultMaterial() SetBulkCeilingFaceDefaultMaterial()
{ {
@ -117,7 +122,8 @@ export default class RoomFlatTopParams extends Component<RoomBaseParamsProps, {}
date.push({ date.push({
contourType: BulkheadCeiling_ContourType.Land, contourType: BulkheadCeiling_ContourType.Land,
contourId: NONE_CONTOUR_ID, contourId: NONE_CONTOUR_ID,
color: 1 color: 1,
deviation: 0
}); });
await store.InitEditorContourItems(date); await store.InitEditorContourItems(date);
@ -177,25 +183,6 @@ export default class RoomFlatTopParams extends Component<RoomBaseParamsProps, {}
box.expandByVector(new Vector3(1, 1, 1)); box.expandByVector(new Vector3(1, 1, 1));
let selectBox = new SelectBox(app.Viewer, AsVector2(box.min), AsVector2(box.max), SelectType.C); let selectBox = new SelectBox(app.Viewer, AsVector2(box.min), AsVector2(box.max), SelectType.C);
for (let g of group)
{
for (let curve of g)
{
if (selectBox.CheckSelectTraverse(curve.GetDrawObjectFromRenderType()))
{
if (!curve.IsClose)
{
AppToaster.show({
message: "内部曲线必须全是闭合多段线!",
timeout: 5000,
intent: Intent.DANGER,
});
return;
}
}
}
}
let objChace: Map<number, ContourData> = new Map(); let objChace: Map<number, ContourData> = new Map();
//载入UI配置 //载入UI配置
let contourStore = HeadCeilingInfoStore.GetInstance(); let contourStore = HeadCeilingInfoStore.GetInstance();
@ -207,7 +194,6 @@ export default class RoomFlatTopParams extends Component<RoomBaseParamsProps, {}
bulkheadCeiling.SetMaterialAtSlot(app.Database.MaterialTable.CurBulkCeilingFaceMaterial, 0); bulkheadCeiling.SetMaterialAtSlot(app.Database.MaterialTable.CurBulkCeilingFaceMaterial, 0);
let matrix = new Matrix4().setPosition(this.props.roomFlatTopEnt.BoundingBox.min.sub(useCurves[0].BoundingBox.min)); let matrix = new Matrix4().setPosition(this.props.roomFlatTopEnt.BoundingBox.min.sub(useCurves[0].BoundingBox.min));
matrix.multiply(new Matrix4().setPosition(0, 0, -bulkheadCeiling.Height));
useCurves[0].ApplyMatrix(matrix); useCurves[0].ApplyMatrix(matrix);
//先根据最外圈曲线绘制吊顶 //先根据最外圈曲线绘制吊顶
@ -219,16 +205,21 @@ export default class RoomFlatTopParams extends Component<RoomBaseParamsProps, {}
//再根据内部曲线绘制吊顶 //再根据内部曲线绘制吊顶
for (let g of group) for (let g of group)
{ {
for (let curve of g) let cu: Curve;
if (g[0] instanceof Circle)
cu = g[0];
else
{ {
if (selectBox.CheckSelectTraverse(curve.GetDrawObjectFromRenderType())) cu = Polyline.Combine(g);
{ cu.ColorIndex = g[0].ColorIndex;
curve.ApplyMatrix(matrix); }
await this._BuildBulkheadCeiling(contourStore, curve, objChace, bulkheadCeiling); if (selectBox.CheckSelectTraverse(cu.GetDrawObjectFromRenderType()))
{
cu.ApplyMatrix(matrix);
await this._BuildBulkheadCeiling(contourStore, cu, objChace, bulkheadCeiling);
for (let curve of g)
curve.Erase(); curve.Erase();
break;
}
} }
} }
//吊顶绑定天花板 //吊顶绑定天花板
@ -240,6 +231,183 @@ export default class RoomFlatTopParams extends Component<RoomBaseParamsProps, {}
app.Editor.ModalManage.DestoryAll(); app.Editor.ModalManage.DestoryAll();
}; };
//提取吊顶轮廓
_PickUpModelingOnHeadCeiling = async () =>
{
let bulkheadCeiling = this.props.headCeilingEnt;
//载入UI配置
let store = HeadCeilingInfoStore.GetInstance();
let config = new DialogUserConfig(store, BoardModalType.BulkheadCeilingContour);
await config.LoadAndInitConfig();
await CommandWrap(async () =>
{
app.Editor.SelectCtrl.Cancel();
app.Editor.ModalManage.ToggleShow();
app.Editor.MaskManage.Clear();
//视角使用俯视图
await new ViewChange(ZAxisN, true).exec();
app.Viewer.CameraCtrl.ZoomExtentsBox3(bulkheadCeiling.BoundingBox.expandByScalar(8000));
let cu: Polyline;
let paths: Curve[] = [];
let firstPath = bulkheadCeiling.ContourData[0].Path;
//获取吊顶轮廓信息
for (let data of bulkheadCeiling.ContourData)
{
let path = JigUtils.Draw(data.Path.Clone().ApplyMatrix(bulkheadCeiling.OCSNoClone));
paths.push(path);
}
let roomFlatTop = bulkheadCeiling.RelativeRoomFlatTop.Object as RoomFlatTop;
//天花板被拉伸,且面积大于吊顶最大轮廓 补填一个最外围的天花板轮廓
if (roomFlatTop.Area > firstPath.Area)
{
let contuor = roomFlatTop.Contour.Clone();
let mtl = new Matrix4().setPosition(roomFlatTop.BoundingBox.min.sub(contuor.BoundingBox.min));
mtl.multiply(new Matrix4().setPosition(0, 0, -bulkheadCeiling.Height));
cu = JigUtils.Draw(contuor.ApplyMatrix(mtl));
paths.push(cu);
}
let isOk = await selectOutlinePosition(paths);
app.Editor.ModalManage.ToggleShow();
if (isOk)
{
//根据吊顶轮廓信息配置Store
let data: BulkheadCeilingContourData[] = [];
for (let contourData of bulkheadCeiling.ContourData)
{
data.push({
contourType: contourData.ContourType,
contourId: contourData.ContourId,
color: 0,
deviation: contourData.Deviation
});
}
if (cu)
{
data.push({
contourType: BulkheadCeiling_ContourType.Hole,
contourId: NONE_CONTOUR_ID,
color: 0,
deviation: 0
});
}
store.m_Option.Height = bulkheadCeiling.Height;
await store.InitEditorContourItems(data);
for (let i = 0; i < paths.length; i++)
paths[i].ColorIndex = data[i].color;
app.Editor.ModalManage.RenderModeless(
HeadCeilingInfoConfigPanel,
{
store,
isNotUpdateStore: true,
directoryId: DirectoryId.CeilingContour,
configType: BoardModalType.BulkheadCeilingContour,
noClose: true
},
{ canMinimize: false, position: ModalPosition.RightMid }
);
app.Editor.MaskManage.Clear();
app.Editor.ModalManage.MinAll();
}
}, "提取吊顶轮廓");
};
//已有的吊顶使用新轮廓,重新生成新吊顶
_RedoContour = async () =>
{
app.Editor.SelectCtrl.Cancel();
app.Editor.ModalManage.ToggleShow();
app.Editor.MaskManage.Clear();
if (!app.Viewer.CameraCtrl.Direction.equals(new Vector3(0, 0, -1)))
await new ViewChange(ZAxisN, false).exec();
AppToaster.show({
message: "请选择该吊顶提取出来的外围轮廓!",
timeout: 5000,
intent: Intent.PRIMARY,
}, "RedoContour");
await CommandWrap(async () =>
{
//获取应用的轮廓
let { contour, group, useCurves } = await SelectExtrudeContour(true, true, true);
AppToaster.dismiss("RedoContour");
if (!contour) return;
if (!(useCurves[0] as Curve)?.IsClose)
{
AppToaster.show({
message: "选择的外围轮廓错误或没有闭合!",
timeout: 5000,
intent: Intent.DANGER,
}, "ApplayContour");
return;
}
let box = contour.BoundingBox.applyMatrix4(app.Viewer.DCS);
box.expandByVector(new Vector3(1, 1, 1));
let selectBox = new SelectBox(app.Viewer, AsVector2(box.min), AsVector2(box.max), SelectType.C);
//载入UI配置
let contourStore = HeadCeilingInfoStore.GetInstance();
let objChace: Map<number, ContourData> = new Map();
let config = new DialogUserConfig(contourStore, BoardModalType.BulkheadCeilingContour);
await config.LoadAndInitConfig();
let bulkheadCeiling = this.props.headCeilingEnt;
let roomFlatTop = bulkheadCeiling.RelativeRoomFlatTop.Object as RoomFlatTop;
bulkheadCeiling.Height = contourStore.m_Option.Height;
bulkheadCeiling.ContourData = [];
let matrix = bulkheadCeiling.OCSInv;
matrix.multiply(new Matrix4().setPosition(roomFlatTop.BoundingBox.min.sub(useCurves[0].BoundingBox.min)));
useCurves[0].ApplyMatrix(matrix);
//先根据最外圈曲线绘制吊顶
await this._BuildBulkheadCeiling(contourStore, useCurves[0] as Curve, objChace, bulkheadCeiling);
for (let c of useCurves)
c.Erase();
//再根据内部曲线绘制吊顶
for (let g of group)
{
let cu: Curve;
if (g[0] instanceof Circle)
cu = g[0];
else
{
cu = Polyline.Combine(g);
cu.ColorIndex = g[0].ColorIndex;
}
if (selectBox.CheckSelectTraverse(cu.GetDrawObjectFromRenderType()))
{
cu.ApplyMatrix(matrix);
await this._BuildBulkheadCeiling(contourStore, cu, objChace, bulkheadCeiling);
for (let curve of g)
curve.Erase();
}
}
bulkheadCeiling.Update();
}, "重做吊顶");
app.Editor.ModalManage.ToggleShow();
app.Editor.ModalManage.DestoryAll();
};
/** /**
* 线 * 线
* *
@ -259,6 +427,7 @@ export default class RoomFlatTopParams extends Component<RoomBaseParamsProps, {}
let materials: number[] = [];//服务端的mtl_id let materials: number[] = [];//服务端的mtl_id
let shapeMaterialSlotData: number[] = []; //轮廓顺序对应的材质序列 let shapeMaterialSlotData: number[] = []; //轮廓顺序对应的材质序列
let height = 0; //范样轮廓高度
let contourShapeId = contourStore.m_Option.Item.find(item => item.color === curve.ColorIndex && item.example.id !== NONE_CONTOUR_ID)?.example.id; let contourShapeId = contourStore.m_Option.Item.find(item => item.color === curve.ColorIndex && item.example.id !== NONE_CONTOUR_ID)?.example.id;
//该曲线有使用吊顶截面轮廓 //该曲线有使用吊顶截面轮廓
@ -325,6 +494,9 @@ export default class RoomFlatTopParams extends Component<RoomBaseParamsProps, {}
} }
} }
} }
//使用范样最高高度 以基点为准
height = dbData.polyline.BoundingBox.max.y;
} }
} }
@ -362,6 +534,9 @@ export default class RoomFlatTopParams extends Component<RoomBaseParamsProps, {}
clonedMtls.push(app.Database.MaterialTable.GetAt(material.Name).Id); clonedMtls.push(app.Database.MaterialTable.GetAt(material.Name).Id);
} }
if (!clonedMtls.length)
clonedMtls.push(app.Database.MaterialTable.CurBulkCeilingFaceMaterial as ObjectId<PhysicalMaterialRecord>);
let example = contourStore.m_Option.Item.find((item) => curve.ColorIndex === item.color).example; let example = contourStore.m_Option.Item.find((item) => curve.ColorIndex === item.color).example;
bulkheadCeiling.ContourData.push({ bulkheadCeiling.ContourData.push({
ContourType: example.contourType, ContourType: example.contourType,
@ -370,199 +545,161 @@ export default class RoomFlatTopParams extends Component<RoomBaseParamsProps, {}
Contour: dbData.polyline, Contour: dbData.polyline,
ContourId: example.id, ContourId: example.id,
Materials: clonedMtls, Materials: clonedMtls,
ShapeMaterialSlotData: shapeMaterialSlotData ShapeMaterialSlotData: shapeMaterialSlotData,
Deviation: example.deviation,
Height: height
}); });
} }
//提取吊顶轮廓 private _GetNewContourDate = async (bulkheadCeiling: BulkheadCeiling, contourStore: HeadCeilingInfoStore) =>
_PickUpModelingOnHeadCeiling = async () =>
{ {
let bulkheadCeiling = this.props.headCeilingEnt; let height = 0; //范样轮廓高度
let objChace: Map<number, ContourData> = new Map();
let contourDatas: BulkheadCeiling_ContourData[] = [];
//载入UI配置 for (let i = 0; i < bulkheadCeiling.ContourData.length; i++)
let store = HeadCeilingInfoStore.GetInstance();
let config = new DialogUserConfig(store, BoardModalType.BulkheadCeilingContour);
await config.LoadAndInitConfig();
await CommandWrap(async () =>
{ {
app.Editor.SelectCtrl.Cancel(); let data = bulkheadCeiling.ContourData[i];
app.Editor.ModalManage.ToggleShow(); let example = contourStore.m_Option.Item[i].example;
app.Editor.MaskManage.Clear();
//视角使用俯视图 data.Deviation = example.deviation;
await new ViewChange(ZAxisN, true).exec(); data.ContourType = example.contourType;
app.Viewer.CameraCtrl.ZoomExtentsBox3(bulkheadCeiling.BoundingBox.expandByScalar(8000));
let cu: Polyline; if (data.ContourId !== example.id)
let paths: Curve[] = [];
let firstPath = bulkheadCeiling.ContourData[0].Path;
//获取吊顶轮廓信息
for (let data of bulkheadCeiling.ContourData)
{ {
let path = JigUtils.Draw(data.Path.Clone().ApplyMatrix(bulkheadCeiling.OCSNoClone)); data.ContourId = example.id;
paths.push(path); if (example.id === 0)
}
let roomFlatTop = bulkheadCeiling.RelativeRoomFlatTop.Object as RoomFlatTop;
//天花板被拉伸,且面积大于吊顶最大轮廓 补填一个最外围的天花板轮廓
if (roomFlatTop.Area > firstPath.Area)
{
let contuor = roomFlatTop.Contour.Clone();
let mtl = new Matrix4().setPosition(roomFlatTop.BoundingBox.min.sub(contuor.BoundingBox.min));
mtl.multiply(new Matrix4().setPosition(0, 0, -bulkheadCeiling.Height));
cu = JigUtils.Draw(contuor.ApplyMatrix(mtl));
paths.push(cu);
}
let isOk = await selectOutlinePosition(paths);
app.Editor.ModalManage.ToggleShow();
if (isOk)
{
//根据吊顶轮廓信息配置Store
let data: BulkheadCeilingContourData[] = [];
for (let contourData of bulkheadCeiling.ContourData)
{ {
data.push({ data.Contour = undefined;
contourType: contourData.ContourType, data.Materials = [];
contourId: contourData.ContourId, data.ShapeMaterialSlotData = [];
color: 0 data.Height = 300;
});
} }
else
if (cu)
{ {
data.push({ let dbData: ContourData = {
contourType: BulkheadCeiling_ContourType.Hole, polyline: undefined,
contourId: NONE_CONTOUR_ID, database: undefined,
color: 0 extData: undefined
}); };
}
await store.InitEditorContourItems(data); let materials: number[] = [];//服务端的mtl_id
let shapeMaterialSlotData: number[] = []; //轮廓顺序对应的材质序列
for (let i = 0; i < paths.length; i++) //该曲线有使用吊顶截面轮廓
paths[i].ColorIndex = data[i].color; if (!objChace.has(example.id))
app.Editor.ModalManage.RenderModeless(
HeadCeilingInfoConfigPanel,
{ {
store, //获取截面轮廓信息
isNotUpdateStore: true, let db = new Database(false, false, true);
directoryId: DirectoryId.CeilingContour, let contourData = await GetCeilingContourDate(example.id.toString());
configType: BoardModalType.BulkheadCeilingContour, if (!contourData)
noClose: true {
}, data.Contour = undefined;
{ canMinimize: false, position: ModalPosition.RightMid } data.Materials = [];
); data.ShapeMaterialSlotData = [];
app.Editor.MaskManage.Clear(); contourDatas.push(data);
app.Editor.ModalManage.MinAll(); continue;
} }
}, "提取吊顶轮廓"); else
}; {
let json = inflateBase64(contourData.toplines.file);
//已有的吊顶使用新轮廓,重新生成新吊顶 let f = new CADFiler(JSON.parse(json));
_RedoContour = async () => db.FileRead(f);
{ dbData.polyline = Contour.Combine(db.ModelSpace.Entitys as Curve[], true) as Polyline;
app.Editor.SelectCtrl.Cancel(); if (dbData.polyline.Area2 > 0)
app.Editor.ModalManage.ToggleShow(); dbData.polyline.Reverse();
app.Editor.MaskManage.Clear();
if (!app.Viewer.CameraCtrl.Direction.equals(new Vector3(0, 0, -1))) let tempF = new CADFiler(db.ExtendedData);
await new ViewChange(ZAxisN, false).exec(); let extData = new BulkheadCeilingShapeTemplateExtendData;
extData.ReadFile(tempF);
AppToaster.show({ dbData.database = db;
message: "请选择该吊顶提取出来的外围轮廓!", dbData.extData = extData;
timeout: 5000,
intent: Intent.PRIMARY,
}, "RedoContour");
await CommandWrap(async () => objChace.set(example.id, dbData);
{ }
//获取应用的轮廓 }
let { contour, group, useCurves } = await SelectExtrudeContour(true, true, true); else
AppToaster.dismiss("RedoContour"); dbData = objChace.get(example.id);
if (!contour) return; //使用范样最高高度 以基点为准
if (!(useCurves[0] as Curve)?.IsClose) height = dbData.polyline.BoundingBox.max.y;
{
AppToaster.show({
message: "选择的外围轮廓错误或没有闭合!",
timeout: 5000,
intent: Intent.DANGER,
}, "ApplayContour");
return;
}
let box = contour.BoundingBox.applyMatrix4(app.Viewer.DCS); //收集材质id
box.expandByVector(new Vector3(1, 1, 1)); if (dbData.extData)
let selectBox = new SelectBox(app.Viewer, AsVector2(box.min), AsVector2(box.max), SelectType.C); for (let [color, mtlId] of dbData.extData.Color_MaterialId)
materials.push(mtlId);
for (let g of group) //材质槽分析
{ for (let i = 0; i < dbData.polyline.EndParam; i++)
for (let curve of g)
{
if (selectBox.CheckSelectTraverse(curve.GetDrawObjectFromRenderType()))
{ {
if (!curve.IsClose) let param = i + 0.5;
let p = dbData.polyline.GetPointAtParam(param);
for (let ent of dbData.database.ModelSpace.Entitys)
{ {
AppToaster.show({ if (ent instanceof Curve && ent.PtOnCurve(p))
message: "内部曲线必须全是闭合多段线!", {
timeout: 5000, let color = ent.ColorIndex;
intent: Intent.DANGER, let materialId = dbData.extData.Color_MaterialId.get(color);
}); if (materialId)
return; shapeMaterialSlotData.push(materials.findIndex((mtlId) => mtlId === materialId));
else
shapeMaterialSlotData.push(0);
break;
}
} }
} }
}
}
//载入UI配置
let contourStore = HeadCeilingInfoStore.GetInstance();
let objChace: Map<number, ContourData> = new Map();
let config = new DialogUserConfig(contourStore, BoardModalType.BulkheadCeilingContour);
await config.LoadAndInitConfig();
let bulkheadCeiling = this.props.headCeilingEnt; //将材质载入到当前图纸
let roomFlatTop = bulkheadCeiling.RelativeRoomFlatTop.Object as RoomFlatTop; let clonedMtls: ObjectId<PhysicalMaterialRecord>[] = [];
bulkheadCeiling.ContourData = []; for (let mtlid of materials)
{
let matrix = bulkheadCeiling.OCSInv; if (mtlid === NONE_MATERIAL_ID)
matrix.multiply(new Matrix4().setPosition(roomFlatTop.BoundingBox.min.sub(useCurves[0].BoundingBox.min))); {
matrix.multiply(new Matrix4().setPosition(0, 0, -bulkheadCeiling.Height)); clonedMtls.push(undefined);
useCurves[0].ApplyMatrix(matrix); continue;
}
//先根据最外圈曲线绘制吊顶 let mtlData = await PostJson(MaterialUrls.detail, { material_id: mtlid }, false);
await this._BuildBulkheadCeiling(contourStore, useCurves[0] as Curve, objChace, bulkheadCeiling);
for (let c of useCurves) if (mtlData.err_code !== RequestStatus.Ok)
c.Erase(); {
//再根据内部曲线绘制吊顶 AppToaster.show({
for (let g of group) message: "截面轮廓内设置的材质已被删除或丢失,请检查!",
{ timeout: 3000,
for (let curve of g) intent: Intent.DANGER,
{ }, "mtl_err");
if (selectBox.CheckSelectTraverse(curve.GetDrawObjectFromRenderType())) clonedMtls.push(undefined);
{ continue;
curve.ApplyMatrix(matrix); }
await this._BuildBulkheadCeiling(contourStore, curve, objChace, bulkheadCeiling);
curve.Erase(); let material = MaterialIn(JSON.parse(inflateBase64(mtlData.materials.file)) as Object[]) as PhysicalMaterialRecord;
break; material.Name = mtlData.materials.name;
app.Database.WblockCloneObejcts(
[material],
app.Database.MaterialTable,
new Map(),
DuplicateRecordCloning.Ignore
);
clonedMtls.push(app.Database.MaterialTable.GetAt(material.Name).Id);
} }
data.Materials = clonedMtls;
data.ContourId = example.id;
data.Contour = dbData.polyline;
data.ShapeMaterialSlotData = shapeMaterialSlotData;
data.Height = height;
} }
} }
bulkheadCeiling.Update(); contourDatas.push(data);
}, "重做吊顶"); }
return contourDatas;
app.Editor.ModalManage.ToggleShow();
app.Editor.ModalManage.DestoryAll();
}; };
render() render()
{ {
let headCeilingEnt = this.props.headCeilingEnt;
return ( return (
<div id="OperRoomFlatTop" className={Classes.DIALOG_CONTAINER}> <div id="OperRoomFlatTop" className={Classes.DIALOG_CONTAINER}>
<div className={Classes.DIALOG}> <div className={Classes.DIALOG}>
@ -578,14 +715,44 @@ export default class RoomFlatTopParams extends Component<RoomBaseParamsProps, {}
</div> </div>
<div> <div>
<div className={Classes.DIALOG_BODY}> <div className={Classes.DIALOG_BODY}>
<Button {
text="轮廓提取" headCeilingEnt &&
onClick={this.props.headCeilingEnt ? this._PickUpModelingOnHeadCeiling : this._PickUpModelingOnFlatTop} <CeilingInfoModifyPanel
/> headCeilingEnt={headCeilingEnt}
<Button headCeilingInfoStore={this._HeadCeilingInfoStore}
text="轮廓应用" />
onClick={this.props.headCeilingEnt ? this._RedoContour : this._ApplayContour} }
/> <div className="apply_button">
<div className="button_left">
<Button
text="轮廓提取"
onClick={this.props.headCeilingEnt ? this._PickUpModelingOnHeadCeiling : this._PickUpModelingOnFlatTop}
/>
<Button
text="拾取轮廓"
onClick={this.props.headCeilingEnt ? this._RedoContour : this._ApplayContour}
/>
</div>
{
headCeilingEnt &&
<div className="button_right">
<Button
text="应用修改的数值"
onClick={() =>
{
EntityUpdateWrap(headCeilingEnt, async () =>
{
await CommandWrap(async () =>
{
headCeilingEnt.ContourData = await this._GetNewContourDate(headCeilingEnt, this._HeadCeilingInfoStore);
headCeilingEnt.Height = this._HeadCeilingInfoStore.m_Option.Height;
}, "修改吊顶");
});
}}
/>
</div>
}
</div>
</div> </div>
</div> </div>
</div> </div>

@ -3,10 +3,11 @@ import { observable } from "mobx";
import { ToplineUrls } from "../../../Common/HostUrl"; import { ToplineUrls } from "../../../Common/HostUrl";
import { IResponseData, PostJson, RequestStatus } from "../../../Common/Request"; import { IResponseData, PostJson, RequestStatus } from "../../../Common/Request";
import { CADFiler } from "../../../DatabaseServices/CADFiler"; import { CADFiler } from "../../../DatabaseServices/CADFiler";
import { BulkheadCeiling_ContourType } from "../../../DatabaseServices/Room/Entity/Ceiling/BulkheadCeiling"; import { BulkheadCeiling, BulkheadCeiling_ContourType } from "../../../DatabaseServices/Room/Entity/Ceiling/BulkheadCeiling";
import { DefaultBulkheadCeilingOption } from "../../../Editor/DefaultConfig";
import { AppToaster } from "../../Components/Toaster"; import { AppToaster } from "../../Components/Toaster";
import { IConfigStore } from "../BoardStore"; import { IConfigStore } from "../BoardStore";
import { BulkheadCeilingOption } from "../OptionInterface/BulkheadCeilingOption"; import { BulkheadCeilingOption, ICeilingItem } from "../OptionInterface/BulkheadCeilingOption";
export const NONE_CONTOUR_ID = -1; export const NONE_CONTOUR_ID = -1;
@ -15,13 +16,14 @@ export interface BulkheadCeilingContourData
contourType: BulkheadCeiling_ContourType; contourType: BulkheadCeiling_ContourType;
contourId: number; contourId: number;
color: number; color: number;
deviation: number; //线条上下偏移量 正数向上
} }
export class HeadCeilingInfoStore implements IConfigStore export class HeadCeilingInfoStore implements IConfigStore
{ {
@observable configName = "默认"; @observable configName = "默认";
@observable configsNames: string[] = []; @observable configsNames: string[] = [];
@observable m_Option: BulkheadCeilingOption = { Item: [] }; @observable m_Option: BulkheadCeilingOption = DefaultBulkheadCeilingOption;
InitOption() InitOption()
{ {
@ -38,15 +40,49 @@ export class HeadCeilingInfoStore implements IConfigStore
{ {
color: i + 1, color: i + 1,
example: { example: {
contourType: BulkheadCeiling_ContourType.Land, //默认是岛 contourType: BulkheadCeiling_ContourType.Land,
id: NONE_CONTOUR_ID, id: NONE_CONTOUR_ID,
name: "", name: "",
logo: "" logo: "",
deviation: 0
} }
}, },
); );
} }
} }
this.m_Option.Height = DefaultBulkheadCeilingOption.Height;
}
async InitItemsForBulkheadCeiling(headCeilingEnt: BulkheadCeiling)
{
this.m_Option.Item = [];
for (let i = 0; i < headCeilingEnt.ContourData.length; i++)
{
let data = headCeilingEnt.ContourData[i];
let item: ICeilingItem = {
color: i + 1,
example: {
contourType: data.ContourType,
id: data.ContourId,
name: "无",
logo: "",
deviation: data.Deviation
}
};
if (data.ContourId > 0)
{
const contourData = await GetCeilingContourDate(data.ContourId.toString());
item.example.name = contourData?.toplines?.name;
item.example.logo = contourData?.toplines?.logo;
}
this.m_Option.Item.push(item);
}
this.m_Option.Height = headCeilingEnt.Height;
} }
/** /**
@ -66,7 +102,8 @@ export class HeadCeilingInfoStore implements IConfigStore
//item中是否包含这个材质 //item中是否包含这个材质
let item = this.m_Option.Item.find(e => ( let item = this.m_Option.Item.find(e => (
e.example.id === data.contourId && e.example.id === data.contourId &&
e.example.contourType === data.contourType e.example.contourType === data.contourType &&
e.example.deviation === data.deviation
)); ));
//有就不添加 //有就不添加
@ -94,6 +131,7 @@ export class HeadCeilingInfoStore implements IConfigStore
id: data.contourId, id: data.contourId,
name: contourData?.toplines?.name ?? "无", name: contourData?.toplines?.name ?? "无",
logo: contourData?.toplines?.logo ?? "", logo: contourData?.toplines?.logo ?? "",
deviation: data.deviation
} }
}, },
); );
@ -112,6 +150,7 @@ export class HeadCeilingInfoStore implements IConfigStore
example.contourType = data.contourType; example.contourType = data.contourType;
example.name = contourData?.toplines?.name ?? "无"; example.name = contourData?.toplines?.name ?? "无";
example.logo = contourData?.toplines?.logo ?? ""; example.logo = contourData?.toplines?.logo ?? "";
example.deviation = data.deviation;
data.color = this.m_Option.Item[index].color; data.color = this.m_Option.Item[index].color;
index++; index++;
break; break;
@ -139,10 +178,10 @@ export class HeadCeilingInfoStore implements IConfigStore
{ {
let ver = file.Read(); let ver = file.Read();
let count = file.Read(); let count = file.Read();
this.m_Option.Item = []; let item = [];
for (let i = 0; i < count; i++) for (let i = 0; i < count; i++)
{ {
this.m_Option.Item.push( item.push(
{ {
color: file.Read(), color: file.Read(),
example: { example: {
@ -150,15 +189,18 @@ export class HeadCeilingInfoStore implements IConfigStore
id: file.Read(), id: file.Read(),
name: file.Read(), name: file.Read(),
logo: file.Read(), logo: file.Read(),
deviation: ver > 1 ? file.Read() : 0
} }
} }
); );
} }
this.m_Option.Item = item;
this.m_Option.Height = ver > 1 ? file.Read() : DefaultBulkheadCeilingOption.Height;
}; };
WriteFile(file: CADFiler = new CADFiler) WriteFile(file: CADFiler = new CADFiler)
{ {
file.Write(1); file.Write(2);
file.Write(this.m_Option.Item.length); file.Write(this.m_Option.Item.length);
for (let item of this.m_Option.Item) for (let item of this.m_Option.Item)
{ {
@ -167,7 +209,10 @@ export class HeadCeilingInfoStore implements IConfigStore
file.Write(item.example.id); file.Write(item.example.id);
file.Write(item.example.name); file.Write(item.example.name);
file.Write(item.example.logo); file.Write(item.example.logo);
file.Write(item.example.deviation);
} }
file.Write(this.m_Option.Height);
return file.Data; return file.Data;
} }

@ -19,15 +19,23 @@ export interface ICeilingItem
id: number; //吊顶轮廓id id: number; //吊顶轮廓id
name: string; name: string;
logo: string; logo: string;
deviation: number; //线条上下偏移量
}; };
} }
export interface BulkheadCeilingOption extends IBaseOption export interface BulkheadCeilingOption extends IBaseOption
{ {
Item: ICeilingItem[]; Item: ICeilingItem[];
Height: number;
} }
export interface BulkheadCeilingProfileMaterialOption extends IBaseOption export interface BulkheadCeilingProfileMaterialOption extends IBaseOption
{ {
Item: ICeilingProfileMaterialItem[]; Item: ICeilingProfileMaterialItem[];
} }
export enum Display
{
Block = "block",
None = "none",
}

Loading…
Cancel
Save