react-planner
Version:
react-planner is a React Component for plans design. Draw a 2D floorplan and navigate it in 3D mode.
855 lines (701 loc) • 29 kB
JavaScript
import * as Three from 'three';
import createGrid from './grid-creator';
import { disposeObject } from './three-memory-cleaner';
export function parseData(sceneData, actions, catalog) {
var planData = {};
planData.sceneGraph = {
unit: sceneData.unit,
layers: {},
busyResources: { layers: {} },
width: sceneData.width,
height: sceneData.height,
LODs: {}
};
planData.plan = new Three.Object3D();
planData.plan.name = 'plan';
// Add a grid to the plan
planData.grid = createGrid(sceneData);
planData.grid.name = 'grid';
planData.boundingBox = new Three.Box3().setFromObject(planData.grid);
planData.boundingBox.name = 'boundingBox';
var promises = [];
sceneData.layers.forEach(function (layer) {
if (layer.id === sceneData.selectedLayer || layer.visible) {
promises = promises.concat(createLayerObjects(layer, planData, sceneData, actions, catalog));
}
});
Promise.all(promises).then(function (value) {
return updateBoundingBox(planData);
});
return planData;
}
function createLayerObjects(layer, planData, sceneData, actions, catalog) {
var promises = [];
planData.sceneGraph.layers[layer.id] = {
id: layer.id,
lines: {},
holes: {},
areas: {},
items: {},
visible: layer.visible,
altitude: layer.altitude
};
planData.sceneGraph.busyResources.layers[layer.id] = {
id: layer.id,
lines: {},
holes: {},
areas: {},
items: {}
};
// Import lines
layer.lines.forEach(function (line) {
promises.push(addLine(sceneData, planData, layer, line.id, catalog, actions.linesActions));
line.holes.forEach(function (holeID) {
promises.push(addHole(sceneData, planData, layer, holeID, catalog, actions.holesActions));
});
});
// Import areas
layer.areas.forEach(function (area) {
promises.push(addArea(sceneData, planData, layer, area.id, catalog, actions.areaActions));
});
// Import items
layer.items.forEach(function (item) {
promises.push(addItem(sceneData, planData, layer, item.id, catalog, actions.itemsActions));
});
return promises;
}
export function updateScene(planData, sceneData, oldSceneData, diffArray, actions, catalog) {
var splitted = diffArray.map(function (el) {
return { op: el.op, path: el.path.split('/'), value: el.value };
});
var filteredDiffs = filterDiffs(splitted, sceneData, oldSceneData);
//***testing additional filter***
filteredDiffs = filteredDiffs.filter(function (_ref) {
var path = _ref.path;
return path[3] !== 'selected';
});
filteredDiffs = filteredDiffs.filter(function (_ref2) {
var path = _ref2.path;
return path[1] !== 'groups';
});
//*******************************
filteredDiffs.forEach(function (_ref3) {
var op = _ref3.op,
path = _ref3.path,
value = _ref3.value;
/* First of all I need to find the object I need to update */
if (path[1] === 'layers') {
var layer = sceneData.getIn(['layers', path[2]]);
if (path.length === 3 && op === 'remove') {
removeLayer(path[2], planData);
} else if (path.length > 3) {
switch (op) {
case 'replace':
replaceObject(path, layer, planData, actions, sceneData, oldSceneData, catalog);
break;
case 'add':
addObject(path, layer, planData, actions, sceneData, oldSceneData, catalog);
break;
case 'remove':
removeObject(path, layer, planData, actions, sceneData, oldSceneData, catalog);
break;
}
}
} else if (path[1] === 'selectedLayer') {
var layerSelectedID = value;
var layerSelected = sceneData.getIn(['layers', layerSelectedID]);
// First of all I check if the new selected layer is not visible
if (!layerSelected.visible) {
// I need to create the objects for this layer
var promises = createLayerObjects(layerSelected, planData, sceneData, actions, catalog);
Promise.all(promises).then(function () {
return updateBoundingBox(planData);
});
}
var layerGraph = planData.sceneGraph.layers[oldSceneData.selectedLayer];
if (layerGraph) {
if (!layerGraph.visible) {
// I need to remove the objects for this layer
for (var lineID in layerGraph.lines) {
removeLine(planData, layerGraph.id, lineID);
}for (var areaID in layerGraph.areas) {
removeArea(planData, layerGraph.id, areaID);
}for (var itemID in layerGraph.items) {
removeItem(planData, layerGraph.id, itemID);
}for (var holeID in layerGraph.holes) {
removeHole(planData, layerGraph.id, holeID);
}
}
}
}
});
return planData;
}
function replaceObject(modifiedPath, layer, planData, actions, sceneData, oldSceneData, catalog) {
var promises = [];
switch (modifiedPath[3]) {
case 'vertices':
if (modifiedPath[5] !== 'selected') {
var vertex = layer.getIn(['vertices', modifiedPath[4]]);
if (modifiedPath[5] === 'x' || modifiedPath[5] === 'y') {
vertex.lines.forEach(function (lineID) {
var lineHoles = oldSceneData.getIn(['layers', layer.id, 'lines', lineID, 'holes']);
if (lineHoles) lineHoles.forEach(function (holeID) {
replaceObject([0, 0, 0, 'holes', holeID, 'selected'], layer, planData, actions, sceneData, oldSceneData, catalog);
});
return replaceObject([0, 0, 0, 'lines', lineID], layer, planData, actions, sceneData, oldSceneData, catalog);
});
vertex.areas.forEach(function (areaID) {
return replaceObject([0, 0, 0, 'areas', areaID], layer, planData, actions, sceneData, oldSceneData, catalog);
});
}
if (modifiedPath[5] === 'areas') {
var areaID = vertex.getIn(['areas', ~~modifiedPath[6]]);
replaceObject([0, 0, 0, 'areas', areaID], layer, planData, actions, sceneData, oldSceneData, catalog);
}
}
break;
case 'holes':
var newHoleData = layer.getIn(['holes', modifiedPath[4]]);
if (catalog.getElement(newHoleData.type).updateRender3D) {
promises.push(updateHole(sceneData, oldSceneData, planData, layer, modifiedPath[4], modifiedPath.slice(5), catalog, actions.holesActions, function () {
return removeHole(planData, layer.id, newHoleData.id);
}, function () {
return addHole(sceneData, planData, layer, newHoleData.id, catalog, actions.holesActions);
}));
} else {
var lineID = newHoleData.line;
if (modifiedPath[5] === 'selected') {
// I remove only the hole without removing the wall
removeHole(planData, layer.id, newHoleData.id);
promises.push(addHole(sceneData, planData, layer, newHoleData.id, catalog, actions.holesActions));
} else {
layer.getIn(['lines', lineID, 'holes']).forEach(function (holeID) {
removeHole(planData, layer.id, holeID);
});
removeLine(planData, layer.id, lineID);
promises.push(addLine(sceneData, planData, layer, lineID, catalog, actions.linesActions));
layer.getIn(['lines', lineID, 'holes']).forEach(function (holeID) {
promises.push(addHole(sceneData, planData, layer, holeID, catalog, actions.holesActions));
});
}
}
break;
case 'lines':
var line = layer.getIn(['lines', modifiedPath[4]]);
if (catalog.getElement(line.type).updateRender3D) {
promises.push(updateLine(sceneData, oldSceneData, planData, layer, modifiedPath[4], modifiedPath.slice(5), catalog, actions.linesActions, function () {
return removeLine(planData, layer.id, modifiedPath[4]);
}, function () {
return addLine(sceneData, planData, layer, modifiedPath[4], catalog, actions.linesActions);
}));
} else {
removeLine(planData, layer.id, modifiedPath[4]);
promises.push(addLine(sceneData, planData, layer, modifiedPath[4], catalog, actions.linesActions));
}
break;
case 'areas':
var area = layer.getIn(['areas', modifiedPath[4]]);
if (catalog.getElement(area.type).updateRender3D) {
promises.push(updateArea(sceneData, oldSceneData, planData, layer, modifiedPath[4], modifiedPath.slice(5), catalog, actions.areaActions, function () {
return removeArea(planData, layer.id, modifiedPath[4]);
}, function () {
return addArea(sceneData, planData, layer, modifiedPath[4], catalog, actions.areaActions);
}));
} else {
if (planData.sceneGraph.layers[layer.id].areas[modifiedPath[4]]) {
removeArea(planData, layer.id, modifiedPath[4]);
}
promises.push(addArea(sceneData, planData, layer, modifiedPath[4], catalog, actions.areaActions));
}
break;
case 'items':
var item = layer.getIn(['items', modifiedPath[4]]);
if (catalog.getElement(item.type).updateRender3D) {
promises.push(updateItem(sceneData, oldSceneData, planData, layer, modifiedPath[4], modifiedPath.slice(5), catalog, actions.itemsActions, function () {
return removeItem(planData, layer.id, modifiedPath[4]);
}, function () {
return addItem(sceneData, planData, layer, modifiedPath[4], catalog, actions.itemsActions);
}));
} else {
removeItem(planData, layer.id, modifiedPath[4]);
promises.push(addItem(sceneData, planData, layer, modifiedPath[4], catalog, actions.itemsActions));
}
break;
case 'visible':
if (!layer.visible) {
var _layerGraph = planData.sceneGraph.layers[layer.id];
for (var _lineID in _layerGraph.lines) {
removeLine(planData, layer.id, _lineID);
}for (var _areaID in _layerGraph.areas) {
removeArea(planData, layer.id, _areaID);
}for (var itemID in _layerGraph.items) {
removeItem(planData, layer.id, itemID);
}for (var holeID in _layerGraph.holes) {
removeHole(planData, layer.id, holeID);
}
} else {
promises = promises.concat(createLayerObjects(layer, planData, sceneData, actions, catalog));
}
break;
case 'opacity':
case 'altitude':
var layerGraph = planData.sceneGraph.layers[layer.id];
for (var _lineID2 in layerGraph.lines) {
removeLine(planData, layer.id, _lineID2);
}for (var _areaID2 in layerGraph.areas) {
removeArea(planData, layer.id, _areaID2);
}for (var _itemID in layerGraph.items) {
removeItem(planData, layer.id, _itemID);
}for (var _holeID in layerGraph.holes) {
removeHole(planData, layer.id, _holeID);
}promises = promises.concat(createLayerObjects(layer, planData, sceneData, actions, catalog));
}
Promise.all(promises).then(function (values) {
return updateBoundingBox(planData);
});
}
function removeObject(modifiedPath, layer, planData, actions, sceneData, oldSceneData, catalog) {
var promises = [];
switch (modifiedPath[3]) {
case 'lines':
// Here I remove the line with all its holes
var lineID = modifiedPath[4];
oldSceneData.getIn(['layers', layer.id, 'lines', lineID, 'holes']).forEach(function (holeID) {
removeHole(planData, layer.id, holeID);
});
removeLine(planData, layer.id, lineID);
if (modifiedPath.length > 5) {
// I removed an hole, so I should add the new line
promises.push(addLine(sceneData, planData, layer, lineID, catalog, actions.linesActions));
layer.getIn(['lines', lineID, 'holes']).forEach(function (holeID) {
promises.push(addHole(sceneData, planData, layer, holeID, catalog, actions.holesActions));
});
}
break;
case 'areas':
if (modifiedPath.length === 5) {
// I am removing an entire area
removeArea(planData, layer.id, modifiedPath[4]);
}
break;
case 'items':
if (modifiedPath.length === 5) {
// I am removing an item
removeItem(planData, layer.id, modifiedPath[4]);
}
break;
}
Promise.all(promises).then(function (values) {
return updateBoundingBox(planData);
});
}
function removeLayer(layerId, planData) {
var layerGraph = planData.sceneGraph.layers[layerId];
for (var lineID in layerGraph.lines) {
removeLine(planData, layerId, lineID);
}for (var areaID in layerGraph.areas) {
removeArea(planData, layerId, areaID);
}for (var itemID in layerGraph.items) {
removeItem(planData, layerId, itemID);
}for (var holeID in layerGraph.holes) {
removeHole(planData, layerId, holeID);
}delete planData.sceneGraph.layers[layerId];
}
function removeHole(planData, layerId, holeID) {
if (planData.sceneGraph.busyResources.layers[layerId].holes[holeID]) {
setTimeout(function () {
return removeHole(planData, layerId, holeID);
}, 100);
return;
}
planData.sceneGraph.busyResources.layers[layerId].holes[holeID] = true;
var hole3D = planData.sceneGraph.layers[layerId].holes[holeID];
if (hole3D) {
planData.plan.remove(hole3D);
disposeObject(hole3D);
delete planData.sceneGraph.layers[layerId].holes[holeID];
delete planData.sceneGraph.LODs[holeID];
hole3D = null;
updateBoundingBox(planData);
}
planData.sceneGraph.busyResources.layers[layerId].holes[holeID] = false;
}
function removeLine(planData, layerId, lineID) {
if (planData.sceneGraph.busyResources.layers[layerId].lines[lineID]) {
setTimeout(function () {
return removeLine(planData, layerId, lineID);
}, 100);
return;
}
planData.sceneGraph.busyResources.layers[layerId].lines[lineID] = true;
var line3D = planData.sceneGraph.layers[layerId].lines[lineID];
if (line3D) {
planData.plan.remove(line3D);
disposeObject(line3D);
delete planData.sceneGraph.layers[layerId].lines[lineID];
delete planData.sceneGraph.LODs[lineID];
line3D = null;
updateBoundingBox(planData);
}
planData.sceneGraph.busyResources.layers[layerId].lines[lineID] = false;
}
function removeArea(planData, layerId, areaID) {
if (planData.sceneGraph.busyResources.layers[layerId].areas[areaID]) {
setTimeout(function () {
return removeArea(planData, layerId, areaID);
}, 100);
return;
}
planData.sceneGraph.busyResources.layers[layerId].areas[areaID] = true;
var area3D = planData.sceneGraph.layers[layerId].areas[areaID];
if (area3D) {
planData.plan.remove(area3D);
disposeObject(area3D);
delete planData.sceneGraph.layers[layerId].areas[areaID];
delete planData.sceneGraph.LODs[areaID];
area3D = null;
updateBoundingBox(planData);
}
planData.sceneGraph.busyResources.layers[layerId].areas[areaID] = false;
}
function removeItem(planData, layerId, itemID) {
if (planData.sceneGraph.busyResources.layers[layerId].items[itemID]) {
setTimeout(function () {
return removeItem(planData, layerId, itemID);
}, 100);
return;
}
planData.sceneGraph.busyResources.layers[layerId].items[itemID] = true;
var item3D = planData.sceneGraph.layers[layerId].items[itemID];
if (item3D) {
planData.plan.remove(item3D);
disposeObject(item3D);
delete planData.sceneGraph.layers[layerId].items[itemID];
delete planData.sceneGraph.LODs[itemID];
item3D = null;
updateBoundingBox(planData);
}
planData.sceneGraph.busyResources.layers[layerId].items[itemID] = false;
}
//TODO generate an area's replace if vertex has been changed
function addObject(modifiedPath, layer, planData, actions, sceneData, oldSceneData, catalog) {
if (modifiedPath.length === 5) {
var addPromise = null,
addAction = null;
switch (modifiedPath[3]) {
case 'lines':
addPromise = addLine;addAction = actions.linesActions;break;
case 'areas':
addPromise = addArea;addAction = actions.areaActions;break;
case 'items':
addPromise = addItem;addAction = actions.itemsActions;break;
case 'holes':
addPromise = addHole;addAction = actions.holesActions;break;
}
if (addPromise) addPromise(sceneData, planData, layer, modifiedPath[4], catalog, addAction).then(function () {
return updateBoundingBox(planData);
});
}
}
function addHole(sceneData, planData, layer, holeID, catalog, holesActions) {
var holeData = layer.getIn(['holes', holeID]);
// Create the hole object
return catalog.getElement(holeData.type).render3D(holeData, layer, sceneData).then(function (object) {
if (object instanceof Three.LOD) {
planData.sceneGraph.LODs[holeID] = object;
}
var pivot = new Three.Object3D();
pivot.name = 'pivot';
pivot.add(object);
var line = layer.getIn(['lines', holeData.line]);
// First of all I need to find the vertices of this line
var vertex0 = layer.vertices.get(line.vertices.get(0));
var vertex1 = layer.vertices.get(line.vertices.get(1));
var offset = holeData.offset;
if (vertex0.x > vertex1.x) {
var tmp = vertex0;
vertex0 = vertex1;
vertex1 = tmp;
offset = 1 - offset;
}
var distance = Math.sqrt(Math.pow(vertex0.x - vertex1.x, 2) + Math.pow(vertex0.y - vertex1.y, 2));
var alpha = Math.asin((vertex1.y - vertex0.y) / distance);
var boundingBox = new Three.Box3().setFromObject(pivot);
var center = [(boundingBox.max.x - boundingBox.min.x) / 2 + boundingBox.min.x, (boundingBox.max.y - boundingBox.min.y) / 2 + boundingBox.min.y, (boundingBox.max.z - boundingBox.min.z) / 2 + boundingBox.min.z];
var holeAltitude = holeData.properties.getIn(['altitude', 'length']);
var holeHeight = holeData.properties.getIn(['height', 'length']);
pivot.rotation.y = alpha;
pivot.position.x = vertex0.x + distance * offset * Math.cos(alpha) - center[2] * Math.sin(alpha);
pivot.position.y = holeAltitude + holeHeight / 2 - center[1] + layer.altitude;
pivot.position.z = -vertex0.y - distance * offset * Math.sin(alpha) - center[2] * Math.cos(alpha);
planData.plan.add(pivot);
planData.sceneGraph.layers[layer.id].holes[holeData.id] = pivot;
applyInteract(pivot, function () {
return holesActions.selectHole(layer.id, holeData.id);
});
var opacity = layer.opacity;
if (holeData.selected) {
opacity = 1;
}
applyOpacity(pivot, opacity);
});
}
function updateHole(sceneData, oldSceneData, planData, layer, holeID, differences, catalog, holesActions, selfDestroy, selfBuild) {
var hole = layer.getIn(['holes', holeID]);
var oldHole = oldSceneData.getIn(['layers', layer.id, 'holes', holeID]);
var mesh = planData.sceneGraph.layers[layer.id].holes[holeID];
if (!mesh) return null;
return catalog.getElement(hole.type).updateRender3D(hole, layer, sceneData, mesh, oldHole, differences, selfDestroy, selfBuild);
}
function addLine(sceneData, planData, layer, lineID, catalog, linesActions) {
if (planData.sceneGraph.busyResources.layers[layer.id].lines[lineID]) {
setTimeout(function () {
return addLine(sceneData, planData, layer, lineID, catalog, linesActions);
}, 100);
return;
}
planData.sceneGraph.busyResources.layers[layer.id].lines[lineID] = true;
var line = layer.getIn(['lines', lineID]);
// First of all I need to find the vertices of this line
var vertex0 = layer.vertices.get(line.vertices.get(0));
var vertex1 = layer.vertices.get(line.vertices.get(1));
if (vertex0.x > vertex1.x) {
var tmp = vertex0;
vertex0 = vertex1;
vertex1 = tmp;
}
return catalog.getElement(line.type).render3D(line, layer, sceneData).then(function (line3D) {
if (line3D instanceof Three.LOD) {
planData.sceneGraph.LODs[line.id] = line3D;
}
var pivot = new Three.Object3D();
pivot.name = 'pivot';
pivot.add(line3D);
pivot.position.x = vertex0.x;
pivot.position.y = layer.altitude;
pivot.position.z = -vertex0.y;
planData.plan.add(pivot);
planData.sceneGraph.layers[layer.id].lines[lineID] = pivot;
applyInteract(pivot, function () {
return linesActions.selectLine(layer.id, line.id);
});
var opacity = layer.opacity;
if (line.selected) {
opacity = 1;
}
applyOpacity(pivot, opacity);
planData.sceneGraph.busyResources.layers[layer.id].lines[lineID] = false;
});
}
function updateLine(sceneData, oldSceneData, planData, layer, lineID, differences, catalog, linesActions, selfDestroy, selfBuild) {
var line = layer.getIn(['lines', lineID]);
var oldLine = oldSceneData.getIn(['layers', layer.id, 'lines', lineID]);
var mesh = planData.sceneGraph.layers[layer.id].lines[lineID];
if (!mesh) return null;
return catalog.getElement(line.type).updateRender3D(line, layer, sceneData, mesh, oldLine, differences, selfDestroy, selfBuild);
}
function addArea(sceneData, planData, layer, areaID, catalog, areaActions) {
if (planData.sceneGraph.busyResources.layers[layer.id].areas[areaID]) {
setTimeout(function () {
return addArea(sceneData, planData, layer, areaID, catalog, areaActions);
}, 100);
return;
}
planData.sceneGraph.busyResources.layers[layer.id].areas[areaID] = true;
var area = layer.getIn(['areas', areaID]);
var interactFunction = function interactFunction() {
return areaActions.selectArea(layer.id, areaID);
};
return catalog.getElement(area.type).render3D(area, layer, sceneData).then(function (area3D) {
if (area3D instanceof Three.LOD) {
planData.sceneGraph.LODs[areaID] = area3D;
}
var pivot = new Three.Object3D();
pivot.name = 'pivot';
pivot.add(area3D);
pivot.position.y = layer.altitude;
planData.plan.add(pivot);
planData.sceneGraph.layers[layer.id].areas[areaID] = pivot;
applyInteract(pivot, interactFunction);
var opacity = layer.opacity;
if (area.selected) {
opacity = 1;
}
applyOpacity(pivot, opacity);
planData.sceneGraph.busyResources.layers[layer.id].areas[areaID] = false;
});
}
function updateArea(sceneData, oldSceneData, planData, layer, areaID, differences, catalog, areaActions, selfDestroy, selfBuild) {
var area = layer.getIn(['areas', areaID]);
var oldArea = oldSceneData.getIn(['layers', layer.id, 'areas', areaID]);
var mesh = planData.sceneGraph.layers[layer.id].areas[areaID];
if (!mesh) return null;
return catalog.getElement(area.type).updateRender3D(area, layer, sceneData, mesh, oldArea, differences, selfDestroy, selfBuild);
}
function addItem(sceneData, planData, layer, itemID, catalog, itemsActions) {
var item = layer.getIn(['items', itemID]);
return catalog.getElement(item.type).render3D(item, layer, sceneData).then(function (item3D) {
if (item3D instanceof Three.LOD) {
planData.sceneGraph.LODs[itemID] = item3D;
}
var pivot = new Three.Object3D();
pivot.name = 'pivot';
pivot.add(item3D);
pivot.rotation.y = item.rotation * Math.PI / 180;
pivot.position.x = item.x;
pivot.position.y = layer.altitude;
pivot.position.z = -item.y;
applyInteract(item3D, function () {
itemsActions.selectItem(layer.id, item.id);
});
var opacity = layer.opacity;
if (item.selected) {
opacity = 1;
}
applyOpacity(pivot, opacity);
planData.plan.add(pivot);
planData.sceneGraph.layers[layer.id].items[item.id] = pivot;
});
}
function updateItem(sceneData, oldSceneData, planData, layer, itemID, differences, catalog, itemsActions, selfDestroy, selfBuild) {
var item = layer.getIn(['items', itemID]);
var oldItem = oldSceneData.getIn(['layers', layer.id, 'items', itemID]);
var mesh = planData.sceneGraph.layers[layer.id].items[itemID];
if (!mesh) return null;
return catalog.getElement(item.type).updateRender3D(item, layer, sceneData, mesh, oldItem, differences, selfDestroy, selfBuild);
}
// Apply interact function to children of an Object3D
function applyInteract(object, interactFunction) {
object.traverse(function (child) {
if (child instanceof Three.Mesh) {
child.interact = interactFunction;
}
});
}
// Apply opacity to children of an Object3D
function applyOpacity(object, opacity) {
object.traverse(function (child) {
if (child instanceof Three.Mesh) {
if (child.material instanceof Three.MultiMaterial) {
child.material.materials.forEach(function (materialChild) {
materialChild.transparent = true;
if (materialChild.maxOpacity) {
materialChild.opacity = Math.min(materialChild.maxOpacity, opacity);
} else if (materialChild.opacity && materialChild.opacity > opacity) {
materialChild.maxOpacity = materialChild.opacity;
materialChild.opacity = opacity;
}
});
} else if (child.material instanceof Array) {
child.material.forEach(function (material) {
material.transparent = true;
if (material.maxOpacity) {
material.opacity = Math.min(material.maxOpacity, opacity);
} else if (material.opacity && material.opacity > opacity) {
material.maxOpacity = material.opacity;
material.opacity = opacity;
}
});
} else {
child.material.transparent = true;
if (child.material.maxOpacity) {
child.material.opacity = Math.min(child.material.maxOpacity, opacity);
} else if (child.material.opacity && child.material.opacity > opacity) {
child.material.maxOpacity = child.material.opacity;
child.material.opacity = opacity;
}
}
}
});
}
function updateBoundingBox(planData) {
var newBoundingBox = new Three.Box3().setFromObject(planData.plan);
if (isFinite(newBoundingBox.max.x) && isFinite(newBoundingBox.min.x) && isFinite(newBoundingBox.max.y) && isFinite(newBoundingBox.min.y) && isFinite(newBoundingBox.max.z) && isFinite(newBoundingBox.min.z)) {
var newCenter = new Three.Vector3((newBoundingBox.max.x - newBoundingBox.min.x) / 2 + newBoundingBox.min.x, (newBoundingBox.max.y - newBoundingBox.min.y) / 2 + newBoundingBox.min.y, (newBoundingBox.max.z - newBoundingBox.min.z) / 2 + newBoundingBox.min.z);
planData.plan.position.sub(newCenter);
planData.grid.position.sub(newCenter);
newBoundingBox.min.sub(newCenter);
newBoundingBox.max.sub(newCenter);
planData.boundingBox = newBoundingBox;
}
}
/**
* Filter the array of diffs
* @param diffArray
* @param sceneData
* @param oldSceneData
* @returns {Array}
*/
function filterDiffs(diffArray, sceneData, oldSceneData) {
return minimizeRemoveDiffsWhenSwitchingLayers(minimizeChangePropertiesAfterSelectionsDiffs(minimizeChangePropertiesDiffs(diffArray, sceneData, oldSceneData), sceneData, oldSceneData), sceneData, oldSceneData);
}
/**
* Reduces the number of remove diffs when switching an hidden layer
* @param diffArray the array of the diffs
* @param sceneData
* @param oldSceneData
* @returns {Array}
*/
function minimizeRemoveDiffsWhenSwitchingLayers(diffArray, sceneData, oldSceneData) {
var foundDiff = void 0;
var i = void 0;
for (i = 0; i < diffArray.length && !foundDiff; i++) {
if (diffArray[i].path[1] === 'selectedLayer') {
foundDiff = diffArray[i];
}
}
if (foundDiff) {
if (!sceneData.getIn(['layers', oldSceneData.selectedLayer, 'visible'])) {
return diffArray.filter(function (_ref4) {
var op = _ref4.op,
path = _ref4.path;
return !(path[path.length - 1] === 'selected' && path[1] === 'layers' && path[2] === oldSceneData.selectedLayer) && !(op === 'remove' && path.indexOf(oldSceneData.selectedLayer) !== -1);
});
}
}
return diffArray;
}
/**
* Reduces the number of change properties diffs for selected elements
* @param diffArray the array of the diffs
* @param sceneData
* @param oldSceneData
* @returns {Array}
*/
function minimizeChangePropertiesAfterSelectionsDiffs(diffArray, sceneData, oldSceneData) {
var idsFound = {};
diffArray.forEach(function (_ref5) {
var path = _ref5.path;
if (path[5] === 'selected') {
idsFound[path[4]] = path[4];
}
});
return diffArray.filter(function (_ref6) {
var path = _ref6.path;
if (path[5] === 'properties') {
return idsFound[path[4]] ? false : true;
}
return true;
});
}
/**
* Reduces the number of change properties diffs
* @param diffArray the array of the diffs
* @param sceneData
* @param oldSceneData
* @returns {Array}
*/
function minimizeChangePropertiesDiffs(diffArray, sceneData, oldSceneData) {
var idsFound = {};
return diffArray.filter(function (_ref7) {
var path = _ref7.path;
if (path[5] === 'properties') {
return idsFound[path[4]] ? false : idsFound[path[4]] = true;
} else if (path[5] === 'misc') {
// Remove misc changes
return false;
}
return true;
});
}