123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340 |
- import { AttachCAD as CAD } from '../index'
- import { Data, _Point, _Line, _window, _door, _column, FloorData } from '../base/processing/index'
- import Stack from '../base/stack'
- import Point from '../core/point'
- import Case from '../architecture/casement'
- import Door from '../architecture/door/index'
- import Column from '../architecture/column'
- import GroundCase from '../architecture/groundCase'
- import SlideDoor from '../architecture/slideDoor'
- import BayCase from '../architecture/bayCase'
- import FurnColumn from '../furniture/column'
- import FurnFlue from '../furniture/flue'
- import { debounce } from '../util'
- import Line from '../core/line'
- import wallline from '../core/wallline'
- import DoubleDoor from '../architecture/doubleDoor'
- import Tagging from '../label/tagging'
- import linearch from '../architecture/linearch'
- import furn from '../furniture/furn'
- import calcRoom from './calcRoom'
- let notSave = false
- export interface transformRet {
- getData: (isCalcRoom?: boolean) => FloorData
-
- loadData: (data: FloorData | Data) => void
- getCurrentData: () => FloorData
- }
- type stackStatus = { previous: boolean, next: boolean }
- export interface stackRet {
- getStackState: () => stackStatus
- preservation: () => void
- previous: () => stackStatus
- stack: Stack
- next: () => stackStatus
- clearStack: () => void
- }
- // 兼容V2
- const compatiblev2 = (data: any): Data => {
- data.column = data.column || []
- data.window = data.window || []
- data.doubleDoor = data.doubleDoor || []
- data.door = data.door || []
- data.groundCase = data.groundCase || []
- data.bayCase = data.bayCase || []
- data.slideDoor = data.slideDoor || []
- data.tagging = data.tagging || []
- data.furnColumn = data.furnColumn || []
- data.furnFlue = data.furnFlue || []
- let eles = ['column', 'window', 'door', 'groundCase', 'bayCase', 'slideDoor', 'tagging', 'furnColumn', 'furnFlue']
- if (data['vertex-xy']) {
- data.vertex = data['vertex-xy']
- data.wall = data['segment'].map(item => ({ id: item.id, p1: item.a, p2: item.b, border: item.border, exterior: item.exterior }))
- }
-
- if (data['outdoor-segment']) {
- data.wall = data.wall.concat(data['outdoor-segment'].map(item => ({ id: item.id, p1: item.a, p2: item.b, border: item.border, exterior: true })))
- data.vertex = data.vertex.concat(data['outdoor-vertex'])
- }
- for (let i = 0; i < data.wall.length; i++) {
- let checkWalls = data.wall.filter(item => item !== data.wall[i])
- let so = checkWalls.find(({ p1, p2 }) => {
- return (p1 === data.wall[i].p1 && p2 === data.wall[i].p2) ||
- (p2 === data.wall[i].p1 && p1 === data.wall[i].p2)
- })
- if (so) {
- eles.forEach(attr => {
- data[attr].forEach((item) => {
- if (item.line === data.wall[i].id) {
- item.line = so.id
- console.log('update', item)
- }
- })
- })
- data.wall.splice(i--, 1)
- }
- }
- data.vertex = data.vertex.filter(p => data.wall.some(({ p1, p2 }) => p.id === p1 || p.id === p2))
- return data
- }
- // 反转cad图所有点的Y轴 因为cad与三维Y方向不一样
- export const roateDataY = (data: Data): Data => {
- data = {
- ...data,
- vertex: data.vertex.map(p => ({ ...p, y: -p.y })),
- window: [...data.window],
- column: [...data.column],
- door: [...data.door],
- groundCase: [...data.groundCase],
- slideDoor: [...data.slideDoor],
- bayCase: [...data.bayCase],
- tagging: [...data.tagging],
- furnColumn: [...data.furnColumn],
- furnFlue: [...data.furnFlue],
- doubleDoor: [...data.doubleDoor]
- };
- [data.window, data.column, data.door, data.slideDoor, data.tagging, data.groundCase, data.bayCase, data.furnColumn, data.furnFlue, data.doubleDoor].forEach((eles) => {
- eles.forEach((ele, i) => {
- eles[i] = {
- ...ele,
- // 反转Y
- pos: ele.pos.map((p, i) => (i % 2) ? -p : p)
- }
- })
- })
- return data
- }
- // 附加数据与svg转换功能
- export const attchTransform = (cad: CAD) => {
- // 获取数据
- cad.getData = (isCalcRoom = false): FloorData => {
- return {
- floors: cad.processings.map(processing => {
- let data = roateDataY(processing.toData())
- data.dire = processing.direction.angle
-
- if (isCalcRoom) {
- data = calcRoom(data, cad)
- }
-
- return data
- })
- }
- }
- // 加载数据
- cad.loadData = (ndata: FloorData | Data) => {
- if (!(ndata as FloorData).floors) {
- (ndata as Data).show = true
- ndata = {floors: [(ndata as Data)]}
- }
- let data: FloorData = JSON.parse(JSON.stringify(ndata)) as FloorData
- if (!data.floors.some(item => item.show)) {
- data.floors[0].show = true
- }
- data.floors = data.floors.map(floor => roateDataY(compatiblev2(floor)))
- notSave = true
- // 卸载旧数据
- cad.processings.forEach(processing => {
- // 卸载旧数据
- processing.attrs.forEach(attr => {
- while (processing[attr].length) {
- // 同步删除
- processing[attr][0].ele.destroy(true, true)
- }
- })
- })
- data.floors.forEach(item => {
- let processing = cad.processings.find(({id}) => id === item.id)
- if (!processing) {
- processing = cad.addProcessing()
- processing.id = item.id
- }
- })
- for (let i = 0; i < cad.processings.length; i++) {
- if (!data.floors.some(({id}) => cad.processings[i].id === id)) {
- cad.delProcessing(cad.processings[i--])
- }
- }
- cad.processings.forEach(processing => {
- for (let i = 0; i < processing.render.elements.length; i++) {
- let ele = processing.render.elements[i]
- let delAttrs = [Case, Door, SlideDoor, DoubleDoor, Column, wallline, Point, GroundCase, Tagging, BayCase, FurnColumn, FurnFlue]
-
- if (delAttrs.some(cls => ele instanceof cls)) {
- processing.render.remove(ele)
- i--
- }
- }
- })
- data.floors.forEach(item => {
- let processing = cad.processings.find(({id}) => {
- return id === item.id
- })
- item.surplus = []
- processing.toEles(item)
- processing.direction.__state.direct = true
- processing.direction.angle = item.dire || 0
- processing.direction.__state.direct = false
- processing.direction.update()
- cad.adapt(item, void 0, void 0, data.floors[0])
- })
- setTimeout(() => notSave = false, 5000)
- }
- }
- // 附加栈功能
- export const attchStack = (cad: CAD) => {
- sessionStorage.clear();
- let current = 0
- let stack = new Stack('cad_' + Date.now())
- cad.stack = stack
- const getRet = (c = current): stackStatus => {
- let slen = stack.getLength()
- let previous = slen === 1 && current === 1 ? false : c > 0
- return { previous: previous, next: c < slen - 1 }
- }
- cad.clearStack = () => {
- sessionStorage.clear()
- stack.setLength(current = 0)
- }
-
- cad.getCurrentData = () => stack.get(current - 1)
- // 保存
- cad.preservation = debounce(() => {
- if ((cad as any).stoppreservation) return;
- // if (notSave) return;
- let newData = cad.getData()
- let prevIndex = stack.getLength() - 1
- // 旧版数据,先注释
- // newData["vertex-xy"] = newData["vertex-xy"].concat(newData.surplus)
- // delete newData.surplus
- if (prevIndex === 0 ||
- JSON.stringify(newData) !== JSON.stringify(stack.get(prevIndex))
- ) {
- // stack.setLength(current + 1)
- stack.push(newData)
- ++current
- }
- }, 500)
- let minStep = 500
- let currDate = Date.now()
- let timeout
- // 撤销
- cad.previous = (): stackStatus => {
- if (!getRet().previous) return getRet()
- --current
- clearTimeout(timeout)
- timeout = setTimeout(() => {
- // console.log(stack.get(current))
- cad.loadData(stack.get(current))
- }, minStep)
- return getRet()
- }
- // 回退
- cad.next = (): stackStatus => {
- if (!getRet().next) return getRet()
- ++current
- clearTimeout(timeout)
- timeout = setTimeout(() => {
- cad.loadData(stack.get(current))
- }, minStep)
- return getRet()
- if (Date.now() - currDate > minStep) {
- currDate = Date.now()
- getRet().next && cad.loadData(stack.get(++current))
- }
- return getRet()
- }
- cad.getStackState = getRet
- let destroy = cad.destroy
- cad.destroy = function (...args) {
- stack = null
- destroy.apply(this, args)
- }
- }
- // 附加自动保存功能
- export const autoPreservation = (cad: CAD) => {
- [Point, Case, Door, Column, GroundCase, SlideDoor, BayCase, FurnColumn, Line, FurnFlue, wallline, DoubleDoor].forEach(cls => {
- let dragend = cls.prototype.dragEnd
- cls.prototype.dragEnd = async function (...args) {
- dragend && await dragend.call(this, ...args)
- setTimeout(() => {
- cad.preservation()
- }, 100)
- }
- let destroy = cad.destroy
- cad.destroy = function (...args) {
- destroy.apply(this, args)
- cls.prototype.dragEnd = dragend
- }
- });
- const increase = cad.increase
- cad.increase = (...args) => {
- let ret = increase.call(cad, ...args)
- if (!ret.error) {
- setTimeout(() => {
- cad.preservation()
- }, 100)
- }
- return ret
- }
- cad.preservation()
- }
|