From d97e9a897609698eda9697149c7831aaf41da76a Mon Sep 17 00:00:00 2001 From: Sean Lilley Date: Tue, 8 Nov 2016 09:54:51 -0500 Subject: [PATCH 01/24] Initial batch table hierarchy support --- .../gallery/3D Tiles Hierarchy.html | 262 ++++++++++++++++++ Source/Scene/Cesium3DTileBatchTable.js | 195 +++++++++++-- Source/Scene/Cesium3DTileFeature.js | 12 +- Source/Scene/Cesium3DTileStyleEngine.js | 1 - Source/Scene/Expression.js | 30 +- .../Hierarchy/BatchTableHierarchy/tile.b3dm | Bin 0 -> 94462 bytes .../BatchTableHierarchy/tileset.json | 47 ++++ .../BatchTableHierarchyBinary/tile.b3dm | Bin 0 -> 95166 bytes .../BatchTableHierarchyBinary/tileset.json | 47 ++++ 9 files changed, 569 insertions(+), 25 deletions(-) create mode 100644 Apps/Sandcastle/gallery/3D Tiles Hierarchy.html create mode 100644 Specs/Data/Cesium3DTiles/Hierarchy/BatchTableHierarchy/tile.b3dm create mode 100644 Specs/Data/Cesium3DTiles/Hierarchy/BatchTableHierarchy/tileset.json create mode 100644 Specs/Data/Cesium3DTiles/Hierarchy/BatchTableHierarchyBinary/tile.b3dm create mode 100644 Specs/Data/Cesium3DTiles/Hierarchy/BatchTableHierarchyBinary/tileset.json diff --git a/Apps/Sandcastle/gallery/3D Tiles Hierarchy.html b/Apps/Sandcastle/gallery/3D Tiles Hierarchy.html new file mode 100644 index 000000000000..bb412cd7a059 --- /dev/null +++ b/Apps/Sandcastle/gallery/3D Tiles Hierarchy.html @@ -0,0 +1,262 @@ + + + + + + + + + Cesium Demo + + + + + + +
+

Loading...

