UNPKG

kitchen-simulator

Version:

It is a kitchen simulator (self-contained micro-frontend).

663 lines (653 loc) 26.7 kB
import _classCallCheck from "@babel/runtime/helpers/esm/classCallCheck"; import _createClass from "@babel/runtime/helpers/esm/createClass"; import { List } from 'immutable'; import { Project, Area, Line, Hole, Item, Vertex } from "./export"; import { GraphInnerCycles, GeometryUtils, IDBroker } from "../utils/export"; import { Layer as LayerModel } from "../models"; import { isEmpty } from "../utils/helper"; var sameSet = function sameSet(set1, set2) { return set1.size === set2.size && set1.isSuperset(set2) && set1.isSubset(set2); }; var sameDirection = function sameDirection(list1, list2) { if (!sameSet(list1, list2)) return false; if (list1.size < 3) return true; var l0 = list1.get(0); var l1 = list1.get(1); var i0 = list2.indexOf(l0); var i1 = list2.indexOf(l1); return (i1 - i0 - 1) % list1.size == 0; }; var Layer = /*#__PURE__*/function () { function Layer() { _classCallCheck(this, Layer); } return _createClass(Layer, null, [{ key: "create", value: function create(state, name, altitude) { var layerID = IDBroker.acquireID(); name = name || "layer ".concat(layerID); altitude = altitude || 0; var layer = new LayerModel({ id: layerID, name: name, altitude: altitude }); state = state.setIn(['scene', 'selectedLayer'], layerID); state = state.setIn(['scene', 'layers', layerID], layer); return { updatedState: state }; } }, { key: "select", value: function select(state, layerID) { if (!state.get('alterate')) state = Project.unselectAll(state).updatedState; state = state.setIn(['scene', 'selectedLayer'], layerID); return { updatedState: state }; } }, { key: "selectAll", value: function selectAll(state, layerID) { if (!state.get('alterate')) state = Project.unselectAll(state).updatedState; state = state.setIn(['scene', 'selectedLayer'], layerID); var layer = state.scene.layers.get(layerID); layer.items.forEach(function (data) { state = Layer.selectElement(state, layerID, 'items', data.id).updatedState; }); layer.lines.forEach(function (data) { state = Layer.selectElement(state, layerID, 'lines', data.id).updatedState; }); layer.holes.forEach(function (data) { state = Layer.selectElement(state, layerID, 'holes', data.id).updatedState; }); layer.areas.forEach(function (data) { state = Layer.selectElement(state, layerID, 'areas', data.id).updatedState; }); layer.vertices.forEach(function (data) { state = Layer.selectElement(state, layerID, 'vertices', data.id).updatedState; }); return { updatedState: state }; } }, { key: "selectElement", value: function selectElement(state, layerID, elementPrototype, elementID) { state = state.setIn(['scene', 'layers', layerID, elementPrototype, elementID, 'selected'], true); state = state.updateIn(['scene', 'layers', layerID, 'selected', elementPrototype], function (elems) { return elems.push(elementID); }); return { updatedState: state }; } }, { key: "unselect", value: function unselect(state, layerID, elementPrototype, elementID) { state = state.setIn(['scene', 'layers', layerID, elementPrototype, elementID, 'selected'], false); state = state.updateIn(['scene', 'layers', layerID, 'selected', elementPrototype], function (elems) { return elems.filter(function (el) { return el.id === elementID; }); }); return { updatedState: state }; } }, { key: "updateMovingState", value: function updateMovingState(state, showflag) { var _state = state, scene = _state.scene; state = state.merge({ scene: scene.mergeIn(['showfg'], showflag) }); return { updatedState: state }; } }, { key: "unselectAll", value: function unselectAll(state, layerID) { var _state$getIn = state.getIn(['scene', 'layers', layerID]), lines = _state$getIn.lines, holes = _state$getIn.holes, items = _state$getIn.items, areas = _state$getIn.areas; if (lines) lines.forEach(function (line) { state = Line.unselect(state, layerID, line.id).updatedState; }); if (holes) holes.forEach(function (hole) { state = Hole.unselect(state, layerID, hole.id).updatedState; }); if (items) items.forEach(function (item) { state = Item.unselect(state, layerID, item.id).updatedState; }); if (areas) areas.forEach(function (area) { state = Area.unselect(state, layerID, area.id).updatedState; }); return { updatedState: state }; } }, { key: "setInitialDoorStyle", value: function setInitialDoorStyle(state, doorStyle, oStyle) { state = state.merge({ doorStyle: doorStyle }); var _state2 = state, scene = _state2.scene; var layerID = scene.get('selectedLayer'); var selectedLayer = scene.layers.get(layerID); selectedLayer = selectedLayer.setIn(['doorStyle'], doorStyle); state = state.merge({ scene: scene.setIn(['layers', layerID], selectedLayer) }); return { updatedState: state }; } }, { key: "setProperties", value: function setProperties(state, layerID, properties) { state = state.mergeIn(['scene', 'layers', layerID], properties); state = state.updateIn(['scene', 'layers'], function (layers) { return layers.sort(function (a, b) { return a.altitude !== b.altitude ? a.altitude - b.altitude : a.order - b.order; }); }); return { updatedState: state }; } }, { key: "remove", value: function remove(state, layerID) { state = state.removeIn(['scene', 'layers', layerID]); state = state.setIn(['scene', 'selectedLayer'], state.scene.selectedLayer !== layerID ? state.scene.selectedLayer : state.scene.layers.first().id); return { updatedState: state }; } }, { key: "removeElement", value: function removeElement(state, layerID, elementPrototype, elementID) { state = state.deleteIn(['scene', 'layers', layerID, elementPrototype, elementID]); return { updatedState: state }; } }, { key: "lineInterior", value: function lineInterior(relatedLine, line, changeLines, vertices, allLines, checkLines) { var _this = this; if (line.vertices[1] === relatedLine.vertices[1] || line.vertices[0] === relatedLine.vertices[0]) { var tmp = line.vertices[0]; line.vertices[0] = line.vertices[1]; line.vertices[1] = tmp; changeLines.push(line); } checkLines.push(relatedLine); checkLines.push(line); var relatedLines = []; GeometryUtils.getRelatedLines(relatedLines, line, vertices, allLines); var delflag = false; if (isEmpty(allLines[line.id])) { delflag = true; } if (relatedLines.length > 1) { var _loop = function _loop(i) { if (!changeLines.some(function (line) { return line.id === relatedLines[i].id; }) && !checkLines.some(function (cline) { return cline.id === relatedLines[i].id; })) { var tline = delflag ? relatedLine : line; _this.lineInterior(tline, relatedLines[i], changeLines, vertices, allLines, checkLines); } }; for (var i = 0; i < relatedLines.length; i++) { _loop(i); } } else return; } }, { key: "interiorsurfacedetect", value: function interiorsurfacedetect(state, drawingLine, vertices, allLineArray, layerID) { var relatedLines = []; var allLines = allLineArray.toJS(); GeometryUtils.getRelatedLines(relatedLines, drawingLine, vertices, allLines); if (isEmpty(relatedLines)) { return { updatedState: state }; } var changeLines = []; var checkLines = []; this.lineInterior(relatedLines[0], drawingLine, changeLines, vertices, allLines, checkLines); for (var i = 0; i < changeLines.length; i++) { // if (changeLines[i].vertices.length === 2) if (!isEmpty(allLines[changeLines[i].id])) { state = state.mergeIn(['scene', 'layers', layerID, 'lines', changeLines[i].id, 'vertices'], changeLines[i].vertices); } } // determine the interior surface var alltriangles = []; var interiorLines = state.getIn(['scene', 'layers', layerID, 'lines']); var tallLines = interiorLines.toJS(); var tallLinesArray = interiorLines.toArray(); var reverseLines = []; tallLinesArray.forEach(function (tline) { var line = tline.toJS(); var relatedLines = []; GeometryUtils.getRelatedLines(relatedLines, line, vertices, tallLines); relatedLines.forEach(function (relLine) { if (relLine.vertices[0] === line.vertices[1]) { if (!reverseLines.some(function (reverseLine) { return reverseLine.id === relLine.id; })) { reverseLines.push(relLine); } if (!reverseLines.some(function (reverseLine) { return reverseLine.id === line.id; })) { reverseLines.push(line); } // get the three points of triangle var x1 = vertices[line.vertices[0]].x; var y1 = vertices[line.vertices[0]].y; var x2 = vertices[line.vertices[1]].x; var y2 = vertices[line.vertices[1]].y; var x3 = vertices[relLine.vertices[1]].x; var y3 = vertices[relLine.vertices[1]].y; // calculate the area of triangle var triArea = Math.abs((y1 + y3) * (x3 - x1) - (y1 + y2) * (x2 - x1) - (y3 + y2) * (x3 - x2)) / 2; var triangle = { points: [{ x: x1, y: y1 }, { x: x2, y: y2 }, { x: x3, y: y3 }], area: triArea }; // determine the + or - symbol of triangle var area = 0; for (var _i = 0; _i < 3; _i++) { var j = (_i + 1) % 3; area += triangle.points[_i].x * triangle.points[j].y; area -= triangle.points[j].x * triangle.points[_i].y; } if (area > 0) { triangle.area = -triangle.area; } alltriangles.push(triangle); } }); }); var reverse = false; var allSum = 0; alltriangles.forEach(function (triangle) { allSum += triangle.area; }); // if all sum of triangle's area is smaller than zero, all walls have to be inverted. if (allSum >= 0) { reverse = false; } else reverse = true; if (reverse) { reverseLines.forEach(function (line) { var tmp = line.vertices[0]; line.vertices[0] = line.vertices[1]; line.vertices[1] = tmp; state = state.mergeIn(['scene', 'layers', layerID, 'lines', line.id, 'vertices'], line.vertices); }); } return { updatedState: state }; } }, { key: "detectAndUpdateAreas", value: function detectAndUpdateAreas(state, layerID, drawingInfor) { var verticesArray = []; //array with vertices coords var linesArray; var virtualArray = []; //array with edges var vertexID_to_verticesArrayIndex = {}; var verticesArrayIndex_to_vertexID = {}; state.getIn(['scene', 'layers', layerID, 'vertices']).forEach(function (vertex) { var verticesCount = verticesArray.push([vertex.x, vertex.y]); var latestVertexIndex = verticesCount - 1; vertexID_to_verticesArrayIndex[vertex.id] = latestVertexIndex; verticesArrayIndex_to_vertexID[latestVertexIndex] = vertex.id; }); var vertexCount = verticesArray.length; var vitual = {}; linesArray = state.getIn(['scene', 'layers', layerID, 'lines']).map(function (line) { return line.vertices.map(function (vertexID) { return vertexID_to_verticesArrayIndex[vertexID]; }).toArray(); }); //open line // if (vertexCount > 1 && !linesArray.some(line => (line[0]==0 && line[1]==vertexCount-1) || (line[1]==0 && line[0]==vertexCount-1))) { // linesArray = linesArray.set(IDBroker.acquireID(), [0, vertexCount-1]); // } var innerCyclesByVerticesArrayIndex = GraphInnerCycles.calculateInnerCycles(verticesArray, linesArray); var innerCyclesByVerticesID = new List(innerCyclesByVerticesArrayIndex).map(function (cycle) { return new List(cycle.map(function (vertexIndex) { return verticesArrayIndex_to_vertexID[vertexIndex]; })); }); // All area vertices should be ordered in counterclockwise order innerCyclesByVerticesID = innerCyclesByVerticesID.map(function (area) { return GraphInnerCycles.isClockWiseOrder(area.map(function (vertexID) { return state.getIn(['scene', 'layers', layerID, 'vertices', vertexID]); })) ? area.reverse() : area; }); var areaIDs = []; //remove areas state.getIn(['scene', 'layers', layerID, 'areas']).forEach(function (area) { var areaInUse = innerCyclesByVerticesID.some(function (vertices) { return sameDirection(vertices, area.vertices); }); if (!areaInUse) { state = Area.remove(state, layerID, area.id).updatedState; } }); //add new areas innerCyclesByVerticesID.forEach(function (cycle, ind) { var areaInUse = state.getIn(['scene', 'layers', layerID, 'areas']).find(function (area) { return sameDirection(area.vertices, cycle); }); if (areaInUse) { areaIDs[ind] = areaInUse.id; state = state.setIn(['scene', 'layers', layerID, 'areas', areaIDs[ind], 'holes'], new List()); } else { var areaVerticesCoords = cycle.map(function (vertexID) { return state.getIn(['scene', 'layers', layerID, 'vertices', vertexID]); }); var resultAdd = Area.add(state, layerID, 'area', areaVerticesCoords, state.catalog); areaIDs[ind] = resultAdd.area.id; state = resultAdd.updatedState; } }); // Build a relationship between areas and their coordinates var verticesCoordsForArea = areaIDs.map(function (id) { var vertices = state.getIn(['scene', 'layers', layerID, 'areas', id]).vertices.map(function (vertexID) { var _state$getIn2 = state.getIn(['scene', 'layers', layerID, 'vertices', vertexID]), x = _state$getIn2.x, y = _state$getIn2.y; return new List([x, y]); }); return { id: id, vertices: vertices }; }); // Find all holes for an area var i, j; for (i = 0; i < verticesCoordsForArea.length; i++) { var holesList = new List(); // The holes for this area var areaVerticesList = verticesCoordsForArea[i].vertices.flatten().toArray(); for (j = 0; j < verticesCoordsForArea.length; j++) { if (i !== j) { var isHole = GeometryUtils.ContainsPoint(areaVerticesList, verticesCoordsForArea[j].vertices.get(0).get(0), verticesCoordsForArea[j].vertices.get(0).get(1)); if (isHole) { holesList = holesList.push(verticesCoordsForArea[j].id); } } } state = state.setIn(['scene', 'layers', layerID, 'areas', verticesCoordsForArea[i].id, 'holes'], holesList); } // Remove holes which are already holes for other areas areaIDs.forEach(function (areaID) { var doubleHoles = new Set(); var areaHoles = state.getIn(['scene', 'layers', layerID, 'areas', areaID, 'holes']); areaHoles.forEach(function (areaHoleID) { var holesOfholes = state.getIn(['scene', 'layers', layerID, 'areas', areaHoleID, 'holes']); holesOfholes.forEach(function (holeID) { if (areaHoles.indexOf(holeID) !== -1) doubleHoles.add(holeID); }); }); doubleHoles.forEach(function (doubleHoleID) { areaHoles = areaHoles.remove(areaHoles.indexOf(doubleHoleID)); }); state = state.setIn(['scene', 'layers', layerID, 'areas', areaID, 'holes'], areaHoles); }); // update direction of lines surrounding area var layer = state.getIn(['scene', 'layers', layerID]); var allAreaLines = GeometryUtils.getAllAreaLines(layer); // check whether the room is colsed. in this case, the allAreaLines have some values and if doesn't close, this value has nothing. layer.lines.forEach(function (line) { allAreaLines.some(function (l) { if (line.vertices.get(0) == l[0] && line.vertices.get(1) == l[1]) { state = state.setIn(['scene', 'layers', layerID, 'lines', line.id, 'vertices', 0], l[1]); state = state.setIn(['scene', 'layers', layerID, 'lines', line.id, 'vertices', 1], l[0]); return true; } else if (line.vertices.get(1) == l[0] && line.vertices.get(0) == l[1]) { return true; } else { return false; } }); }); // var separatedLine = []; var allLinesArray = state.getIn(['scene', 'layers', layerID, 'lines']); allLinesArray.forEach(function (line) { var isAreaLine = false; isAreaLine = allAreaLines.some(function (areaLine) { if (areaLine[0] == line.vertices.get(0) && areaLine[1] == line.vertices.get(1) || areaLine[0] == line.vertices.get(1) && areaLine[1] == line.vertices.get(0)) return true; }); // console.log( // 'Layer_Vertices', // layer.vertices.get(line.vertices.get(0)).toJS() // ); if (!isAreaLine) { if (!(GeometryUtils.isPointInArea(GeometryUtils.getAllArea(layer), layer.vertices.get(line.vertices.get(0))) && GeometryUtils.isPointInArea(GeometryUtils.getAllArea(layer), layer.vertices.get(line.vertices.get(1))))) { separatedLine.push(line); } } }); var separatedLineCnt = separatedLine.length; if (separatedLineCnt == 1) { separatedLine.forEach(function (line) { var ptArray = [], pt3 = [], pt4 = []; ptArray.push(verticesArray[vertexID_to_verticesArrayIndex[line.vertices.get(0)]]); ptArray.push(verticesArray[vertexID_to_verticesArrayIndex[line.vertices.get(1)]]); pt3.push(ptArray[1][1] - ptArray[0][1] + ptArray[1][0]); pt3.push(ptArray[0][0] - ptArray[1][0] + ptArray[1][1]); ptArray.push(pt3); pt4.push(ptArray[0][0] + ptArray[2][0] - ptArray[1][0]); pt4.push(ptArray[0][1] + ptArray[2][1] - ptArray[1][1]); ptArray.push(pt4); var pointArray = []; ptArray.forEach(function (pt) { var point = { x: pt[0], y: pt[1] }; pointArray.push(point); }); pointArray.reverse(); var resultAdd = Area.add(state, layerID, 'area', pointArray, state.catalog); state = resultAdd.updatedState; }); } else if (separatedLineCnt > 1) { var ptXArray = [], ptYArray = [], ptXMin, ptXMax, ptYMin, ptYMAX; separatedLine.forEach(function (line) { ptXArray.push(verticesArray[vertexID_to_verticesArrayIndex[line.vertices.get(0)]][0]); ptXArray.push(verticesArray[vertexID_to_verticesArrayIndex[line.vertices.get(1)]][0]); ptYArray.push(verticesArray[vertexID_to_verticesArrayIndex[line.vertices.get(0)]][1]); ptYArray.push(verticesArray[vertexID_to_verticesArrayIndex[line.vertices.get(1)]][1]); }); ptXMin = Math.min.apply(null, ptXArray); ptXMax = Math.max.apply(null, ptXArray); ptYMin = Math.min.apply(null, ptYArray); ptYMAX = Math.max.apply(null, ptYArray); var pointArray = []; pointArray.push({ x: ptXMin, y: ptYMin }); pointArray.push({ x: ptXMax, y: ptYMin }); pointArray.push({ x: ptXMax, y: ptYMAX }); pointArray.push({ x: ptXMin, y: ptYMAX }); var resultAdd = Area.add(state, layerID, 'area', pointArray, state.catalog); state = resultAdd.updatedState; if (!isEmpty(drawingInfor)) { var allVertices = state.getIn(['scene', 'layers', layerID, 'vertices']); var resultInterior = this.interiorsurfacedetect(state, drawingInfor.drawingLine.toJS(), allVertices.toJS(), allLinesArray, layerID); if (!isEmpty(resultInterior)) { state = resultInterior.updatedState; } } } return { updatedState: state }; } }, { key: "removeZeroLengthLines", value: function removeZeroLengthLines(state, layerID) { var updatedState = state.getIn(['scene', 'layers', layerID, 'lines']).reduce(function (newState, line) { var v_id0 = line.getIn(['vertices', 0]); var v_id1 = line.getIn(['vertices', 1]); var v0 = newState.getIn(['scene', 'layers', layerID, 'vertices', v_id0]); var v1 = newState.getIn(['scene', 'layers', layerID, 'vertices', v_id1]); if (GeometryUtils.verticesDistance(v0, v1) === 0) { newState = Line.remove(newState, layerID, line.id).updatedState; } return newState; }, state); return { updatedState: updatedState }; } }, { key: "mergeEqualsVertices", value: function mergeEqualsVertices(state, layerID, vertexID) { //1. find vertices to remove var vertex = state.getIn(['scene', 'layers', layerID, 'vertices', vertexID]); if (vertex === undefined || vertex === null) return { updatedState: state }; var doubleVertices = state.getIn(['scene', 'layers', layerID, 'vertices']).filter(function (v) { return v.id !== vertexID && GeometryUtils.samePoints(vertex, v) // && //!v.lines.contains( vertexID ) && //!v.areas.contains( vertexID ) ; }); if (doubleVertices.isEmpty()) return { updatedState: state }; doubleVertices.forEach(function (doubleVertex) { var reduced = doubleVertex.lines.reduce(function (reducedState, lineID) { reducedState = reducedState.updateIn(['scene', 'layers', layerID, 'lines', lineID, 'vertices'], function (vertices) { if (vertices) { return vertices.map(function (v) { return v === doubleVertex.id ? vertexID : v; }); } }); reducedState = Vertex.addElement(reducedState, layerID, vertexID, 'lines', lineID).updatedState; return reducedState; }, state); var biReduced = doubleVertex.areas.reduce(function (reducedState, areaID) { reducedState = reducedState.updateIn(['scene', 'layers', layerID, 'areas', areaID, 'vertices'], function (vertices) { if (vertices) return vertices.map(function (v) { return v === doubleVertex.id ? vertexID : v; }); }); reducedState = Vertex.addElement(reducedState, layerID, vertexID, 'areas', areaID).updatedState; return reducedState; }, reduced); state = Vertex.remove(biReduced, layerID, doubleVertex.id, null, null, true).updatedState; }); return { updatedState: state }; } }, { key: "setPropertiesOnSelected", value: function setPropertiesOnSelected(state, layerID, properties) { var selected = state.getIn(['scene', 'layers', layerID, 'selected']); selected.lines.forEach(function (lineID) { return state = Line.setProperties(state, layerID, lineID, properties).updatedState; }); selected.holes.forEach(function (holeID) { return state = Hole.setProperties(state, layerID, holeID, properties).updatedState; }); selected.areas.forEach(function (areaID) { return state = Area.setProperties(state, layerID, areaID, properties).updatedState; }); selected.items.forEach(function (itemID) { return state = Item.setProperties(state, layerID, itemID, properties).updatedState; }); return { updatedState: state }; } }, { key: "updatePropertiesOnSelected", value: function updatePropertiesOnSelected(state, layerID, properties) { var selected = state.getIn(['scene', 'layers', layerID, 'selected']); selected.lines.forEach(function (lineID) { return state = Line.updateProperties(state, layerID, lineID, properties).updatedState; }); selected.holes.forEach(function (holeID) { return state = Hole.updateProperties(state, layerID, holeID, properties).updatedState; }); selected.areas.forEach(function (areaID) { return state = Area.updateProperties(state, layerID, areaID, properties).updatedState; }); selected.items.forEach(function (itemID) { return state = Item.updateProperties(state, layerID, itemID, properties).updatedState; }); return { updatedState: state }; } }, { key: "setAttributesOnSelected", value: function setAttributesOnSelected(state, layerID, attributes) { var selected = state.getIn(['scene', 'layers', layerID, 'selected']); selected.lines.forEach(function (lineID) { return state = Line.setAttributes(state, layerID, lineID, attributes).updatedState; }); selected.holes.forEach(function (holeID) { return state = Hole.setAttributes(state, layerID, holeID, attributes).updatedState; }); selected.items.forEach(function (itemID) { return state = Item.setAttributes(state, layerID, itemID, attributes).updatedState; }); //selected.areas.forEach(areaID => state = Area.setAttributes( state, layerID, areaID, attributes ).updatedState); return { updatedState: state }; } }]); }(); export { Layer as default };