Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Do not throw when there are less unique positions than required for rendering. #2386

Merged
merged 8 commits into from
Jan 9, 2015
1 change: 1 addition & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ Change Log
* `GeoJsonDataSource` now supports polygons with holes.
* `ConstantProperty` can now hold any value; previously it was limited to values that implemented `equals` and `clones` functions, as well as a few special cases.
* Fixed a bug in `EllipsoidGeodesic` that caused it to modify the `height` of the positions passed to the constructor or to to `setEndPoints`.
* Instead of throwing an exception when there are not enough unique positions to define a geometry, creating a `Primitive` will succeed, but not render. [#2375](https://github.com/AnalyticalGraphicsInc/cesium/issues/2375)

### 1.5 - 2015-01-05

Expand Down
8 changes: 2 additions & 6 deletions Source/Core/CorridorGeometry.js
Original file line number Diff line number Diff line change
Expand Up @@ -794,9 +794,7 @@ define([
* Computes the geometric representation of a corridor, including its vertices, indices, and a bounding sphere.
*
* @param {CorridorGeometry} corridorGeometry A description of the corridor.
* @returns {Geometry} The computed vertices and indices.
*
* @exception {DeveloperError} Count of unique positions must be greater than 1.
* @returns {Geometry|undefined} The computed vertices and indices.
*/
CorridorGeometry.createGeometry = function(corridorGeometry) {
var positions = corridorGeometry._positions;
Expand All @@ -809,11 +807,9 @@ define([
cleanPositions = positions;
}

//>>includeStart('debug', pragmas.debug);
if (cleanPositions.length < 2) {
throw new DeveloperError('Count of unique positions must be greater than 1.');
return undefined;
}
//>>includeEnd('debug');

var ellipsoid = corridorGeometry._ellipsoid;
var vertexFormat = corridorGeometry._vertexFormat;
Expand Down
8 changes: 2 additions & 6 deletions Source/Core/CorridorOutlineGeometry.js
Original file line number Diff line number Diff line change
Expand Up @@ -461,9 +461,7 @@ define([
* Computes the geometric representation of a corridor, including its vertices, indices, and a bounding sphere.
*
* @param {CorridorOutlineGeometry} corridorOutlineGeometry A description of the corridor.
* @returns {Geometry} The computed vertices and indices.
*
* @exception {DeveloperError} Count of unique positions must be greater than 1.
* @returns {Geometry|undefined} The computed vertices and indices.
*/
CorridorOutlineGeometry.createGeometry = function(corridorOutlineGeometry) {
var positions = corridorOutlineGeometry._positions;
Expand All @@ -476,11 +474,9 @@ define([
cleanPositions = positions;
}

//>>includeStart('debug', pragmas.debug);
if (cleanPositions.length < 2) {
throw new DeveloperError('Count of unique positions must be greater than 1.');
return undefined;
}
//>>includeEnd('debug');

var ellipsoid = corridorOutlineGeometry._ellipsoid;
var params = {
Expand Down
65 changes: 29 additions & 36 deletions Source/Core/PolygonGeometry.js
Original file line number Diff line number Diff line change
Expand Up @@ -806,10 +806,7 @@ define([
* Computes the geometric representation of a polygon, including its vertices, indices, and a bounding sphere.
*
* @param {PolygonGeometry} polygonGeometry A description of the polygon.
* @returns {Geometry} The computed vertices and indices.
*
* @exception {DeveloperError} At least three positions are required.
* @exception {DeveloperError} Duplicate positions result in not enough positions to form a polygon.
* @returns {Geometry|undefined} The computed vertices and indices.
*/
PolygonGeometry.createGeometry = function(polygonGeometry) {
var vertexFormat = polygonGeometry._vertexFormat;
Expand Down Expand Up @@ -839,44 +836,40 @@ define([
var holes = outerNode.holes;
outerRing = PolygonPipeline.removeDuplicates(outerRing);
if (outerRing.length < 3) {
throw new DeveloperError('At least three positions are required.');
continue;
}

var numChildren = holes ? holes.length : 0;
if (numChildren === 0) {
// The outer polygon is a simple polygon with no nested inner polygon.
polygonHierarchy.push({
outerRing : outerRing,
holes : []
});
polygons.push(outerRing);
} else {
// The outer polygon contains inner polygons
var polygonHoles = [];
for (i = 0; i < numChildren; i++) {
var hole = holes[i];
hole.positions = PolygonPipeline.removeDuplicates(hole.positions);
if (hole.positions.length < 3) {
throw new DeveloperError('At least three positions are required.');
}
polygonHoles.push(hole.positions);
var numChildren = defined(holes) ? holes.length : 0;
var polygonHoles = [];
for (i = 0; i < numChildren; i++) {
var hole = holes[i];
hole.positions = PolygonPipeline.removeDuplicates(hole.positions);
if (hole.positions.length < 3) {
continue;
}
polygonHoles.push(hole.positions);

var numGrandchildren = 0;
if (defined(hole.holes)) {
numGrandchildren = hole.holes.length;
}
var numGrandchildren = 0;
if (defined(hole.holes)) {
numGrandchildren = hole.holes.length;
}

for ( var j = 0; j < numGrandchildren; j++) {
queue.enqueue(hole.holes[j]);
}
for ( var j = 0; j < numGrandchildren; j++) {
queue.enqueue(hole.holes[j]);
}
polygonHierarchy.push({
outerRing : outerRing,
holes : polygonHoles
});
var combinedPolygon = PolygonPipeline.eliminateHoles(outerRing, polygonHoles);
polygons.push(combinedPolygon);
}

polygonHierarchy.push({
outerRing : outerRing,
holes : polygonHoles
});

var combinedPolygon = polygonHoles.length > 0 ? PolygonPipeline.eliminateHoles(outerRing, polygonHoles) : outerRing;
polygons.push(combinedPolygon);
}

if (polygons.length === 0) {
return undefined;
}

outerPositions = polygons[0];
Expand Down
65 changes: 27 additions & 38 deletions Source/Core/PolygonOutlineGeometry.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,37 +44,29 @@ define([
var createGeometryFromPositionsSubdivided = [];

function createGeometryFromPositions(ellipsoid, positions, minDistance, perPositionHeight) {
var cleanedPositions = PolygonPipeline.removeDuplicates(positions);

//>>includeStart('debug', pragmas.debug);
if (cleanedPositions.length < 3) {
throw new DeveloperError('Duplicate positions result in not enough positions to form a polygon.');
}
//>>includeEnd('debug');

var tangentPlane = EllipsoidTangentPlane.fromPoints(cleanedPositions, ellipsoid);
var positions2D = tangentPlane.projectPointsOntoPlane(cleanedPositions, createGeometryFromPositionsPositions);
var tangentPlane = EllipsoidTangentPlane.fromPoints(positions, ellipsoid);
var positions2D = tangentPlane.projectPointsOntoPlane(positions, createGeometryFromPositionsPositions);

var originalWindingOrder = PolygonPipeline.computeWindingOrder2D(positions2D);
if (originalWindingOrder === WindingOrder.CLOCKWISE) {
positions2D.reverse();
cleanedPositions.reverse();
positions.reverse();
}

var subdividedPositions;
var i;

var length = cleanedPositions.length;
var length = positions.length;
var index = 0;

if (!perPositionHeight) {
var numVertices = 0;
for (i = 0; i < length; i++) {
numVertices += PolygonGeometryLibrary.subdivideLineCount(cleanedPositions[i], cleanedPositions[(i + 1) % length], minDistance);
numVertices += PolygonGeometryLibrary.subdivideLineCount(positions[i], positions[(i + 1) % length], minDistance);
}
subdividedPositions = new Float64Array(numVertices * 3);
for (i = 0; i < length; i++) {
var tempPositions = PolygonGeometryLibrary.subdivideLine(cleanedPositions[i], cleanedPositions[(i + 1) % length], minDistance, createGeometryFromPositionsSubdivided);
var tempPositions = PolygonGeometryLibrary.subdivideLine(positions[i], positions[(i + 1) % length], minDistance, createGeometryFromPositionsSubdivided);
var tempPositionsLength = tempPositions.length;
for (var j = 0; j < tempPositionsLength; ++j) {
subdividedPositions[index++] = tempPositions[j];
Expand All @@ -83,8 +75,8 @@ define([
} else {
subdividedPositions = new Float64Array(length * 2 * 3);
for (i = 0; i < length; i++) {
var p0 = cleanedPositions[i];
var p1 = cleanedPositions[(i + 1) % length];
var p0 = positions[i];
var p1 = positions[(i + 1) % length];
subdividedPositions[index++] = p0.x;
subdividedPositions[index++] = p0.y;
subdividedPositions[index++] = p0.z;
Expand Down Expand Up @@ -121,40 +113,32 @@ define([
}

function createGeometryFromPositionsExtruded(ellipsoid, positions, minDistance, perPositionHeight) {
var cleanedPositions = PolygonPipeline.removeDuplicates(positions);

//>>includeStart('debug', pragmas.debug);
if (cleanedPositions.length < 3) {
throw new DeveloperError('Duplicate positions result in not enough positions to form a polygon.');
}
//>>includeEnd('debug');

var tangentPlane = EllipsoidTangentPlane.fromPoints(cleanedPositions, ellipsoid);
var positions2D = tangentPlane.projectPointsOntoPlane(cleanedPositions, createGeometryFromPositionsPositions);
var tangentPlane = EllipsoidTangentPlane.fromPoints(positions, ellipsoid);
var positions2D = tangentPlane.projectPointsOntoPlane(positions, createGeometryFromPositionsPositions);

var originalWindingOrder = PolygonPipeline.computeWindingOrder2D(positions2D);
if (originalWindingOrder === WindingOrder.CLOCKWISE) {
positions2D.reverse();
cleanedPositions.reverse();
positions.reverse();
}

var subdividedPositions;
var i;

var length = cleanedPositions.length;
var length = positions.length;
var corners = new Array(length);
var index = 0;

if (!perPositionHeight) {
var numVertices = 0;
for (i = 0; i < length; i++) {
numVertices += PolygonGeometryLibrary.subdivideLineCount(cleanedPositions[i], cleanedPositions[(i + 1) % length], minDistance);
numVertices += PolygonGeometryLibrary.subdivideLineCount(positions[i], positions[(i + 1) % length], minDistance);
}

subdividedPositions = new Float64Array(numVertices * 3 * 2);
for (i = 0; i < length; ++i) {
corners[i] = index / 3;
var tempPositions = PolygonGeometryLibrary.subdivideLine(cleanedPositions[i], cleanedPositions[(i + 1) % length], minDistance, createGeometryFromPositionsSubdivided);
var tempPositions = PolygonGeometryLibrary.subdivideLine(positions[i], positions[(i + 1) % length], minDistance, createGeometryFromPositionsSubdivided);
var tempPositionsLength = tempPositions.length;
for (var j = 0; j < tempPositionsLength; ++j) {
subdividedPositions[index++] = tempPositions[j];
Expand All @@ -164,8 +148,8 @@ define([
subdividedPositions = new Float64Array(length * 2 * 3 * 2);
for (i = 0; i < length; ++i) {
corners[i] = index / 3;
var p0 = cleanedPositions[i];
var p1 = cleanedPositions[(i + 1) % length];
var p0 = positions[i];
var p1 = positions[(i + 1) % length];

subdividedPositions[index++] = p0.x;
subdividedPositions[index++] = p0.y;
Expand Down Expand Up @@ -479,10 +463,7 @@ define([
* Computes the geometric representation of a polygon outline, including its vertices, indices, and a bounding sphere.
*
* @param {PolygonOutlineGeometry} polygonGeometry A description of the polygon outline.
* @returns {Geometry} The computed vertices and indices.
*
* @exception {DeveloperError} At least three positions are required.
* @exception {DeveloperError} Duplicate positions result in not enough positions to form a polygon.
* @returns {Geometry|undefined} The computed vertices and indices.
*/
PolygonOutlineGeometry.createGeometry = function(polygonGeometry) {
var ellipsoid = polygonGeometry._ellipsoid;
Expand All @@ -502,15 +483,19 @@ define([
while (queue.length !== 0) {
var outerNode = queue.dequeue();
var outerRing = outerNode.positions;

outerRing = PolygonPipeline.removeDuplicates(outerRing);
if (outerRing.length < 3) {
throw new DeveloperError('At least three positions are required.');
continue;
}

var numChildren = outerNode.holes ? outerNode.holes.length : 0;
// The outer polygon contains inner polygons
for (i = 0; i < numChildren; i++) {
var hole = outerNode.holes[i];
hole.positions = PolygonPipeline.removeDuplicates(hole.positions);
if (hole.positions.length < 3) {
continue;
}
polygons.push(hole.positions);

var numGrandchildren = 0;
Expand All @@ -526,6 +511,10 @@ define([
polygons.push(outerRing);
}

if (polygons.length === 0) {
return undefined;
}

var geometry;
var geometries = [];
var minDistance = CesiumMath.chordLength(granularity, ellipsoid.maximumRadius);
Expand Down
11 changes: 3 additions & 8 deletions Source/Core/PolylineGeometry.js
Original file line number Diff line number Diff line change
Expand Up @@ -286,10 +286,7 @@ define([
* Computes the geometric representation of a polyline, including its vertices, indices, and a bounding sphere.
*
* @param {PolylineGeometry} polylineGeometry A description of the polyline.
* @returns {Geometry} The computed vertices and indices.
*
* @exception {DeveloperError} At least two unique positions are required.
*
* @returns {Geometry|undefined} The computed vertices and indices.
*/
PolylineGeometry.createGeometry = function(polylineGeometry) {
var width = polylineGeometry._width;
Expand All @@ -310,13 +307,11 @@ define([
if (!defined(positions)) {
positions = polylineGeometry._positions;
}
var positionsLength = positions.length;

//>>includeStart('debug', pragmas.debug);
var positionsLength = positions.length;
if (positionsLength < 2) {
throw new DeveloperError('At least two unique positions are required.');
return undefined;
}
//>>includeEnd('debug');

if (followSurface) {
var heights = PolylinePipeline.extractHeights(positions, ellipsoid);
Expand Down
14 changes: 3 additions & 11 deletions Source/Core/PolylineVolumeGeometry.js
Original file line number Diff line number Diff line change
Expand Up @@ -369,25 +369,17 @@ define([
* Computes the geometric representation of a polyline with a volume, including its vertices, indices, and a bounding sphere.
*
* @param {PolylineVolumeGeometry} polylineVolumeGeometry A description of the polyline volume.
* @returns {Geometry} The computed vertices and indices.
*
* @exception {DeveloperError} Count of unique polyline positions must be greater than 1.
* @exception {DeveloperError} Count of unique shape positions must be at least 3.
* @returns {Geometry|undefined} The computed vertices and indices.
*/
PolylineVolumeGeometry.createGeometry = function(polylineVolumeGeometry) {
var positions = polylineVolumeGeometry._positions;
var cleanPositions = PolylineVolumeGeometryLibrary.removeDuplicatesFromPositions(positions, polylineVolumeGeometry._ellipsoid);
var shape2D = polylineVolumeGeometry._shape;
shape2D = PolylineVolumeGeometryLibrary.removeDuplicatesFromShape(shape2D);

//>>includeStart('debug', pragmas.debug);
if (cleanPositions.length < 2) {
throw new DeveloperError('Count of unique polyline positions must be greater than 1.');
if (cleanPositions.length < 2 || shape2D.length < 3) {
return undefined;
}
if (shape2D.length < 3) {
throw new DeveloperError('Count of unique shape positions must be at least 3.');
}
//>>includeEnd('debug');

if (PolygonPipeline.computeWindingOrder2D(shape2D) === WindingOrder.CLOCKWISE) {
shape2D.reverse();
Expand Down
14 changes: 3 additions & 11 deletions Source/Core/PolylineVolumeOutlineGeometry.js
Original file line number Diff line number Diff line change
Expand Up @@ -275,25 +275,17 @@ define([
* Computes the geometric representation of the outline of a polyline with a volume, including its vertices, indices, and a bounding sphere.
*
* @param {PolylineVolumeOutlineGeometry} polylineVolumeOutlineGeometry A description of the polyline volume outline.
* @returns {Geometry} The computed vertices and indices.
*
* @exception {DeveloperError} Count of unique polyline positions must be greater than 1.
* @exception {DeveloperError} Count of unique shape positions must be at least 3.
* @returns {Geometry|undefined} The computed vertices and indices.
*/
PolylineVolumeOutlineGeometry.createGeometry = function(polylineVolumeOutlineGeometry) {
var positions = polylineVolumeOutlineGeometry._positions;
var cleanPositions = PolylineVolumeGeometryLibrary.removeDuplicatesFromPositions(positions, polylineVolumeOutlineGeometry._ellipsoid);
var shape2D = polylineVolumeOutlineGeometry._shape;
shape2D = PolylineVolumeGeometryLibrary.removeDuplicatesFromShape(shape2D);

//>>includeStart('debug', pragmas.debug);
if (cleanPositions.length < 2) {
throw new DeveloperError('Count of unique polyline positions must be greater than 1.');
if (cleanPositions.length < 2 || shape2D.length < 3) {
return undefined;
}
if (shape2D.length < 3) {
throw new DeveloperError('Count of unique shape positions must be at least 3.');
}
//>>includeEnd('debug');

if (PolygonPipeline.computeWindingOrder2D(shape2D) === WindingOrder.CLOCKWISE) {
shape2D.reverse();
Expand Down
Loading