+
+ + + diff --git a/Source/Scene/Cesium3DTileBatchTable.js b/Source/Scene/Cesium3DTileBatchTable.js index 2080059f7c42..bb2b340c66fa 100644 --- a/Source/Scene/Cesium3DTileBatchTable.js +++ b/Source/Scene/Cesium3DTileBatchTable.js @@ -78,7 +78,22 @@ define([ * @private */ this.batchTableBinary = batchTableBinary; - this._batchTableBinaryProperties = Cesium3DTileBatchTable.getBinaryProperties(featuresLength, batchTableJson, batchTableBinary); + + var batchTableHierarchy; + var batchTableBinaryProperties; + if (defined(batchTableJson)) { + // Extract the hierarchy and remove it from the batch table json + batchTableHierarchy = batchTableJson.HIERARCHY; + if (defined(batchTableHierarchy)) { + delete batchTableJson.HIERARCHY; + batchTableHierarchy = initializeHierarchy(batchTableHierarchy, batchTableBinary); + } + // Get the binary properties + batchTableBinaryProperties = Cesium3DTileBatchTable.getBinaryProperties(featuresLength, batchTableJson, batchTableBinary); + } + + this._batchTableHierarchy = batchTableHierarchy; + this._batchTableBinaryProperties = batchTableBinaryProperties; // PERFORMANCE_IDEA: These parallel arrays probably generate cache misses in get/set color/show // and use A LOT of memory. How can we use less memory? @@ -116,6 +131,53 @@ define([ this._textureStep = textureStep; } + function initializeHierarchy(json, binary) { + var i; + var binaryAccessor; + + var instancesLength = json.instancesLength; + var classes = json.classes; + var classIds = json.classIds; + var parentIds = json.parentIds; + + if (defined(classIds.byteOffset)) { + classIds.componentType = defaultValue(classIds.componentType, 'SHORT'); + classIds.type = 'SCALAR'; + binaryAccessor = getBinaryAccessor(classIds); + classIds = binaryAccessor.createArrayBufferView(binary.buffer, binary.byteOffset + classIds.byteOffset, instancesLength); + } + + if (defined(parentIds.byteOffset)) { + parentIds.componentType = defaultValue(parentIds.componentType, 'SHORT'); + parentIds.type = 'SCALAR'; + binaryAccessor = getBinaryAccessor(parentIds); + parentIds = binaryAccessor.createArrayBufferView(binary.buffer, binary.byteOffset + parentIds.byteOffset, instancesLength); + } + + var classesLength = classes.length; + for (i = 0; i < classesLength; ++i) { + var classInstancesLength = classes[i].length; + var properties = classes[i].instances; + var binaryProperties = Cesium3DTileBatchTable.getBinaryProperties(classInstancesLength, properties, binary); + classes[i].instances = combine(binaryProperties, properties); + } + + var classCounts = arrayFill(new Array(classesLength), 0); + var classIndexes = new Array(instancesLength); + for (i = 0; i < instancesLength; ++i) { + var classId = classIds[i]; + classIndexes[i] = classCounts[classId]; + ++classCounts[classId]; + } + + return { + classes : classes, + classIds : classIds, + classIndexes : classIndexes, + parentIds : parentIds + }; + } + Cesium3DTileBatchTable.getBinaryProperties = function(featuresLength, json, binary) { var binaryProperties; if (defined(json)) { @@ -369,13 +431,103 @@ define([ return names; }; + Cesium3DTileBatchTable.prototype.isDerived = function(batchId, className) { + var hierarchy = this._batchTableHierarchy; + if (!defined(hierarchy)) { + return false; + } + var instanceIndex = batchId; + while (instanceIndex !== -1) { + var classId = hierarchy.classIds[instanceIndex]; + var instanceClass = hierarchy.classes[classId]; + if (instanceClass.name === className) { + return true; + } + // Recursively check parent + instanceIndex = hierarchy.parentIds[instanceIndex]; + } + return false; + }; + + Cesium3DTileBatchTable.prototype.isClass = function(batchId, className) { + var hierarchy = this._batchTableHierarchy; + if (!defined(hierarchy)) { + return false; + } + var classId = hierarchy.classIds[batchId]; + var instanceClass = hierarchy.classes[classId]; + return instanceClass.name === className; + }; + + function getBinaryProperty(binaryProperty, index) { + var typedArray = binaryProperty.typedArray; + var componentCount = binaryProperty.componentCount; + if (componentCount === 1) { + return typedArray[index]; + } else { + return binaryProperty.type.unpack(typedArray, index * componentCount); + } + } + + function setBinaryProperty(binaryProperty, index, value) { + var typedArray = binaryProperty.typedArray; + var componentCount = binaryProperty.componentCount; + if (componentCount === 1) { + typedArray[index] = value; + } else { + binaryProperty.type.pack(value, typedArray, index * componentCount); + } + } + + function getHierarchyProperty(batchTable, batchId, name) { + var hierarchy = batchTable._batchTableHierarchy; + var instanceIndex = batchId; + while (instanceIndex !== -1) { + var classId = hierarchy.classIds[instanceIndex]; + var instanceClass = hierarchy.classes[classId]; + var indexInClass = hierarchy.classIndexes[instanceIndex]; + var propertyValues = instanceClass.instances[name]; + if (defined(propertyValues)) { + if (defined(propertyValues.typedArray)) { + return getBinaryProperty(propertyValues, indexInClass); + } else { + return clone(propertyValues[indexInClass], true); + } + } + // Recursively check parent for the property + instanceIndex = hierarchy.parentIds[instanceIndex]; + } + return undefined; + } + + function setHierarchyProperty(batchTable, batchId, name, value) { + var hierarchy = batchTable._batchTableHierarchy; + var instanceIndex = batchId; + while (instanceIndex !== -1) { + var classId = hierarchy.classIds[instanceIndex]; + var instanceClass = hierarchy.classes[classId]; + var indexInClass = hierarchy.classIndexes[instanceIndex]; + var propertyValues = instanceClass.instances[name]; + if (defined(propertyValues)) { + if (defined(propertyValues.typedArray)) { + setBinaryProperty(propertyValues, indexInClass, value); + } else { + propertyValues[indexInClass] = clone(value, true); + } + return true; + } + // Recursively check parent for the property + instanceIndex = hierarchy.parentIds[instanceIndex]; + } + return false; + } + Cesium3DTileBatchTable.prototype.getProperty = function(batchId, name) { var featuresLength = this.featuresLength; //>>includeStart('debug', pragmas.debug); if (!defined(batchId) || (batchId < 0) || (batchId > featuresLength)) { throw new DeveloperError('batchId is required and between zero and featuresLength - 1 (' + featuresLength - + ').'); } - if (!defined(name)) { throw new DeveloperError('name is required.'); } @@ -385,24 +537,26 @@ define([ return undefined; } + if (defined(this._batchTableHierarchy)) { + var hierarchyProperty = getHierarchyProperty(this, batchId, name); + if (defined(hierarchyProperty)) { + return hierarchyProperty; + } + } + if (defined(this._batchTableBinaryProperties)) { var binaryProperty = this._batchTableBinaryProperties[name]; if (defined(binaryProperty)) { - var typedArray = binaryProperty.typedArray; - var componentCount = binaryProperty.componentCount; - if (componentCount === 1) { - return typedArray[batchId]; - } else { - return binaryProperty.type.unpack(typedArray, batchId * componentCount); - } + return getBinaryProperty(binaryProperty, batchId); } } var propertyValues = this.batchTableJson[name]; - if (!defined(propertyValues)) { - return undefined; + if (defined(propertyValues)) { + return clone(propertyValues[batchId], true); } - return clone(propertyValues[batchId], true); + + return undefined; }; Cesium3DTileBatchTable.prototype.setProperty = function(batchId, name, value) { @@ -417,16 +571,16 @@ define([ } //>>includeEnd('debug'); + if (defined(this._batchTableHierarchy)) { + if (setHierarchyProperty(this, batchId, name, value)) { + return; + } + } + if (defined(this._batchTableBinaryProperties)) { var binaryProperty = this._batchTableBinaryProperties[name]; if (defined(binaryProperty)) { - var typedArray = binaryProperty.typedArray; - var componentCount = binaryProperty.componentCount; - if (componentCount === 1) { - typedArray[batchId] = value; - } else { - binaryProperty.type.pack(value, typedArray, batchId * componentCount); - } + setBinaryProperty(binaryProperty, batchId, value); return; } } @@ -473,9 +627,6 @@ define([ '} \n'; } - /** - * @private - */ Cesium3DTileBatchTable.prototype.getVertexShaderCallback = function(handleTranslucent, batchIdAttributeName) { if (this.featuresLength === 0) { return; diff --git a/Source/Scene/Cesium3DTileFeature.js b/Source/Scene/Cesium3DTileFeature.js index 7c9b929521bd..d9294b961ff6 100644 --- a/Source/Scene/Cesium3DTileFeature.js +++ b/Source/Scene/Cesium3DTileFeature.js @@ -168,5 +168,15 @@ define([ this._content.featurePropertiesDirty = true; }; + // TODO : add doc + Cesium3DTileFeature.prototype.isClass = function(className) { + return this._batchTable.isClass(this._batchId, className); + }; + + // TODO : add doc + Cesium3DTileFeature.prototype.isDerived = function(className) { + return this._batchTable.isDerived(this._batchId, className); + }; + return Cesium3DTileFeature; -}); \ No newline at end of file +}); diff --git a/Source/Scene/Cesium3DTileStyleEngine.js b/Source/Scene/Cesium3DTileStyleEngine.js index 98a56a93288b..54fdbb7a05ae 100644 --- a/Source/Scene/Cesium3DTileStyleEngine.js +++ b/Source/Scene/Cesium3DTileStyleEngine.js @@ -103,7 +103,6 @@ define([ if (!content.applyStyleWithShader(frameState, style)) { applyStyleWithBatchTable(content, stats, style); } - } function applyStyleWithBatchTable(content, stats, style) { diff --git a/Source/Scene/Expression.js b/Source/Scene/Expression.js index c10ac18cb8b4..9bfa4bee769b 100644 --- a/Source/Scene/Expression.js +++ b/Source/Scene/Expression.js @@ -338,6 +338,22 @@ define([ } val = createRuntimeAst(expression, args[0]); return new Node(ExpressionNodeType.UNARY, call, val); + } else if (call === 'isClass') { + //>>includeStart('debug', pragmas.debug); + if (args.length < 1 || args.length > 1) { + throw new DeveloperError('Error: ' + call + ' requires exactly one argument.'); + } + //>>includeEnd('debug'); + val = createRuntimeAst(expression, args[0]); + return new Node(ExpressionNodeType.UNARY, call, val); + } else if (call === 'isDerived') { + //>>includeStart('debug', pragmas.debug); + if (args.length < 1 || args.length > 1) { + throw new DeveloperError('Error: ' + call + ' requires exactly one argument.'); + } + //>>includeEnd('debug'); + val = createRuntimeAst(expression, args[0]); + return new Node(ExpressionNodeType.UNARY, call, val); } else if (call === 'abs') { //>>includeStart('debug', pragmas.debug); if (args.length < 1 || args.length > 1) { @@ -591,6 +607,10 @@ define([ node.evaluate = node._evaluateNaN; } else if (node._value === 'isFinite') { node.evaluate = node._evaluateIsFinite; + } else if (node._value === 'isClass') { + node.evaluate = node._evaluateIsClass; + } else if (node._value === 'isDerived') { + node.evaluate = node._evaluateIsDerived; } else if (node._value === 'abs') { node.evaluate = node._evaluateAbsoluteValue; } else if (node._value === 'cos') { @@ -924,6 +944,14 @@ define([ return isFinite(this._left.evaluate(feature)); }; + Node.prototype._evaluateIsClass = function(feature) { + return feature.isClass(this._left.evaluate(feature)); + }; + + Node.prototype._evaluateIsDerived = function(feature) { + return feature.isDerived(this._left.evaluate(feature)); + }; + Node.prototype._evaluateAbsoluteValue = function(feature) { return Math.abs(this._left.evaluate(feature)); }; @@ -1161,7 +1189,7 @@ define([ return 'sqrt(' + left + ')'; } //>>includeStart('debug', pragmas.debug); - else if ((value === 'isNaN') || (value === 'isFinite') || (value === 'String')) { + else if ((value === 'isNaN') || (value === 'isFinite') || (value === 'String') || (value === 'isClass') || (value === 'isDerived')) { throw new DeveloperError('Error generating style shader: "' + value + '" is not supported.'); } //>>includeEnd('debug'); diff --git a/Specs/Data/Cesium3DTiles/Hierarchy/BatchTableHierarchy/tile.b3dm b/Specs/Data/Cesium3DTiles/Hierarchy/BatchTableHierarchy/tile.b3dm new file mode 100644 index 0000000000000000000000000000000000000000..99c68bbb129bd337b0ea2452cc7165ba37fdc4c6 GIT binary patch literal 94462 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 TsHaFLwX@>S{e-zwy~F+kzB(h= literal 0 HcmV?d00001 diff --git a/Specs/Data/Cesium3DTiles/Hierarchy/BatchTableHierarchy/tileset.json b/Specs/Data/Cesium3DTiles/Hierarchy/BatchTableHierarchy/tileset.json new file mode 100644 index 000000000000..a6e7411f7352 --- /dev/null +++ b/Specs/Data/Cesium3DTiles/Hierarchy/BatchTableHierarchy/tileset.json @@ -0,0 +1,47 @@ +{ + "asset": { + "version": "0.0" + }, + "geometricError": 20, + "root": { + "transform": [ + 0.9686356343768792, + 0.24848542777253735, + 0, + 0, + -0.15986460744966327, + 0.623177611820219, + 0.765567091384559, + 0, + 0.19023226619126932, + -0.7415555652213445, + 0.6433560667227647, + 0, + 1215011.9317263428, + -4736309.3434217675, + 4081602.0044800863, + 1 + ], + "refine": "add", + "boundingVolume": { + "box": [ + 0, + 0, + 2, + 10, + 0, + 0, + 0, + 10, + 0, + 0, + 0, + 2 + ] + }, + "geometricError": 0, + "content": { + "url": "tile.b3dm" + } + } +} diff --git a/Specs/Data/Cesium3DTiles/Hierarchy/BatchTableHierarchyBinary/tile.b3dm b/Specs/Data/Cesium3DTiles/Hierarchy/BatchTableHierarchyBinary/tile.b3dm new file mode 100644 index 0000000000000000000000000000000000000000..28f075a5bc282abf47266afe09c7062e1b78ad9f GIT binary patch literal 95166 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 J?o{uP{{ZNT{Gb2; literal 0 HcmV?d00001 diff --git a/Specs/Data/Cesium3DTiles/Hierarchy/BatchTableHierarchyBinary/tileset.json b/Specs/Data/Cesium3DTiles/Hierarchy/BatchTableHierarchyBinary/tileset.json new file mode 100644 index 000000000000..a6e7411f7352 --- /dev/null +++ b/Specs/Data/Cesium3DTiles/Hierarchy/BatchTableHierarchyBinary/tileset.json @@ -0,0 +1,47 @@ +{ + "asset": { + "version": "0.0" + }, + "geometricError": 20, + "root": { + "transform": [ + 0.9686356343768792, + 0.24848542777253735, + 0, + 0, + -0.15986460744966327, + 0.623177611820219, + 0.765567091384559, + 0, + 0.19023226619126932, + -0.7415555652213445, + 0.6433560667227647, + 0, + 1215011.9317263428, + -4736309.3434217675, + 4081602.0044800863, + 1 + ], + "refine": "add", + "boundingVolume": { + "box": [ + 0, + 0, + 2, + 10, + 0, + 0, + 0, + 10, + 0, + 0, + 0, + 2 + ] + }, + "geometricError": 0, + "content": { + "url": "tile.b3dm" + } + } +} From 1f39c5126b2ebda26778ac3ef4b3cb56778baa66 Mon Sep 17 00:00:00 2001 From: Sean Lilley Date: Wed, 9 Nov 2016 11:12:25 -0500 Subject: [PATCH 02/24] Remove hasProperty and getPropertyNames --- Source/Scene/Batched3DModel3DTileContent.js | 7 ----- Source/Scene/Cesium3DTileBatchTable.js | 28 ------------------- Source/Scene/Cesium3DTileContent.js | 11 -------- Source/Scene/Composite3DTileContent.js | 8 ------ Source/Scene/Empty3DTileContent.js | 8 ------ Source/Scene/Instanced3DModel3DTileContent.js | 7 ----- Source/Scene/PointCloud3DTileContent.js | 10 ------- Source/Scene/Tileset3DTileContent.js | 8 ------ .../Scene/Batched3DModel3DTileContentSpec.js | 1 - Specs/Scene/Cesium3DTileBatchTableSpec.js | 28 ------------------- Specs/Scene/Cesium3DTileProviderSpec.js | 3 -- Specs/Scene/PointCloud3DTileContentSpec.js | 3 -- 12 files changed, 122 deletions(-) diff --git a/Source/Scene/Batched3DModel3DTileContent.js b/Source/Scene/Batched3DModel3DTileContent.js index 16b62638bee7..49279d6c7306 100644 --- a/Source/Scene/Batched3DModel3DTileContent.js +++ b/Source/Scene/Batched3DModel3DTileContent.js @@ -122,13 +122,6 @@ define([ } } - /** - * Part of the {@link Cesium3DTileContent} interface. - */ - Batched3DModel3DTileContent.prototype.hasProperty = function(name) { - return this.batchTable.hasProperty(name); - }; - /** * Part of the {@link Cesium3DTileContent} interface. */ diff --git a/Source/Scene/Cesium3DTileBatchTable.js b/Source/Scene/Cesium3DTileBatchTable.js index bb2b340c66fa..52512b1b7eeb 100644 --- a/Source/Scene/Cesium3DTileBatchTable.js +++ b/Source/Scene/Cesium3DTileBatchTable.js @@ -403,34 +403,6 @@ define([ result); }; - Cesium3DTileBatchTable.prototype.hasProperty = function(name) { - //>>includeStart('debug', pragmas.debug); - if (!defined(name)) { - throw new DeveloperError('name is required.'); - } - //>>includeEnd('debug'); - - var json = this.batchTableJson; - return defined(json) && defined(json[name]); - }; - - Cesium3DTileBatchTable.prototype.getPropertyNames = function() { - var names = []; - var json = this.batchTableJson; - - if (!defined(json)) { - return names; - } - - for (var name in json) { - if (json.hasOwnProperty(name)) { - names.push(name); - } - } - - return names; - }; - Cesium3DTileBatchTable.prototype.isDerived = function(batchId, className) { var hierarchy = this._batchTableHierarchy; if (!defined(hierarchy)) { diff --git a/Source/Scene/Cesium3DTileContent.js b/Source/Scene/Cesium3DTileContent.js index 1f8e82413628..e8911f7646b0 100644 --- a/Source/Scene/Cesium3DTileContent.js +++ b/Source/Scene/Cesium3DTileContent.js @@ -124,17 +124,6 @@ define([ } }); - /** - * Determines if the tile's batch table has a property. If it does, each feature in - * the tile will have the property. - * - * @param {String} name The case-sensitive name of the property. - * @returns {Boolean} true if the property exists; otherwise, false. - */ - Cesium3DTileContent.prototype.hasProperty = function(name) { - DeveloperError.throwInstantiationError(); - }; - /** * Returns the {@link Cesium3DTileFeature} object for the feature with the * given batchId. This object is used to get and modify the diff --git a/Source/Scene/Composite3DTileContent.js b/Source/Scene/Composite3DTileContent.js index b0a3c14de0c7..c9347aad6070 100644 --- a/Source/Scene/Composite3DTileContent.js +++ b/Source/Scene/Composite3DTileContent.js @@ -118,14 +118,6 @@ define([ } }); - /** - * Part of the {@link Cesium3DTileContent} interface. Composite3DTileContent - * always returns false. Instead call hasProperty for a tile in the composite. - */ - Composite3DTileContent.prototype.hasProperty = function(name) { - return false; - }; - /** * Part of the {@link Cesium3DTileContent} interface. Composite3DTileContent * always returns undefined. Instead call getFeature for a tile in the composite. diff --git a/Source/Scene/Empty3DTileContent.js b/Source/Scene/Empty3DTileContent.js index 421b524db86f..88e845df81a5 100644 --- a/Source/Scene/Empty3DTileContent.js +++ b/Source/Scene/Empty3DTileContent.js @@ -79,14 +79,6 @@ define([ } }); - /** - * Part of the {@link Cesium3DTileContent} interface. Empty3DTileContent - * always returns false since a tile of this type does not have any features. - */ - Empty3DTileContent.prototype.hasProperty = function(name) { - return false; - }; - /** * Part of the {@link Cesium3DTileContent} interface. Empty3DTileContent * always returns undefined since a tile of this type does not have any features. diff --git a/Source/Scene/Instanced3DModel3DTileContent.js b/Source/Scene/Instanced3DModel3DTileContent.js index aa4a8e4048ec..4f85673fa8f0 100644 --- a/Source/Scene/Instanced3DModel3DTileContent.js +++ b/Source/Scene/Instanced3DModel3DTileContent.js @@ -145,13 +145,6 @@ define([ } } - /** - * Part of the {@link Cesium3DTileContent} interface. - */ - Instanced3DModel3DTileContent.prototype.hasProperty = function(name) { - return this.batchTable.hasProperty(name); - }; - /** * Part of the {@link Cesium3DTileContent} interface. */ diff --git a/Source/Scene/PointCloud3DTileContent.js b/Source/Scene/PointCloud3DTileContent.js index e86e94f57b1e..96f7a237efb9 100644 --- a/Source/Scene/PointCloud3DTileContent.js +++ b/Source/Scene/PointCloud3DTileContent.js @@ -186,16 +186,6 @@ define([ } } - /** - * Part of the {@link Cesium3DTileContent} interface. - */ - PointCloud3DTileContent.prototype.hasProperty = function(name) { - if (defined(this.batchTable)) { - return this.batchTable.hasProperty(name); - } - return false; - }; - /** * Part of the {@link Cesium3DTileContent} interface. * diff --git a/Source/Scene/Tileset3DTileContent.js b/Source/Scene/Tileset3DTileContent.js index 9fd0d5c09296..bf8be7fa87c3 100644 --- a/Source/Scene/Tileset3DTileContent.js +++ b/Source/Scene/Tileset3DTileContent.js @@ -77,14 +77,6 @@ define([ } }); - /** - * Part of the {@link Cesium3DTileContent} interface. Tileset3DTileContent - * always returns false since a tile of this type does not have any features. - */ - Tileset3DTileContent.prototype.hasProperty = function(name) { - return false; - }; - /** * Part of the {@link Cesium3DTileContent} interface. Tileset3DTileContent * always returns undefined since a tile of this type does not have any features. diff --git a/Specs/Scene/Batched3DModel3DTileContentSpec.js b/Specs/Scene/Batched3DModel3DTileContentSpec.js index ff34b4915793..948780cc9ca5 100644 --- a/Specs/Scene/Batched3DModel3DTileContentSpec.js +++ b/Specs/Scene/Batched3DModel3DTileContentSpec.js @@ -181,7 +181,6 @@ defineSuite([ var content = tileset._root.content; expect(content.featuresLength).toBe(10); expect(content.innerContents).toBeUndefined(); - expect(content.hasProperty('id')).toBe(true); expect(content.getFeature(0)).toBeDefined(); }); }); diff --git a/Specs/Scene/Cesium3DTileBatchTableSpec.js b/Specs/Scene/Cesium3DTileBatchTableSpec.js index f717358910cd..bc96d075bc9d 100644 --- a/Specs/Scene/Cesium3DTileBatchTableSpec.js +++ b/Specs/Scene/Cesium3DTileBatchTableSpec.js @@ -229,34 +229,6 @@ defineSuite([ expect(batchTable.getColor(0, result)).toEqual(Color.YELLOW); }); - it('hasProperty throws with undefined name', function() { - var batchTable = new Cesium3DTileBatchTable(mockContent, 1); - expect(function() { - batchTable.hasProperty(); - }).toThrowDeveloperError(); - }); - - it('hasProperty', function() { - var batchTableJson = { - height: [0.0] - }; - var batchTable = new Cesium3DTileBatchTable(mockContent, 1, batchTableJson); - expect(batchTable.hasProperty('height')).toEqual(true); - expect(batchTable.hasProperty('id')).toEqual(false); - }); - - it('getPropertyNames', function() { - var batchTable = new Cesium3DTileBatchTable(mockContent, 1); - expect(batchTable.getPropertyNames()).toEqual([]); - - var batchTableJson = { - height: [0.0], - id : [0] - }; - batchTable = new Cesium3DTileBatchTable(mockContent, 1, batchTableJson); - expect(batchTable.getPropertyNames()).toEqual(['height', 'id']); - }); - it('getProperty throws with invalid batchId', function() { var batchTable = new Cesium3DTileBatchTable(mockContent, 1); expect(function() { diff --git a/Specs/Scene/Cesium3DTileProviderSpec.js b/Specs/Scene/Cesium3DTileProviderSpec.js index 08fc6554c1c0..0fdb71b85faa 100644 --- a/Specs/Scene/Cesium3DTileProviderSpec.js +++ b/Specs/Scene/Cesium3DTileProviderSpec.js @@ -13,9 +13,6 @@ defineSuite([ expect(function() { return content.innerContents; }).toThrowDeveloperError(); - expect(function() { - return content.hasProperty('height'); - }).toThrowDeveloperError(); expect(function() { return content.getFeature(0); }).toThrowDeveloperError(); diff --git a/Specs/Scene/PointCloud3DTileContentSpec.js b/Specs/Scene/PointCloud3DTileContentSpec.js index dec0f6ba5b87..3d1deb2ac851 100644 --- a/Specs/Scene/PointCloud3DTileContentSpec.js +++ b/Specs/Scene/PointCloud3DTileContentSpec.js @@ -292,7 +292,6 @@ defineSuite([ var content = tileset._root.content; expect(content.featuresLength).toBe(0); expect(content.innerContents).toBeUndefined(); - expect(content.hasProperty('name')).toBe(false); expect(content.getFeature(0)).toBeUndefined(); }); }); @@ -302,7 +301,6 @@ defineSuite([ var content = tileset._root.content; expect(content.featuresLength).toBe(8); expect(content.innerContents).toBeUndefined(); - expect(content.hasProperty('name')).toBe(true); expect(content.getFeature(0)).toBeDefined(); }); }); @@ -315,7 +313,6 @@ defineSuite([ var content = tileset._root.content; expect(content.featuresLength).toBe(0); expect(content.innerContents).toBeUndefined(); - expect(content.hasProperty('name')).toBe(false); expect(content.getFeature(0)).toBeUndefined(); }); }); From 2043bff8c7d661d30ab4254a28bbf9cd5a5ddadf Mon Sep 17 00:00:00 2001 From: Sean Lilley Date: Wed, 9 Nov 2016 15:25:52 -0500 Subject: [PATCH 03/24] Change root node condition to be when the parentId equals itself --- Source/Scene/Cesium3DTileBatchTable.js | 38 ++++++++++++------ .../Hierarchy/BatchTableHierarchy/tile.b3dm | Bin 94462 -> 94462 bytes .../BatchTableHierarchyBinary/tile.b3dm | Bin 95166 -> 95190 bytes 3 files changed, 25 insertions(+), 13 deletions(-) diff --git a/Source/Scene/Cesium3DTileBatchTable.js b/Source/Scene/Cesium3DTileBatchTable.js index 52512b1b7eeb..0fdbc2425335 100644 --- a/Source/Scene/Cesium3DTileBatchTable.js +++ b/Source/Scene/Cesium3DTileBatchTable.js @@ -141,14 +141,14 @@ define([ var parentIds = json.parentIds; if (defined(classIds.byteOffset)) { - classIds.componentType = defaultValue(classIds.componentType, 'SHORT'); + classIds.componentType = defaultValue(classIds.componentType, 'UNSIGNED_SHORT'); classIds.type = 'SCALAR'; binaryAccessor = getBinaryAccessor(classIds); classIds = binaryAccessor.createArrayBufferView(binary.buffer, binary.byteOffset + classIds.byteOffset, instancesLength); } if (defined(parentIds.byteOffset)) { - parentIds.componentType = defaultValue(parentIds.componentType, 'SHORT'); + parentIds.componentType = defaultValue(parentIds.componentType, 'UNSIGNED_SHORT'); parentIds.type = 'SCALAR'; binaryAccessor = getBinaryAccessor(parentIds); parentIds = binaryAccessor.createArrayBufferView(binary.buffer, binary.byteOffset + parentIds.byteOffset, instancesLength); @@ -409,16 +409,20 @@ define([ return false; } var instanceIndex = batchId; - while (instanceIndex !== -1) { + while (true) { var classId = hierarchy.classIds[instanceIndex]; var instanceClass = hierarchy.classes[classId]; if (instanceClass.name === className) { return true; } + // Stop the traversal when the instance has no parent (its parentId equals itself) + var parentId = hierarchy.parentIds[instanceIndex]; + if (parentId === instanceIndex) { + return false; + } // Recursively check parent - instanceIndex = hierarchy.parentIds[instanceIndex]; + instanceIndex = parentId; } - return false; }; Cesium3DTileBatchTable.prototype.isClass = function(batchId, className) { @@ -454,7 +458,7 @@ define([ function getHierarchyProperty(batchTable, batchId, name) { var hierarchy = batchTable._batchTableHierarchy; var instanceIndex = batchId; - while (instanceIndex !== -1) { + while (true) { var classId = hierarchy.classIds[instanceIndex]; var instanceClass = hierarchy.classes[classId]; var indexInClass = hierarchy.classIndexes[instanceIndex]; @@ -466,16 +470,20 @@ define([ return clone(propertyValues[indexInClass], true); } } - // Recursively check parent for the property - instanceIndex = hierarchy.parentIds[instanceIndex]; + // Stop the traversal when the instance has no parent (its parentId equals itself) + var parentId = hierarchy.parentIds[instanceIndex]; + if (parentId === instanceIndex) { + return undefined; + } + // Recursively check parent + instanceIndex = parentId; } - return undefined; } function setHierarchyProperty(batchTable, batchId, name, value) { var hierarchy = batchTable._batchTableHierarchy; var instanceIndex = batchId; - while (instanceIndex !== -1) { + while (true) { var classId = hierarchy.classIds[instanceIndex]; var instanceClass = hierarchy.classes[classId]; var indexInClass = hierarchy.classIndexes[instanceIndex]; @@ -488,10 +496,14 @@ define([ } return true; } - // Recursively check parent for the property - instanceIndex = hierarchy.parentIds[instanceIndex]; + // Stop the traversal when the instance has no parent (its parentId equals itself) + var parentId = hierarchy.parentIds[instanceIndex]; + if (parentId === instanceIndex) { + return false; + } + // Recursively check parent + instanceIndex = parentId; } - return false; } Cesium3DTileBatchTable.prototype.getProperty = function(batchId, name) { diff --git a/Specs/Data/Cesium3DTiles/Hierarchy/BatchTableHierarchy/tile.b3dm b/Specs/Data/Cesium3DTiles/Hierarchy/BatchTableHierarchy/tile.b3dm index 99c68bbb129bd337b0ea2452cc7165ba37fdc4c6..16a99c7d6f544883adec201367da3dee5fb26c17 100644 GIT binary patch delta 21 dcmezOkoDg~)(!HkOvc8|imcleSsCwU0{~@q2h;!n delta 21 dcmezOkoDg~)(!HkOuB~6imcleSsCwU0{~?p2h0Ef diff --git a/Specs/Data/Cesium3DTiles/Hierarchy/BatchTableHierarchyBinary/tile.b3dm b/Specs/Data/Cesium3DTiles/Hierarchy/BatchTableHierarchyBinary/tile.b3dm index 28f075a5bc282abf47266afe09c7062e1b78ad9f..3afd696765c3c2a30d2d01e06183fc8ddcb7e813 100644 GIT binary patch delta 87 zcmdn@ob}psR=yC6WUE+g1{DUTYuo|O@)UtLn dDJV=fU<=wD#kPu(MG>gInS*0H2M6P}Yyea}7q0*S delta 58 zcmccioOR!GR=y Date: Wed, 9 Nov 2016 15:29:26 -0500 Subject: [PATCH 04/24] Naming isExactClass and isClass --- Apps/Sandcastle/gallery/3D Tiles Hierarchy.html | 4 ++-- Source/Scene/Cesium3DTileBatchTable.js | 4 ++-- Source/Scene/Cesium3DTileFeature.js | 8 ++++---- Source/Scene/Expression.js | 14 +++++++------- 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/Apps/Sandcastle/gallery/3D Tiles Hierarchy.html b/Apps/Sandcastle/gallery/3D Tiles Hierarchy.html index bb412cd7a059..33d70bed5a64 100644 --- a/Apps/Sandcastle/gallery/3D Tiles Hierarchy.html +++ b/Apps/Sandcastle/gallery/3D Tiles Hierarchy.html @@ -70,7 +70,7 @@ addStyle('Color all doors', { "color" : { "conditions" : [ - ["isClass('door')", "color('orange')"], + ["isExactClass('door')", "color('orange')"], ["true", "color('white')"] ] } @@ -79,7 +79,7 @@ addStyle('Color all features derived from door', { "color" : { "conditions" : [ - ["isDerived('door')", "color('orange')"], + ["isClass('door')", "color('orange')"], ["true", "color('white')"] ] } diff --git a/Source/Scene/Cesium3DTileBatchTable.js b/Source/Scene/Cesium3DTileBatchTable.js index 0fdbc2425335..84b8656365a5 100644 --- a/Source/Scene/Cesium3DTileBatchTable.js +++ b/Source/Scene/Cesium3DTileBatchTable.js @@ -403,7 +403,7 @@ define([ result); }; - Cesium3DTileBatchTable.prototype.isDerived = function(batchId, className) { + Cesium3DTileBatchTable.prototype.isClass = function(batchId, className) { var hierarchy = this._batchTableHierarchy; if (!defined(hierarchy)) { return false; @@ -425,7 +425,7 @@ define([ } }; - Cesium3DTileBatchTable.prototype.isClass = function(batchId, className) { + Cesium3DTileBatchTable.prototype.isExactClass = function(batchId, className) { var hierarchy = this._batchTableHierarchy; if (!defined(hierarchy)) { return false; diff --git a/Source/Scene/Cesium3DTileFeature.js b/Source/Scene/Cesium3DTileFeature.js index d9294b961ff6..356a29b8b3a2 100644 --- a/Source/Scene/Cesium3DTileFeature.js +++ b/Source/Scene/Cesium3DTileFeature.js @@ -169,13 +169,13 @@ define([ }; // TODO : add doc - Cesium3DTileFeature.prototype.isClass = function(className) { - return this._batchTable.isClass(this._batchId, className); + Cesium3DTileFeature.prototype.isExactClass = function(className) { + return this._batchTable.isExactClass(this._batchId, className); }; // TODO : add doc - Cesium3DTileFeature.prototype.isDerived = function(className) { - return this._batchTable.isDerived(this._batchId, className); + Cesium3DTileFeature.prototype.isClass = function(className) { + return this._batchTable.isClass(this._batchId, className); }; return Cesium3DTileFeature; diff --git a/Source/Scene/Expression.js b/Source/Scene/Expression.js index 9bfa4bee769b..1944f5ae18e2 100644 --- a/Source/Scene/Expression.js +++ b/Source/Scene/Expression.js @@ -338,7 +338,7 @@ define([ } val = createRuntimeAst(expression, args[0]); return new Node(ExpressionNodeType.UNARY, call, val); - } else if (call === 'isClass') { + } else if (call === 'isExactClass') { //>>includeStart('debug', pragmas.debug); if (args.length < 1 || args.length > 1) { throw new DeveloperError('Error: ' + call + ' requires exactly one argument.'); @@ -346,7 +346,7 @@ define([ //>>includeEnd('debug'); val = createRuntimeAst(expression, args[0]); return new Node(ExpressionNodeType.UNARY, call, val); - } else if (call === 'isDerived') { + } else if (call === 'isClass') { //>>includeStart('debug', pragmas.debug); if (args.length < 1 || args.length > 1) { throw new DeveloperError('Error: ' + call + ' requires exactly one argument.'); @@ -607,9 +607,9 @@ define([ node.evaluate = node._evaluateNaN; } else if (node._value === 'isFinite') { node.evaluate = node._evaluateIsFinite; - } else if (node._value === 'isClass') { + } else if (node._value === 'isExactClass') { node.evaluate = node._evaluateIsClass; - } else if (node._value === 'isDerived') { + } else if (node._value === 'isClass') { node.evaluate = node._evaluateIsDerived; } else if (node._value === 'abs') { node.evaluate = node._evaluateAbsoluteValue; @@ -945,11 +945,11 @@ define([ }; Node.prototype._evaluateIsClass = function(feature) { - return feature.isClass(this._left.evaluate(feature)); + return feature.isExactClass(this._left.evaluate(feature)); }; Node.prototype._evaluateIsDerived = function(feature) { - return feature.isDerived(this._left.evaluate(feature)); + return feature.isClass(this._left.evaluate(feature)); }; Node.prototype._evaluateAbsoluteValue = function(feature) { @@ -1189,7 +1189,7 @@ define([ return 'sqrt(' + left + ')'; } //>>includeStart('debug', pragmas.debug); - else if ((value === 'isNaN') || (value === 'isFinite') || (value === 'String') || (value === 'isClass') || (value === 'isDerived')) { + else if ((value === 'isNaN') || (value === 'isFinite') || (value === 'String') || (value === 'isExactClass') || (value === 'isClass')) { throw new DeveloperError('Error generating style shader: "' + value + '" is not supported.'); } //>>includeEnd('debug'); From 4fb68fea84aef1dc023cbd4d7071431c8dd7eb8c Mon Sep 17 00:00:00 2001 From: Sean Lilley Date: Wed, 9 Nov 2016 16:35:47 -0500 Subject: [PATCH 05/24] Check for circular dependencies --- Source/Scene/Cesium3DTileBatchTable.js | 24 +++++++++++++++++- .../Hierarchy/BatchTableHierarchy/tile.b3dm | Bin 94462 -> 94462 bytes .../BatchTableHierarchyBinary/tile.b3dm | Bin 95190 -> 95190 bytes 3 files changed, 23 insertions(+), 1 deletion(-) diff --git a/Source/Scene/Cesium3DTileBatchTable.js b/Source/Scene/Cesium3DTileBatchTable.js index 84b8656365a5..440d2fb1b59f 100644 --- a/Source/Scene/Cesium3DTileBatchTable.js +++ b/Source/Scene/Cesium3DTileBatchTable.js @@ -133,6 +133,7 @@ define([ function initializeHierarchy(json, binary) { var i; + var classId; var binaryAccessor; var instancesLength = json.instancesLength; @@ -165,11 +166,32 @@ define([ var classCounts = arrayFill(new Array(classesLength), 0); var classIndexes = new Array(instancesLength); for (i = 0; i < instancesLength; ++i) { - var classId = classIds[i]; + classId = classIds[i]; classIndexes[i] = classCounts[classId]; ++classCounts[classId]; } + // Check for circular dependencies + //>>includeStart('debug', pragmas.debug); + var visited = new Array(instancesLength); + for (i = 0; i < instancesLength; ++i) { + arrayFill(visited, false); + var instanceIndex = i; + while (true) { + visited[instanceIndex] = true; + var parentId = parentIds[instanceIndex]; + if (parentId === instanceIndex) { + // Stop the traversal when the instance has no parent (its parentId equals itself) + break; + } + if (visited[parentId]) { + throw new DeveloperError('Circular dependency detected in the batch table hierarchy.'); + } + instanceIndex = parentId; + } + } + //>>includeEnd('debug'); + return { classes : classes, classIds : classIds, diff --git a/Specs/Data/Cesium3DTiles/Hierarchy/BatchTableHierarchy/tile.b3dm b/Specs/Data/Cesium3DTiles/Hierarchy/BatchTableHierarchy/tile.b3dm index 16a99c7d6f544883adec201367da3dee5fb26c17..4cf1c3f60944b8c3f208c7a70fdf85654aafd48a 100644 GIT binary patch delta 24 gcmezOkoDg~)(v8;j0Te>SRXWhXWjmtm61Ig0E^rS`Tzg` delta 25 hcmezOkoDg~)(v8;Ovc8O#aSOT|6twzgO!mj8vv813NZix diff --git a/Specs/Data/Cesium3DTiles/Hierarchy/BatchTableHierarchyBinary/tile.b3dm b/Specs/Data/Cesium3DTiles/Hierarchy/BatchTableHierarchyBinary/tile.b3dm index 3afd696765c3c2a30d2d01e06183fc8ddcb7e813..2cfdd3d660f02c20785b13cf69c810d54dd57cdf 100644 GIT binary patch delta 20 ccmcciob}ps)(rw2j10|!9NPss7>{NH09Gjm>i_@% delta 20 ccmcciob}ps)(rw2jEc>I9NPss7>{NH09SJd3;+NC From 0a725f7263f8d96ddf79ce11c7b46f500e17ab1f Mon Sep 17 00:00:00 2001 From: Sean Lilley Date: Thu, 10 Nov 2016 13:36:59 -0500 Subject: [PATCH 06/24] Added getClassName built-in function --- Source/Scene/Cesium3DTileBatchTable.js | 10 ++++++++-- Source/Scene/Expression.js | 16 +++++++++++++++- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/Source/Scene/Cesium3DTileBatchTable.js b/Source/Scene/Cesium3DTileBatchTable.js index 440d2fb1b59f..43e2074a89e4 100644 --- a/Source/Scene/Cesium3DTileBatchTable.js +++ b/Source/Scene/Cesium3DTileBatchTable.js @@ -426,6 +426,8 @@ define([ }; Cesium3DTileBatchTable.prototype.isClass = function(batchId, className) { + // PERFORMANCE_IDEA : cache results in the ancestor classes to speed up this check if + // this area becomes a hotspot var hierarchy = this._batchTableHierarchy; if (!defined(hierarchy)) { return false; @@ -448,13 +450,17 @@ define([ }; Cesium3DTileBatchTable.prototype.isExactClass = function(batchId, className) { + return (this.getClassName(batchId) === className); + }; + + Cesium3DTileBatchTable.prototype.getClassName = function(batchId) { var hierarchy = this._batchTableHierarchy; if (!defined(hierarchy)) { - return false; + return undefined; } var classId = hierarchy.classIds[batchId]; var instanceClass = hierarchy.classes[classId]; - return instanceClass.name === className; + return instanceClass.name; }; function getBinaryProperty(binaryProperty, index) { diff --git a/Source/Scene/Expression.js b/Source/Scene/Expression.js index 1944f5ae18e2..87397c9ac465 100644 --- a/Source/Scene/Expression.js +++ b/Source/Scene/Expression.js @@ -354,6 +354,14 @@ define([ //>>includeEnd('debug'); val = createRuntimeAst(expression, args[0]); return new Node(ExpressionNodeType.UNARY, call, val); + } else if (call === 'getClassName') { + //>>includeStart('debug', pragmas.debug); + if (args.length < 1 || args.length > 1) { + throw new DeveloperError('Error: ' + call + ' requires exactly one argument.'); + } + //>>includeEnd('debug'); + val = createRuntimeAst(expression, args[0]); + return new Node(ExpressionNodeType.UNARY, call, val); } else if (call === 'abs') { //>>includeStart('debug', pragmas.debug); if (args.length < 1 || args.length > 1) { @@ -611,6 +619,8 @@ define([ node.evaluate = node._evaluateIsClass; } else if (node._value === 'isClass') { node.evaluate = node._evaluateIsDerived; + } else if (node._value === 'getClassName') { + node.evaluate = node._evaluateGetClassName; } else if (node._value === 'abs') { node.evaluate = node._evaluateAbsoluteValue; } else if (node._value === 'cos') { @@ -952,6 +962,10 @@ define([ return feature.isClass(this._left.evaluate(feature)); }; + Node.prototype._evaluateGetClassName = function(feature) { + return feature.getClassName(this._left.evaluate(feature)); + }; + Node.prototype._evaluateAbsoluteValue = function(feature) { return Math.abs(this._left.evaluate(feature)); }; @@ -1189,7 +1203,7 @@ define([ return 'sqrt(' + left + ')'; } //>>includeStart('debug', pragmas.debug); - else if ((value === 'isNaN') || (value === 'isFinite') || (value === 'String') || (value === 'isExactClass') || (value === 'isClass')) { + else if ((value === 'isNaN') || (value === 'isFinite') || (value === 'String') || (value === 'isExactClass') || (value === 'isClass') || (value === 'getClassName')) { throw new DeveloperError('Error generating style shader: "' + value + '" is not supported.'); } //>>includeEnd('debug'); From 26bc421a8ed35111abf4c09ef1832d221347123c Mon Sep 17 00:00:00 2001 From: Sean Lilley Date: Tue, 15 Nov 2016 15:34:33 -0500 Subject: [PATCH 07/24] Support multiple parents --- .idea/misc.xml | 13 - .../gallery/3D Tiles Hierarchy.html | 13 +- Source/Scene/Cesium3DTileBatchTable.js | 276 +++++++++++++----- .../Hierarchy/BatchTableHierarchy/tile.b3dm | Bin 94462 -> 94462 bytes .../BatchTableHierarchyBinary/tile.b3dm | Bin 95190 -> 95054 bytes .../tile.b3dm | Bin 0 -> 94790 bytes .../tileset.json | 47 +++ 7 files changed, 255 insertions(+), 94 deletions(-) delete mode 100644 .idea/misc.xml create mode 100644 Specs/Data/Cesium3DTiles/Hierarchy/BatchTableHierarchyMultipleParents/tile.b3dm create mode 100644 Specs/Data/Cesium3DTiles/Hierarchy/BatchTableHierarchyMultipleParents/tileset.json diff --git a/.idea/misc.xml b/.idea/misc.xml deleted file mode 100644 index 72abef0a7321..000000000000 --- a/.idea/misc.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/Apps/Sandcastle/gallery/3D Tiles Hierarchy.html b/Apps/Sandcastle/gallery/3D Tiles Hierarchy.html index 33d70bed5a64..c38ce003e46d 100644 --- a/Apps/Sandcastle/gallery/3D Tiles Hierarchy.html +++ b/Apps/Sandcastle/gallery/3D Tiles Hierarchy.html @@ -34,7 +34,7 @@ }); var scene = viewer.scene; -var tilesetUrl = '../../../Specs/Data/Cesium3DTiles/Hierarchy/BatchTableHierarchy'; +var tilesetUrl = '../../../Specs/Data/Cesium3DTiles/Hierarchy/BatchTableHierarchyMultipleParents'; var tileset = scene.primitives.add(new Cesium.Cesium3DTileset({ url : tilesetUrl, debugShowStatistics : true @@ -96,6 +96,17 @@ } }); +addStyle('Style by classifier', { + "color" : { + "conditions" : [ + ["isClass('classifier_new') && isClass('classifier_old')", "color('purple')"], + ["isClass('classifier_new')", "color('red')"], + ["isClass('classifier_old')", "color('blue')"], + ["true", "color()"] + ] + } +}); + function setStyle(style) { return function() { tileset.style = new Cesium.Cesium3DTileStyle(style); diff --git a/Source/Scene/Cesium3DTileBatchTable.js b/Source/Scene/Cesium3DTileBatchTable.js index 43e2074a89e4..d0366a72b880 100644 --- a/Source/Scene/Cesium3DTileBatchTable.js +++ b/Source/Scene/Cesium3DTileBatchTable.js @@ -139,7 +139,9 @@ define([ var instancesLength = json.instancesLength; var classes = json.classes; var classIds = json.classIds; + var parentCounts = json.parentCounts; var parentIds = json.parentIds; + var parentIdsLength = instancesLength; if (defined(classIds.byteOffset)) { classIds.componentType = defaultValue(classIds.componentType, 'UNSIGNED_SHORT'); @@ -148,11 +150,27 @@ define([ classIds = binaryAccessor.createArrayBufferView(binary.buffer, binary.byteOffset + classIds.byteOffset, instancesLength); } + var parentIndexes; + if (defined(parentCounts)) { + if (defined(parentCounts.byteOffset)) { + parentCounts.componentType = defaultValue(parentCounts.componentType, 'UNSIGNED_SHORT'); + parentCounts.type = 'SCALAR'; + binaryAccessor = getBinaryAccessor(parentCounts); + parentCounts = binaryAccessor.createArrayBufferView(binary.buffer, binary.byteOffset + parentCounts.byteOffset, instancesLength); + } + parentIndexes = new Array(instancesLength); + parentIdsLength = 0; + for (i = 0; i < instancesLength; ++i) { + parentIndexes[i] = parentIdsLength; + parentIdsLength += parentCounts[i]; + } + } + if (defined(parentIds.byteOffset)) { parentIds.componentType = defaultValue(parentIds.componentType, 'UNSIGNED_SHORT'); parentIds.type = 'SCALAR'; binaryAccessor = getBinaryAccessor(parentIds); - parentIds = binaryAccessor.createArrayBufferView(binary.buffer, binary.byteOffset + parentIds.byteOffset, instancesLength); + parentIds = binaryAccessor.createArrayBufferView(binary.buffer, binary.byteOffset + parentIds.byteOffset, parentIdsLength); } var classesLength = classes.length; @@ -171,33 +189,40 @@ define([ ++classCounts[classId]; } - // Check for circular dependencies - //>>includeStart('debug', pragmas.debug); - var visited = new Array(instancesLength); - for (i = 0; i < instancesLength; ++i) { - arrayFill(visited, false); - var instanceIndex = i; - while (true) { - visited[instanceIndex] = true; - var parentId = parentIds[instanceIndex]; - if (parentId === instanceIndex) { - // Stop the traversal when the instance has no parent (its parentId equals itself) - break; - } - if (visited[parentId]) { - throw new DeveloperError('Circular dependency detected in the batch table hierarchy.'); - } - instanceIndex = parentId; - } - } - //>>includeEnd('debug'); - - return { + var hierarchy = { classes : classes, classIds : classIds, classIndexes : classIndexes, + parentCounts : parentCounts, + parentIndexes : parentIndexes, parentIds : parentIds }; + + //>>includeStart('debug', pragmas.debug); + validateHierarchy(hierarchy); + //>>includeEnd('debug'); + + return hierarchy; + } + + function validateHierarchy(hierarchy) { + // TODO : this can be optimized by marking instances that have already been checked + // Check for circular dependencies + var classIds = hierarchy.classIds; + var instancesLength = classIds.length; + var visited = new Array(instancesLength); + + var validateInstance = function(hierarchy, instanceIndex) { + if (visited[instanceIndex]) { + throw new DeveloperError('Circular dependency detected in the batch table hierarchy.'); + } + visited[instanceIndex] = true; + }; + + for (var i = 0; i < instancesLength; ++i) { + arrayFill(visited, false); + traverseHierarchy(hierarchy, i, validateInstance); + } } Cesium3DTileBatchTable.getBinaryProperties = function(featuresLength, json, binary) { @@ -425,44 +450,6 @@ define([ result); }; - Cesium3DTileBatchTable.prototype.isClass = function(batchId, className) { - // PERFORMANCE_IDEA : cache results in the ancestor classes to speed up this check if - // this area becomes a hotspot - var hierarchy = this._batchTableHierarchy; - if (!defined(hierarchy)) { - return false; - } - var instanceIndex = batchId; - while (true) { - var classId = hierarchy.classIds[instanceIndex]; - var instanceClass = hierarchy.classes[classId]; - if (instanceClass.name === className) { - return true; - } - // Stop the traversal when the instance has no parent (its parentId equals itself) - var parentId = hierarchy.parentIds[instanceIndex]; - if (parentId === instanceIndex) { - return false; - } - // Recursively check parent - instanceIndex = parentId; - } - }; - - Cesium3DTileBatchTable.prototype.isExactClass = function(batchId, className) { - return (this.getClassName(batchId) === className); - }; - - Cesium3DTileBatchTable.prototype.getClassName = function(batchId) { - var hierarchy = this._batchTableHierarchy; - if (!defined(hierarchy)) { - return undefined; - } - var classId = hierarchy.classIds[batchId]; - var instanceClass = hierarchy.classes[classId]; - return instanceClass.name; - }; - function getBinaryProperty(binaryProperty, index) { var typedArray = binaryProperty.typedArray; var componentCount = binaryProperty.componentCount; @@ -483,10 +470,81 @@ define([ } } + var scratchStack = []; + function traverseHierarchyMultipleParents(hierarchy, instanceIndex, endConditionCallback) { + var parentCounts = hierarchy.parentCounts; + var parentIds = hierarchy.parentIds; + var parentIndexes = hierarchy.parentIndexes; + + var stack = scratchStack; + stack.push(instanceIndex); + while (stack.length > 0) { + instanceIndex = stack.pop(); + var result = endConditionCallback(hierarchy, instanceIndex); + if (defined(result)) { + // The end condition was met, stop the traversal and return the result + return result; + } + var parentCount = parentCounts[instanceIndex]; + var parentIndex = parentIndexes[instanceIndex]; + for (var i = 0; i < parentCount; ++i) { + var parentId = parentIds[parentIndex + i]; + if (parentId !== instanceIndex) { + stack.push(parentId); + } + } + } + } + + function traverseHierarchySingleParent(hierarchy, instanceIndex, endConditionCallback) { + while (true) { + var result = endConditionCallback(hierarchy, instanceIndex); + if (defined(result)) { + // The end condition was met, stop the traversal and return the result + return result; + } + var parentId = hierarchy.parentIds[instanceIndex]; + if (parentId === instanceIndex) { + // Stop the traversal when the instance has no parent (its parentId equals itself) + break; + } + instanceIndex = parentId; + } + } + + function traverseHierarchy(hierarchy, instanceIndex, endConditionCallback) { + var parentCounts = hierarchy.parentCounts; + if (defined(parentCounts)) { + return traverseHierarchyMultipleParents(hierarchy, instanceIndex, endConditionCallback); + } else { + return traverseHierarchySingleParent(hierarchy, instanceIndex, endConditionCallback); + } + } + + function hasPropertyInHierarchy(batchTable, batchId, name) { + var hierarchy = batchTable._batchTableHierarchy; + var result = traverseHierarchy(hierarchy, batchId, function (hierarchy, instanceIndex) { + var classId = hierarchy.classIds[instanceIndex]; + var instances = hierarchy.classes[classId].instances; + if (defined(instances[name])) { + return true; + } + }); + return defined(result); + } + + function getPropertyNamesInHierarchy(batchTable, batchId, names) { + var hierarchy = batchTable._batchTableHierarchy; + traverseHierarchy(hierarchy, batchId, function (hierarchy, instanceIndex) { + var classId = hierarchy.classIds[instanceIndex]; + var instances = hierarchy.classes[classId].instances; + names.push.apply(Object.keys(instances)); + }); + } + function getHierarchyProperty(batchTable, batchId, name) { var hierarchy = batchTable._batchTableHierarchy; - var instanceIndex = batchId; - while (true) { + return traverseHierarchy(hierarchy, batchId, function (hierarchy, instanceIndex) { var classId = hierarchy.classIds[instanceIndex]; var instanceClass = hierarchy.classes[classId]; var indexInClass = hierarchy.classIndexes[instanceIndex]; @@ -498,20 +556,12 @@ define([ return clone(propertyValues[indexInClass], true); } } - // Stop the traversal when the instance has no parent (its parentId equals itself) - var parentId = hierarchy.parentIds[instanceIndex]; - if (parentId === instanceIndex) { - return undefined; - } - // Recursively check parent - instanceIndex = parentId; - } + }); } function setHierarchyProperty(batchTable, batchId, name, value) { var hierarchy = batchTable._batchTableHierarchy; - var instanceIndex = batchId; - while (true) { + var result = traverseHierarchy(hierarchy, batchId, function (hierarchy, instanceIndex) { var classId = hierarchy.classIds[instanceIndex]; var instanceClass = hierarchy.classes[classId]; var indexInClass = hierarchy.classIndexes[instanceIndex]; @@ -524,15 +574,81 @@ define([ } return true; } - // Stop the traversal when the instance has no parent (its parentId equals itself) - var parentId = hierarchy.parentIds[instanceIndex]; - if (parentId === instanceIndex) { - return false; + }); + return defined(result); + } + + Cesium3DTileBatchTable.prototype.isClass = function(batchId, className) { + // PERFORMANCE_IDEA : cache results in the ancestor classes to speed up this check if + // this area becomes a hotspot + var hierarchy = this._batchTableHierarchy; + if (!defined(hierarchy)) { + return false; + } + var result = traverseHierarchy(hierarchy, batchId, function(hierarchy, instanceIndex) { + var classId = hierarchy.classIds[instanceIndex]; + var instanceClass = hierarchy.classes[classId]; + if (instanceClass.name === className) { + return true; } - // Recursively check parent - instanceIndex = parentId; + }); + return defined(result); + }; + + Cesium3DTileBatchTable.prototype.isExactClass = function(batchId, className) { + return (this.getClassName(batchId) === className); + }; + + Cesium3DTileBatchTable.prototype.getClassName = function(batchId) { + var hierarchy = this._batchTableHierarchy; + if (!defined(hierarchy)) { + return undefined; } - } + var classId = hierarchy.classIds[batchId]; + var instanceClass = hierarchy.classes[classId]; + return instanceClass.name; + }; + + Cesium3DTileBatchTable.prototype.hasProperty = function(batchId, name) { + //>>includeStart('debug', pragmas.debug); + if (!defined(name)) { + throw new DeveloperError('name is required.'); + } + //>>includeEnd('debug'); + + var hierarchy = this._batchTableHierarchy; + if (defined(hierarchy)) { + if (hasPropertyInHierarchy(this, batchId)) { + return true; + } + } + + var json = this.batchTableJson; + return defined(json) && defined(json[name]); + }; + + Cesium3DTileBatchTable.prototype.getPropertyNames = function(batchId) { + //>>includeStart('debug', pragmas.debug); + if (!defined(batchId)) { + throw new DeveloperError('batchId required.'); + } + //>>includeEnd('debug'); + + var names = []; + var json = this.batchTableJson; + var hierarchy = this._batchTableHierarchy; + + if (!defined(json)) { + return names; + } + + if (defined(hierarchy)) { + getPropertyNamesInHierarchy(this, batchId, names); + } + + names = names.concat(Object.keys(json)); + return names; + }; Cesium3DTileBatchTable.prototype.getProperty = function(batchId, name) { var featuresLength = this.featuresLength; diff --git a/Specs/Data/Cesium3DTiles/Hierarchy/BatchTableHierarchy/tile.b3dm b/Specs/Data/Cesium3DTiles/Hierarchy/BatchTableHierarchy/tile.b3dm index 4cf1c3f60944b8c3f208c7a70fdf85654aafd48a..16a99c7d6f544883adec201367da3dee5fb26c17 100644 GIT binary patch delta 25 hcmezOkoDg~)(v8;Ovc8O#aSOT|6twzgO!mj8vv813NZix delta 24 gcmezOkoDg~)(v8;j0Te>SRXWhXWjmtm61Ig0E^rS`Tzg` diff --git a/Specs/Data/Cesium3DTiles/Hierarchy/BatchTableHierarchyBinary/tile.b3dm b/Specs/Data/Cesium3DTiles/Hierarchy/BatchTableHierarchyBinary/tile.b3dm index 2cfdd3d660f02c20785b13cf69c810d54dd57cdf..53ac2a305df58f44d2bbfa7d902572277fcf6aed 100644 GIT binary patch delta 236 zcmcciob}u@R>36Wlw3vz1_r-kMg|Tx1_q6Zg7uRNSw$z?ut-ka_ng_p$Yk;dMuW*W z7)6;)%#AjGV4TRvXgc`=tM=rz%vH>$#%4fi?a84mwM?calixGyOkyo!GO*ZO!n%a9 zo{<3pnHZRXRzLtDF%||8WCde326hHHB*@3W&mh1c$RLjdB^V?bq!^?b6p)}I0~j{T Mb8MIAVBDS!07D8TbN~PV delta 344 zcmX^2jP=@cR>36Wlw3vz28L_Jj0_xX3=A743f4238cu%CXfW~6VY- zU;r{788ZR-%##zZ35z0&g4l4GdaN=)6)Z@Y70L$DK&LaX1F;+q%m) l99RMFnF5vomhb1^`StEK~ph diff --git a/Specs/Data/Cesium3DTiles/Hierarchy/BatchTableHierarchyMultipleParents/tile.b3dm b/Specs/Data/Cesium3DTiles/Hierarchy/BatchTableHierarchyMultipleParents/tile.b3dm new file mode 100644 index 0000000000000000000000000000000000000000..e23ca8826c28b7fed2c98771551679b4a4824d7d GIT binary patch literal 94790 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 z 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 Date: Tue, 15 Nov 2016 15:54:16 -0500 Subject: [PATCH 08/24] Add hasPropertyName and getPropertyNames back --- Source/Scene/Batched3DModel3DTileContent.js | 7 ++++ Source/Scene/Cesium3DTileBatchTable.js | 3 ++ Source/Scene/Cesium3DTileContent.js | 12 ++++++ Source/Scene/Composite3DTileContent.js | 8 ++++ Source/Scene/Empty3DTileContent.js | 8 ++++ Source/Scene/Instanced3DModel3DTileContent.js | 7 ++++ Source/Scene/PointCloud3DTileContent.js | 10 +++++ Source/Scene/Tileset3DTileContent.js | 8 ++++ .../Scene/Batched3DModel3DTileContentSpec.js | 1 + Specs/Scene/Cesium3DTileBatchTableSpec.js | 42 +++++++++++++++++++ Specs/Scene/Cesium3DTileProviderSpec.js | 3 ++ Specs/Scene/PointCloud3DTileContentSpec.js | 3 ++ 12 files changed, 112 insertions(+) diff --git a/Source/Scene/Batched3DModel3DTileContent.js b/Source/Scene/Batched3DModel3DTileContent.js index 49279d6c7306..d20cb1e2eb84 100644 --- a/Source/Scene/Batched3DModel3DTileContent.js +++ b/Source/Scene/Batched3DModel3DTileContent.js @@ -122,6 +122,13 @@ define([ } } + /** + * Part of the {@link Cesium3DTileContent} interface. + */ + Batched3DModel3DTileContent.prototype.hasProperty = function(batchId, name) { + return this.batchTable.hasProperty(batchId, name); + }; + /** * Part of the {@link Cesium3DTileContent} interface. */ diff --git a/Source/Scene/Cesium3DTileBatchTable.js b/Source/Scene/Cesium3DTileBatchTable.js index d0366a72b880..ffd7834aaa18 100644 --- a/Source/Scene/Cesium3DTileBatchTable.js +++ b/Source/Scene/Cesium3DTileBatchTable.js @@ -611,6 +611,9 @@ define([ Cesium3DTileBatchTable.prototype.hasProperty = function(batchId, name) { //>>includeStart('debug', pragmas.debug); + if (!defined(batchId)) { + throw new DeveloperError('batchId is required.'); + } if (!defined(name)) { throw new DeveloperError('name is required.'); } diff --git a/Source/Scene/Cesium3DTileContent.js b/Source/Scene/Cesium3DTileContent.js index e8911f7646b0..e63d77075858 100644 --- a/Source/Scene/Cesium3DTileContent.js +++ b/Source/Scene/Cesium3DTileContent.js @@ -124,6 +124,18 @@ define([ } }); + /** + * Determines if the tile's batch table has a property. If it does, each feature in + * the tile will have the property. + * + * @param {Number} batchId The batchId for the feature. + * @param {String} name The case-sensitive name of the property. + * @returns {Boolean} true if the property exists; otherwise, false. + */ + Cesium3DTileContent.prototype.hasProperty = function(batchId, name) { + DeveloperError.throwInstantiationError(); + }; + /** * Returns the {@link Cesium3DTileFeature} object for the feature with the * given batchId. This object is used to get and modify the diff --git a/Source/Scene/Composite3DTileContent.js b/Source/Scene/Composite3DTileContent.js index c9347aad6070..499f17919379 100644 --- a/Source/Scene/Composite3DTileContent.js +++ b/Source/Scene/Composite3DTileContent.js @@ -118,6 +118,14 @@ define([ } }); + /** + * Part of the {@link Cesium3DTileContent} interface. Composite3DTileContent + * always returns false. Instead call hasProperty for a tile in the composite. + */ + Composite3DTileContent.prototype.hasProperty = function(batchId, name) { + return false; + }; + /** * Part of the {@link Cesium3DTileContent} interface. Composite3DTileContent * always returns undefined. Instead call getFeature for a tile in the composite. diff --git a/Source/Scene/Empty3DTileContent.js b/Source/Scene/Empty3DTileContent.js index 88e845df81a5..65b45ade6d1b 100644 --- a/Source/Scene/Empty3DTileContent.js +++ b/Source/Scene/Empty3DTileContent.js @@ -79,6 +79,14 @@ define([ } }); + /** + * Part of the {@link Cesium3DTileContent} interface. Empty3DTileContent + * always returns false since a tile of this type does not have any features. + */ + Empty3DTileContent.prototype.hasProperty = function(batchId, name) { + return false; + }; + /** * Part of the {@link Cesium3DTileContent} interface. Empty3DTileContent * always returns undefined since a tile of this type does not have any features. diff --git a/Source/Scene/Instanced3DModel3DTileContent.js b/Source/Scene/Instanced3DModel3DTileContent.js index 4f85673fa8f0..c1e72aea42e3 100644 --- a/Source/Scene/Instanced3DModel3DTileContent.js +++ b/Source/Scene/Instanced3DModel3DTileContent.js @@ -145,6 +145,13 @@ define([ } } + /** + * Part of the {@link Cesium3DTileContent} interface. + */ + Instanced3DModel3DTileContent.prototype.hasProperty = function(batchId, name) { + return this.batchTable.hasProperty(batchId, name); + }; + /** * Part of the {@link Cesium3DTileContent} interface. */ diff --git a/Source/Scene/PointCloud3DTileContent.js b/Source/Scene/PointCloud3DTileContent.js index 96f7a237efb9..8c2f762bfe13 100644 --- a/Source/Scene/PointCloud3DTileContent.js +++ b/Source/Scene/PointCloud3DTileContent.js @@ -186,6 +186,16 @@ define([ } } + /** + * Part of the {@link Cesium3DTileContent} interface. + */ + PointCloud3DTileContent.prototype.hasProperty = function(batchId, name) { + if (defined(this.batchTable)) { + return this.batchTable.hasProperty(batchId, name); + } + return false; + }; + /** * Part of the {@link Cesium3DTileContent} interface. * diff --git a/Source/Scene/Tileset3DTileContent.js b/Source/Scene/Tileset3DTileContent.js index bf8be7fa87c3..49a7daba114a 100644 --- a/Source/Scene/Tileset3DTileContent.js +++ b/Source/Scene/Tileset3DTileContent.js @@ -77,6 +77,14 @@ define([ } }); + /** + * Part of the {@link Cesium3DTileContent} interface. Tileset3DTileContent + * always returns false since a tile of this type does not have any features. + */ + Tileset3DTileContent.prototype.hasProperty = function(batchId, name) { + return false; + }; + /** * Part of the {@link Cesium3DTileContent} interface. Tileset3DTileContent * always returns undefined since a tile of this type does not have any features. diff --git a/Specs/Scene/Batched3DModel3DTileContentSpec.js b/Specs/Scene/Batched3DModel3DTileContentSpec.js index 948780cc9ca5..cae42963166c 100644 --- a/Specs/Scene/Batched3DModel3DTileContentSpec.js +++ b/Specs/Scene/Batched3DModel3DTileContentSpec.js @@ -181,6 +181,7 @@ defineSuite([ var content = tileset._root.content; expect(content.featuresLength).toBe(10); expect(content.innerContents).toBeUndefined(); + expect(content.hasProperty(0, 'id')).toBe(true); expect(content.getFeature(0)).toBeDefined(); }); }); diff --git a/Specs/Scene/Cesium3DTileBatchTableSpec.js b/Specs/Scene/Cesium3DTileBatchTableSpec.js index bc96d075bc9d..a54e47867280 100644 --- a/Specs/Scene/Cesium3DTileBatchTableSpec.js +++ b/Specs/Scene/Cesium3DTileBatchTableSpec.js @@ -229,6 +229,48 @@ defineSuite([ expect(batchTable.getColor(0, result)).toEqual(Color.YELLOW); }); + it('hasProperty throws with undefined batchId', function() { + var batchTable = new Cesium3DTileBatchTable(mockContent, 1); + expect(function() { + batchTable.hasProperty(); + }).toThrowDeveloperError(); + }); + + it('hasProperty throws with undefined name', function() { + var batchTable = new Cesium3DTileBatchTable(mockContent, 1); + expect(function() { + batchTable.hasProperty(0); + }).toThrowDeveloperError(); + }); + + it('hasProperty', function() { + var batchTableJson = { + height: [0.0] + }; + var batchTable = new Cesium3DTileBatchTable(mockContent, 1, batchTableJson); + expect(batchTable.hasProperty(0, 'height')).toEqual(true); + expect(batchTable.hasProperty(0, 'id')).toEqual(false); + }); + + it('getPropertyNames throws with undefined batchId', function() { + var batchTable = new Cesium3DTileBatchTable(mockContent, 1); + expect(function() { + batchTable.getPropertyNames(); + }).toThrowDeveloperError(); + }); + + it('getPropertyNames', function() { + var batchTable = new Cesium3DTileBatchTable(mockContent, 1); + expect(batchTable.getPropertyNames(0)).toEqual([]); + + var batchTableJson = { + height: [0.0], + id : [0] + }; + batchTable = new Cesium3DTileBatchTable(mockContent, 1, batchTableJson); + expect(batchTable.getPropertyNames(0)).toEqual(['height', 'id']); + }); + it('getProperty throws with invalid batchId', function() { var batchTable = new Cesium3DTileBatchTable(mockContent, 1); expect(function() { diff --git a/Specs/Scene/Cesium3DTileProviderSpec.js b/Specs/Scene/Cesium3DTileProviderSpec.js index 0fdb71b85faa..234cf1c9dd31 100644 --- a/Specs/Scene/Cesium3DTileProviderSpec.js +++ b/Specs/Scene/Cesium3DTileProviderSpec.js @@ -13,6 +13,9 @@ defineSuite([ expect(function() { return content.innerContents; }).toThrowDeveloperError(); + expect(function() { + return content.hasProperty(0, 'height'); + }).toThrowDeveloperError(); expect(function() { return content.getFeature(0); }).toThrowDeveloperError(); diff --git a/Specs/Scene/PointCloud3DTileContentSpec.js b/Specs/Scene/PointCloud3DTileContentSpec.js index 3d1deb2ac851..214f83ea9393 100644 --- a/Specs/Scene/PointCloud3DTileContentSpec.js +++ b/Specs/Scene/PointCloud3DTileContentSpec.js @@ -292,6 +292,7 @@ defineSuite([ var content = tileset._root.content; expect(content.featuresLength).toBe(0); expect(content.innerContents).toBeUndefined(); + expect(content.hasProperty(0, 'name')).toBe(false); expect(content.getFeature(0)).toBeUndefined(); }); }); @@ -301,6 +302,7 @@ defineSuite([ var content = tileset._root.content; expect(content.featuresLength).toBe(8); expect(content.innerContents).toBeUndefined(); + expect(content.hasProperty(0, 'name')).toBe(true); expect(content.getFeature(0)).toBeDefined(); }); }); @@ -313,6 +315,7 @@ defineSuite([ var content = tileset._root.content; expect(content.featuresLength).toBe(0); expect(content.innerContents).toBeUndefined(); + expect(content.hasProperty(0, 'name')).toBe(false); expect(content.getFeature(0)).toBeUndefined(); }); }); From ccb8babf3ad66190085c24a742508bae226f418b Mon Sep 17 00:00:00 2001 From: Sean Lilley Date: Thu, 17 Nov 2016 10:24:25 -0500 Subject: [PATCH 09/24] Cleanup and more comments --- Source/Scene/Cesium3DTileBatchTable.js | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/Source/Scene/Cesium3DTileBatchTable.js b/Source/Scene/Cesium3DTileBatchTable.js index ffd7834aaa18..c12e09ab5bfb 100644 --- a/Source/Scene/Cesium3DTileBatchTable.js +++ b/Source/Scene/Cesium3DTileBatchTable.js @@ -158,7 +158,7 @@ define([ binaryAccessor = getBinaryAccessor(parentCounts); parentCounts = binaryAccessor.createArrayBufferView(binary.buffer, binary.byteOffset + parentCounts.byteOffset, instancesLength); } - parentIndexes = new Array(instancesLength); + parentIndexes = new Uint16Array(instancesLength); parentIdsLength = 0; for (i = 0; i < instancesLength; ++i) { parentIndexes[i] = parentIdsLength; @@ -182,7 +182,7 @@ define([ } var classCounts = arrayFill(new Array(classesLength), 0); - var classIndexes = new Array(instancesLength); + var classIndexes = new Uint16Array(instancesLength); for (i = 0; i < instancesLength; ++i) { classId = classIds[i]; classIndexes[i] = classCounts[classId]; @@ -206,7 +206,7 @@ define([ } function validateHierarchy(hierarchy) { - // TODO : this can be optimized by marking instances that have already been checked + // PERFORMANCE_IDEA : this can be optimized by marking instances that have already been checked // Check for circular dependencies var classIds = hierarchy.classIds; var instancesLength = classIds.length; @@ -477,6 +477,7 @@ define([ var parentIndexes = hierarchy.parentIndexes; var stack = scratchStack; + stack.length = 0; stack.push(instanceIndex); while (stack.length > 0) { instanceIndex = stack.pop(); @@ -489,6 +490,8 @@ define([ var parentIndex = parentIndexes[instanceIndex]; for (var i = 0; i < parentCount; ++i) { var parentId = parentIds[parentIndex + i]; + // Stop the traversal when the instance has no parent (its parentId equals itself) + // else add the parent to the stack to continue the traversal. if (parentId !== instanceIndex) { stack.push(parentId); } @@ -513,6 +516,8 @@ define([ } function traverseHierarchy(hierarchy, instanceIndex, endConditionCallback) { + // Traverse over the hierarchy and process each instance with the endConditionCallback. + // When the endConditionCallback returns a value, the traversal stops and that value is returned. var parentCounts = hierarchy.parentCounts; if (defined(parentCounts)) { return traverseHierarchyMultipleParents(hierarchy, instanceIndex, endConditionCallback); @@ -523,7 +528,7 @@ define([ function hasPropertyInHierarchy(batchTable, batchId, name) { var hierarchy = batchTable._batchTableHierarchy; - var result = traverseHierarchy(hierarchy, batchId, function (hierarchy, instanceIndex) { + var result = traverseHierarchy(hierarchy, batchId, function(hierarchy, instanceIndex) { var classId = hierarchy.classIds[instanceIndex]; var instances = hierarchy.classes[classId].instances; if (defined(instances[name])) { @@ -535,7 +540,7 @@ define([ function getPropertyNamesInHierarchy(batchTable, batchId, names) { var hierarchy = batchTable._batchTableHierarchy; - traverseHierarchy(hierarchy, batchId, function (hierarchy, instanceIndex) { + traverseHierarchy(hierarchy, batchId, function(hierarchy, instanceIndex) { var classId = hierarchy.classIds[instanceIndex]; var instances = hierarchy.classes[classId].instances; names.push.apply(Object.keys(instances)); @@ -544,7 +549,7 @@ define([ function getHierarchyProperty(batchTable, batchId, name) { var hierarchy = batchTable._batchTableHierarchy; - return traverseHierarchy(hierarchy, batchId, function (hierarchy, instanceIndex) { + return traverseHierarchy(hierarchy, batchId, function(hierarchy, instanceIndex) { var classId = hierarchy.classIds[instanceIndex]; var instanceClass = hierarchy.classes[classId]; var indexInClass = hierarchy.classIndexes[instanceIndex]; @@ -561,7 +566,7 @@ define([ function setHierarchyProperty(batchTable, batchId, name, value) { var hierarchy = batchTable._batchTableHierarchy; - var result = traverseHierarchy(hierarchy, batchId, function (hierarchy, instanceIndex) { + var result = traverseHierarchy(hierarchy, batchId, function(hierarchy, instanceIndex) { var classId = hierarchy.classIds[instanceIndex]; var instanceClass = hierarchy.classes[classId]; var indexInClass = hierarchy.classIndexes[instanceIndex]; @@ -579,8 +584,7 @@ define([ } Cesium3DTileBatchTable.prototype.isClass = function(batchId, className) { - // PERFORMANCE_IDEA : cache results in the ancestor classes to speed up this check if - // this area becomes a hotspot + // PERFORMANCE_IDEA : cache results in the ancestor classes to speed up this check if this area becomes a hotspot var hierarchy = this._batchTableHierarchy; if (!defined(hierarchy)) { return false; From 2e24750983a3f9d2c187534632bb7fc4c8c8bd4a Mon Sep 17 00:00:00 2001 From: Sean Lilley Date: Thu, 17 Nov 2016 12:02:03 -0500 Subject: [PATCH 10/24] Small fixes and doc --- Source/Scene/Cesium3DTileBatchTable.js | 24 ++++++++++++++ Source/Scene/Cesium3DTileFeature.js | 39 +++++++++++++++++++++-- Source/Scene/Expression.js | 9 +++--- Specs/Scene/Cesium3DTileBatchTableSpec.js | 6 ++++ 4 files changed, 71 insertions(+), 7 deletions(-) diff --git a/Source/Scene/Cesium3DTileBatchTable.js b/Source/Scene/Cesium3DTileBatchTable.js index c12e09ab5bfb..f5652b6f82b2 100644 --- a/Source/Scene/Cesium3DTileBatchTable.js +++ b/Source/Scene/Cesium3DTileBatchTable.js @@ -213,6 +213,9 @@ define([ var visited = new Array(instancesLength); var validateInstance = function(hierarchy, instanceIndex) { + if (instanceIndex >= instancesLength) { + throw new DeveloperError('Parent index ' + instanceIndex + ' exceeds the total number of instances: ' + instancesLength); + } if (visited[instanceIndex]) { throw new DeveloperError('Circular dependency detected in the batch table hierarchy.'); } @@ -584,6 +587,15 @@ define([ } Cesium3DTileBatchTable.prototype.isClass = function(batchId, className) { + //>>includeStart('debug', pragmas.debug); + if (!defined(batchId)) { + throw new DeveloperError('batchId is required.'); + } + if (!defined(className)) { + throw new DeveloperError('className is required.'); + } + //>>includeEnd('debug'); + // PERFORMANCE_IDEA : cache results in the ancestor classes to speed up this check if this area becomes a hotspot var hierarchy = this._batchTableHierarchy; if (!defined(hierarchy)) { @@ -600,10 +612,22 @@ define([ }; Cesium3DTileBatchTable.prototype.isExactClass = function(batchId, className) { + //>>includeStart('debug', pragmas.debug); + if (!defined(className)) { + throw new DeveloperError('className is required.'); + } + //>>includeEnd('debug'); + return (this.getClassName(batchId) === className); }; Cesium3DTileBatchTable.prototype.getClassName = function(batchId) { + //>>includeStart('debug', pragmas.debug); + if (!defined(batchId)) { + throw new DeveloperError('batchId is required.'); + } + //>>includeEnd('debug'); + var hierarchy = this._batchTableHierarchy; if (!defined(hierarchy)) { return undefined; diff --git a/Source/Scene/Cesium3DTileFeature.js b/Source/Scene/Cesium3DTileFeature.js index 356a29b8b3a2..651fc33b712e 100644 --- a/Source/Scene/Cesium3DTileFeature.js +++ b/Source/Scene/Cesium3DTileFeature.js @@ -168,15 +168,50 @@ define([ this._content.featurePropertiesDirty = true; }; - // TODO : add doc + /** + * Returns whether the feature's class name equals className. Unlike {@link Cesium3DTileFeature#isClass} + * this function only checks the feature's exact class and not base classes. + *

+ * This function returns false if no batch table hierarchy is present. + *

+ * + * @param {String} className The name to check against. + * @returns {Boolean} Whether the feature's class name equals className + * + * @private + */ Cesium3DTileFeature.prototype.isExactClass = function(className) { return this._batchTable.isExactClass(this._batchId, className); }; - // TODO : add doc + /** + * Returns whether the feature's class or any base classes are named className. + *

+ * This function returns false if no batch table hierarchy is present. + *

+ * + * @param {String} className The name to check against. + * @returns {Boolean} Whether the feature's class or base classes are named className + * + * @private + */ Cesium3DTileFeature.prototype.isClass = function(className) { return this._batchTable.isClass(this._batchId, className); }; + /** + * Returns the feature's class name. + *

+ * This function returns undefined if no batch table hierarchy is present. + *

+ * + * @returns {String} The feature's class name. + * + * @private + */ + Cesium3DTileFeature.prototype.getClassName = function() { + return this._batchTable.getClassName(this._batchId); + }; + return Cesium3DTileFeature; }); diff --git a/Source/Scene/Expression.js b/Source/Scene/Expression.js index 723b3106fefd..eac1a5208679 100644 --- a/Source/Scene/Expression.js +++ b/Source/Scene/Expression.js @@ -358,12 +358,11 @@ define([ return new Node(ExpressionNodeType.UNARY, call, val); } else if (call === 'getClassName') { //>>includeStart('debug', pragmas.debug); - if (args.length < 1 || args.length > 1) { - throw new DeveloperError('Error: ' + call + ' requires exactly one argument.'); + if (args.length > 0) { + throw new DeveloperError('Error: ' + call + ' does not take any argument.'); } //>>includeEnd('debug'); - val = createRuntimeAst(expression, args[0]); - return new Node(ExpressionNodeType.UNARY, call, val); + return new Node(ExpressionNodeType.UNARY, call); } else if (call === 'abs') { //>>includeStart('debug', pragmas.debug); if (args.length < 1 || args.length > 1) { @@ -979,7 +978,7 @@ define([ }; Node.prototype._evaluateGetClassName = function(frameState, feature) { - return feature.getClassName(this._left.evaluate(frameState, feature)); + return feature.getClassName(); }; Node.prototype._evaluateAbsoluteValue = function(frameState, feature) { diff --git a/Specs/Scene/Cesium3DTileBatchTableSpec.js b/Specs/Scene/Cesium3DTileBatchTableSpec.js index a54e47867280..e56383333642 100644 --- a/Specs/Scene/Cesium3DTileBatchTableSpec.js +++ b/Specs/Scene/Cesium3DTileBatchTableSpec.js @@ -640,6 +640,12 @@ defineSuite([ }); }); + it('renders tileset with batch table hierarchy', function() { + return Cesium3DTilesTester.loadTileset(scene, batchTableHierarchyUrl).then(function(tileset) { + expectRender(tileset); + }); + }); + it('destroys', function() { return Cesium3DTilesTester.loadTileset(scene, withoutBatchTableUrl).then(function(tileset) { var content = tileset._root.content; From e3ea1bb83c79e0a1715c3ce01a829200e11c63a5 Mon Sep 17 00:00:00 2001 From: Sean Lilley Date: Thu, 17 Nov 2016 15:57:32 -0500 Subject: [PATCH 11/24] Initial tests --- Source/Core/IndexDatatype.js | 2 +- Source/DataSources/PropertyBag.js | 2 +- Source/Scene/Cesium3DTileBatchTable.js | 20 ++- Source/Scene/Cesium3DTileFeature.js | 41 ++++- Specs/Scene/Cesium3DTileBatchTableSpec.js | 177 +++++++++++++++++++++- Specs/Scene/ExpressionSpec.js | 97 ++++++++++++ 6 files changed, 319 insertions(+), 20 deletions(-) diff --git a/Source/Core/IndexDatatype.js b/Source/Core/IndexDatatype.js index 7ffad3c9bc46..4ce79d1eba8c 100644 --- a/Source/Core/IndexDatatype.js +++ b/Source/Core/IndexDatatype.js @@ -96,7 +96,7 @@ define([ * or Uint32Array depending on the number of vertices. * * @param {Number} numberOfVertices Number of vertices that the indices will reference. - * @param {Any} indicesLengthOrArray Passed through to the typed array constructor. + * @param {*} indicesLengthOrArray Passed through to the typed array constructor. * @returns {Uint16Array|Uint32Array} A Uint16Array or Uint32Array constructed with indicesLengthOrArray. * * @example diff --git a/Source/DataSources/PropertyBag.js b/Source/DataSources/PropertyBag.js index 21b2930fa7e4..0dc855e147b6 100644 --- a/Source/DataSources/PropertyBag.js +++ b/Source/DataSources/PropertyBag.js @@ -102,7 +102,7 @@ define([ * Adds a property to this object. * * @param {String} propertyName The name of the property to add. - * @param {Any} [value] The value of the new property, if provided. + * @param {*} [value] The value of the new property, if provided. * @param {Function} [createPropertyCallback] A function that will be called when the value of this new property is set to a value that is not a Property. * * @exception {DeveloperError} "propertyName" is already a registered property. diff --git a/Source/Scene/Cesium3DTileBatchTable.js b/Source/Scene/Cesium3DTileBatchTable.js index f5652b6f82b2..664fae1d908e 100644 --- a/Source/Scene/Cesium3DTileBatchTable.js +++ b/Source/Scene/Cesium3DTileBatchTable.js @@ -587,9 +587,10 @@ define([ } Cesium3DTileBatchTable.prototype.isClass = function(batchId, className) { + var featuresLength = this.featuresLength; //>>includeStart('debug', pragmas.debug); - if (!defined(batchId)) { - throw new DeveloperError('batchId is required.'); + if (!defined(batchId) || (batchId < 0) || (batchId > featuresLength)) { + throw new DeveloperError('batchId is required and between zero and featuresLength - 1 (' + featuresLength - + ').'); } if (!defined(className)) { throw new DeveloperError('className is required.'); @@ -622,9 +623,10 @@ define([ }; Cesium3DTileBatchTable.prototype.getClassName = function(batchId) { + var featuresLength = this.featuresLength; //>>includeStart('debug', pragmas.debug); - if (!defined(batchId)) { - throw new DeveloperError('batchId is required.'); + if (!defined(batchId) || (batchId < 0) || (batchId > featuresLength)) { + throw new DeveloperError('batchId is required and between zero and featuresLength - 1 (' + featuresLength - + ').'); } //>>includeEnd('debug'); @@ -638,9 +640,10 @@ define([ }; Cesium3DTileBatchTable.prototype.hasProperty = function(batchId, name) { + var featuresLength = this.featuresLength; //>>includeStart('debug', pragmas.debug); - if (!defined(batchId)) { - throw new DeveloperError('batchId is required.'); + if (!defined(batchId) || (batchId < 0) || (batchId > featuresLength)) { + throw new DeveloperError('batchId is required and between zero and featuresLength - 1 (' + featuresLength - + ').'); } if (!defined(name)) { throw new DeveloperError('name is required.'); @@ -659,9 +662,10 @@ define([ }; Cesium3DTileBatchTable.prototype.getPropertyNames = function(batchId) { + var featuresLength = this.featuresLength; //>>includeStart('debug', pragmas.debug); - if (!defined(batchId)) { - throw new DeveloperError('batchId required.'); + if (!defined(batchId) || (batchId < 0) || (batchId > featuresLength)) { + throw new DeveloperError('batchId is required and between zero and featuresLength - 1 (' + featuresLength - + ').'); } //>>includeEnd('debug'); diff --git a/Source/Scene/Cesium3DTileFeature.js b/Source/Scene/Cesium3DTileFeature.js index 651fc33b712e..5baf678066ee 100644 --- a/Source/Scene/Cesium3DTileFeature.js +++ b/Source/Scene/Cesium3DTileFeature.js @@ -103,6 +103,37 @@ define([ } }); + /** + * Returns whether the feature contains this property. This includes properties from this feature's + * class and inherited classes, in addition to the standard batch table properties. + *

+ * {@link Cesium3DTileFeature#show} and {@link Cesium3DTileFeature#color} are not equivalent to + * 'show' and 'color' properties; the former are runtime-specific properties + * that are not part of the feature's properties in the stored 3D Tileset. + *

+ * + * @param {String} name The case-sensitive name of the property. + * @returns {Boolean} Whether the feature contains this property. + */ + Cesium3DTileFeature.prototype.hasProperty = function(name) { + return this._batchTable.hasProperty(this._batchId, name); + }; + + /** + * Returns an array of property names for the feature. This includes properties from this feature's + * class and inherited classes, in addition to the standard batch table properties. + *

+ * {@link Cesium3DTileFeature#show} and {@link Cesium3DTileFeature#color} are not equivalent to + * 'show' and 'color' properties; the former are runtime-specific properties + * that are not part of the feature's properties in the stored 3D Tileset. + *

+ * + * @returns {String[]} The names of the feature's properties. + */ + Cesium3DTileFeature.prototype.getPropertyNames = function() { + return this._batchTable.getPropertyNames(this._batchId); + }; + /** * Returns the value of the feature's property with the given name. *

@@ -112,7 +143,7 @@ define([ *

* * @param {String} name The case-sensitive name of the property. - * @returns {Any} The value of the property or undefined if the property does not exist. + * @returns {*} The value of the property or undefined if the property does not exist. * * @example * // Display all the properties for a feature in the console log. @@ -143,7 +174,7 @@ define([ *

* * @param {String} name The case-sensitive name of the property. - * @param {Any} value The value of the property that will be copied. + * @param {*} value The value of the property that will be copied. * * @example * var height = feature.getProperty('Height'); // e.g., the height of a building @@ -170,7 +201,7 @@ define([ /** * Returns whether the feature's class name equals className. Unlike {@link Cesium3DTileFeature#isClass} - * this function only checks the feature's exact class and not base classes. + * this function only checks the feature's exact class and not inherited classes. *

* This function returns false if no batch table hierarchy is present. *

@@ -185,13 +216,13 @@ define([ }; /** - * Returns whether the feature's class or any base classes are named className. + * Returns whether the feature's class or any inherited classes are named className. *

* This function returns false if no batch table hierarchy is present. *

* * @param {String} className The name to check against. - * @returns {Boolean} Whether the feature's class or base classes are named className + * @returns {Boolean} Whether the feature's class or inherited classes are named className * * @private */ diff --git a/Specs/Scene/Cesium3DTileBatchTableSpec.js b/Specs/Scene/Cesium3DTileBatchTableSpec.js index e56383333642..41406570e094 100644 --- a/Specs/Scene/Cesium3DTileBatchTableSpec.js +++ b/Specs/Scene/Cesium3DTileBatchTableSpec.js @@ -10,6 +10,7 @@ defineSuite([ 'Core/Matrix3', 'Core/Matrix4', 'Renderer/ContextLimits', + 'Scene/Cesium3DTileStyle', 'Specs/Cesium3DTilesTester', 'Specs/createScene' ], function( @@ -23,6 +24,7 @@ defineSuite([ Matrix3, Matrix4, ContextLimits, + Cesium3DTileStyle, Cesium3DTilesTester, createScene) { 'use strict'; @@ -34,6 +36,9 @@ defineSuite([ var withBatchTableUrl = './Data/Cesium3DTiles/Batched/BatchedWithBatchTable/'; var withoutBatchTableUrl = './Data/Cesium3DTiles/Batched/BatchedWithoutBatchTable/'; var batchLengthZeroUrl = './Data/Cesium3DTiles/Batched/BatchedNoBuildings/'; + var batchTableHierarchyUrl = './Data/Cesium3DTiles/Hierarchy/BatchTableHierarchy/'; + var batchTableHierarchyBinaryUrl = './Data/Cesium3DTiles/Hierarchy/BatchTableHierarchyBinary/'; + var batchTableHierarchyMultipleParentsUrl = './Data/Cesium3DTiles/Hierarchy/BatchTableHierarchyMultipleParents/'; var result = new Color(); @@ -229,11 +234,17 @@ defineSuite([ expect(batchTable.getColor(0, result)).toEqual(Color.YELLOW); }); - it('hasProperty throws with undefined batchId', function() { + it('hasProperty throws with invalid batchId', function() { var batchTable = new Cesium3DTileBatchTable(mockContent, 1); expect(function() { batchTable.hasProperty(); }).toThrowDeveloperError(); + expect(function() { + batchTable.hasProperty(-1); + }).toThrowDeveloperError(); + expect(function() { + batchTable.hasProperty(2); + }).toThrowDeveloperError(); }); it('hasProperty throws with undefined name', function() { @@ -252,11 +263,17 @@ defineSuite([ expect(batchTable.hasProperty(0, 'id')).toEqual(false); }); - it('getPropertyNames throws with undefined batchId', function() { + it('getPropertyNames throws with invalid batchId', function() { var batchTable = new Cesium3DTileBatchTable(mockContent, 1); expect(function() { batchTable.getPropertyNames(); }).toThrowDeveloperError(); + expect(function() { + batchTable.getPropertyNames(-1); + }).toThrowDeveloperError(); + expect(function() { + batchTable.getPropertyNames(2); + }).toThrowDeveloperError(); }); it('getPropertyNames', function() { @@ -640,10 +657,160 @@ defineSuite([ }); }); - it('renders tileset with batch table hierarchy', function() { - return Cesium3DTilesTester.loadTileset(scene, batchTableHierarchyUrl).then(function(tileset) { - expectRender(tileset); + it('isExactClass throws with invalid batchId', function() { + var batchTable = new Cesium3DTileBatchTable(mockContent, 1); + expect(function() { + batchTable.isExactClass(); + }).toThrowDeveloperError(); + expect(function() { + batchTable.isExactClass(2, 'door'); + }).toThrowDeveloperError(); + expect(function() { + batchTable.isExactClass(-1, 'door'); + }).toThrowDeveloperError(); + }); + + it('isExactClass throws with undefined className', function() { + var batchTable = new Cesium3DTileBatchTable(mockContent, 1); + expect(function() { + batchTable.isExactClass(0); + }).toThrowDeveloperError(); + }); + + it('isClass throws with invalid batchId', function() { + var batchTable = new Cesium3DTileBatchTable(mockContent, 1); + expect(function() { + batchTable.isClass(); + }).toThrowDeveloperError(); + expect(function() { + batchTable.isClass(2, 'door'); + }).toThrowDeveloperError(); + expect(function() { + batchTable.isClass(-1, 'door'); + }).toThrowDeveloperError(); + }); + + it('isClass throws with undefined className', function() { + var batchTable = new Cesium3DTileBatchTable(mockContent, 1); + expect(function() { + batchTable.isClass(0); + }).toThrowDeveloperError(); + }); + + it('getClassName throws with invalid batchId', function() { + var batchTable = new Cesium3DTileBatchTable(mockContent, 1); + expect(function() { + batchTable.getClassName(); + }).toThrowDeveloperError(); + expect(function() { + batchTable.getClassName(1000); + }).toThrowDeveloperError(); + expect(function() { + batchTable.getClassName(-1); + }).toThrowDeveloperError(); + }); + + function checkHierarchyStyling(tileset) { + // Check that a feature is colored from a generic batch table property. + tileset.style = new Cesium3DTileStyle({color : "${height} === 6.0 ? color('red') : color('green')"}); + expect(scene.renderForSpecs()[0]).toBeGreaterThan(0); // Expect red + + // Check that a feature is colored from a class property. + tileset.style = new Cesium3DTileStyle({color : "${roof_name} === 'roof2' ? color('red') : color('green')"}); + expect(scene.renderForSpecs()[0]).toBeGreaterThan(0); // Expect red + + // Check that a feature is colored from an inherited property. + tileset.style = new Cesium3DTileStyle({color : "${building_name} === 'building2' ? color('red') : color('green')"}); + expect(scene.renderForSpecs()[0]).toBeGreaterThan(0); // Expect red + + // Check isExactClass + tileset.style = new Cesium3DTileStyle({color : "isExactClass('roof') ? color('red') : color('green')"}); + expect(scene.renderForSpecs()[0]).toBeGreaterThan(0); // Expect red + tileset.style = new Cesium3DTileStyle({color : "isExactClass('door') ? color('red') : color('green')"}); + expect(scene.renderForSpecs()[1]).toBeGreaterThan(0); // Expect green + + // Check isClass + tileset.style = new Cesium3DTileStyle({color : "isClass('roof') ? color('red') : color('green')"}); + expect(scene.renderForSpecs()[0]).toBeGreaterThan(0); // Expect red + tileset.style = new Cesium3DTileStyle({color : "isClass('zone') ? color('red') : color('green')"}); + expect(scene.renderForSpecs()[0]).toBeGreaterThan(0); // Expect red + + // Check getClassName + tileset.style = new Cesium3DTileStyle({color : "getClassName() === 'roof' ? color('red') : color('green')"}); + expect(scene.renderForSpecs()[0]).toBeGreaterThan(0); // Expect red + tileset.style = new Cesium3DTileStyle({color : "getClassName() === 'zone' ? color('red') : color('green')"}); + expect(scene.renderForSpecs()[1]).toBeGreaterThan(0); // Expect green + } + + function checkHierarchyProperties(tileset) { + // Check isExactClass, isClass, and getClassName in Cesium3DTileFeature + var content = tileset._root.content; + var batchTable = content.batchTable; + var hierarchy = batchTable._batchTableHierarchy; + + var doorFeature = content.getFeature(4); + var roofFeature = content.getFeature(8); + expect(doorFeature.isExactClass('door')).toBe(true); + expect(doorFeature.isExactClass('building')).toBe(false); + expect(doorFeature.isClass('door')).toBe(true); + expect(doorFeature.isClass('doorknob')).toBe(false); + expect(doorFeature.isClass('building')).toBe(true); + expect(doorFeature.getClassName()).toBe('door'); + expect(doorFeature.hasProperty('door')).toBe(true); + expect(doorFeature.hasProperty('height')).toBe(true); + + // Includes batch table properties and hierarchy properties from all inherited classes + expect(doorFeature.getPropertyNames()).toEqual(['door', 'building', 'zone', 'height', 'area']); // TODO depending on the url this will also contain classifier_old and classifier_new + + expect(doorFeature.getProperty('height')).toBe(5.0); // Gets generic property + expect(doorFeature.getProperty('door_name')).toBe('door0'); // Gets class property + expect(doorFeature.getProperty('building_name')).toBe('building0'); // Gets inherited property + + // Sets generic property + doorFeature.setProperty('height', 10.0); + expect(doorFeature.getProperty('height')).toBe(10.0); + + // Sets class property. + doorFeature.setProperty('door_name', 'new_door'); + expect(doorFeature.getProperty('door_name')).toBe('new_door'); + expect(roofFeature.getProperty('door_name')).toBeUndefined(); + + // Sets inherited property. Check that both door and roof respond to the property change. + doorFeature.setProperty('building_name', 'new_building'); + expect(doorFeature.getProperty('building_name')).toBe('new_building'); + expect(roofFeature.getProperty('building_name')).toBe('new_building'); + + // Check properties when there is no hierarchy + batchTable._batchTableHierarchy = undefined; + expect(doorFeature.isExactClass('door')).toBe(false); + expect(doorFeature.isClass('door')).toBe(false); + expect(doorFeature.getClassName()).toBeUndefined(); + expect(doorFeature.hasProperty('door')).toBe(false); + expect(doorFeature.hasProperty('height')).toBe(true); + expect(doorFeature.getPropertyNames()).toEqual(['height', 'area']); + expect(doorFeature.getProperty('height')).toBe(10.0); + expect(doorFeature.getProperty('door_name')).toBeUndefined(); + expect(doorFeature.getProperty('building_name')).toBeUndefined(); + batchTable._batchTableHierarchy = hierarchy; + } + + function checkBatchTableHierarchy(url) { + return Cesium3DTilesTester.loadTileset(scene, url).then(function(tileset) { + checkHierarchyStyling(tileset); + checkHierarchyProperties(tileset); }); + } + + it('renders tileset with batch table hierarchy', function() { + return checkBatchTableHierarchy(batchTableHierarchyUrl); + }); + + it('renders tileset with batch table hierarchy using binary properties', function() { + return checkBatchTableHierarchy(batchTableHierarchyBinaryUrl); + }); + + it('renders tileset with batch table hierarchy with multiple parent classes', function() { + return checkBatchTableHierarchy(batchTableHierarchyMultipleParentsUrl); }); it('destroys', function() { diff --git a/Specs/Scene/ExpressionSpec.js b/Specs/Scene/ExpressionSpec.js index 3bc68400eee0..98caa181e443 100644 --- a/Specs/Scene/ExpressionSpec.js +++ b/Specs/Scene/ExpressionSpec.js @@ -13,6 +13,8 @@ defineSuite([ function MockFeature() { this._properties = {}; + this._className = undefined; + this._inheritedClassName = undefined; this._content = { _tileset : { timeSinceLoad : 0.0 @@ -28,6 +30,26 @@ defineSuite([ return this._properties[name]; }; + MockFeature.prototype.setClass = function(className) { + this._className = className; + }; + + MockFeature.prototype.setInheritedClass = function(className) { + this._inheritedClassName = className; + }; + + MockFeature.prototype.isExactClass = function(className) { + return this._className === className; + }; + + MockFeature.prototype.isClass = function(className) { + return (this._className === className) || (this._inheritedClassName === className); + }; + + MockFeature.prototype.getClassName = function() { + return this._className; + }; + it('parses backslashes', function() { var expression = new Expression('"\\he\\\\\\ll\\\\o"'); expect(expression.evaluate(frameState, undefined)).toEqual('\\he\\\\\\ll\\\\o'); @@ -827,6 +849,60 @@ defineSuite([ expect(expression.evaluate(frameState, undefined)).toEqual(false); }); + it('evaluates isExactClass function', function() { + var feature = new MockFeature(); + feature.setClass('door'); + + var expression = new Expression('isExactClass("door")'); + expect(expression.evaluate(frameState, feature)).toEqual(true); + + expression = new Expression('isExactClass("roof")'); + expect(expression.evaluate(frameState, feature)).toEqual(false); + }); + + it('throws if isExactClass takes an invalid number of arguments', function() { + expect(function() { + return new Expression('isExactClass()'); + }).toThrowDeveloperError(); + + expect(function() { + return new Expression('isExactClass("door", "roof")'); + }).toThrowDeveloperError(); + }); + + it('evaluates isClass function', function() { + var feature = new MockFeature(); + + feature.setClass('door'); + feature.setInheritedClass('building'); + + var expression = new Expression('isClass("door") && isClass("building")'); + expect(expression.evaluate(frameState, feature)).toEqual(true); + }); + + it('throws if isClass takes an invalid number of arguments', function() { + expect(function() { + return new Expression('isClass()'); + }).toThrowDeveloperError(); + + expect(function() { + return new Expression('isClass("door", "building")'); + }).toThrowDeveloperError(); + }); + + it('evaluates getClassName function', function() { + var feature = new MockFeature(); + feature.setClass('door'); + var expression = new Expression('getClassName()'); + expect(expression.evaluate(frameState, feature)).toEqual('door'); + }); + + it('throws if getClassName takes an invalid number of arguments', function() { + expect(function() { + return new Expression('getClassName("door")'); + }).toThrowDeveloperError(); + }); + it('evaluates abs function', function() { var expression = new Expression('abs(-1)'); expect(expression.evaluate(frameState, undefined)).toEqual(1); @@ -1756,4 +1832,25 @@ defineSuite([ return expression.getShaderExpression('', {}); }).toThrowDeveloperError(); }); + + it('throws when getting shader expression for isExactClass', function() { + var expression = new Expression('isExactClass("door")'); + expect(function() { + return expression.getShaderExpression('', {}); + }).toThrowDeveloperError(); + }); + + it('throws when getting shader expression for isClass', function() { + var expression = new Expression('isClass("door")'); + expect(function() { + return expression.getShaderExpression('', {}); + }).toThrowDeveloperError(); + }); + + it('throws when getting shader expression for getClassName', function() { + var expression = new Expression('getClassName()'); + expect(function() { + return expression.getShaderExpression('', {}); + }).toThrowDeveloperError(); + }); }); From 3862829a233ce8dd7e9dd80fc2d8aeb7ba8d8574 Mon Sep 17 00:00:00 2001 From: Sean Lilley Date: Fri, 18 Nov 2016 16:34:12 -0500 Subject: [PATCH 12/24] Updated tests, some issues with checking circular dependencies --- Source/Scene/Cesium3DTileBatchTable.js | 109 +++++++++------ .../Hierarchy/BatchTableHierarchy/tile.b3dm | Bin 94462 -> 94434 bytes .../BatchTableHierarchy/tileset.json | 10 +- .../BatchTableHierarchyBinary/tile.b3dm | Bin 95054 -> 95026 bytes .../BatchTableHierarchyBinary/tileset.json | 10 +- .../tile.b3dm | Bin 94790 -> 94770 bytes .../tileset.json | 10 +- .../Scene/Batched3DModel3DTileContentSpec.js | 2 +- Specs/Scene/Cesium3DTileBatchTableSpec.js | 131 ++++++++++++++++-- 9 files changed, 202 insertions(+), 70 deletions(-) diff --git a/Source/Scene/Cesium3DTileBatchTable.js b/Source/Scene/Cesium3DTileBatchTable.js index 664fae1d908e..74da679a3253 100644 --- a/Source/Scene/Cesium3DTileBatchTable.js +++ b/Source/Scene/Cesium3DTileBatchTable.js @@ -189,13 +189,17 @@ define([ ++classCounts[classId]; } + // Marks visited instances when traversing over the batch table hierarchy + var visited = new Uint32Array(instancesLength); + var hierarchy = { classes : classes, classIds : classIds, classIndexes : classIndexes, parentCounts : parentCounts, parentIndexes : parentIndexes, - parentIds : parentIds + parentIds : parentIds, + visited : visited }; //>>includeStart('debug', pragmas.debug); @@ -206,25 +210,21 @@ define([ } function validateHierarchy(hierarchy) { - // PERFORMANCE_IDEA : this can be optimized by marking instances that have already been checked // Check for circular dependencies var classIds = hierarchy.classIds; var instancesLength = classIds.length; - var visited = new Array(instancesLength); - var validateInstance = function(hierarchy, instanceIndex) { + var validateInstance = function(hierarchy, instanceIndex, stack) { if (instanceIndex >= instancesLength) { throw new DeveloperError('Parent index ' + instanceIndex + ' exceeds the total number of instances: ' + instancesLength); } - if (visited[instanceIndex]) { + if (stack.indexOf(instanceIndex) >= 0) { throw new DeveloperError('Circular dependency detected in the batch table hierarchy.'); } - visited[instanceIndex] = true; }; for (var i = 0; i < instancesLength; ++i) { - arrayFill(visited, false); - traverseHierarchy(hierarchy, i, validateInstance); + traverseHierarchyTree(hierarchy, i, validateInstance); } } @@ -474,23 +474,36 @@ define([ } var scratchStack = []; - function traverseHierarchyMultipleParents(hierarchy, instanceIndex, endConditionCallback) { + var marker = 0; + function traverseHierarchyTree(hierarchy, instanceIndex, endConditionCallback) { var parentCounts = hierarchy.parentCounts; var parentIds = hierarchy.parentIds; var parentIndexes = hierarchy.parentIndexes; + // Ignore instances that have already been visited. This occurs in diamond inheritance situations. + // Use a marker value to indicate that an instance has been visited, which increments with each run. + // This is more efficient than clearing the visited array every time. + var visited = hierarchy.visited; + var visitedMarker = ++marker; + var stack = scratchStack; stack.length = 0; stack.push(instanceIndex); + while (stack.length > 0) { instanceIndex = stack.pop(); - var result = endConditionCallback(hierarchy, instanceIndex); + if (visited[instanceIndex] === visitedMarker) { + // This instance has already been visited, stop traversal + continue; + } + visited[instanceIndex] = visitedMarker; + var result = endConditionCallback(hierarchy, instanceIndex, stack); if (defined(result)) { // The end condition was met, stop the traversal and return the result return result; } - var parentCount = parentCounts[instanceIndex]; - var parentIndex = parentIndexes[instanceIndex]; + var parentCount = defined(parentCounts) ? parentCounts[instanceIndex] : 1; + var parentIndex = defined(parentCounts) ? parentIndexes[instanceIndex] : instanceIndex; for (var i = 0; i < parentCount; ++i) { var parentId = parentIds[parentIndex + i]; // Stop the traversal when the instance has no parent (its parentId equals itself) @@ -502,7 +515,7 @@ define([ } } - function traverseHierarchySingleParent(hierarchy, instanceIndex, endConditionCallback) { + function traverseHierarchyLinear(hierarchy, instanceIndex, endConditionCallback) { while (true) { var result = endConditionCallback(hierarchy, instanceIndex); if (defined(result)) { @@ -523,9 +536,9 @@ define([ // When the endConditionCallback returns a value, the traversal stops and that value is returned. var parentCounts = hierarchy.parentCounts; if (defined(parentCounts)) { - return traverseHierarchyMultipleParents(hierarchy, instanceIndex, endConditionCallback); + return traverseHierarchyTree(hierarchy, instanceIndex, endConditionCallback); } else { - return traverseHierarchySingleParent(hierarchy, instanceIndex, endConditionCallback); + return traverseHierarchyLinear(hierarchy, instanceIndex, endConditionCallback); } } @@ -546,7 +559,11 @@ define([ traverseHierarchy(hierarchy, batchId, function(hierarchy, instanceIndex) { var classId = hierarchy.classIds[instanceIndex]; var instances = hierarchy.classes[classId].instances; - names.push.apply(Object.keys(instances)); + for (var name in instances) { + if (instances.hasOwnProperty(name)) { + names[name] = true; + } + } }); } @@ -650,15 +667,18 @@ define([ } //>>includeEnd('debug'); - var hierarchy = this._batchTableHierarchy; - if (defined(hierarchy)) { - if (hasPropertyInHierarchy(this, batchId)) { + var json = this.batchTableJson; + if (defined(json) && defined(json[name])) { + return true; + } + + if (defined(this._batchTableHierarchy)) { + if (hasPropertyInHierarchy(this, batchId, name)) { return true; } } - var json = this.batchTableJson; - return defined(json) && defined(json[name]); + return false; }; Cesium3DTileBatchTable.prototype.getPropertyNames = function(batchId) { @@ -669,20 +689,27 @@ define([ } //>>includeEnd('debug'); - var names = []; var json = this.batchTableJson; - var hierarchy = this._batchTableHierarchy; if (!defined(json)) { - return names; + return []; } - if (defined(hierarchy)) { - getPropertyNamesInHierarchy(this, batchId, names); + if (!defined(this._batchTableHierarchy)) { + return Object.keys(json); } - names = names.concat(Object.keys(json)); - return names; + // Has a batch table hierarchy. Build a hash map of property names to avoid duplicates. + // Different classes in the hierarchy may have identical property names. + var names = {}; + for (var name in json) { + if (json.hasOwnProperty(name)) { + names[name] = true; + } + } + getPropertyNamesInHierarchy(this, batchId, names); + + return Object.keys(names); }; Cesium3DTileBatchTable.prototype.getProperty = function(batchId, name) { @@ -700,13 +727,6 @@ define([ return undefined; } - if (defined(this._batchTableHierarchy)) { - var hierarchyProperty = getHierarchyProperty(this, batchId, name); - if (defined(hierarchyProperty)) { - return hierarchyProperty; - } - } - if (defined(this._batchTableBinaryProperties)) { var binaryProperty = this._batchTableBinaryProperties[name]; if (defined(binaryProperty)) { @@ -719,6 +739,13 @@ define([ return clone(propertyValues[batchId], true); } + if (defined(this._batchTableHierarchy)) { + var hierarchyProperty = getHierarchyProperty(this, batchId, name); + if (defined(hierarchyProperty)) { + return hierarchyProperty; + } + } + return undefined; }; @@ -734,12 +761,6 @@ define([ } //>>includeEnd('debug'); - if (defined(this._batchTableHierarchy)) { - if (setHierarchyProperty(this, batchId, name, value)) { - return; - } - } - if (defined(this._batchTableBinaryProperties)) { var binaryProperty = this._batchTableBinaryProperties[name]; if (defined(binaryProperty)) { @@ -748,6 +769,12 @@ define([ } } + if (defined(this._batchTableHierarchy)) { + if (setHierarchyProperty(this, batchId, name, value)) { + return; + } + } + if (!defined(this.batchTableJson)) { // Tile payload did not have a batch table. Create one for new user-defined properties. this.batchTableJson = {}; diff --git a/Specs/Data/Cesium3DTiles/Hierarchy/BatchTableHierarchy/tile.b3dm b/Specs/Data/Cesium3DTiles/Hierarchy/BatchTableHierarchy/tile.b3dm index 16a99c7d6f544883adec201367da3dee5fb26c17..6dfd5056a370c4bb977e132f42dc45313bbf5bc9 100644 GIT binary patch literal 94434 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 z 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 literal 94462 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 diff --git a/Specs/Data/Cesium3DTiles/Hierarchy/BatchTableHierarchy/tileset.json b/Specs/Data/Cesium3DTiles/Hierarchy/BatchTableHierarchy/tileset.json index a6e7411f7352..cd19543ab8eb 100644 --- a/Specs/Data/Cesium3DTiles/Hierarchy/BatchTableHierarchy/tileset.json +++ b/Specs/Data/Cesium3DTiles/Hierarchy/BatchTableHierarchy/tileset.json @@ -2,7 +2,7 @@ "asset": { "version": "0.0" }, - "geometricError": 20, + "geometricError": 70, "root": { "transform": [ 0.9686356343768792, @@ -27,16 +27,16 @@ "box": [ 0, 0, - 2, - 10, + 25, + 100, 0, 0, 0, - 10, + 100, 0, 0, 0, - 2 + 50 ] }, "geometricError": 0, diff --git a/Specs/Data/Cesium3DTiles/Hierarchy/BatchTableHierarchyBinary/tile.b3dm b/Specs/Data/Cesium3DTiles/Hierarchy/BatchTableHierarchyBinary/tile.b3dm index 53ac2a305df58f44d2bbfa7d902572277fcf6aed..4786afac9d1500402626e03c27bb6442fed13dc7 100644 GIT binary patch literal 95026 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 literal 95054 zcmeFa2Y41$xBfjd&rC!_qzH%wFkq*JP%TNQg3?436)6D%M5;6k76b$p3-+!Qd+!A` z3HE}$_ud;SirxS3-p{NjlK@K2`+ClIeOKN&bFa1cv-Vo|Ub{>So>94DCi$M{^`Gv0 zHL^T!=fLxtP@bLLyHC$ST?cjVeQ@^fv$KmQPoGgZd34eAzD1MA%^07(dv5!d*`p^G zPM=;hJ$v_|v$H1`PAbaYJ$uZQDbprQo-!)CW%k6_GN)b3^5*hoHY27NA5ELt*`tn{ zQ8Zxe*y%+x@Y|^)j;BnTI%RUvv8bA#WMZvvmQYKkCDM{;3AE%{;w)*FuuQUYDkW;# zlqq8qiK6qF`KK=F=Mhs2izhQ*hGtJI8iVbqi8G53M-@$+IOPbGanp*5CT9<8nKrgw zsHJ)#sa{B`7m~RZ2kVH!i4*z72CFg${ansrYVqU=7*Cm2IC-3C#B9b*D?CaZobeIG zlgCUsVx6(=(5`J2#>9ED-l(A7NUArI>WyTj-i(@AJaJ6%itM*Esp0}i+;#o$yS=XeE^ollWQ&qdZc~7q@KNX|m zSwMLSam#I_SF}-^s@ZYrbN}mRyFBbwb4Xrp?(KQ1Z+hZ{%x@=t`F!3( zKVB2}yDj}4$@yLZq><`-0lIQ8xrDP0bJu+VZ_ua(~D;mPnql{_sp?li>4h|TyzB2`B9m|2)9!t?hBasx=q-B z#W{JI&{wMnA16@ zWBZ(zt#T_>we8rlRmavHJ9KE@wta{8T{^by*r8pAqEn@$Tu)DYI+^&76+)f=j3}aPiaxi(yv`K{%tCE3s?b~<$uVsN=>;Ezx%4x|_f#A$p zRUy~DGimydhDaB#^boae**3#VdNOTXLyL}Na%fx3OqPl>$6Z&dICFA!#c(sHOWQ8x zGbg^$%n-}aYS%WmO9ft|3TKQS-)GF<@iLQimh66aW0F?RuEM;w+hFpO&PDoKRXn+H z+EF949>peJ1BKJL6-is^vP*jU#<%C4yX3Uzu5jkGV%@$M&M4fyW%jWdms*%1={Aw8%?N6sjkJe{36Hl0<-UA40-oHVMK`x&-ARwRdZ zjxoh!$IhJ2W<0cQ>kcjL)GtMoil@s>1@q}si$>3!SU9a><@n;s#gn;4xGjAK_s`Sa zozv)}vUksc?2Mw(<0ls%&b|Ha<$7B;K_?YWAD<>CO;cy;wBkuzSZ2kKq=hrMSd5xE zBW*Nr!2W#(_ZiS1N107Hb0KP(-G9KKeqH+}e~fqNmf3@Q9@KrnfI&T!qw==wk1eyi zbsgNjcb^`~dYfmEXR|8i`j`CG_OJ3`;Mc?;P(MZ2xAw>C$uWB}1($ywP-gUZzs$}a zJ)V1c?k-6rxwbS6b()?wa5t@3SE(E~RBpJ|r)dLIfDtb3W4RzHi3#s|EJ{aRzt^_9 zh*Wf+o*C);>Fk3?958UiV2!DBt`1EvoHTV}k-HyIX><`c`n$(6F1!B5zwqds&cM*h zOkH|rFkxp-a~Z;0`RqMlI?seW8t&VB(1_&zL^ld2vlevop)fSk8w_`sJ$2fYvBeW% z!(Gc%?S(^%M(y2~F`floHTDNW8&fVNkE1EQO;*8>{6N`(+be%YLJkLvGSy4qe z9LcYQ)PDc^rA_HlV=oTO6rF_4# zpLF9%n~Hl^r5`f`%Ir#z%IryrbahluZOkiJ$6Hio+r;o!^q$zatWC_-CPqbj+sqQi zxmvS~IxjNV98A-_Ij;lbjkRcU;V7+}q3t?%Zr`$9mv-*XXy)W%EqXWIW{y~A!ntiO zIR&``8L{s4T6f0DuHs~hlNHY`{hpa8nHi(n%p}Q77uA+eg7W#G`tm7IJ{w$p`2@(G zp3(J7#R*VxJ{+6Kqf1Gg({(n2p)BCcWYKC~|DsQ>^I&R97kx7!-1#-C+t#GH9+;z2eR^D-`D!(;?*g7{i3eFs> z*aMfA@}QM(PygefISNYD=@WRbn7$5_Up!PkwpqRQlM5C-yR0DZ%O?4K-%IOVzt7I! zVzVg)HTGCuAbs_O$pwE5UG8iySUbtt@4VaA`D(kM)3O5Tve~M8+RvsROmQ~5E#D!( z%`a05?%s5Hfpqz-HD;Of*U&cEtkoIj;tm-EuGHWK*&;$Gn}qmd`L}v;vw0$)@+14l4^8`*u6o6lE_?AYpWDOw<;TX(?M2wgUUOmX$0s??(%(4aB-a<^^2nppx^h|L$#R?a;mIy^x;pT<-DwOG=%rez~t zdyM#tkJYQK_Eht)b!L2=&shr#w6Cg<&2LTfQCxA;m};!dr{<2@%BST-aV>Akr}a^~ z#g(o-Rc(#4{JZ?K_b6B5Y&P;Q{>DK*Em!Kh@l=1;!e2bKhe=mk?Wxk`)9Nihs#jb$ zcIcWL=2N=Gl5V+@Zn@IFD*LDQOt*D;-Yo4?{7?L1f$O8#R$ftDWM0{NS(d9>NRlnl%6Vv&R>usLM-iSw1zlEuUs1o@OJSZXbyAskk=oZf(Znu5}^) zYODRp#@*`0)9l65e2SY}@61E#=3lzF+1!>-o7>t`ZEjn=;+nlUn@{CdKDAz?i-WB@ zTg%4T)}Z4V?LV%H}ff7d~ChQk94)w zo+@2y#Of8x?8U+52OHz5HDWxqE{vz6+K(Q~q^tt$K~&t30bKmhxdfl>^yZT-B?;7E8L;pKPRS&56JGSiRb6U7CNbGvnj> z&hvxzRrOKN4C14>;wC;CTl1;8qqg#CIZ<58oAPOWlx}gQYrj!j<1GI!|Li@=l{lM? z{ENSFkWcC2roJ0b^;ge4;;B7My4q?_l`fxFZ~0NZ;<~Xz*W56l(k+&B%awG?mG)KH z>zPgU;;H94>!Y6iTu$JlXF}_j>aAb07iZ&O{gO}V@~P)i*(-`oQRLhKf3&=t?KnI zz~w)#cR7je#X&a8kGN@#7*DMWEdAP&epPVwlydl+fQs?vOK7*{AlcCZ)2x*EnWRmTiJIX zGQQyXEiWrrTK5{K|NPjp3i{czF1*5Q*4{hc>1H$Hr9}m%-@JB#(;Ix)KHu~U=boMM zDL-bP)D>6t#=&&Os%&pI#>Y6T-t0{`n}OT`{Gr@1~o7 z)yt3BCw1jq^~S+;#j0#?HpWM7O*i`_&!oN~4rXI<<gQoVBDZPR==PfSv9{7H+a%jcHyhK9L()&u zzv-3j(|_kYr(otSc?IQvJMG1K0aE%LccyKYpzBn9K|-H{ZhrK;e)Bk`>y$pno#n9# z;(GmVx@1zC6l_@sBTF?yPVUmNdI0Sy+v9#8_9}#xxKZmY*P@&RlWI4 z+oap3>pgz7xJfn%~R<_gFQt5Th*{^J?W<}0se2qcQUe7FQyQ=%-Qt7hk_UR;Nvv#|I&PMm= z&u0xR>vh|>Qt9$}$-5Js&o3Vy;QXt;)$D;~EBcRi_42v+p)t;<>@OHs=zJPa-G^H& z>9Tq7^21A|i~n=`Ov|)Yz4|5p%kG)t{EJV+112~=-+bNQ@zisD&rt(hAH_%96jyzh z&r|Oo>3phf>o12ppOzDgs~qZn-ufur;!1aIx1Hg5%D=d&Ub(vFw;ARBu@Psp5eMnY zo4ARm@+@8a)nD02mmjs2e)`ulolmP5PqSBC=^8sdkC;#C7E8M2O1kXTM?Ke{cT|7J zLG`N}_RsWXvzPmowT}Dv(F6T5{jz#-GkfDK4(f~fl>WsheVtF)-#)TmX6$ylzi(!I z%|`t)8}&>6l`C;mT#dDK*{fbQPwm~;@mJfgx9FRh!&a}jW-p%RQ{2p_bn#J6WFtSe zj%K{LuhX?ItX{FqUL2Gk*&9!-5#ySU%-n+%!gtD_uE}PuaNfWnHMPINY|`a5wj?-p1Y5l-kOtcxqm$U((IL z)r*_W6Zw=M*_SjPmYLhCS6tQ0UVO}_c-p#_uDNZTZ7r*<)}V2=JxBGnFUhCcS{`hF zlTZ1vu~S>w$o|EZYf77sf6H-}enHvWt}pM^|Dm)=!*`rsYw`D`@4Z@Xlk@GHu3w*Q zzt*+Y{8{?LPZezHKK!oBRrA+>C>{QNT7PEBPZ^)`zss!moXxPSzbn0J(|290#|yvD z_*`}SYG`PvUv%A%89ws4LyHeewXdp= zGxvDk@ljlH)0p-ezB=Rc{F&dnw(@B?QC!QL@@ajPZgHhIs{N~LYn?Kc#i~w0g^rY!p{xCtY*Hd`h=i(k)lgEmzuC zW&cvG4_#aFZ1%#3&Zqc)dB8_*o-1zW`5$HarF!d^?8VtQXdRhP>GHW-yHA|Ga=1M2 zV`s1a-n#G;=hJM|FSAj<#9#i6zv5cI`oQRKXq|1-mN^gAdXU?b9+dPrIIH+Fv5jU+7w0gxdd*dLV z;$}XjYd%{(wbm@3n%kC7vk_0T5l{KId@8PuyXKL(r}-2& z^-J?my7`wbZmO5Pd`g#}cTfGs>6+VCuefF}&gN6Ol~1h~>EdAP&epPVwlydl?R%C7 z?Ms#iwUr-@o$PJww7*GLztmRt_1d>CYj}CjGI8$vURqaQw%DvqS)EzE%A~KJ(7No` zyL&mC3)Z%B_Uf0~Za$?)nRMB-UC_hXZ2CbPXQTYI`K3+SZaq0&x&1pIzIL4KKuu5^u^=7af^Zn30WuB1CZ^ilijVGD8`2i4d4Jf}=~md_t|ZI|iew%yv5HH`aZ z_2Ops##tQH7xO8-VdGrqQ}+8^-YzqCuXoSQjIY_KUuGi?@~>Qpo8oG$rORIRvgvS7 zuH&z^^;hR+=CIW(uGx#H`4l(vDP4Rt?y`{|TSuq1Z0~ff3#(Twvlj=KAKDsEtr6p? zb!R-a?u@6c3-Pq|=<*P+Q}by&ZQaSn){$~$YfXG?ZkvteQ#O`Q@ewzTk>W~MPUKTI z%8Ay6+KR)L$M$yf+3IcFZB4m3fKTz%yi&iUn}4epH=8H&DL=Abd~e#nbk!@ablHoK z`4mrE*U~k&jkB#~wbdFl&bH^M-u5N=bn7wBgY9qfDL*!LZZE<{_KTjKTlURUbscBv zcQmc*`ch+$d1c?NspIrNhR!Rib56O<_!{+G-WGI9x7GaFs{7muHfy)5<8pQPrt`|4 z&r0jH#>~z5l>aXu-on}Ja^AeMU1q0aojz`!<0GG&znJErd>T*n*J4SpvFZfpQ~FhR zo#6PZt<|gTS2gBl{0}>KZibKZ`E~6w?W^iz&rxYUiYsm!)5)LB%lNz~d%kNcpOzEF zwY({x)<@|USNhS%oZ#9TXZd&eA9+HVawX1YBmd%W9OTn-rM??a_4gb2i{~QzNLSnb z-O{>zTD|2*Hj3-U4qbD@d`h=i(k)lgEmzuCWq;mL>9*pzx?$R<_;2>|=5C%V?ne)7 zp6QqBtzWViXXBuCWIm4<=^-#uJubk zWusV6?On_96o;?3Nc*&U@suCgi>LV%H|0b=r7I`mw0f7%*xoqEr?{C<>6*`$Ppvh}r{=ch(`>}kY{XN1 zET4*N<1Tv}cdZNYSKCwa=4Zy;>c!LS#nXI>n_KV9L+R#Uy13cgmQS18j~|-WHMgx^ zam`+w&8KoJpIR@{#lhB{t!3kEYfv`Y_bd;O_!wu^o4x5~ljNL?Yr5H6T;o$Y56M{4cfPQHS&bczDODd$SKp}8|+4RNS! zZyb``tgZTJv82zh_h;$NPk-R@Z@Tqe^+{cMkd5+_)Mb-wYr5H(A8TtqlX1JbbjgR%q_$OmYe{F0|S;iJ*4DV{t*!i5*0m3qjr7Vkw)T_U%*O0x zV{wzZaj0x>94xNpgYlPcv80cfJ*RBv3u~wIAM47q>{XxCUCyylev-NymqgnQ`BZ)7 z+$Q~-pQL}|W_)Zc%trO*GwI*-%JzH$F5^3JS^As%9P~M*`Ywz_cfX-0Z9M9eHl|m$ zv9?M3q|Ka!f7!U-h?T6DZvJJH)c?so-8TJwTzWxS`uljg-lKw(`lQb}rRDafSGFmj zjkPtOX`6Ig>1H!$9X-t%o09 z<7+nRm)WRa@~>Qpo8oG$rOV#Nu8TodpTX}!s->v?8Q_0k-hQM8Zn+)cd`*5tvlms>%!`dr>#@-X*_M+sV}yUlq*|n z;$w5$Y%HI$v3$zExM_^UN4jz%pR!R-v@XFX`sr z>c!3GiG0eB?6;qOrt>dd^@=N9_Tpnc#naZcbj@w!thsHRwFZr|?K$#k`;vUBt>wY? zH~F;v&FQRt*~ngF%bt}d&eGXO^3)goP7J3jm+T`M8}`;b%^9r;wUw^5p0pu$p7Nuy zCAQNwug$0Y!`0Pm4C#Z5r5u}2p*M6zC###PVuf0&Y5@)lK zfAKdC@@ctJ-;JmGEB@jsKho7!d#ZH#w0g^r>J?XGCtdTwd`h=i(k)lgEmv+|g#&BA zwG~g+iSsG`tR>e+#bu3U`lWj7m+ZyaIJh+x`;;!9taE3t9DZK&KxeQ1vKM5=S2pUG z*{EOQFaO40ajjpnmyP<%-sIYf1ACwIY4zeMKe883^C@o1iF`^|PQ*tx(&a~OrL(s> zpH^@4ME2sKdgVvlv__1l)`juZ95bF;7sk`-70c|6gM5mc`IN5tET6L1TC;p=Zd*Rh zMm)_%Jmuf=skk=ovbS;9x)6W0)&6ATZuN?5_Tp(i#ZCRvJd|$!rHh;DWiOx7`PDjW4nZJC!&mksmM*(j!Llpn=pjMF+knWN6T*X!D3054ePK}y7;s9GHq3_e#t*;FWoQrur^#=jgNT7 z_p7dt;v;T~t31djW0v+wTgJorw47L6`B6T_M}3rTaa}!a*>@aI`4>0UD_8768UL~o zXR{Fp>GCOVnj^}ybn#bzWg}gF)K)rstMh5~;%WAZD_vu!`CvY!TP*1sJLO8c?A6Ek ze${bMz1EiXMQh9YsI_JNvU+hdd*dt)>WkK^^-Ftzjh*%Y8$0a*Hoj(~ewmH>CI8Bm zxGApjm%WXP_A13vTkTaghpk>b&0ajsr+AuA>EffD$VPsotF87_=~^RJuUKX;p30AG zjHlL!bj8)Wkd63g-5F0?7gldPZJnA=<7w+oK5ZQ-SGLx~$L6-#SUzQA`ILWg(-?`5 zbmc@oWuu&EU8t=%u;019TfL3Dttqv&wXb=le%Tz5f9a|hH=8H&DL<-bZ_UhY)hn*q zi;wvfPt9%PthsHRHMfnk)}V2=Jx4xmUy@I?wLIAVCjYj-Ii0mH8`*1Y*|SQ-Svvbj ziTa}7iQ#ndVjs!a=v{#3jOL@-O4mG1+7P=$`O(-C+v%Fu=2QOJ|6RStkUqFr%CY%W z4rFiKRImP8Ea_T*vXQPeC;sAN^=hkiY5uj&jF0-u7?i~KtEG&Ar6{^BV=($!Xb zs&x6ZddrXM6<1>?UGu?wO1D_jEmzVlSMmL7DQnEN6;IZQ^C|wUCD%vAWsPO}rF!d^ z?8VtQxHUz;!ob?A2fPg3S2JM*T7y^-KKa-}o!8^-K1$QGeN+Tw8Hq z?{hw_UOeST_Tp(i#Z5VpPwC2u_{c`O{HU#Ty$ewOt={H|?8QO#%8$5djTld@3*)Id zW<0enjHlHrmf0Hz`4l(vDP8kfK4q`9X8F|IwtSk6c$$rP%D?4Pac$gXZ{x0YA^vKs z{mI7N>J``Q#nXI>oBE}BDBb)^7dO?*UOuJEkM>mQ%B|HauGx#T`BZM@Q|m>#IM}+g zwQQVi4a&y$6Wf<84{9qv8avtB*lAr$SHIL&_Mi8Bpk(1yQ}gxhK>9mP7gf;tZgqv( z@SV%)37b6Azy5K!)Ai2ZbiJ!LpRpfjlhot5c?k|qk7HG^PuNu8ta`Ig=*}j|IT_dV zgnb1L)-U64`7sU)&MGcB=Iayk)ko9Scj;=I)McZbn7!#{qxz&?*=N$;a%=V$%WRTu zO_z;vsI1G6wN2`k?bUB`k*7S!M`c~#w#-KQdTdIpE%8beOE%IK%j^?vOZ1H_u6J!? z{}uG4jr8@{IL=9KW|OebL(gzd=#ImB>@$7Q{IGsmPArz{HMY!&JoV9Z>$~ccy4hGx zWN*1jwl&@C%}>(aa+~xo-E5L=rOV!UT3f46a;U5)ZKNv)^xyp*h;)2a&{=ma%!ak; z^n{JpjEdj<`B#1H$Jr!xRd4nQ-Pt5LC*zu)u&=@!EGb(${0- zI2(WYH=BgL?Om1mI}Yoy&-BH(8Gq%+V#WJODP!sOOpUX2%@e%1=_4eX_0T zW@CP=t@%&pxw1{Nt#spKx^Ymw`APaWy|O*ugT3p94B8?7zR$P)%>Vx~>G8Mz3O4zb zY$&_$-AO;PiQCGb`K;iF-z(UdeX?G9e*DcESwZJF_jd@gN$S{T>hsgz$Mw7WZqC2o zce>diEBH*>n_k%lU(Ubk_4fes>1^Uyu0FxR?2#4ht!=VidWE=2pNUxJGd~@>yuX#> zt{pw8^ye`zHox$S(!7^bolD;t*rUa+zvSfS2D_Ht_WG%LLx0Z6|83CF(!A^L%qzI6 zl>h&DE|<9Ryw>w3mj3bWLnYU5|623drbIR`6+Kh3OUDyh)Y<#6{NJuEDLL=s?eaG5 zbC~%ok`VwJ=; zrP!4G5OyflnRVmdEfV#4vHw!}pMFzGNuSTREBP62>VxG>b^Mm6diq^L|MSH&_L+~* zE69Oj=c|v2oRq|QyMnxx#(7g8)hBlnSNU_iXm@T zEYZ0iIV6`Q%Bk`x{)(;flCB(S9Hp1frA&Q^YGeCS>3@!Vreyoxhm|ILmL_7A#$%^g z&OV-Nvd@b-xH+Oet1p@(%8U9)zw#3OvU>F^FSd7_HCHrG5YMm$Je5=N)EFw);t9w6#2mJIaWs3))jZ8t%~j12n?K|- z-_{Gc&$o3HuQ{byW1@ODZ)1BmPsn{&|#;-5F1}E@J*}J;pp` zpHD9HY~95?-F%Mo>DE!4E4S9-e7d=vu(5o~#`2lR+$*KudGQ*tan~BLao4)AanENy zYrSaP-Fk_~-L0uOpKk3dN6H0xusNVSxVfQxCFXX1Vs6KKU^>6r6XYkhx4A8!Hn&}F z<27ZRwH}SL%da?V-YFN_Pc-k8FXchwFW$_7QmvcB*xCMOYu}BX_-O2nv-KsJhh%@^ieS_uGWZ~f0}#vck@znGIlZGOY6w4H5K+%?Wu|VN_{C&Ut<2Y zU#<6=8~0uI+6OY%U-F;1-o;~Q`>M-hysxhBx@q&jG~Ng78f0s#MEg}dF1G(`{@DJn zHT8dTU5l?NwqNO5Z~K+;%uDdhOYpS%b*@ud^NBr5egCgrr{Xo@c*bkQ#@((*w*T9` zmep_YI;DMrJ*tH`C;aDYANs$zW+nEV4PIZg1L_*a{eb3}?lElNcKy^^&|YQN*<@c5 zdCO;PGx`q$czeY$(#crVp@)V#Kw=zdjm!0uP` zsd3!WqRydu0e@${BK^m9%=M13vwMaL*TfB6H*H_l_}cxp@n7$~g!U@s zI=&Co{%>>G>fQLqW%0B%5^Hf&f5O3aW74b z`~T=V70&^?7HAH*Yk}%@-;lUp{U1GxCD!#uU9%EVDN?={-Q^c`&&LChBcpb^CU_FJ;Eg_SNM5Qetkq=T5C>J$uIMQTJnc ziJaK|s`6H0?Bf00jZ1PL#(yUN$?HhMMtL$D-LKl1{+riyH#ZWoD%?jY|K!T;tI7Q~ z=BaDtfArj%@M-r~dKR;>)1GP9xQ%{pOy-A1#QmzCS@Lubrad)rzxtm(i`l-XdGNQ_ti+yU*K6BXGtWU<3-+wR ze6an^`PSZ{wUB&f+&Eoc?H%ubqPzFja=`yKMt62@KX*+s@1i$cZ~K5OHd2q@g_qyQ z#%U)pDDv^RHTdHk8Avk9#?1=kp)e z=D#~n{zv?)Ft7gYdGc?MdsXwZA^VLR>+-o#^?v=k^Q6lB-8)>h(mG4aztjKid6JI3 zvHM}87P+N=-P@a*dyK@p0(-A08~YAbQvH3u`uo2A?j?TzqxZe`{>QD; z^?avr&&csRuK)NwN&N0nKHc7+cRG58jo-7`dvbj*vv1S({$zvi|Fyp*-kJZ`--A2l`ujeATcf{mO5{iH+}t-Iy>mpmOC z*J$l;|N7sd#ox=cmTla%pI3MmtLk;C(zT$(t_7;E{=V=2MqT&(?i#wGTqUoq)!+Bi z-x)XN`kuIFu={FvozgvW;u~n@@89$uOJkt_CI8+mwzt1W)!zZG^S2*~Sk>S6)6X6D z_Z7Os}##Ut#s`o?7c)`+vOl-F-s!_x+KzdEH+aA$8WWE&k6rh`Az?CV{}=rZyYyN zzo9%-wch!!!nkitUy?TE_u-0Eo}a(fGvDqvW?Yo(wB5$^rRw?F7!H+esxVI+=X~1J zW@GfK^RHTd9EbJfGdZRkqi;-KD%zxTkoLWidKKo$#&AyBY$y*KuCFu)Hilaj=E=W3 z?#aIYCwj#({pUTc>iyctxslB6#*9VA=ASty`&iXnZS=J!!>6kKt;%}e&^P^Ly?R^y zeLp?s!u0<(G;j55Rjx;WdmT*9;iR6N8-J@;f8S64_Z8xILGC*g&mZ-kRM=5zdw$=*Nf8(xh$@#4JLn`Z=ruGNDi>&^>@7|l)ci#2>P2K z@8fMBj_=vrH}UH4`0T@Tck%3*<$tS?xW4Dd&%c>(_x2tm-V@e&){`H7w@dszjC;O|_Y>VS z*f+lFf4{#G{~fu+H}~rA`{jRc?Eam9{P)=QY+K>Em3zy~--9KuWyxoajk&JH`LF)I zpZ@QR>DpJ}zgfrqf_=xY{=Q%R@AuvJ?MmM!{`Ot8t{3*+AbH=uak^Sp<@+8*zbegvf5_WLk40uK(f_LOckdU}yN%0R z)%jGlzyI#IyM9(7KO3^I`nXrEUoOuZGdGepnK@9tZ)|A1{zv?)l(&E8unxCmU;aVg z(E8m_{f5SIL-ke7&xY)s|NQhC*cg37{5MqpZ_ksB;hePDP#!i^zs?-km^u6pbE9HT zsI_t8pgIH98K}-cbq1<4 zP@RG53{+>JIs?@isLnuj2C6eqoq_5MRA-<%1JxO*&OmhrsxwfXf$9uYXP`O*)fuSH zKy?PHGfI_t8pgIH98K}-cbq1<4P@RG53{+>JIs?@isLnuj2C6eqoq_5MRA-<% z1JxO*&OmhrsxwfXf$9uYXP`O*)fuSHKy?QG#~JXwfVP2`@}yv9y8CR#0T zYmQo!x1qGPw=Gd?gS9Dd2a7GhEhsl3ejTqVQdo!DCSEh@n!%{9w>^yNp>Gdv?`2cU z_L_tB!7Vu(fGxo0)VBb40JFUvk-}`+?1U6_~E(~|{+It<4xyT(jI>5aHeQDu!1UpdM5$xo3M(f0xi`Eg@g;Fk56Jz`eXYN_p7t;pO9Dcl3NP-z%V0fd4LDSE6-7?+SMF zx>M?k?99;}7Tsakk#Y~T9_Zb@p2%)qFQl*=)_Ws`UGdTzDJ&pHAEYp!sQVy=d2nit z6z+@Mm->CYzF77_?+f2`;Em*H;1zN- zpmsQNgf|Kt?u|wYhtqNlQaB91MM&YHL>h|}4u!!ur0@{aTb7Lv5;uT zfG6So81Q)H$($#F$5A?k^JH(4lZ%LUoOde6ag+)W;aSAE7%5y#)Ju@UGrdbW&V<9IoR@K&0mI8UFXuQN=1chHGVn6WOK5Q^ zxD>e*50`k$@Od%%GH{uQRuf4z4*(XK_m9lXQ4lhWp1R&#hoy`hVor# zccI_u-Hp7%y9X(}1M7Q{!rSq(0x7(W822HCw-WV!r0^CvEkOz&Kt4eI{ay){_o0`7 zC0;3|Qv9s&%J6(IdKtKqi1(na1Xp?wQhLyP2)rA-i*q6PF!&Jl4}*_*kD@)oxf1PR zid{kurvTX=jADSVSiOOV3% zy$`?-C@oK21?LGlNL$2od)ccO}Tkw18 zR(n6-?=$c-%4@tIDXroB0qqOqPk8$R{U`7zZ!M*@-p}CI;Flb~5a(x5EPf%{H{h>$ z{|5XH`5Wi2;A%?0bN=T2;p87gTkZYHv6}KX#q`Uj-ve^1%>*TBK2#`6RJM>wUB z!Zp+een?&D{{*whUkkI)k0?cc7NsnI6L77!iT^X_FYv1YZo+Rh_+?Wt%dd$PX3=gl zq%gv3Eu=6c#^y+2;HUiBNMXv~f+OYopzqh=@O=;T{JI>T|Cd*fU+VbvIO~G7Db@4q zBkSX#w!bAlH%H$R+|qAAsR0pd`3>Q)8G1voq2Gv7BN*27xAGe!8zDF4Xbktp^reQs zHQ1QittoHgZ;Q4KXCt(&k=s#f1UAA~6Qr;q-kTzY4T#+gDclk^^^o=b?Wt*ozCF0T zpG_$n`=)+#JTyUX4mS5&P-=ny?fe~xwhj6Y;Ew)Ily*RF%drzIc7oy7ly^qk8GR>z z7vzrqu1MjISnq}u?tqt;NMQ?Nv_cA-6SXx`m<^|TNMRdf8|qv8ZLw^H-WF`@=TOSQ zPfNcYo_9lU2j&uSSF~I(*Kbd$z25=c1>BkQ7jI|3BiMoZj+8t3ozXgR=Av~(cA=CD z=Hg{{q_7>{_dp7Bh`lFL*cLYRkZt_EsM!;JFK{nEk5V4?d-(Zy*d09|EWmRYv;wfe z?@FmFF+2I){O-uE$j%(yVbL9i9sOTfUp@RD=so?OV0SEf@>?&ko4+?w*o~IGk;1O{ z?Sm8+5NRKzFdqi{B87SItA`Z!MfRnBU%wxg`=Iv&`{SVxT7R&=KY-Ez{P*_%@OmK! zAou3{jnZ%M>&4LnM!&K4d-%Vz<_Gu#k-`DA-w!G5kH*BbwAv5-0Pq0+Pj4XS@8DnT9S30bm%{_FsEfY8f1p3aKL|X?KiEG6d9Xj!KNLBX z^ANNl$RYkPe>gZCs}bl!s2>3yM9oNWq+dw8gTOG zA|B_T1czhMPXbT!Po{J-43F_o@fRUaM$YC~1ouVsNa0C%KNBfjNbIwa!UeFIk37*oo0_xG&j!!-&!Kb<_GkL%;$boRx!}3} zd6dq>{~7-IL^}=reDDJQLQ3Z&Pv^K078k6#WYDN+Mo@ zb|rYFe-)*x{Hwu>!HYO2fY*RmQ-2M3t$!WbwVYR?U4y)y(v{$qc)0;7yaMkxB8AI| zeG^i+3^wzTOZ}Uvxe5Jd@MixOO1EHtqkk(NZa}{kybaISqumDH=HE`~c4A)Z-{Ieh zyd8NR$DOda6NcBYmL~XjaZK><=9ob39mqTVd%!#Vdy&FBXt@F@ydA&yA%(XQ>3*c} zRv0{h6y5^A`AA_2vV{5v{8B9MM=u4-@Ngem8Cd48q_h(MD_G6lPyNrp&-~B* zFZ?h4ufVVTul;ZQZ~fKaYX3X`d;bT24Y;DY??Em8b>i_2d4*u@{f%c~> z|Aq7dKL`SkGZlnE6l8%}!6reCVAG%`STooxs1SGH4Jq z1RDm8f~|ta!Pel`!8XCR!FE9tuu0G~XclZAWP{m3^PokrL$D*bW3W@ObFfRWE4XX0 z8(K?OZiQ?ev=EnV6KA01n5X=qc z1@nUwg9X9D;H2Q>;FMrdaB6T`a5{K;a7M5=I5Rj4JS#XmI43waI1fB8I6t@`xG=Z~ zyePOhxFonVxD323xI9=AEDe@{%Yx;>6~UFkRp3>@)xkBvwZV1Zb;0$)4an<*8-tsW zH*(&9b}jPS;O5{K@D{9YMZcE%Tfyt7xedH6xSe*_fj1!U;J7}xlk;})F6!B-pQO#RNZ}KBc@8Oj zoEXm|g^v>T1*Gt?;6;wd;P4{nOB|2D@FmWdIUa`jEBx{j_!8w;Xz?QWD)Lo4yb!#G z&*#x!178bXr}R1zp9|iA!?WmbfNunEQhF1H&jfD;ZzJDCKF#qq+~1}ztAcmHx2b&x zd^dOx?Oo0{(cVG6Pw7qYO?-WT6uyD?50S#xiTx2$_!?|pLB1M%OwC8=AA=tUpHTV) z`wxRp@$doqr{Jf-XOup}|NFt`M0*$gbMTAcOG=+3-{bfa7GJ{f9m-#!eTDvI@HO&_ z;2Wgy3#`9I3O~ooYNYTpVtj`beoEBuk-|^l^a@h=1M&yzzYo@6`5pQia82+dr62LL zI`|3C-=hBnt|j6(Xluc>!OxU_4t@c@2EXEb0Q?pFh5BE?--6%Ke&bw=_ABxaN^8Nj zc=;14{0Z-WA%#B@+e`iBa1Cr;q4Wcf*nc5kL3$}a6;KLNe`1|V{Xshfr7-my{!*!s zx-b<{ic-H5Ei1JNGD>BEzXzM7e&u`sE+z1+k*a~dX=+n&6D&5xwkDXB+6*bo!c#4z zFv9odNMT6K+DKsvMq40-0sLMGws2U7avkcoNY%x%HhNvK9v(JFs|VIg)u&V+|Fu#p zgPO?t$jvxQDV4&nCPxhzmBP11s*E*XKeZ)NSfBO{kivR+Y={)rCDJQFLx+u0TcK}7 z?JKMzl^UQord0#<#$e;rgTa=ZW#B{X9gS0skiy1Tyv#aml-fGAO=??k+thZcCdlnl zO;gQ~O*xyOZG+q`O*e;_W<`u?MZ3R)LvjKur+5JFb~{|`aCcn+%r{x6z)lzu1Mh?cV@zT~9_f&-`>2=12} zgti}NKeU0!{VDYW`{8RaQrH*o2Ox#}68k`;a39$8M)pY!q2@sJA>feIL6i={{(#iM zco>X+FnDn45K4#OfB)1_qV0!16g)IFjM7l#AdX?M7zV?El!v1YM<13Nfjl%d5-B_s z>q4Y(C|*V(g@+JhG*WmlQO6*K2f?W~Qdop6qJB(jES96u$AV*1<0y^8URJQt#m z2aAa~60I04P8~++u+#)_1UQ_t4LA{;K>b8;Qfe~VB+g>AiO4CGios&MOhpRExxyZTHpOBh| zcMQkTFv@}N(X8)WEEXVzC(?c)QaB%vCn1INh}0V?JUMj=cnYQ7tRj^bqA#M=Li9!8 zBKC^~obA94$VFInaJUGIz0prjotio=bvk%@>WtK4yg4ssJ$+A19dmR=+e}UFuDx= zM)1beO_Xj*-3(q1F5z4X-U8lC{Vm|F;7zI9kiwg2b30OaBVO)63U46Bok-zzM7;|s zygqd|$MtZyoAVxyYhic~=e-=)z&|_TuJSN;6tg0(H`O~MSBqW z2&Gc66km@bg(Y}@3@Lno*pDNH_rqod^1jp))I5&<1o%YiNlH&*|5)lNJUoj26!=tX z6{S`9eAAcarDX$4aFD)Lq8UrD`&<;&==fv=@rr}R30UP`@z=NHl60N*6y z3uteGZ>HX&^j7L^@Okh#&ZXcx;M>%{1HPMj5A9vfH__ffzE9~*@J+mYfE2!g_YaZ6 z*NOcRQurEdRv=$ZeN4?q=pTb0r#_+d3HBeRKE=Za=%0e0;rV^E&%n=8pHuprnD3^( zNPUU?9Qhu{m$3K}hVQVJmZrYqSep8pV=1*?Aiqp~1AdYE7AgFKmaCD%&++>mQurB> zzDEi_g~1O<;V1B0ffTMmuA%;i)Q?zxkNzY06CS=p`w9FhwU*La{I6y;e}i0${FZY$ zrRA{uhT|(3Er;({tnVwa_!%i&OZ#7t!k_T?D^mC)kyapuzomW$f2Xv9Rix4{=zq}a z7xX{CKiDsR=DY&D8ukhnsP33f7{oX1FQ(b;Ek#CSb%-pE&hEv8Ye98sL_AuK{j`Y{0oCSd&si&IVy4CmRv1X1Enc zP0EcaZ53`!)LLLI%GV(f$zZcEgik;3i5T{yOb!!De= za%=;`T{(B-*c#?7`DIsdSIRAEu?yG=*$NLkhpq9s6MAc~b=Zbd8zSx)wuQqE=xxEa zVGgAn7`6!8g}KNaWOI&OxaZQB?65tUOKp3wL)a0m17{9edt@g{IbaUHIwOT`@!ka~ zY(wnbk;2xnX^CtV?m^A&=zD;BgnLrj6Z3Jb9Ai4^AJr593|M~uCZ!o7&v8!6lqPA!qb zKFB`Q_YU{La&Po~zZ}us@~#;Q+8Z*p0J3I1n5_ z{XlTPa1h#loc+)SBKN1%5A27R!AN0WydQuR?n~?gk-~jo(-PSy974^3=tICE;X#xR z!v28pU_1;)KNvg&&-Z~9vmMQQ!2*)C|2`GWHGXkvjL?Bup7xS97YY`JDm012#dpz!eZJ_Knlm>aUxPU zjz}$$!b#y|a5ANqtRj^rpiiOI1oSE36!we5I2(eEkyEg0>~IPeyP;1Cr-p}z)4*xr z^l(NvGn@s^3XecL(v^=w9v#jOj{%Pfj}4Ctj}Pa7bHWqCx#7HUJ~%%-FP0j9o`e(8?FFXg!hH_hYy4$U`bdSmW3!1u!U!w_=v!mq<`!f(UX;Og+Z z@cZzGa1FR7{4x9~TpRuj{v7@i{u=%k{to^g{t^Be{uO%BpPYX57auKDPDKHioG8iy zv!YF+8quavO|WLPSyU_9JgN=Wj<$&EM0KNjV7;h*v}M#FY6v!r8bw=0jiar>t)p$C zZKLg?CSa4OY1Ay*KFS8OqvlbIXoqM=aK~t;Xy<5`XxC`BsAbeDY8|zS+D181yC^qm zA9aX2f*qqyQRk>jv^%(av`4gOv{#e|=0*8YLDV(s26l_OM?IpRQ7^Dpw0G1y>J#k) z?i1}B^^N*P{lWgxfM{T}Uo;3D6zv}kM(!US5FLm-fO9a~e#rfzA<;qLL0BD(z901m zgM+9!1Uw`fO1nYeVC113`$xk#hl0bYJ2V=Bzro;O$|IvfN+UT(pdE-Dg|`FIM}ecF z(Ue9X!eg-%boEFVO3a8QL2&C|Eyc~%XP9?@sNa19n9*q=EiDq+5fx~RhV>l+k@EFcx zIVQsVIDR<>Jcjadw3rPZk31d^M@Mt;c@+8_a87grr4xvFWHc8JN1)FI=SK4=&4b~r zXnu4eavpLf$BA%1k-p4`7Jw&Gy8v7morJcKa~|3PrNDLfM|7a)a;iE$xPcm`1~LJCiZ({V`Q z#mI}PzbLu{%L~yj0WXOzrF1ENE{HC}^ZDqPftM5UJhaQf%cCWfmPAXzbHQ^si@;^z zQtFq1%cCpMmUCW?whVbCrOUy~@p2VXcp2WWMhY(__BBZ1C9pXTd2w_tHP@hD3tk&t zN9j83ua2(A!&T_lgE!#$O0*lm8=@O2-AK&k(M{3K$QzMYaNG=wn_;+&wNw<{!ci36 z%27n^O~{+0+rXQm+mXVXXn6-xcq4xAL<(;p(p^a5^)R>_DZCDT$03FHAn&36?&w}D z??S&9T!Du>(N=&fqWdV_hyOcR&9@=%L*C9gj?y^T-NtbXjK;zD7S?w$7WX5C_tE|V zq;LfuOOV2QiF6!NSQ?dqWt5I%6{++9`bt_ofW8u3$$oJ^=Xh`eawS$19InLTSoG59 z!RVprVesMTk?2w6Bhh2g@(a<6lwRO`9_?}DOL%)6{Uz|F=w(VTN3VcSflqL} zN}N|fv3QketH9Urz6yL6`8wxo;4_ro;CwxL)5$l9_Du8^$1{}Qru0_y4pE;2pQHRP zES?9Sr~DrAUx?mE3SXf1z32n#K7i4S(T6a43H?Lx!{{SQA4MO7FN3dez6yQ{RsYuuiufvHF*C6Dg1%he)0{dRg_sO~5S9S0T71 zSfBbWDL2S!h}M9!F4~sJMwIG;b@8$lQdkG?jgi7Fh`lvZSQ|F0qpiVhsM#8Q8*rPf zZ7FSwedDa{@URv7c3=}cH$rOyHpyyAsVOlVWHrm$9@!MxkYjsTY!AaNvtDD|v$L|% zn`bo#x5uJ6zqJ6HW$l0zHlyW^NMTd_?t~OJA=1uB;dU_C1u5JXeygKh9PUbaSL%1k z+6~K{(RTw|;$bJWmSD@QR+L)df5)shqZY_k$Q?Ler}R4fT5x2;=yle9cGerL`Bqu2 z|6e!f9Uf(s#bIgphfxGn#JW4X>+S}LArP7b5D6^;f;178Fi9rKKr#uFNeCcPMN~S7 zs8j_hA|L_+p@}q6Q7|+qDjifhh?RZsOeUf1%KAtC3Fo=*@0|PH@0|0sJUo<(T0Y46 zRZz9RD_>ZO*Q;#%%0*avQZWMNY1K)9|JkAui##Oc0`)0sAVK8 zPVyaAHPuZGQxn!SwM=camU+n3K_6n&#;bwWFj1y1tjnr;_%)cX2Wv7@AJ#Vyb6!nY z8*PBqGLJAGh7Fl(V4}%a8`dUnWEvASVnpNBL7R}R4t^8Z#55&pYMQ}%Fba#IPBUn` zh@o12_$b-y!$;8Oj7MPuq85zirlnt7Qmuh`3~NB#is&)ZnyL+9L*mEjA{s^$x1oL` z(-yUC#B3YWj=6Sp)Y!DAqbB(6VSCeosDpU|HigX?F|Z?ig87c{N!Y=3LM=OR&Qqvm zd$K%@TDGIcGpJ=7s&+;#+nQLcEj`3Cx?qpfVHbuIYfa~I9O(kP5XW&wER09v$Df~p3Xp)GM=&+MXHf}TteG+riyPIq2Xu3i-vt3~~lY-Zc zk%ZS3O(jZ#N#ydNmWgCfLoHp@PDd>h=q3)0H{F>@$L|ii8!wTU^=T%93?BRpm|=WG zKJurUOsaLm&xBc~2T>-Pg7u(_9(351I2$h;zlZ6GW|>~7WfrS@qn4Ruc^0+wQKJuP znL*X(P)jd8#i5pc(Z0+-XZo?S4}L$`&-5qiPo8JZ05bQ+9{>kZu@~MzIM56t8f2b_ zJz+K@1`dYLGd~!`(2XsAWI8i9`FEVayE0 z9|nh+;Y7n(|FRiDhL`Y1z>#Er5pN_MX+{x^qUH-`v>AhrLWf{u=wb{V4(3~mF=Me9 z^9mNj>}Yh183#w3S5eE+oH-t~97W#OP|J~2dL6YKK?iT3mc!{U4z-+sPGJ5GGm(|A z<4=T>$nYB8Bsj@TCYntC@qEqW(8=hljOIkm>24f0mX4a!?^wR?maLe9T2AKtsi@^7 zGQNpgPNY&CYWbF#2B#6l@fF!MVn{iyW%Whs()6 zAHI*SU@V6Vh*mOIm{opVMYRQHHMW5GL!#AY4OJJyg~T7x#Ui+fcrEo8n{}w=VrJKx z^~|lOqYummI$DCi0d6oGi8h*#;ZnGakpnlukD1>DKY<&~r>Nyd&iM?r+(4GisO5TU ze2!YKrRo=`AIFx$!bIsSII z-RvORLB-8xCp~yNGtt;iu*+vm4!oeuC|$_uX8}CbI|bW_AzUYxd#oW$eP+ zgMLl43+^Jl-KvVV(O?x6O5)N(uBdLHA+D=;9b1?jb&ocO3ti`3^m5zDF&Ovib+q@(5W@pq7WJ zaT2vWMAcKM~;*p(XfBv7hOolrA!I z=w&&5+TS|o81XBI*^+1}m4+pCBWhWaOd+Uc33A_rS{A3~&8THDwzVjOTHc^b^jXHw zTZnIAzKqJU@@D+9upAj~!Yc>MsXS46@`q@ZDUFs#Z)B_>T0wuMG27q@`ZZd~H(y@2 zqL$@3|2EXJ92sv%Ez43V*WB)B1>J#v2eY|+MK-z(zanSdhF=j@)M|4pV6|O3ZfDx*yYKl~KSY0(#Q?*nZ*49I+qbSvdbyZLG^{^Vi26{vd6|F|Fks7Os znyMLWrWie{=4t_3s3qQG{M8(TjRXFKZ|qs$m+g5gG|cYLrH6jK;#TdPU>( zs>Z|ddQGqE4NZU(G*Oc@SySK?P1T!vOVi*qP1oC+p_y=|X5r2D$M2wX^seT@xtgc> zdQS`B0==(=TBOBru|CieE!8r(OgUPv6V4u07Zg;R#T~W7+ z?8jHs?M`+CEG)Z=eGCiB>`thKW%sZfVqw|6?0Nb}b|3qr{uy)nd|r24rqAU_Oi6S4 z9M0G{r!PJ^CLt=M;82z;z8Xh-uI%`}i)Z!l@((&+ggF9!W}xZJpP=Kj+nVf~2et@n1n^tTQ#v?eh2vo}wPn5grld2qKs!(h$d>oW{0s8@D~@OJeKm4>IsV|~S6^^D3tG=R{W^VJ zv8rY^wZa!9uJF zy8hO#SQLDHu9ytIKK!%@eEa$5@iVB2*O?Su&}sG1K*9V*!kuBkp2D5f&WyeM6Xs6! G3Hc91)&1Q7 diff --git a/Specs/Data/Cesium3DTiles/Hierarchy/BatchTableHierarchyBinary/tileset.json b/Specs/Data/Cesium3DTiles/Hierarchy/BatchTableHierarchyBinary/tileset.json index a6e7411f7352..cd19543ab8eb 100644 --- a/Specs/Data/Cesium3DTiles/Hierarchy/BatchTableHierarchyBinary/tileset.json +++ b/Specs/Data/Cesium3DTiles/Hierarchy/BatchTableHierarchyBinary/tileset.json @@ -2,7 +2,7 @@ "asset": { "version": "0.0" }, - "geometricError": 20, + "geometricError": 70, "root": { "transform": [ 0.9686356343768792, @@ -27,16 +27,16 @@ "box": [ 0, 0, - 2, - 10, + 25, + 100, 0, 0, 0, - 10, + 100, 0, 0, 0, - 2 + 50 ] }, "geometricError": 0, diff --git a/Specs/Data/Cesium3DTiles/Hierarchy/BatchTableHierarchyMultipleParents/tile.b3dm b/Specs/Data/Cesium3DTiles/Hierarchy/BatchTableHierarchyMultipleParents/tile.b3dm index e23ca8826c28b7fed2c98771551679b4a4824d7d..553c5d77a341679c3990760f24aa6cfda71dbdad 100644 GIT binary patch literal 94770 zcmeFa2VfP|*7kp9&P+r^q+%;!V8o{l4%2eTRAHS!?gJ_FB(gyG)Ds9i2aRvX@9C zI#2TwjW$Bz-?p5`WcTaecS!M&KK%~L?s-ghS^4xCCFNsErw=SGA3tM4cF+8-IoV?- zl}w*rIz7AR@ME&eOD30Q_skwUWy-XP%t5o>m>55zkSe(3=-Z`e{$Mk}j-X*4Yjp^ND zdiR*#Bc|t737nTb^0?!2sw4;7zfH`j$>fxzllR;US+WdS zb}TcN70ZZaBb|x7YFU^zWy-i%7V@jj4*fi8YDro740@J5t#mB5qbJQQMI2Q+Y0{J< zvgy7vGWIHny`yWj#zi*bA}KDC)wqnFSvF~GS^0Q=t%;ABj4GK{T0$B+=jL?I>(rxrPJWM0 z8oc!H7S<{h+H{3Cy&8q1r7Cx`q5a{Po)>K_pOjl{~RLHHGVz(KTjVmjiHmbbz zh`;fERB6dH*QZ=fo@qijmK+^Lr{T9=i#&g;>g4!J~3B~>iUmWGIDcL z2TRNyTAQ`4E6CB&g|*xbr&Af;@);?wQEg6sZVua?F!q0J16s^obMm_7DYay%q*Xgn#|T2>sIY0+lr-NJuuzk1m~Rp%a^y7lP7D#_mbS^09{y&z8yqul%f9Wo{30;NY%vp6ISJ1sj*Z+*1E~%+eVrr&&Nsp(E z3ry*e%#Xjxo7>v!IC;3{MU$sTZjbeoXK0_|fyG1C6HC+TTzxo4m&_P5q5s&w<7FnP zxm=g2y`Ei_sU5L9j{KzNkXvY@%gRfp9W_czQf#7SP%>>=$x$gQx}(K3FuDWn-h)}5 zlRa}5y$4{-$&@u zz3NQp-mObPt~gisSnIUp6%ccvn!cAx{Td6eTCP~F}7^nxS7*a4=H*WNuBzobaL5rxv644om+>Q zlickMtC~ZW(P($hHkoV7tmvt$WCquZ(KBbHjP@BkwEwXFgZIW!dJ|4xi*mB}9z0}F@xb_x z(GH!HJ*@A6eFhI6vb%D$zAgJ>PIm9&VSW1b-#uP$^9=HAR%KiQ3c2BeF{dEe*q+rn@xUO)JxNiaU(x*q}Bt z3NXs0eH<4gB{Ak*4-2WN8}^#3i-;S^bfDCzrtVX-4;r=KKBIe4fV2|II|%Mjky&))r}^JK&g>|XtbjEe71 zbfcu4wV?YCg`tri(wWwpJX6M%O@a;gDpR!=9#A@Z&w-5bEacA>&w4rTjLAXZ>jhh7_rE9mYuHWvtgKTWD;XXqK59r&+Ewbt@Q`|S$Djlx> z-uw3*GPLioA;o(SWwrLL621%J)0>c8*5K7uywW>Sl^>W->pL|nfA?Yi2lgGhd;dN5 z*bm>dTE9zGX~r+>x2nJVvVOm^pLFj@o2q+PwI9<1%Iu1fO7BUrbahov*WVq+tfMWe zx@~Out9p;^Th=DxY7?WXy=`VO<9w}IR>pW{4>KdubbHPluV`Z}EiW0Zbu+wk_wGDw z_2}$wbZ3^AY0@9s(vU%^{IuCR<6-!d~ z-!ER)OKm4SKA^XB*}V740B6(p>y)1#H+iAgBfmE9-S)Y?dP|qjM!yemKEH0$!ueNy zu&8+4x@_tf4d^Xh{P$^-;$!vdm;ASzlZq=o zi+iT{>~&iU*WY11U+i_s=oYSz;v;T~tG>(USs$hNsBQ6%gIpgiCl*&Z{Qcp@={`!g zxYE`3@|FD^Px%*T)hkyEAL#G;Yc}F+HsT;%c@sDBRGy`azxpd1>GGqt(m%Q|<MO1D_jEmzWIuRflicXuy;O^So+Z_R6&?#o*Tw@mkONLkBtzpP%| z%-%SQgZg4VrQh+dluy~8e|^jJ*p08hd3t=!M*T7y^-KPhD{)g?jkR>yt6nzS4c*-3 zP;DE`+B`jntzL1>UOdgGxS3Ds;-j3%Mt*D^y?I4S*SfHJ#WH(wP<~`@JheuQr`DbE z)VedCwl2ie)}wgZIyIlh)7G7AY#k|Aw${YQ=C;{bK4oM1lz(y47%8rF^;cMXREhyw>71<@+qF0SL&B^^KbRyX7fZoe- zWAmvT$X@w0p6ai~lCJ$pHqy1nh`;z)z1nI|HUC;?#z#IE59`od`>Ogl@v0Ob#T7S= zsm98DYVN45d|FNv*Yc)(S|6obTO2!*d*0fJojJG-uV>&b_?3O zJ}U0QOWUXWrF!d^?8VtQXdRhP>GC8kTD{E^ z+5Z6t)hj>ZrZr+bwJwaO=9ux+x-gzruUKYp9OP5n%%^nCXZckAwbm@3n%kC7vk_0T zQLg0Q@~OBs?y|RW*SZjYwblM)<8JkeYxd%4KE+M_(ma%I{-ukX>SZsV(&a~cs&vh5 zt5;mJ7iaUS+{&lci*#|Yb!ThYINKVOjqNA4FIgVcR(>>gvbV9*x|Xhfsjcj_hqd{6 zRk6lM`-gP(MZZs4{khY%U)G!VxwFxpDjW4nZF6US>2%rjJ@89sqnNT$eiZY*@hM$C zKMcQgJ{!SN{$=wsd+NM;saW#4&2gVQpRzx6>SxZU@pL(iVo8_H*C&2eEM5Fd?*A&? zR`u$a{4e?<6<2)bp7n)`tML&}?W@YY`Y1l)rnt(3e6H^Kne(Z(vv2v-`Lvu^T=~&@ zu|7(-xYE^jMZeXKr~HeX>XoY-&Rw1MFB@?-8*z}XyosB5D$mlzU;UMhboo(R>ASw2 z@@e(rY4(aMU1O*DU_PZ=Ea{dj>9SWJwXbSziG%93wyZB&Th>RdE$f%ni<{XSXK_$p z%%^ni0XBBp18nTH2iW+UjrwIa>X-a0SK_9)8f)pYSG{bsSBbycYOk_6Z1v)4_Tp(i z#m#(57a!$BHu57~ZMCOL*BY^U#WH(wP<~`%JheuQr`Cn>)SNV)wl2ie)}wgZIyIlh z)7G7AY#k|Aw${YQ=C;{bK4oM1lz(y47%8rF71< zw)Qoz)Gu*1|I$@2ZZ=QkQ+`yx$>u5l(p9gxW-mU{=8Wc}+Dg|v zjoav6S@}^+-78Diyf&ZmuX}6NYYaEySzWP|5A&%U$ll_rUj4OL(zX6%BVB7w{Kd!W z)mH1${A-;VAN5zy4BA)KM?Eu$kK&4(_-Jg+r{<2@%BST-aV>Akr}a^~#g(r8Ms1C= z{HtDjk8&l>W+VUNZye;)a;3f-PxV*)#Z!KytF87_>GEmymLJtCuEtKf=7#x{Zn30W zuB2P8w6Dru&upp}Pd(RJANA~~ScLhG06tzWViXXBupn@{QTspnGJD~A{H>?(Wp zSI@3CzOqp)vk?dJmw)50xYAWGd)X+Ko~6}R9Q3R%pH{E9X0N#BQ{0pj`IN4lh>vWf z%a7Vh*Si4uw0gxddvTDi{D_;@i1F0AFrJ!Y##8IUcv`(;nZ0q4PjNG!(lwtgpIU2{ zPt9%1r`d?7*@&n7TRs)n#$EO{?phb(ueREsY}~D0Jk4G_&8N7jUz&%~&A)VUQ@!lv zQ@Z?UPnE9RTD{_$y*Qgsf?HKpK*K3t=U^Fvx&DgT{gy{x-LJ~Hm+Btp6ly3uT;SGQ3ft!?Rmmaf0Dk*-)~Z*66dzJuzmt^8Nl<2KT(+ZfL{H?uK& z*`TL6n{FJc+Z%^CH{-89S}f@r+Xq{9aD6mgd6vEE2VwB%H@yGt|?aEr8jTzMHQWO*UoHMn@%?y<<)e>l&-#; zZvIs-KV~1-6<77f!F0u{Zf`cm$2hCr>`gbDIOlj=)6L%E8XxOd^_&<7<^IBFzbRH9 zO;_KgTOLf8jdEi4rklO$<9cBfYwf@r-jb8?%=UdYZH8#-X~s zafov>{_3N}lCH7UHAa0j-TJQjxNbI<6WLp?;%!Ygd-D^w7awaYy}C`jt#q?7-8jVk z#QmFI-9C|M-CO5{Bfcq4B);YBM|pmvt1LZkqu=8;rdPMIwsHHojed{Ym>#c}ZvNwb zr2jj6Yuoy!l G+g0sjb)PDmz3J6$EUxO!r`f2j)mP7$0C;JhN4DdB5))SGsq_i+rc+Ub^Mw{_;29+^kaiS-<(qH!Il8*%bFp+3UVq zZAX3CtWvsc&b+Icvw5gV%8%~P`vm^-NiQ_2lrEo@n>2Gio38Ynf7Sms&|hBAxS^|; z&z`?DbUtNY@j(OU(|GDW++s9(p@zvRF4mFCXB_;hOC)bUw7 z%ya!sy)X4#AH_%96jyzh&o^c^a6Z-c_aU1&pOzDgs~qb6v-MHB#g(qMS6#5V<0=2* zrh4V7|2A8s{mVw2%|;xgD{ta9@hZ>dS-SYEzp{}oKWZ!esC!dBtzJCMUU8*s?DRZh zKBZeM>6R<$vR5Bd?@Lo0RKNdq2eCVepgn-F&us z8+Th%YAc`Osd=S-NjLviFK#wZ$PsjX~e-{$AbDqB>Z={QRtb=g_2FOyc!t$gMAlwNP% z+{)EiXQgds&pgxREqCTT*H-hV?}78G*vxr*j?2}3<1ec`W?f4EFr1h6DgSTxKik>N zt2ei@-ncm~?l#BGP5V4_>ZQ(J`81yDuf>x7^@&$F8|fwYU*Y(RkJYQ~qA%v9{m(t? z@-!d$oV))ym8tiob1OSMp5mjp;-)cO-Sg74&)K(J;@Zlm%E-($X-0nr?@F6@+n<85g*w|mmjs2erLA}98asac_MqgPgA|}BW_wF##8IU zcxsLrPpu2%Y4wU__QpXz#m#(5*L=2oYOPs5HMcFFW+R?vqg=_q*>vUEEYJd-;?uKbvfx(lxiOUUAJ{oXw|lE1y~~ z(#65novmf#Y-><9+V?CE+LtU3YAZh)JK5XVX@8TheyOeOTU5SP`A*h4Hy=h__O{d2 zmsg&DyYk|uKe>Lb&U(A@r_!IC&Fq;ed-Y3gUp#BAn?JI7=%%&KX3pCyogd}rm~|^F z2VAz!H=hJw)97eIE%ckk< zH7*b0e@(wN>9(rZ+>`%7EmCpCr)=hrj?div-*r5-uXcF+9oI+k5jVwE9^|vx<3Br} zYJ1ZDzc`S)?^~HQjAO8OP&Zq2m*z^7L*uBu~gY@{CjrwIa>X-a0 zSK_9)8f)pYSG{a{-}r&!ueO`7{vbVvtzL1>UOdgGxS3Ds;-j3%Mt*D^-P!F!r)!N^ zy<(ZYI4D1|H=bG}##8Igcxv4lPg@t_Y3oruZJnA=<7w+oHnxtGD_d*gV{_YVET6Km ze9FJLX^a$Cx^g0)vQbX7F4R^W4!rUgH=nKE#@*JG+RCSRYF?>d(#^lsi<`|8`IH~o zul+pbU%KiQSGw%Q$9#&Xt!wF;+s4_}vf6458fV*cRB!u|e5$SG!S*-#lph;AwUv$R z%TL~Z`Im+FInL6r9lzN1<(ZA!EZ?bfO8>2Mo8`@ZUYxc$>8$%)-X=Vr?b>Soy!T3W z6`PrD?{&Fq``q@+Ppy~I8~vW0_9_26+_%WtEIOvm@*gh0*TtPy+$Qbw#V1o7luzTS z{#q>Q^@~zIrSH=w+wm74t5@50bF$O^7x!GxM?TALxyRkFs*i8_eq^J#8awHl8|G8G#gcBhl5V-uzAF1)Tc+BI=j~VC?R<*= zpaFNgd9Ju4ce*>>FV$PWWG~LfLF>qTN|(~{iQ*+FCYF!vlt5+q7k1HfQg)>2bGu@icq!G@s(8erX;`H~-SbP4%*uPwDdW z%k-44xo!1|Yxd%7K9yVf)OwLF4z})WEgNTBgR;@SXL-=RWO-0q`O(8$0e=XR*nw*%=NH*Zo!=erf(*;6)r+j6?uG@JZ#rRh&!{GQYGeZh3St2dwW zWA<@faaC^|OjoSx_GV*zjI-*^-gL8xbB@O~-Rv!{@v(jx|9C9v54Q4_x1GC9rTS>P z`Yv5<Ncw{d?ekr+r+zFe`Od#zFRRy?QLolMA1{y7Js*=eRzat~{%)>f^fdAREhx>9UEpHQnsZ zPuyPq<9V)b6K`wzH=fqk>djBwzv*!s=~_qi3%+t=E&Zz>eypOi?%J6RYt!jwqqS!G z6^j#2SKm!H|FV%EvybbxPK|?Xq$^f+d$Tbf^fX<38i|mRqy8SY{J%Yr1TVLv>w#tZiJc zZXeFuX1T4MwMT9L7hP-9Y@}DWv9+f9r!PL&_1AR8GJ9)lYh3l#R{pE&+6T-=dUYG) z9Oq^>W-l9y8`q6Pb$jDraWx-|zjTWwz1zIj%cm9H1JbotgZQs=efE~ysdQOW4durz4?jzH@&(&-<&J?4qTb~zTbK|-rH&L{4tHulz5-^$IWzVBPT`dHm(YxOO%H@&)z@l?HZ z`7|4~wfgEgjB_v><70k|oB3%S@rm1;UY)Y#j?U)R9k+8fxInEtYiIwEL}n zv2^h-yr6x$t?Jb;`M)Bkqw_C5FMpZi`1Ieax#Ow#rT4wQh3ljEh@0Z7@ABEgii>n;!{j>E^y2X{QwqwfMIiB(_ZmL(V?*C|qw13%%v)PD)bmdLl#8Y{e zF8=DTY^2MN+Dbotuar-#7f-WST;6PaCBB za@dgi={~MHY~ysltX|yA-Z+bc`eHt%cL+V_Q}(|-5vIqk*`hxxY<$f|{W2T%Oa7HB zaZ_B4wd)H$RWF-QuUK259IEX}h2K@!9JYGJm4BP7=2P6vr*!dAPSh9qv2|4c)YVSc zy0Ci1GJA1Qeq?VvwMLAm)}8Uxx-*`(F2vK;qj=gnHJ`@Q)}3r@9Vu6~*2E`0w<80BgK`joXDqaloPEBwH1fEyLWN(+3IcFZB41Ie2S;$mHH*!{9C=a**uX? z`H}q>FQoiSSH0p&m%aFyPw}*MEnRclINMrQTdhIkY7~BtckG<5T(Xa(ZP;6TY0k`NO{lGO&C|FIv3n^$ib-sz7c#HS zr~Jd!)oTptgNvmcn@{CH_Qp;1>aWF;uKh_i(zWKqUwo`yZMCPGf2}j)qy91my|k~Y zkBouiqqySc^1xV`Pt6^*l~2ow;#%I6PwS&}iz{9GrP>;2`B%O6Lgh-F%|`yk-#Eyp zLfZS6l6=(&f|YEkCMPT#cP{%?sq?{rM9xyUWJ`| z$E*EAy85Euv2(iiOZYh(?WwX+ztom_>2%pJFP)8I%0~H7Ovc#h^2r=^J~x7+{LAK2 z_Eh@d>gAKXIG?hopU$W8R30prblI>DE2WD+YcJha^_qL~&)ReT#fP=w;%a=vGrC`O zeH0&YQ(WaiJ{dFTQ*9X!=hJdxapgzr#ri1S;!0Or_8rGl{>4r8$`yN1+P`eX*=)o? zy7DG&nj^}ybn#bzWg}gF)K)rstMh5~;%WAZD_vu!`CvY!TP*38E9tUVAEWzK$3gX4 zThFtv6nY}nDKe92N zS|i3&>%w?y-5F0?7vgE_Q9Ny(nor|t>rOVdj+84~YvPlh+mVgsQ#O`Q`4=~hk>W~M zPUKTI%8Ay6+KL1Fo$I^R+qm1BQd?X5npf(V%>ntBu6l8^c_N?kqk8t%^xRgx;+nnq zm{0N4+&0dd+s4_}vf6458fV*cRB!u|e5$SGLH0Iw@?&GCwz84EerL~GCeG5?N0zBC z`W-u`ix>My+D7jJG-os))mFOZY21d`%ak9*B(~EvPtB+Nv;Vt#jUjz-v6N%;sT|1O zxT#+KwOG=%{$wLvYfk*d$LiHq>(cydof#kXmoZot-LF<;*qbWURvb>` z8D2iEUOeST_Tp(i#Z5VpPwC2u_{c`O{HU#Ty$g^}t5+6gTrJUGrH!Wv{hn`P9B;`7|5xG#l}hf6J%h+PKT!#$D?|{MAdP_2x73<80!36t`E5gVUo}RqSInRXD5O>|?sKiRzb$XFRUyG5abU zWWS-D$X@jq|Jr!j$_d%U>Z9rEyL7dU>#|W!%-(dfQGHym?lW$0xix!>Wj67)rpv}S zRM+Ll+Q#+j_Ubod*-L$wkLo(*8_h=g25gpDTjDKKEZIm`EVGZbU536xRPWkG{;TM5 z8|fRcah&7a%qC{9b&%#9(;bHm*r)q~ZCtMsOa0Z@GADYekEUDSRUg;Q#&RNi%T>Is z>1JEdj<`H%V0S~H*Nwi=Td2d77|s@TVDs&H1l*~fHe6V+?(rsKx-n0*xv*01V0 zk-c)I+%q=rJFMyIyL8Kg>B@t0V)mw+z3St-?BhP;_Lf_-w^(KqZ)>`2j6-!@eynX= zuWqk?Yn-Az;V(MBX)U{Y>B@06d$-n9Pdr;kPFF0mkF~WmEn3z zcbwzg%qC`Udza%(z43P(HejFb3$}5+N~~xHv(Vfr8CT(vv`n{T-w%2d`ZNP@OrTrB1yKyjk)uG2ZJ6*r?TUvKE z>&8s3xcr8SHk^g8CA(L2{5h{JXHmZ2vErV$&MqAOQ(n=pLxxur-nzK3*Nqj0iNpyN z8gKpUbn>K%-~aXKQqDG!%~ILCTDoFsqdgC6%USg6ElZbP`sp@>8}~oVd@hyGoNq2z z%30W}-(f|4Tlp27MT^$u6-7P^@p;4U@3gDnEV=@25ziaoxil7QX=GD@&C(x&E)~() zHdbF4`LB@w=?j-G?f=C#OMik}suw4;rB6kw0YDU8_^RepKFQl0yfLvp!PIaNNz zKZ@=2C`XKu{%M@lw?rbUUn)Ja=eI=Sk3&~1-LBtZ6)~R`u~-$+*eRB?$KL|^)p$l6 z+#FG#)fdeXwVgn{pi0yLlVgyLm$H3(5Tga`8_TC`ET4tUy$bqW7_AW-cdZc{cdZK>cdcWs7md4HFVVQW zH5KL4t^H^oDi<~fln0l;C|^#G@@R9LI?cs&er;}RJSt*7ZEm~VMr+DAYdsogmtS$# zyi+c;pJ?7GU&@2VU%Z(E716q}v9tZn*1j9N7&ph+`V!AWJU_Be&6^VzM0H23iD=B4JO_8#?_^M;s>+j}$yS})OFr@3v{ z1-D)ptMqk{+@!CM^vTUFjZ{=`>st1c8z*y4Kr%WjqUGJPTtyt^P09sc6mHx>Mi($F5V+8gV?MHDcp# z*CX5iYki%H_KCLIS7ZK*qJ7BS<3;P<-TS5X9?k6Zo@#Sjd#cUte|*h~?Kw4GUlcpK zhG~xJe!%u^cRkixh;xqjC6>1$#@6!2{Z+n7l+%$K!d3?}4#;?W^+d_U-uosr=Z!8eNMWPwi(~ z|62QzPpxOIyYzgH8c*e2a~_UvJfi!+e|uev-K+dJ zuWN4qk9gXCC7%DsT&JSztnL3A#|q^$8sC3(or>mwuJLxyGOSG9KBzKYNE{R4f}+Hw18jHm8bEtcK`xOEu42hf^xdtj{I z_EqOU+LzK}XZvdWeknG$&7bobtw+uC!dOn0id&SoDq|Pz=WblI->6M=zgndHYEH(l zBQYCy-HU8=ziMOp-@K-~bsdXUHd}=)1 z8G8><6z!`T51o2mGaH-#vZ?ai8oLJBxM)AuKA`zy`@il3bv>`~xixmJvHQTn|H)_7 z_;Z2ATseyESH{!b3r0Nc`t|?&>r}K)*!`-WSqgOz7Of|{U;R&?#oXMEt!uls{^gp* zysFR{dk^5&Z*;xZyEyiAcfYDNgRk!|~VJ&rcf0god5y z{lC%w+v8rFoYcm~^`(M-(a+lG|EOR8CRZ+Q+y*YjJ@ppT zn&Q?}zo7Q>#NyR<-qyskrh4bU4*99c{vVAyd8}=}T->_mt)~2Mp#C56uWQ~m5ZCpq zruqf7pC>hqZ%y?zjblyqbZlwrrDM@%{&0+j17wq>C}X70IS1J^J1J$o4OK)K>A#&j$6>o?$urclQ-$ zC-1e8>dCH)yTE*gNw=z2Ettd}k8P zZTYn4?!SF!65Dh1zR32air9XY`M%G5s{Sn_mS=bEwtY4JeTuzNd#jtP(Vpt|)%bkY zo*M13_P$i#gQ|>Od|a@#YmqY!p7Q24wduRIne60R|$#pHd|ETg_TJu644 z_EhZ`vG>o)mFBe03eH;n9a`*~Vt?PYR6L_~VecM`lvB=H{T*7gr`r3{|LuR17P|&% zUKQ!A{vKY}g6JBi_oa3%aO+ijhjJ2q6Sn(R?G5hTZ?v~4Z@OPC(wvL#SEK#N{XMF3 zSjefr`H_vghHl`xsc(Xr@B7iWk7zBp{40O#t$+I+Bz}F5jiVa}?v*p&_ha`Jv1^ds zZ@YVy*mcUjL1?bJJvBCm?b=u6x)!@v$$a1E@7tpLRd;_7?f-g?%Y5HY-H*9zjrQKm z_x%%Wz1aTm?mKl&iLU4Fny$HH*O%D6joq(SME9%d`;F*&=kB9o*Cx%!BHce}PHInO zUH|R%oxLLSeSiJ^mBu9VeLr=Lw)<*bqwRjx{$^g^o!v8a?AccD0qoh<=CwZEg=;NP@I>*60>r!wF7wFBEfy*sY$`)9S;kbO<>pKGdjekxMW?X}kb zYwx8~eG(7-tBG^G-t6j>x4*m(cj2OU!W+=*(BIm8Ylz#_m4CeN|B3G6)?wV^oNJ>y z|8>Zlv#;y8)P+B5%l_3SZ~ur-UHc2C+RoeBaE{wJ{&mPtP4=}J>$r{cQ-^*z`?}_> z4)Y|=tu}g1dHCD!t>-=N@sGbtiN9m1&3l#TeRbyhe&)a5*WV;$zVBzg@7ud@ z_xEP;zwe6PQ`vtjmwpcx|Be&;Te2$qYJ9(qzVFy~UVEQx-*@aiu+`i59rt}R+Ed;C zeop-F*`oJ*_C4DD{aN%qTJNoOX8!yA)OR1fFSYmc?mCtEzMrRkFZ18;^WW{pzSrnG zclx_b^fwG{eMNtVV1JKV6#XrM{dcDB{Ws03Zerjc_0| zFOIw8Ux)nEWM9+x)>QBO)S+L_zOH$z!#t^pXHE4r<>7DZ>%gb3{f*Db+US4Fa|83C zraaWO-o>rMxYwpHahtm4&Dqy=T4mS4A4BJm)Iy#53GmP#^@gP8-qSI z^}+gyO=#zX0kQ!{GO;P=CSXJA8YDKuUjPP_8zmZ3YQ(u2S{AYi-m=h}fK3ujDK$+r z12+aY;%H8sW}sL!Ct7{51>Wm}n<86swg4MY+MKgxVhbm?AX12Q@f#&tA%%^o-8Rvhy4EmioY)RVP0+Ukw@YMG%1&$#HU*n;HV4~) z+f&~LYzt;5c0dZVY10lV+zv18k;2x*=ztV%OVo}?VXMTB9IfE6BWDiBHZaWL+=*jr zn0Mlr959D+CtBS^`0Rk53+5*BDCH5ceWEiQ+M#y_J16of<->4?L_wkp zG9THNqYK=-(3dueu3#5xyMo;k-O;*n=A(5*_Mnsx=Hsg;QrH>qyC8*m#NHJt%!N%S zcS#iCp(lC~Sd{2RsTclxB#MdF4ZRrbo#;cU7}=ep4=nn? zuq)-=(RN4gljw`=o!A2@?2YxFNMSKv`XPnAh|wP@EF$Uvq_7Z9osh!4kb6--ATbcj z{^$e2fr&ws2H~e)VsAX}iM}^Dn239z4F(4%_Mx;-VqdT?xI1Taa0s|B^+Uj+iD76% zIR~Q+LGDLsFgO@5`y+*W?h<*@wP~u=p2V;LgVmKc5 zM;{K3!1I1+Bft@fk(5Rfb7p=uowlyA*`k5i9

CrUV)Q+o(Ifk<(rIxT8&2cDDRp8MsWch=a9T}9KO8)q{bCa5=HOPy!?D`R;o(^9ggzxPEipYY1DuhVnV5x~ znK&YGB=QK(S!mOd(-TJ}js}m$>KOFt)E@)RpypWc*u-(Pn*q*3&gPhzIG*!3@C52+ zCr-rQEN~X(lM*LWI*Ic{v?GzH;O$8CQ@~Rar&2mKaT<6GcofI!#5oNVi_?jAEO-Xq zj|GoMp2>LzIGfU0oM$HHI5~%CvlC}?%%*$}rLz;~67>Y|1j^^Z;zaO7%I6dRq{IbC z;YrkeiivH@-@ygDV+(sS2O-beo!{FwdXJQ2?@Vo?=@EUU@ygw67_@$B8gtIZ& zkWv$`DY7XZ8hXv}xhZ-xu$kAKQgb3U@LIrO6Z95f3$G=mmN2aEZSHM>Y>C{MV+*)% zL0{^5TY_6qyCvnVysgo;;%tewC2|`|Ey0%f+7>Bnf%jHOVRK@)Mhct3rU|mCw;eUD z(YFJ)^Rg*rW8cc#9uM21Zx3$owV~7o|J!(NiMADbTW|-j9i_I&tvTAkq8$vkq}(2@ zJ$gH@19AtiBT~2n);l7FZSj(W6t*G8PDtVQMD2tWX2YooQn)j6XX-n7xmfOmo(txB zd6e?-ljC*9^N#49!F(ciM9T;By#h)FUKg+f*q-y}M0>9**oFG8l)HJ|(YkTwqjg30 zpp*~hl%{&qh&mP=OL;mhO2JafGl)OVn~4;TqjrWji@I4b z8t)weqY3CofJb;oQaaK*3M>N;0UL;gPgC4k`@C@%vN@v3GSnn)v4)RRoF&uN?K8L;>?VSzIq4sR>9PeDT zb2!gLI~#c(r8B`Z@pV2@cn01tKnhPM_Jv5{X|Op3d8&62H5Z~^1YYD_OzC3mFYqqG z!};i!fR}ieQo0oX=XrC9b`JVn@G|dmN^_Cta$F9J%VBsn<#}lH&@cC{Kwjoui4gejMoKq&H-T4x^EfAhH-k4(e=~TCcPrX0oD0xyM&3qg0k{A!wL2kcuzVQ30$hfNhtQUR%e+cTmH1!6YJLD&iF}ZA zGNs9|dw}CU7)^%neXQ>(SS&{hD{22IQn(C{k0FH>L^=g2eB65ie1g&`tRj^jMSqf3 zkD@;bKFNNuoUeXo%g->gSQ4;hfm!}Wem#FHe}90#mp>33=nwMu_6Pg>fcyCS`a}Go{xEQu zzn{Oqe}I1=c%Xj}+QF_o967=t=^p|f;*atV^-KKG;Anr0Kh`hx$ARPg@%{wA%s&h~ z%%A8_@+bS{V7WiVpXwj(PXnj<)BPF#On(+Q%RjS8a&!R#y{3S&Yum=_K){Z z@K5wl@=x|p@lW+n^H2BB@Xz$m^5^(x`{(%Qg6I0@`RDr=_!oi~`WN{Z`AaC*S^zQ=i!s>4HTd2Pqyp@`Jz#pNa+F2`_UF6m*8z7`Vw%7{}82z{D;B2!8n0=|KK z0}n6zZ{qVM^f$pb{kJH+MZ_2Vx8d*t`rF{!{z^(KVYtG7$A1^O68SvGyKsM(zC7o@ z2fj<~d*J*22Waneu0(qe`5~p1;7WXbgcQDw_m7dnw}|}-QuropUPr#+e@e|K=%0e0 z`kzty4EvA$&++gP`sd*1{whkV@c*Iz1<~F|{{sBd|BBKV$PYNag2h)be2?;KwAJWe z`ClWy^uIw0zr^}qNZ}WF`4%Z$MU3x|!q18NJyQ4?oL)x?e?a~~{rCPFEWblv1FrGc zQd*0jZ~Y(f{4ew$!F5FZ25lX<&i{$hPyWx~*WhZ-N5EgepQ--^{MG*r?N`oqXulwT zr?d`ShnGK)!XNSeCsMeU*oowy4%fiubxJ?*i2Wz>bz~yxC4EYM@(-+&$=_**pcEv3 z#a}WRP!}XaN@4OhqGcsFLWapK@Hc;>m}=3_%Y=VbP(VBowl1(W! z#eaijrC%S}6uAj!1*Ho3)#s=OqYC)eOD<#0H%&G}3Y*ftIa1gJk1deG#zcDEZ{e_I za&z>}sePSQq*8PAEojvoeG71l|#>*k&j-83q2^5Q+iPi?p z#d{mD9WswI7u<8UlnRnviP|1)Pq`Z`I)EK0cPDz7Q+|cTM&}3U{SVF;ch- zUV0;iJ&Dl=DeO+v-I2l`$-W#t;Lw+I4~}jy+=FvZj;=88$1i(;drB>c`Z#c0ay+H+_!*s? zfaenQ31Ar!4@D~j%aVstIxIO690eZ2xidHkoJjp7aB{L7Z8B#W+9c!@N@ZXfUZx_2 z6YzdGQaGO2(~!b(u<3^^O-`p~8v1l_dU6J(8Q345oQa32=rh4tc%Fhb3!Ifag3=Mh zoSZx|c@**pWI4xCus8~alUPeTCy(aXIe84n&eR@>JSurCcx3W8r0_^u&PEE4!0+)$ z;VdGZfE3Pz!HG!W4EXg!3Qt0wME!}$ld(Jj{bcYIJRFa93V2HLR7$7fe>SW6Smde5 z<2dsu<-zV)j-z3e2j8Pv-}zXah7_Jk`_qxaQ}B2OQg||v`XPm9CeH%TqSTL7q|)i= zb7*xs`W$c$`^9OToxv{1IaqaZI0uV8(a%htojfObE_iP8yyW@F^O6@NFGOCzc|O`X z$a9hxB`*dq#_AIEbEv-rJeQhF!Ap~KX?HGoKJqe-^OBcy&IRXDcUkfZ{GAV;Px;E^ zRg|veyaMe)f|+)u1U@ZF99#&xRyBcL9w`&XqST5;r&wZa^&@#*MXN& zx`FfhdgckRM4nNmBYSJ%JQ1#ru;;;UmO;3MqUTHcOBXC7-6|DfFkor<2c6dItL^lh5Me z3G`>dXOquSdJg}OC!Z(Uqv+3rE0QlzdLH>0#|yA{0fx&dzlioC`U}aIkSmfeBZVul zeg!Ff9xtyVh0hV=HKg!aqP~t4J_DyENZ}jEH>iI-`6iaHp}z^fnS6`VTljf3`8J+k zL4O-uNyL}YR)Q;&?@)Rt`7Zbp_#)@E;CtY^)V~M5pZoyrea@9=?;$^=v=Us2myeLb zxAFclQur3JKS2uLgv}D<8_7?p`2_t_@YCdHls?1$)H1n48{b9lifoEw7;sH-1ridP@>DK`u@qtuXd zQ?vlt2yX#;Bd}4>m{Q}Q3Ahm$ax^7Q6HqLg60IKC4Da>8O_0qwn}PKywcudugH1S_g4y79)Mta+gRO%$NMUQ*v_%SA;bjM;a9d)uLkhPhYI~$`o1g>7 zHgM>`*^y%_7(w z@!kU|+?m)tk-|=}$wBTE>_SaX^j*MRf?X-?ihYk@H#~Gl-woU?D5O+~|87AM(Yl}) zfxUuaN=3-79L2CGhG7Ba-e|qii-SJMUcv52VK1!vB85eG*#jvoB*vad;ci6jhZOD# zryQiPKe9jd{el5l?ukAC91!e9X)pZj5e&q0U-W_CAR_LLHV7OP>`iI!U@+JR?9JH} z+y@*?{XXEn!4R~4IR~NbgB(g}5I6`g!;r#(c;62x+>6-zBZUKClY{IZ96-(f=m&rY z1P4+&5c~atgYYm6{UGpQJP$=X7(6%_PH8wX_YFn_Bay?ALpVmlVk8XrVJ$Tc4&i7T zjN)iY?Fi(^;81WxP=XYWpygausf9F5EwOw?;))3mRKBy6qeC`B2qX3 zkCTwX@kGi&3MU8UU^%56R*^~*(WlUABKj0?3j4)joGrjDkW;YQ!r>Gwc0`{XObreX zrh(If>A{R(W-tq!6&!(fq$?kVJUTcgI2JrMI4+nS93Pwjo)DZEoD`fKoC2N_oEn@K zoF1G3o)MfGoE6Lo&IZp8&I!&9&I`^5&krsLE(|UTE(R|SE(tCT<_4F6mj#yx^MWga zE5R#+tAeY8Yl8XU{NUQ)y5RcY2JnVp0oskOd=v8K;FjQ4@YdkA;P&8-U?I3LxHGsb zxI4H9yeC)`+#4(o?gQ@&?hhUa9t@U%OM-`jhl59grQp(_B3Kqw2Ft%@G|&v@Cw?iuKXJE_27-*P4La&t>Eoo zW$+I8PVjEE<;Ljit{=w;mfAY~n~QcGW zox}XFAnX!$1-pjb!tP;@uqW6v+$G#K+$}5w3&WzYS6CeO278Bn!rjBZ;U3@~;htf? zuzxrJ91!jm4h#o{dxLw2gTsBoeZwK(kZ@=?3^_F1FWeuwALlT%eUbZy2ZRTL2V!*) z`o7d31P-C*VDR8@IPHdj!;m95hK3_Khl7VuHzFK`zhU4o%7=y}ln&(_g|9?LNq zhR1Rq$1w@!v-#y%@L0;TX>kmAJo0!v937s3&!f;!08a={q;w(?j|@+O!x88wfhUD0 zQ#u)jv%*utQ;{blXL6hh_fzT1jPNw@RBBHHPY=&PJDu}nw9}AhQaTwt8DD21g(u;C z4pMj`vCl>dPk_yA~E5oZOU4@^^!mIH-7yWAR8X{hbb`5waPQ@4{t!bp7R>C>yQg5T?1Z&mm877tMPslQg{`yZ$=8Qgw1T^72z$^ z+>Cw;cuROIrCYJTDZC92H=^GL-j3%5Xt#s6hj&oAgP7Nc3&T5+cOY-zxDyt4!tgrQ zQfYV>M`?IBM=7-nk#~mofD6M#NZ~?S-is98f#1bQ;q64a4=KD22KOU{x595WQuqM! z0qXA$AH?!L^asHucvy_K1Y8n6MCl>?-^*&g2l)_k5$AYH<6(CX$6YWQ58u03-(^@l zj1)dZ`$v$%C3swl6h26#*+^kUxC~rIX*R1!rAN>!Y4r$tC0NOR@i6BEa3Zo2tBDRP zu{aLBB3vFm8a@U-7Cs(6fqXoCGJFd8B+VQnw;}34c$3Pf&h2e1+1>oG+n0g?trnPocjGz8bzp>9z26 z@LBL_jyH(&Iw%%z5bZheO}sw`zJPp-^G$FCrMEfX3RgP0l4vW!cQ{s1ewWfa;d?}V z5qy#I`>=Qke2MZ0#D6*b5Gj0_+7H5ysQU;;uY@1N=vDNO!H>gFD18!s3cd!u&iMxT z8TcvnpMjr)pM~3~Wk$Gs?}gTA(%OY>d_n*^*LYurXdXM+zI^eG8;;Gh%Ov6gGs-x8auHR@7{X zz7@Dt*4C7^#(s;eZSb%;`ZnOUcy5WdEx2t~D@v`1**vRt)^^BN$QB&i{eRt@cX*W5 z5{IQ^2BQclh}{)X69^#?N+f`h&>|p66Hy79WRq-2cEe^<0Fe>|R62;LR0Sy_AOZrR zi8N7BFqF_#I;eCIEB8IS*@SYhT>r>FVV?8;X3lrMnfY2C9?GGMN9eGk?B=;wkt+CA zr7C=c6;(M_4O-+;)X>72kD-PSllO7d@F6M%poS09K_F`Q0R5fu3-qu$adqYcr3Nbl z@N2*zGCYnK1cRg|QBCqcCVTy=p*7J*8F@r`^j8h5LPvRg`&DEQ-+WC8Mh$Cnel656 zh>RhqVGSys@eA>=w$#C|!|WNpA`{iZ59O>{_@OXV_W1=f_Q3u8>cjfdK*G=l@`N-*pJ0UH)kEt^xHN)|Sk)N69`lW1eP)`#Ch{cb)rVnd1lB;F zVmt|(G8Z9{J=^~11P2kgH zZvvk}TQi=95kzemt);C;+fpq;p1~rB+Yvn@?Wx)nHYI+RE+SzhaR=%*la8oiGiEzT zC+0fQQFG}`M=kI>!_Lx$sEa%YTf$b1DA*M~$9z}#JnSOfP{S^q^8#wvnJh1&hMlPK z5^C6is@+k;juMS^q=#rm5A0bw?7^^N?dd#*BRyab;uy||hOuZY8M;dxIbXt$gK=Ub zvQhCxiKmAb@Z({;BoHOgVK+$>JDPw#kJ;(n&b4%vBxq+g3HFp^yq=5%yd*S*C;=vr z%Yhoklii6L+Nhn18phF03>quFm`TO&1$&8$$i;f6q>;gap9a&!P2?tjilkGmCw@B2 zkW8XL%gd;tn;QL4!!)YCf*QK$DF!v{ zkM?K&6&b+Fe)t3602xR$kUTHTATsyG9|W_h*at5gX3Jor!SX8X4YL?ga0q;r`5|zq z48t4B$i^FjzDAS{v&r&0YB-4OZ=i+)sXZJu96&cQXnz^O%y9e>aDSDN<_;b2g0+$f4r~XpefEq4kcD-z5ZX+FiDx2tN8U7}?Nj4L0 zmM`FPxPp-bx4Fia5Lw8jT&wu%U0BIBQ?H34cAlkThwraY{NFt!#2it z>~lKY&iD>nN9Va5*$%f8=W@n2xC7lmhHqsjIlsZ*33tjaqFq$nD!b|7Yy91Cx8xD! z(cxFJNA{w5=$F`Ddf&^nY>|C%FSGmLemQ`*pOJ^R5B;7f59X2U2h?yk*?&Y0cTxKw zYPgeba?u@fh?#@7k} z#R)pxM|=|RB>oBc2|X@9qlU*>{R?V%j4Y>6!=uzVjT#=I>KWAVFg@j>hG)^U%%72S ztUQf>4xW?qMCZwKN-mK37yJwGA{Bqey9h7JC8A66EBpzbWaPlh@K@$9!{6k0yx$lX z@h+o(5M6{9$?_*^c!BJHp@!$F{WofOj&5?%vvP%*zwxiYD{_ne#rTuC68Z<{-J&Ik zO6qUqE1@NsE2*W3O6l)ZE3JNLDgILIcY5&C%Zwa)SxKMfx6V1D{K{drH0q~iU}?P- zH7rdgf7GxPxo<-aOH%W8)UX8GT9ic%Z_z9CS=Pfli0@#&td?Wt?fB(jc{1FFS00wv z3Pcsi@2_j53|axbm9dIw75$aLOoOZFS9CSsdYvoSHYWNvHJ1T1>)UYxuzT-Qrr1$8(dLO(`@7D+P zL4625qz~g+Jnu9Lfg>|)_ z*4G9a2E+6TZK&be2sYBj+C-n!2pFMHX;Y2VX0Vwy*B07RTftTurB7>XZ3EkATfApH zaXYlVKC2yI2koexw6k`BUGzEas?TdT*iB#17xg9W4!di#_E4+Fz!;6yIJId!jMoHB zRJ$g@B<-omnxYQqP^YG9FLgnerm0)gH3Md7reI8jDC&G#Pw!Wk9 z>LfTxC+ifQs?*>!ov!cc`#J;8(3$#y&eGX%w$8zu>xn-^=jlf}AI{eWx==sXMR1XR zqKkEjE`>|=Q(dOZbp>3ZIl59;>1w!I*XUaPOxMA6`nj&x4Z0C-)J?isztAmki+-tJ z>DRgyZq;w}TivGH^*hbg9lBF@>2A%_J-S!->3%%`59s&$gZ`)o;Xys5hxLdag-7+6 z9@i6k5}wqb^k@A=Pr*}qTF>ZNJqOR}dA*<)^%A_KzbaeY6#HNNx7}iI{Fj(wZ~W8o zVsHHOmLfAh_M0jyh5?8NnN%ag$XE(&6vIp4n^q=fO_DB6UW_7z=_Ly|H%@UvN zw7M=In6)46CcR-H~9S)lf@D!GY$H*IkD>%bWCua|))N_BbxU?g+@h3$*n0x0tkb zEmX5KzVWIo)jfv;3fl>)9UKxEZce+Z5l$sRa8~a==14+vbo>0~Jvpzx6C`D|H;1<| z&$6rU2TKaCrQgk-i02B@qpc}1cALXp_$2b@1nnb=4~nVH1n8mIFOcVi%n0q zx(W|?U!e5pv_!kZ?y#lNz3+AK9df&@jsHNZ* zc^!KnTR=wsbM`(6^ZfF!(Q_jUuGjNyLw(2E@G`quU|yqukl>IYix0jup%&kjd-C{# zU{^wn=V_Vu&o}x1Wb@r%Pc~n0O}6|;=2?*MUvoTz@2i>J#qpX~Uwz^2ENngh^qcf` z&8iv&H=~ZZ8D11-Or~sM)!05M(P`-py77M1%_BW4^KZ7dtS=$oNRY*cKwjn)YgRy< z(;eVV7nB@m>J?T>yrxpJrG_Q{!aYm8Z*U!2X9kv&M|32f`j;+G6SwFVM+AX z2;!qIcxwYa`Fxpf(z9<_LBWD|Al8}eG|%LJyh+}}+>88sW1cAY;OaYNQWY%o6=IFg z^|W@)BH!zC&7|-3;irZ7+b=kepFu5L)`ZByPU{AE3l=mIYz^}D6l|q-di2$wFn6k- G|9=2}R?)2h literal 94790 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 z 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 Date: Mon, 21 Nov 2016 12:14:47 -0500 Subject: [PATCH 13/24] Share visited array --- Source/Scene/Cesium3DTileBatchTable.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Source/Scene/Cesium3DTileBatchTable.js b/Source/Scene/Cesium3DTileBatchTable.js index 74da679a3253..b817fe66217b 100644 --- a/Source/Scene/Cesium3DTileBatchTable.js +++ b/Source/Scene/Cesium3DTileBatchTable.js @@ -189,17 +189,13 @@ define([ ++classCounts[classId]; } - // Marks visited instances when traversing over the batch table hierarchy - var visited = new Uint32Array(instancesLength); - var hierarchy = { classes : classes, classIds : classIds, classIndexes : classIndexes, parentCounts : parentCounts, parentIndexes : parentIndexes, - parentIds : parentIds, - visited : visited + parentIds : parentIds }; //>>includeStart('debug', pragmas.debug); @@ -474,16 +470,20 @@ define([ } var scratchStack = []; + var scratchVisited = []; var marker = 0; function traverseHierarchyTree(hierarchy, instanceIndex, endConditionCallback) { + var classIds = hierarchy.classIds; var parentCounts = hierarchy.parentCounts; var parentIds = hierarchy.parentIds; var parentIndexes = hierarchy.parentIndexes; + var instancesLength = classIds.length; // Ignore instances that have already been visited. This occurs in diamond inheritance situations. // Use a marker value to indicate that an instance has been visited, which increments with each run. // This is more efficient than clearing the visited array every time. - var visited = hierarchy.visited; + var visited = scratchVisited; + visited.length = Math.max(visited.length, instancesLength); var visitedMarker = ++marker; var stack = scratchStack; From 425a0e650c1d624d42160a9b12878df968ba09e4 Mon Sep 17 00:00:00 2001 From: Sean Lilley Date: Mon, 21 Nov 2016 14:08:54 -0500 Subject: [PATCH 14/24] Refactored validateHierarchy --- Source/Scene/Cesium3DTileBatchTable.js | 50 ++++++++++++------ .../BatchTableHierarchyBinary/tile.b3dm | Bin 95026 -> 95026 bytes 2 files changed, 35 insertions(+), 15 deletions(-) diff --git a/Source/Scene/Cesium3DTileBatchTable.js b/Source/Scene/Cesium3DTileBatchTable.js index b817fe66217b..bd03c911ed8a 100644 --- a/Source/Scene/Cesium3DTileBatchTable.js +++ b/Source/Scene/Cesium3DTileBatchTable.js @@ -206,22 +206,42 @@ define([ } function validateHierarchy(hierarchy) { - // Check for circular dependencies + var stack = scratchStack; + stack.length = 0; + var classIds = hierarchy.classIds; var instancesLength = classIds.length; - var validateInstance = function(hierarchy, instanceIndex, stack) { - if (instanceIndex >= instancesLength) { - throw new DeveloperError('Parent index ' + instanceIndex + ' exceeds the total number of instances: ' + instancesLength); - } - if (stack.indexOf(instanceIndex) >= 0) { - throw new DeveloperError('Circular dependency detected in the batch table hierarchy.'); - } - }; - for (var i = 0; i < instancesLength; ++i) { - traverseHierarchyTree(hierarchy, i, validateInstance); + validateInstance(hierarchy, i, stack); + } + } + + function validateInstance(hierarchy, instanceIndex, stack) { + var parentCounts = hierarchy.parentCounts; + var parentIds = hierarchy.parentIds; + var parentIndexes = hierarchy.parentIndexes; + var classIds = hierarchy.classIds; + var instancesLength = classIds.length; + + if (instanceIndex >= instancesLength) { + throw new DeveloperError('Parent index ' + instanceIndex + ' exceeds the total number of instances: ' + instancesLength); + } + if (stack.indexOf(instanceIndex) > -1) { + throw new DeveloperError('Circular dependency detected in the batch table hierarchy.'); + } + + stack.push(instanceIndex); + var parentCount = defined(parentCounts) ? parentCounts[instanceIndex] : 1; + var parentIndex = defined(parentCounts) ? parentIndexes[instanceIndex] : instanceIndex; + for (var i = 0; i < parentCount; ++i) { + var parentId = parentIds[parentIndex + i]; + // Stop the traversal when the instance has no parent (its parentId equals itself), else continue the traversal. + if (parentId !== instanceIndex) { + validateInstance(hierarchy, parentId, stack); + } } + stack.pop(instanceIndex); } Cesium3DTileBatchTable.getBinaryProperties = function(featuresLength, json, binary) { @@ -472,7 +492,7 @@ define([ var scratchStack = []; var scratchVisited = []; var marker = 0; - function traverseHierarchyTree(hierarchy, instanceIndex, endConditionCallback) { + function traverseHierarchyMultipleParents(hierarchy, instanceIndex, endConditionCallback) { var classIds = hierarchy.classIds; var parentCounts = hierarchy.parentCounts; var parentIds = hierarchy.parentIds; @@ -515,7 +535,7 @@ define([ } } - function traverseHierarchyLinear(hierarchy, instanceIndex, endConditionCallback) { + function traverseHierarchySingleParent(hierarchy, instanceIndex, endConditionCallback) { while (true) { var result = endConditionCallback(hierarchy, instanceIndex); if (defined(result)) { @@ -536,9 +556,9 @@ define([ // When the endConditionCallback returns a value, the traversal stops and that value is returned. var parentCounts = hierarchy.parentCounts; if (defined(parentCounts)) { - return traverseHierarchyTree(hierarchy, instanceIndex, endConditionCallback); + return traverseHierarchyMultipleParents(hierarchy, instanceIndex, endConditionCallback); } else { - return traverseHierarchyLinear(hierarchy, instanceIndex, endConditionCallback); + return traverseHierarchySingleParent(hierarchy, instanceIndex, endConditionCallback); } } diff --git a/Specs/Data/Cesium3DTiles/Hierarchy/BatchTableHierarchyBinary/tile.b3dm b/Specs/Data/Cesium3DTiles/Hierarchy/BatchTableHierarchyBinary/tile.b3dm index 4786afac9d1500402626e03c27bb6442fed13dc7..0943b189d9d98bc6ae1423cd9c880a44676b3a9d 100644 GIT binary patch delta 23 dcmdn=jCIp9)(t8gEDS) Date: Mon, 21 Nov 2016 14:32:39 -0500 Subject: [PATCH 15/24] Added Sandcastle image --- Apps/Sandcastle/gallery/3D Tiles Hierarchy.jpg | Bin 0 -> 15007 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 Apps/Sandcastle/gallery/3D Tiles Hierarchy.jpg diff --git a/Apps/Sandcastle/gallery/3D Tiles Hierarchy.jpg b/Apps/Sandcastle/gallery/3D Tiles Hierarchy.jpg new file mode 100644 index 0000000000000000000000000000000000000000..22d9d9be59b9610aaeec8d71cd4820eeefef5789 GIT binary patch literal 15007 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 Date: Tue, 22 Nov 2016 11:26:43 -0500 Subject: [PATCH 16/24] Added back styling tests --- .../Hierarchy/BatchTableHierarchy/tile.b3dm | Bin 94434 -> 94438 bytes .../BatchTableHierarchyBinary/tile.b3dm | Bin 95026 -> 95030 bytes .../tile.b3dm | Bin 94770 -> 94774 bytes Specs/Scene/Cesium3DTileBatchTableSpec.js | 6 +++--- 4 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Specs/Data/Cesium3DTiles/Hierarchy/BatchTableHierarchy/tile.b3dm b/Specs/Data/Cesium3DTiles/Hierarchy/BatchTableHierarchy/tile.b3dm index 6dfd5056a370c4bb977e132f42dc45313bbf5bc9..77156b3dccb6baf4d596ef1ad6ae1dec3344751c 100644 GIT binary patch delta 24858 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%0AybSR+4mMJ$?_C7B-O#r76Wlm)d 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 QUXSbZwVU7eUpMafe`K#2CIA2c diff --git a/Specs/Data/Cesium3DTiles/Hierarchy/BatchTableHierarchyBinary/tile.b3dm b/Specs/Data/Cesium3DTiles/Hierarchy/BatchTableHierarchyBinary/tile.b3dm index 0943b189d9d98bc6ae1423cd9c880a44676b3a9d..eb06f1087456fbf432d97312b0b7089ceaea6df9 100644 GIT binary patch delta 24858 zcmZ|XeYBocc_#2EP)SI#ELf|=4v2x^5?M(g;bTT}I8JmbFl~|6mg*V=BVXcznL<0$ zF?(T$84X>20YOYzgS7+*LdAfJ*q*$BQ2DGf)e-58)R_cy5piZ=_y{nwfBSi_hv&TD zA6Z_{ey;nvulwHn-k$foN58sbudnUcYwqbseCWJa&6zW2J z{TJnk6^E}pdfCe5$1FQ~=`l->UVhlymrtxLJ>sypFFSns(v?RoTfX9`WlL8aal|o4 z9I@u@%T|2gu!GL~;GZ0H>>nOE5pvke7M2}(_|eB4wQ}jwWk(%x%!;MUj#=@6j~#Z< z2hZ4i%G}YO^A2Be*wXIb<~J_bAvumH zOh+ty!9AU3))@_-p^d*=7PbBR*}qxdi^3912B%%HU{!u**|Mou{fEwk_3wSYRnv+& z@1{k4l{ehl8FD_d&RqE4Eo0XXk!m6e|M#amQ32on?xKGGj@;`_{T_#-vT#%;K?;!A zelv=19p^J|ebaQ&M!~=G&)?LaWG`}(6QI2jWiFyHL%M=PC)4!ANgY;w*5wMnnkZ9R zB!D}jMkP*-Uz{4h7|nDrnz3Xw;~LEv&G_MDnsn>oca-jgbCeSvQd(*((^3hTvrQ7i zxaxXrw*6O;3UX8b2;HebHZP^y-Oh0y2LO(L(yb3 z;|*uL3sPoUuu+WbTt3!wLE#HdCvwvfrIYOwi-T`_@A&k=%{2V@9~|6@sqf45r6+a| z+PQk|OQdW5^5AwKm<+)VkwZD;d|>Xuty_}5`PChEx}(X!x}A#~$2P7#q|2qtoo1Pu zvKIohG)`5VWU%WM2X@)0fT665b-gBmaf>0Er*2w2?S@t4*Bh%y&Z*r~>`1x79%b->fnaH`SLle9~Mv{d5ky@2e!>B!!@sIvE2mpFXgiY9Xk za~R=HzjP1Wc_Dx(Ovv>LJKIQuiC52SRU-ZB`c6nv zB<+%P=Nmgr^iMAC5`3bXlmO>r^?F^hwM$0x-9MV!H1Xf?7hU2QZCzY@aB0arApPm1 z^V+DW;0HT9Ls@qKB{=V!U1Ekdp57U#KNzglXmJ*Ys%NH8J6@TXUH zqFHA&e2HP(=S(!wstG3665lfXuER|)Qx$t9}3B^Pcb{EjZ zcNb*)+y%AZ(%Kc0%0g0^1lq-%#P%D;w~ph|Qh->ORt|F3B@Um_Xfk)%$#wp7h&a*~ zBto!Y*DGvNvMyQpOz03!jGB}fH61bPV8&>hj#5QA&0KPtd5vi2ba6j^I2kA1%E&R4 z6CO@Fij$7gXU;Yii9KiwQ6#N49)g+p>F;-AllAO&)e>(5yP8 zoyI-h)g?gkLgEB46j4Sq->?%N)0t_pMlq&y`B={dMN{me-KDEOHyu$z*+0SAKl|$= zxawh_idEyipLSu@`cxc_-xWAF4y9PwVeL7k3i%OQyCn4^H0*RoR02P8TepvYRzJ&2 zrp*!61^gtouHqzvjUf)~u2Dd{|MNny`Ah@QJOIzM7* zrYjPsbGD!sS(+mcNesJq1jn@m)?GrnB|$h6C?F{KiK(*D4b+)x&^0Ou2_5@=d3g8^J0oTuhb8Wl1c0XV=D83F_j76IwrI|qA*b( zTC;uk)K9kfD)zyaW;k-`G!7F*1rnqJiDBzRktFj`TQCzo%M;DI#NkUEP3ClkCafzA z;lNd=G}j*dvViFLMN5_dCSV<6&ZNYs>4;GWEk;d8jAotD@H-Qw6XhqunYkkAv-0`6$)4>m(y13yVE;@ZGc-0x-=r!qd{QCLt zrH3w=7cmhmSrUXFP7KAg_3(qk8Jcc7W$bz=It(V7#7U4UBWnFE=P#OGbkdR2sti^= zj6cLUx`JPZ40#pFa1t9sC6%RuVKP|zw|{k?c36T{52q8s zI-x7!2ZwKch%3MJ3DVM#(%u9lSwtm^pFxSBe4u8&^ z1E>A_-1|Rz{G2)SD?ZZm7<-0?9PbC5(mza+5j$b-33{F6T zui5w#=bA%09L}Vu=kS9kImu;xei2YbLlWFx)b+_W3iL1h;NdzfJ~~4j{!qVo@Gr@R zSiphDUwFXo(c)*%8u@+jcQ!xQuphC1{i^3iA9>=;5xnmC=SF*f;mpQ4es#z9J(XV=@WY)_`!emk>*qa z=Gt$!YrFpHQy=LQ;4mEy6R^%P$Ea4r3Q#c)Oh+vIFMe1$(Y)X^0TRRZ&!?7%!bt|F zTQI&VeeQp8pU#B!-+SotLNyVE-}~B56#xA9KhtmD zRlj(;-{Wu;7LLN`>sH}TV*3pX@B-;aUw*o^QSeire7Zl$S(i9`MkC5xG+~Bx1&2Cg{7UD|{3$P395z{Jh9Ljq#dq{OK4i&5hjqnQpyGnR~IT%);bpVB$a_#tJSv@0XW zP)>L_X(>)xDgkr0Nn%)6XyWLK=@84r_2rB;?NsMQ_CBK}n5Z^7Tq=W;AnVNKtXy9; z>EQ44hE5;0E-{SHP>Cp~nQzz$kL%2|U^f>bTb9emdM+rUV$+G-bTsK?`@~jGX)ZqZ zAMYAn`sn4&HN5o1D_S)xcilPq$%i|<=L2_+F52UYo-^~!%bSVMAG@u^GIY>k+h%cA z@4TXQ>yabw8vV`g4*&es+j`BFyULxTor~8u(nEuAR*l}EO<0vO7=*oXgUTd#k@wy`1iKhYCzTt9Nfs`84{J3|sPXJ0S+jXQhM znSa>Ysv(-LNSw~uf>a47F?{CYyIX8b*S|kl-?rf7ci%nIF0Mn8Km{>DG~H5tjH*}x zjM9O{{d@n8K^7t83TWmmRh6!7q=SGLnG z@yTaj*%xL#g>70^u57Mj!Z<|~CVJD8U4S-T_N9)m;xp%czKMpTvT(8m45a{xQy5L0 zgG#O7&F}qubIQd0i#kyzto!|)P6*Imm?(3)LKM~&hHzjyV&NZb=rpsQvw~mz+RY0s z;?AhVsqu?b2Q5ZTM~r4&vhZVqCUen*9qM$nPF(3*>V&7IA#rLfwOzX;NJ}No-s5NQ zO@{)+{=+R>`@PS)y$}DpHLtc0xMzH@mlw4!-}s z);XH5ec|5jz%Jg=^l@IZdHZPdpLV%u{@dg4FHKaycmA$R9H*^~<76<-yjAzMPN?9w z7k7rT?f^=#=mc)Xhkyg^TlOHORN<{*ZuhZW=QbyZ+oCs znXWLA)|r}A2`4cu_NqtjX-0out7qD}Zr%KidwPAG_V+&_F#&5GcbsZ9tO6C|z=Tu` z|M+vAXx14GUt-wyITO)@Y4$ z&)(ywqcj$>MR z^_=6&>Kj|@ZauvVc8H!ld%-Ny9s6!-?b>h0g01h|v%{ZQyPy}9V82IhXq<=Nv2g3N zCw9qhKX73)MDy`8Iukk?qYAEn|J^0?aLECkD17L?T?K-(-bQrwfO@@83DUbt0xEu>QV( zoWE7KBnXFT1;hl+bnD5p%YxpiidDcVAz1JQ_jH(O*3%&ziESV3eCVj^;Ut68EjZo! zOsQ9_fEV}a0yzD>2d{6UDp+#u_3gAveDnJ2`^v1RGJK|E!e~Vkrup92c6?nt@BJNL z!R4x7T-QWHQdvkUQ-K7jK;l$J6i2cjefhd(l!>Q4*=c5-Q9AgHMzfl$fB#bt5m8RH zg&`!EkYM=G4|Sqh&so7|!nzJIXHsI+bi}B07Ne%)sZW+pG%qAeKui#2E~2ngot7H8 zwA2YtN5f$>97gG_y*C~z5d8Y<7WR9ebwZh3mIn8^iG}`jE43;U6w4r%&a<@AeZwC;>w( zvGte;mTZzAP7KAg_3(F<@k2;M*TclYvx3K+Na7?Ib|ofmKj7KX=kELHNRh$5*eD(Z zcnC()l>`KbV||DxMTh)!H~i!pbIL475kiWINla)m!O&>pYM7Z z_Kn!?HTCB|BoC9Mi|)C(58iOw^{rwYn7Qy1i|^Ys>xpGz5)V0Nlo~KeitAJ$K{$ek z>%YvzBtIsG=HN1!%ptmG&EJjQ{pk8uWw5pjus*~(fs?KT;|ybi!yoIEJ~*PoRwr3R zhr!u`7-cRdf@30@L!FLOy1g_)dwpSB+i&<6|Ng#NxQ^c;;nWdrI2@xJyy3QI8kRVi z(P+{Mzu__n_97;NC7Ts6;KWcaC9&ZLhch%iG*R-9fF#aklFCxSFd6*rM|X^l`og!{ zSqWA>EOv->LRZ4CxU`3mycl8uL(v4|q`l!MSvbSkV4RrfaQ*&wD3stN7&vX!2;Sp? zd0R71yT7&IW!Q*@)5djz(@$JoUsK+5WviIbnu;ZeXo7P=Sx>M8leqHh-wSmdc#;#- zLvtmh1Ry2x5XZzMKPHmcnMeU}lEI5kn!ok-18!(Vj&bR$_d?qR4@v2Y02n7iL#%U? z>*3QJ;^bO%Qt3p8!P$bCNO0C8G-=5CkOR+|^Yc;tGI})r`+%);=A2)j+jq?se|t2i zw1*+7F3ut)V3LDJXviOO=64BtPWZ$1`CIGv|4A?uf?qk{B|ags?fd?5viA1@&8af^tLZHlAqh(`Y*4UxqRtgPr*c2J#}LfU3SaWErIndfB#oA_y6pcw$9Mq zd)?AB@sB@XbJL7bKZYk)`~45nlIO3V@Qe zq8at8)vta3s#YaK%t@?znr~gVxoL{sf;^ ztn1d-f4s3zfWve+Ou#zF9HTnjzW-H$ijiPKg5m#iLMNJaM#GmFwtYURL=;XkINgHr z73nvtkIZ~#=8sEt;l*j&|Gcl}oRin}RX%>sC;Q5>&RqC0&4kLDXsfKAo4qb>n)uJ( zeM!H4uiLz~-{KOI%0g0^1lq-%#P+*YQ$?-gY~OHUYopkYA9q22kh3l^{T$e6GCI~Q z%{52bq8dUOr+Jrrq+!#Mb;-hKLWl5U)TG3y@rzO87o(Yu?HkI4{akXId5vhCX8dq6 zPP&zmW2isjV@^7XlaA77&NeahvohX$qDb0eJOndw%h9*BQ=RqfeMU=5i8AVNsVwI} zf~+%_vqF;&e)-AYcL_XrAu%j~p@?#w`G%eFn9fX#HHtBv%g1^yD4Jr&ohU6J`$s7I zCm2b9_x1K##Wh?nlvS$nzVaGYZM{%>PQ7MVIXBnT$q);h`5|Z1+sYSLX_2HgdBexm z(;ZO>s@t}1A8QpYnKnmM7w}`wx{8wwc2VKL?ivL!w4{t*2zI?DfpLo=71wQ8<%(5h z-G*jJV&+;W>UKrc`4LMqU6DAQ)6o>!{{J76*b7&u;JB8+x?8dCZF3!t1S*ROqUo0E zV^qZoV3ZClw%)F#J!nN z!nr!Cqt;jEMJf}(bxb%b5rv7?JE8G)@u9mfX?zveJE7a-F-KwHWD8C!H9;znIF%7a zlB`~*Z9AB#w_p>^x?kVv1U{oM)6D4#O;}eL!hz|CEgtGM+eGsshed#2yII#E=1fYA znvNKC&|=hd#Awzf3qK~RW@+vs%BfSGmKwRV^w4_3)6#Gl4M(>mP(7m(XYcW|_ohPu zVsAOR{_k(I_jzIO6ToRinNyj=2qyu|oOOJ+A56#X3OnFgmpJ?vN_8F4xHdL06B)nE zbm#iEeiU(XvE+hEC&bdReMT3~MF%Ua2o~Vhs>Ch!$wdOI#`{Wa*wtC9ZXDMuj>^Q= z!`U!SJ)DgrDUJ@gQ)=>tY1V^EvrN6Fx|9HEeZ5|56)hRj+L~Vfha#eIlEGZp3#D=JRXP4Cwwb^&VkyRmrAiZ)!m`d><(Iy)m{5(mO=a$a?4P?J z`{ypm9*3i{aCDR*-C|DS6o7C2#c!4NQ*28n*sYb5>^93uPJs4Cl+lR74Cx9E9axoa zSJ)xDgkr0i6K~5h~nsq=@83Az4==8Ss(8`erfFzoIAidP+87_1h94Ha>9ucvR<#* z{)AhXIDCep$*2P!)33Rubn}hmgvYf}jO$!JL~}vmn~roMH(lGZs*~*#i-T`_>*Y1W zG+ghKnfCwxhERz!D&wqPC_Tw93mhDWQZVdL4mmaXj1Ea!i)h&Cjwb#3-vw>mHr66q zE?q7WwRZyI&bo?|3^s;1u+dWiLs=JVJd?n<#gK~YHq4BFh}}}RfuZ8R<(fOy+uw-V z3c*Cv6^YY2Elrhh62mSYu`#WB>n`;VsebIVRjdLWLNIf#SD0wl z(;@2;+dkO&h$eho87K3QcEM@a_@~${b<|ogqjg%Es0!*xwJIg9qt;huow@LtjtOUl z37W+NQoR&ffHu}Uq3cB5Lt};nYg%q#HU%; zOMAg7ApzL}qRi zj8lw8l(~q)4mA$GkxNG%@N~3s%DAN=aVkMtDslE+K=$5rs6dr2s_cE%B@SP=qRE`X z97eb#fd}rq5I__rTr4xb)X|>tS z{+VxBWn%H`7Z)@2o31HeHo*1Ety#D}Zw#mMDlW4~s}gYQA6(k7FBpRTK0l&kp~e~F zapF}26AgFCo|wgNoHBMg2xt`~!1@>u*Jl_VCJr9(XPLl%rLGhKUR=KWvonvJ^_Nqs z3|2iXc!+UyCH&xUtPk;|=73-N_9h_7LK+4KoNkG;IoMv=rE}Q{>mgz|o z;g>-`Urk*b;#tXZ$0wOdFNPC9~5<5%~bNE9X z&PzJ=?|+5~g0p`Ks2wp*TT~B!@3EVDT*bE3e}{xqc?}OZGr{y=rW-ExK{CMuAtM*j zKDct+0ZH8OIN2=zfHTXq_3(r3eF2v){5~% zBWX(lf)ikUh;?o#I^?(Zj$0l5v_1Nl?=G|5seovLhjxP`4AyGNtPinH;ONj0;|ybi!--B8TV}U+m>@#K1Thyw*^Y3m zXUk%4QYRd-_51%hbLt-lEUEvFuitcUssHL94fuk&;ra~E;?(!EIQ97zIa|g$1O6_NHGfNnlz{ePybjlQJ!gpPyS9!q#Nk-4_?nH~`&Q5)V;oLF$io=-0iFd$~|Pt~A7;vVBAS;a5wiuW~kR#!G}xai8~|3A_wz2yJ^ delta 24850 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 Q*W>zp-ImW@xM}DA1Db{vz5oCK diff --git a/Specs/Data/Cesium3DTiles/Hierarchy/BatchTableHierarchyMultipleParents/tile.b3dm b/Specs/Data/Cesium3DTiles/Hierarchy/BatchTableHierarchyMultipleParents/tile.b3dm index 553c5d77a341679c3990760f24aa6cfda71dbdad..56b174d069ee6ed79b0f891472c61a84b74f3e98 100644 GIT binary patch delta 24858 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 S`^xKaeZGF{=QeKM_5T2qNfosK diff --git a/Specs/Scene/Cesium3DTileBatchTableSpec.js b/Specs/Scene/Cesium3DTileBatchTableSpec.js index 36bdb85bd5c5..e26a66e6aec2 100644 --- a/Specs/Scene/Cesium3DTileBatchTableSpec.js +++ b/Specs/Scene/Cesium3DTileBatchTableSpec.js @@ -53,7 +53,7 @@ defineSuite([ // One feature is located at the center, point the camera there var center = Cartesian3.fromRadians(centerLongitude, centerLatitude); - scene.camera.lookAt(center, new HeadingPitchRange(0.0, -1.57, 15.0)); + scene.camera.lookAt(center, new HeadingPitchRange(0.0, -1.57, 20.0)); }); afterAll(function() { @@ -572,7 +572,7 @@ defineSuite([ Cesium3DTilesTester.expectRenderTileset(scene, tileset); // Reset maximum texture size - ContextLimits._maximumVertexTextureImageUnits = maximumTextureSize; + ContextLimits._maximumTextureSize = maximumTextureSize; }); }); @@ -806,7 +806,7 @@ defineSuite([ function checkBatchTableHierarchy(url, multipleParents) { return Cesium3DTilesTester.loadTileset(scene, url).then(function(tileset) { - //checkHierarchyStyling(tileset); + checkHierarchyStyling(tileset); checkHierarchyProperties(tileset, multipleParents); }); } From c0852de845749b929da2f6199abde4ef60a85f4c Mon Sep 17 00:00:00 2001 From: Sean Lilley Date: Tue, 22 Nov 2016 12:26:38 -0500 Subject: [PATCH 17/24] Fixes --- Source/Scene/Cesium3DTileBatchTable.js | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/Source/Scene/Cesium3DTileBatchTable.js b/Source/Scene/Cesium3DTileBatchTable.js index c6f5fa8a2f8a..d4783943f851 100644 --- a/Source/Scene/Cesium3DTileBatchTable.js +++ b/Source/Scene/Cesium3DTileBatchTable.js @@ -205,6 +205,7 @@ define([ return hierarchy; } + //>>includeStart('debug', pragmas.debug); function validateHierarchy(hierarchy) { var stack = scratchStack; stack.length = 0; @@ -243,6 +244,7 @@ define([ } stack.pop(instanceIndex); } + //>>includeEnd('debug'); Cesium3DTileBatchTable.getBinaryProperties = function(featuresLength, json, binary) { var binaryProperties; @@ -474,9 +476,8 @@ define([ var componentCount = binaryProperty.componentCount; if (componentCount === 1) { return typedArray[index]; - } else { - return binaryProperty.type.unpack(typedArray, index * componentCount); } + return binaryProperty.type.unpack(typedArray, index * componentCount); } function setBinaryProperty(binaryProperty, index, value) { @@ -517,7 +518,7 @@ define([ continue; } visited[instanceIndex] = visitedMarker; - var result = endConditionCallback(hierarchy, instanceIndex, stack); + var result = endConditionCallback(hierarchy, instanceIndex); if (defined(result)) { // The end condition was met, stop the traversal and return the result return result; @@ -557,9 +558,8 @@ define([ var parentCounts = hierarchy.parentCounts; if (defined(parentCounts)) { return traverseHierarchyMultipleParents(hierarchy, instanceIndex, endConditionCallback); - } else { - return traverseHierarchySingleParent(hierarchy, instanceIndex, endConditionCallback); } + return traverseHierarchySingleParent(hierarchy, instanceIndex, endConditionCallback); } function hasPropertyInHierarchy(batchTable, batchId, name) { @@ -597,9 +597,8 @@ define([ if (defined(propertyValues)) { if (defined(propertyValues.typedArray)) { return getBinaryProperty(propertyValues, indexInClass); - } else { - return clone(propertyValues[indexInClass], true); } + return clone(propertyValues[indexInClass], true); } }); } @@ -639,6 +638,8 @@ define([ if (!defined(hierarchy)) { return false; } + + // PERFORMANCE_IDEA : treat class names as integers for faster comparisons var result = traverseHierarchy(hierarchy, batchId, function(hierarchy, instanceIndex) { var classId = hierarchy.classIds[instanceIndex]; var instanceClass = hierarchy.classes[classId]; From 77419bb5f33f404962240b5d45f02d478a617774 Mon Sep 17 00:00:00 2001 From: Sean Lilley Date: Tue, 22 Nov 2016 13:26:02 -0500 Subject: [PATCH 18/24] Remove unneeded check --- Source/Scene/Cesium3DTileBatchTable.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/Scene/Cesium3DTileBatchTable.js b/Source/Scene/Cesium3DTileBatchTable.js index d4783943f851..273c99ab63d9 100644 --- a/Source/Scene/Cesium3DTileBatchTable.js +++ b/Source/Scene/Cesium3DTileBatchTable.js @@ -523,8 +523,8 @@ define([ // The end condition was met, stop the traversal and return the result return result; } - var parentCount = defined(parentCounts) ? parentCounts[instanceIndex] : 1; - var parentIndex = defined(parentCounts) ? parentIndexes[instanceIndex] : instanceIndex; + var parentCount = parentCounts[instanceIndex]; + var parentIndex = parentIndexes[instanceIndex]; for (var i = 0; i < parentCount; ++i) { var parentId = parentIds[parentIndex + i]; // Stop the traversal when the instance has no parent (its parentId equals itself) From ecf3a875d3681bc031bad7e84c2c027ec0110e14 Mon Sep 17 00:00:00 2001 From: Sean Lilley Date: Tue, 22 Nov 2016 15:11:32 -0500 Subject: [PATCH 19/24] Add more tests --- Specs/Scene/Cesium3DTileBatchTableSpec.js | 81 +++++++++++++++++++++++ 1 file changed, 81 insertions(+) diff --git a/Specs/Scene/Cesium3DTileBatchTableSpec.js b/Specs/Scene/Cesium3DTileBatchTableSpec.js index e26a66e6aec2..6c41cb5d2970 100644 --- a/Specs/Scene/Cesium3DTileBatchTableSpec.js +++ b/Specs/Scene/Cesium3DTileBatchTableSpec.js @@ -860,7 +860,55 @@ defineSuite([ expect(batchTable.getPropertyNames(0).sort()).toEqual(['building_name', 'door_name', 'window_name']); }); + it('validates hierarchy with multiple parents (2)', function() { + // zone + // / | \ + // building0 | \ + // / \ | \ + // door0 door1 / + // \ | / + // window0 + var batchTableJson = { + HIERARCHY : { + instancesLength : 4, + classIds : [0, 1, 1, 2, 3], + parentCounts : [3, 1, 2, 1, 0], + parentIds : [1, 2, 4, 3, 3, 4, 4], + classes : [{ + name : 'window', + length : 1, + instances : { + window_name : ['window0'] + } + }, { + name : 'door', + length : 2, + instances : { + door_name : ['door0', 'door1'] + } + }, { + name : 'building', + length : 1, + instances : { + building_name : ['building0'] + } + }, { + name : 'zone', + length : 1, + instances : { + zone_name : ['zone0'] + } + }] + } + }; + var batchTable = new Cesium3DTileBatchTable(mockContent, 5, batchTableJson); + expect(batchTable.getPropertyNames(0).sort()).toEqual(['building_name', 'door_name', 'window_name', 'zone_name']); // check window + expect(batchTable.hasProperty(1, 'zone_name')).toEqual(true); // check door0 + expect(batchTable.hasProperty(2, 'zone_name')).toEqual(true); // check door1 + }); + it('throws if hierarchy has a circular dependency', function() { + // window0 -> door0 -> building0 -> window0 var batchTableJson = { HIERARCHY : { instancesLength : 3, @@ -892,6 +940,39 @@ defineSuite([ }).toThrowDeveloperError(); }); + it('throws if hierarchy has a circular dependency (2)', function() { + // window0 -> door0 -> building0 -> window1 -> door0 + var batchTableJson = { + HIERARCHY : { + instancesLength : 4, + classIds : [0, 1, 2, 0], + parentIds : [1, 2, 3, 1], + classes : [{ + name : 'window', + length : 2, + instances : { + window_name : ['window0', 'window1'] + } + }, { + name : 'door', + length : 1, + instances : { + door_name : ['door0'] + } + }, { + name : 'building', + length : 1, + instances : { + building_name : ['building0'] + } + }] + } + }; + expect(function() { + return new Cesium3DTileBatchTable(mockContent, 4, batchTableJson); + }).toThrowDeveloperError(); + }); + it('throws if an instance\'s parentId exceeds instancesLength', function() { var batchTableJson = { HIERARCHY : { From e4622c7b069859e68399e2518641986126146fae Mon Sep 17 00:00:00 2001 From: Sean Lilley Date: Tue, 22 Nov 2016 15:29:07 -0500 Subject: [PATCH 20/24] Update Sandcastle --- .../gallery/3D Tiles Hierarchy.html | 47 +++++-------------- 1 file changed, 11 insertions(+), 36 deletions(-) diff --git a/Apps/Sandcastle/gallery/3D Tiles Hierarchy.html b/Apps/Sandcastle/gallery/3D Tiles Hierarchy.html index c38ce003e46d..b02b7bcbb18b 100644 --- a/Apps/Sandcastle/gallery/3D Tiles Hierarchy.html +++ b/Apps/Sandcastle/gallery/3D Tiles Hierarchy.html @@ -36,8 +36,7 @@ var scene = viewer.scene; var tilesetUrl = '../../../Specs/Data/Cesium3DTiles/Hierarchy/BatchTableHierarchyMultipleParents'; var tileset = scene.primitives.add(new Cesium.Cesium3DTileset({ - url : tilesetUrl, - debugShowStatistics : true + url : tilesetUrl })); tileset.readyPromise.then(function(tileset) { @@ -205,6 +204,7 @@ } }, Cesium.ScreenSpaceEventType.MOUSE_MOVE); +// When a feature is left clicked, print it's class name and properties handler.setInputAction(function(movement) { if (!pickingEnabled) { return; @@ -212,16 +212,19 @@ var feature = current.feature; if (Cesium.defined(feature)) { - if (feature.getProperty('clicked')) { - console.log('already clicked'); - } else { - // TODO : Do something interesting here - feature.setProperty('clicked', true); + console.log('Class: ' + feature.getClassName()); + console.log('Properties:'); + var propertyNames = feature.getPropertyNames(); + var length = propertyNames.length; + for (var i = 0; i < length; ++i) { + var name = propertyNames[i]; + var value = feature.getProperty(name); + console.log(' ' + name + ': ' + value); } } }, Cesium.ScreenSpaceEventType.LEFT_CLICK); -//When a feature is double middle clicked, hide it +// When a feature is double middle clicked, hide it handler.setInputAction(function(movement) { if (!pickingEnabled) { return; @@ -232,34 +235,6 @@ } }, Cesium.ScreenSpaceEventType.MIDDLE_DOUBLE_CLICK); -/////////////////////////////////////////////////////////////////////////////// - -Sandcastle.addToolbarButton('Stats on/off', function() { - tileset.debugShowStatistics = !tileset.debugShowStatistics; -}); - -Sandcastle.addToolbarButton('Pick stats on/off', function() { - tileset.debugShowPickStatistics = !tileset.debugShowPickStatistics; -}); - -Sandcastle.addToolbarButton('Freeze on/off', function() { - tileset.debugFreezeFrame = !tileset.debugFreezeFrame; -}); - -Sandcastle.addToolbarButton('Colorize on/off', function() { - tileset.debugColorizeTiles = !tileset.debugColorizeTiles; -}); - -Sandcastle.addToolbarButton('BV on/off', function() { - tileset.debugShowBoundingVolume = !tileset.debugShowBoundingVolume; -}); - -Sandcastle.addToolbarButton('Contents BV on/off', function() { - tileset.debugShowContentBoundingVolume = !tileset.debugShowContentBoundingVolume; -}); - -/////////////////////////////////////////////////////////////////////////////// - //Sandcastle_End Sandcastle.finishedLoading(); } From 1d759ca6c298980080905de8c69a746eeb4aa98a Mon Sep 17 00:00:00 2001 From: Sean Lilley Date: Mon, 12 Dec 2016 15:50:11 -0500 Subject: [PATCH 21/24] Code and Sandcastle updates --- ...ml => 3D Tiles Batch Table Hierarchy.html} | 77 +++++++++++++++--- ...jpg => 3D Tiles Batch Table Hierarchy.jpg} | Bin Source/Scene/Cesium3DTileBatchTable.js | 19 ++--- Source/Scene/Cesium3DTileFeature.js | 4 +- Source/Scene/Expression.js | 12 +-- Specs/Scene/Cesium3DTileBatchTableSpec.js | 23 +++--- Specs/Scene/ExpressionSpec.js | 14 ++-- 7 files changed, 98 insertions(+), 51 deletions(-) rename Apps/Sandcastle/gallery/{3D Tiles Hierarchy.html => 3D Tiles Batch Table Hierarchy.html} (81%) rename Apps/Sandcastle/gallery/{3D Tiles Hierarchy.jpg => 3D Tiles Batch Table Hierarchy.jpg} (100%) diff --git a/Apps/Sandcastle/gallery/3D Tiles Hierarchy.html b/Apps/Sandcastle/gallery/3D Tiles Batch Table Hierarchy.html similarity index 81% rename from Apps/Sandcastle/gallery/3D Tiles Hierarchy.html rename to Apps/Sandcastle/gallery/3D Tiles Batch Table Hierarchy.html index b02b7bcbb18b..592c3f1f3615 100644 --- a/Apps/Sandcastle/gallery/3D Tiles Hierarchy.html +++ b/Apps/Sandcastle/gallery/3D Tiles Batch Table Hierarchy.html @@ -29,12 +29,64 @@ 'use strict'; //Sandcastle_Begin +// In this demo doorknobs, doors, roofs, and walls are styled via the batch table hierarchy. +// Since buildings and zones are not backed by geometry they are not styled directly. However +// styles may be written that take building and zone properties into account. +// +// Hierarchy layout (doorknobs are children of doors): +// +// zone0 +// building0 +// roof0 +// wall0 +// door0 - doorknob0 +// door1 - doorknob1 +// door2 - doorknob2 +// door3 - doorknob3 +// building1 +// roof1 +// wall1 +// door4 - doorknob4 +// door5 - doorknob5 +// door6 - doorknob6 +// door7 - doorknob7 +// building2 +// roof2 +// wall2 +// door8 - doorknob8 +// door9 - doorknob9 +// door10 - doorknob10 +// door11 - doorknob11 +// +// Class properties: +// +// zone: +// * zone_building +// * zone_name +// building: +// * building_area +// * building_name +// wall: +// * wall_paint +// * wall_windows +// * wall_name +// roof: +// * roof_paint +// * roof_name +// door: +// * door_mass +// * door_width +// * door_name +// doorknob: +// * doorknob_size +// * doorknob_name + var viewer = new Cesium.Viewer('cesiumContainer', { scene3DOnly : true }); var scene = viewer.scene; -var tilesetUrl = '../../../Specs/Data/Cesium3DTiles/Hierarchy/BatchTableHierarchyMultipleParents'; +var tilesetUrl = '../../../Specs/Data/Cesium3DTiles/Hierarchy/BatchTableHierarchy'; var tileset = scene.primitives.add(new Cesium.Cesium3DTileset({ url : tilesetUrl })); @@ -84,24 +136,25 @@ } }); -addStyle('Style by height', { +addStyle('Color features by class name', { "color" : { + "expression" : "regExp('door(.*)').exec(getExactClassName())", "conditions" : [ - ["${height} >= 10", "color('purple')"], - ["${height} >= 6", "color('red')"], - ["${height} >= 5", "color('orange')"], - ["true", "color('blue')"] + ["${expression} === 'knob'", "color('yellow')"], + ["${expression} === ''", "color('lime')"], + ["${expression} === null", "color('gray')"], + ["true", "color('blue'"] ] } }); -addStyle('Style by classifier', { +addStyle('Style by height', { "color" : { "conditions" : [ - ["isClass('classifier_new') && isClass('classifier_old')", "color('purple')"], - ["isClass('classifier_new')", "color('red')"], - ["isClass('classifier_old')", "color('blue')"], - ["true", "color()"] + ["${height} >= 10", "color('purple')"], + ["${height} >= 6", "color('red')"], + ["${height} >= 5", "color('orange')"], + ["true", "color('blue')"] ] } }); @@ -212,7 +265,7 @@ var feature = current.feature; if (Cesium.defined(feature)) { - console.log('Class: ' + feature.getClassName()); + console.log('Class: ' + feature.getExactClassName()); console.log('Properties:'); var propertyNames = feature.getPropertyNames(); var length = propertyNames.length; diff --git a/Apps/Sandcastle/gallery/3D Tiles Hierarchy.jpg b/Apps/Sandcastle/gallery/3D Tiles Batch Table Hierarchy.jpg similarity index 100% rename from Apps/Sandcastle/gallery/3D Tiles Hierarchy.jpg rename to Apps/Sandcastle/gallery/3D Tiles Batch Table Hierarchy.jpg diff --git a/Source/Scene/Cesium3DTileBatchTable.js b/Source/Scene/Cesium3DTileBatchTable.js index 273c99ab63d9..07cefc3d035d 100644 --- a/Source/Scene/Cesium3DTileBatchTable.js +++ b/Source/Scene/Cesium3DTileBatchTable.js @@ -206,8 +206,9 @@ define([ } //>>includeStart('debug', pragmas.debug); + var scratchValidateStack = []; function validateHierarchy(hierarchy) { - var stack = scratchStack; + var stack = scratchValidateStack; stack.length = 0; var classIds = hierarchy.classIds; @@ -657,10 +658,10 @@ define([ } //>>includeEnd('debug'); - return (this.getClassName(batchId) === className); + return (this.getExactClassName(batchId) === className); }; - Cesium3DTileBatchTable.prototype.getClassName = function(batchId) { + Cesium3DTileBatchTable.prototype.getExactClassName = function(batchId) { var featuresLength = this.featuresLength; //>>includeStart('debug', pragmas.debug); if (!defined(batchId) || (batchId < 0) || (batchId > featuresLength)) { @@ -689,17 +690,7 @@ define([ //>>includeEnd('debug'); var json = this.batchTableJson; - if (defined(json) && defined(json[name])) { - return true; - } - - if (defined(this._batchTableHierarchy)) { - if (hasPropertyInHierarchy(this, batchId, name)) { - return true; - } - } - - return false; + return (defined(json) && defined(json[name])) || (defined(this._batchTableHierarchy) && hasPropertyInHierarchy(this, batchId, name)); }; Cesium3DTileBatchTable.prototype.getPropertyNames = function(batchId) { diff --git a/Source/Scene/Cesium3DTileFeature.js b/Source/Scene/Cesium3DTileFeature.js index 5baf678066ee..c82894b8353a 100644 --- a/Source/Scene/Cesium3DTileFeature.js +++ b/Source/Scene/Cesium3DTileFeature.js @@ -240,8 +240,8 @@ define([ * * @private */ - Cesium3DTileFeature.prototype.getClassName = function() { - return this._batchTable.getClassName(this._batchId); + Cesium3DTileFeature.prototype.getExactClassName = function() { + return this._batchTable.getExactClassName(this._batchId); }; return Cesium3DTileFeature; diff --git a/Source/Scene/Expression.js b/Source/Scene/Expression.js index e710fe62f853..ab38082abf2d 100644 --- a/Source/Scene/Expression.js +++ b/Source/Scene/Expression.js @@ -363,7 +363,7 @@ define([ //>>includeEnd('debug'); val = createRuntimeAst(expression, args[0]); return new Node(ExpressionNodeType.UNARY, call, val); - } else if (call === 'getClassName') { + } else if (call === 'getExactClassName') { //>>includeStart('debug', pragmas.debug); if (args.length > 0) { throw new DeveloperError('Error: ' + call + ' does not take any argument.'); @@ -617,8 +617,8 @@ define([ node.evaluate = node._evaluateIsExactClass; } else if (node._value === 'isClass') { node.evaluate = node._evaluateIsClass; - } else if (node._value === 'getClassName') { - node.evaluate = node._evaluateGetClassName; + } else if (node._value === 'getExactClassName') { + node.evaluate = node._evaluategetExactClassName; } else if (defined(unaryFunctions[node._value])) { node.evaluate = getEvaluateUnaryFunction(node._value); } else if (node._value === 'Boolean') { @@ -971,8 +971,8 @@ define([ return feature.isClass(this._left.evaluate(frameState, feature)); }; - Node.prototype._evaluateGetClassName = function(frameState, feature) { - return feature.getClassName(); + Node.prototype._evaluategetExactClassName = function(frameState, feature) { + return feature.getExactClassName(); }; Node.prototype._evaluateBooleanConversion = function(frameState, feature) { @@ -1202,7 +1202,7 @@ define([ return 'sqrt(' + left + ')'; } //>>includeStart('debug', pragmas.debug); - else if ((value === 'isNaN') || (value === 'isFinite') || (value === 'String') || (value === 'isExactClass') || (value === 'isClass') || (value === 'getClassName')) { + else if ((value === 'isNaN') || (value === 'isFinite') || (value === 'String') || (value === 'isExactClass') || (value === 'isClass') || (value === 'getExactClassName')) { throw new DeveloperError('Error generating style shader: "' + value + '" is not supported.'); } //>>includeEnd('debug'); diff --git a/Specs/Scene/Cesium3DTileBatchTableSpec.js b/Specs/Scene/Cesium3DTileBatchTableSpec.js index 6c41cb5d2970..b09ebe910e3b 100644 --- a/Specs/Scene/Cesium3DTileBatchTableSpec.js +++ b/Specs/Scene/Cesium3DTileBatchTableSpec.js @@ -697,16 +697,16 @@ defineSuite([ }).toThrowDeveloperError(); }); - it('getClassName throws with invalid batchId', function() { + it('getExactClassName throws with invalid batchId', function() { var batchTable = new Cesium3DTileBatchTable(mockContent, 1); expect(function() { - batchTable.getClassName(); + batchTable.getExactClassName(); }).toThrowDeveloperError(); expect(function() { - batchTable.getClassName(1000); + batchTable.getExactClassName(1000); }).toThrowDeveloperError(); expect(function() { - batchTable.getClassName(-1); + batchTable.getExactClassName(-1); }).toThrowDeveloperError(); }); @@ -735,15 +735,15 @@ defineSuite([ tileset.style = new Cesium3DTileStyle({color : "isClass('zone') ? color('red') : color('green')"}); expect(scene.renderForSpecs()[0]).toBeGreaterThan(0); // Expect red - // Check getClassName - tileset.style = new Cesium3DTileStyle({color : "getClassName() === 'roof' ? color('red') : color('green')"}); + // Check getExactClassName + tileset.style = new Cesium3DTileStyle({color : "getExactClassName() === 'roof' ? color('red') : color('green')"}); expect(scene.renderForSpecs()[0]).toBeGreaterThan(0); // Expect red - tileset.style = new Cesium3DTileStyle({color : "getClassName() === 'zone' ? color('red') : color('green')"}); + tileset.style = new Cesium3DTileStyle({color : "getExactClassName() === 'zone' ? color('red') : color('green')"}); expect(scene.renderForSpecs()[1]).toBeGreaterThan(0); // Expect green } function checkHierarchyProperties(tileset, multipleParents) { - // Check isExactClass, isClass, and getClassName in Cesium3DTileFeature + // Check isExactClass, isClass, and getExactClassName in Cesium3DTileFeature var content = tileset._root.content; var batchTable = content.batchTable; var hierarchy = batchTable._batchTableHierarchy; @@ -755,7 +755,7 @@ defineSuite([ expect(doorFeature.isClass('door')).toBe(true); expect(doorFeature.isClass('doorknob')).toBe(false); expect(doorFeature.isClass('building')).toBe(true); - expect(doorFeature.getClassName()).toBe('door'); + expect(doorFeature.getExactClassName()).toBe('door'); expect(doorFeature.hasProperty('door_name')).toBe(true); expect(doorFeature.hasProperty('height')).toBe(true); @@ -794,7 +794,7 @@ defineSuite([ batchTable._batchTableHierarchy = undefined; expect(doorFeature.isExactClass('door')).toBe(false); expect(doorFeature.isClass('door')).toBe(false); - expect(doorFeature.getClassName()).toBeUndefined(); + expect(doorFeature.getExactClassName()).toBeUndefined(); expect(doorFeature.hasProperty('door_name')).toBe(false); expect(doorFeature.hasProperty('height')).toBe(true); expect(doorFeature.getPropertyNames()).toEqual(['height', 'area']); @@ -907,6 +907,8 @@ defineSuite([ expect(batchTable.hasProperty(2, 'zone_name')).toEqual(true); // check door1 }); + //>>includeStart('debug', pragmas.debug); + // Circular dependencies are only caught in debug builds. it('throws if hierarchy has a circular dependency', function() { // window0 -> door0 -> building0 -> window0 var batchTableJson = { @@ -972,6 +974,7 @@ defineSuite([ return new Cesium3DTileBatchTable(mockContent, 4, batchTableJson); }).toThrowDeveloperError(); }); + //>>includeEnd('debug'); it('throws if an instance\'s parentId exceeds instancesLength', function() { var batchTableJson = { diff --git a/Specs/Scene/ExpressionSpec.js b/Specs/Scene/ExpressionSpec.js index bcbb8908a6b6..4e9da5f70935 100644 --- a/Specs/Scene/ExpressionSpec.js +++ b/Specs/Scene/ExpressionSpec.js @@ -48,7 +48,7 @@ defineSuite([ return (this._className === className) || (this._inheritedClassName === className); }; - MockFeature.prototype.getClassName = function() { + MockFeature.prototype.getExactClassName = function() { return this._className; }; @@ -892,16 +892,16 @@ defineSuite([ }).toThrowDeveloperError(); }); - it('evaluates getClassName function', function() { + it('evaluates getExactClassName function', function() { var feature = new MockFeature(); feature.setClass('door'); - var expression = new Expression('getClassName()'); + var expression = new Expression('getExactClassName()'); expect(expression.evaluate(frameState, feature)).toEqual('door'); }); - it('throws if getClassName takes an invalid number of arguments', function() { + it('throws if getExactClassName takes an invalid number of arguments', function() { expect(function() { - return new Expression('getClassName("door")'); + return new Expression('getExactClassName("door")'); }).toThrowDeveloperError(); }); @@ -1989,8 +1989,8 @@ defineSuite([ }).toThrowDeveloperError(); }); - it('throws when getting shader expression for getClassName', function() { - var expression = new Expression('getClassName()'); + it('throws when getting shader expression for getExactClassName', function() { + var expression = new Expression('getExactClassName()'); expect(function() { return expression.getShaderExpression('', {}); }).toThrowDeveloperError(); From 989957114285697dd03639a67fb972e2cca3d956 Mon Sep 17 00:00:00 2001 From: Sean Lilley Date: Mon, 12 Dec 2016 16:38:08 -0500 Subject: [PATCH 22/24] Remove comma --- Source/Scene/Expression.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Scene/Expression.js b/Source/Scene/Expression.js index a67b1c50b192..7edb2d791ee2 100644 --- a/Source/Scene/Expression.js +++ b/Source/Scene/Expression.js @@ -62,7 +62,7 @@ define([ asin : Math.asin, atan : Math.atan, radians : CesiumMath.toRadians, - degrees : CesiumMath.toDegrees, + degrees : CesiumMath.toDegrees }; /** From 7bb29fe97aa0f940ad1c3ddc6503357d9582f7f7 Mon Sep 17 00:00:00 2001 From: Sean Lilley Date: Mon, 12 Dec 2016 17:04:57 -0500 Subject: [PATCH 23/24] Throw error when setting an inherited property --- Source/Scene/Cesium3DTileBatchTable.js | 5 +++++ Specs/Scene/Cesium3DTileBatchTableSpec.js | 10 +++++----- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/Source/Scene/Cesium3DTileBatchTable.js b/Source/Scene/Cesium3DTileBatchTable.js index 4ba007cf51da..dd3f289c5e89 100644 --- a/Source/Scene/Cesium3DTileBatchTable.js +++ b/Source/Scene/Cesium3DTileBatchTable.js @@ -612,6 +612,11 @@ define([ var indexInClass = hierarchy.classIndexes[instanceIndex]; var propertyValues = instanceClass.instances[name]; if (defined(propertyValues)) { + //>>includeStart('debug', pragmas.debug); + if (instanceIndex !== batchId) { + throw new DeveloperError('Inherited property "' + name + '" is read-only.'); + } + //>>includeEnd('debug'); if (defined(propertyValues.typedArray)) { setBinaryProperty(propertyValues, indexInClass, value); } else { diff --git a/Specs/Scene/Cesium3DTileBatchTableSpec.js b/Specs/Scene/Cesium3DTileBatchTableSpec.js index b09ebe910e3b..96bb91520b4b 100644 --- a/Specs/Scene/Cesium3DTileBatchTableSpec.js +++ b/Specs/Scene/Cesium3DTileBatchTableSpec.js @@ -780,15 +780,15 @@ defineSuite([ doorFeature.setProperty('height', 10.0); expect(doorFeature.getProperty('height')).toBe(10.0); - // Sets class property. + // Sets class property doorFeature.setProperty('door_name', 'new_door'); expect(doorFeature.getProperty('door_name')).toBe('new_door'); expect(roofFeature.getProperty('door_name')).toBeUndefined(); - // Sets inherited property. Check that both door and roof respond to the property change. - doorFeature.setProperty('building_name', 'new_building'); - expect(doorFeature.getProperty('building_name')).toBe('new_building'); - expect(roofFeature.getProperty('building_name')).toBe('new_building'); + // Throws error when setting inherited property + expect(function() { + doorFeature.setProperty('building_name', 'new_building'); + }).toThrowDeveloperError(); // Check properties when there is no hierarchy batchTable._batchTableHierarchy = undefined; From 75cdf2f8568578af4365ab5fced9ba8baf4a7fb4 Mon Sep 17 00:00:00 2001 From: Sean Lilley Date: Mon, 12 Dec 2016 17:10:58 -0500 Subject: [PATCH 24/24] Add comment for scratchVisited --- Source/Scene/Cesium3DTileBatchTable.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Source/Scene/Cesium3DTileBatchTable.js b/Source/Scene/Cesium3DTileBatchTable.js index dd3f289c5e89..6fc8b90cf00e 100644 --- a/Source/Scene/Cesium3DTileBatchTable.js +++ b/Source/Scene/Cesium3DTileBatchTable.js @@ -491,8 +491,9 @@ define([ } } - var scratchStack = []; + // The size of this array equals the maximum instance count among all loaded tiles, which has the potential to be large. var scratchVisited = []; + var scratchStack = []; var marker = 0; function traverseHierarchyMultipleParents(hierarchy, instanceIndex, endConditionCallback) { var classIds = hierarchy.classIds;