cesium icon indicating copy to clipboard operation
cesium copied to clipboard

PolygonGeometry with holes have broken surfaces

Open ArgentumHHH opened this issue 1 year ago • 11 comments

What happened?

Now I have encountered a problem when changing from version 1.119 to versions after 1.120. I created a PolygonGeometry that provides polygon boundary coordinate data and polygon hole coordinate data to create a polygon with holes. Generally, there is no problem with the coordinate data of holes, but many boundary coordinates in urban areas may have holes and broken surfaces. The city boundary coordinate data is arranged in order and is valid latitude and longitude data in terms of format. It can be successfully rendered as PolylineGeometry or PolygonGeometry, but using the city coordinate data as polygon hole coordinate data may result in broken surfaces.

PolygonGeometry with holes created in version 1.119: 1 119

PolygonGeometry with holes created in version 1.120 has a broken surface in the lower left corner, and most of the city boundary coordinates have a broken surface in the lower left corner: 1 120

Reproduction steps

No response

Sandcastle example

No response

Environment

Browser: CesiumJS Version: Operating System:

ArgentumHHH avatar Nov 08 '24 03:11 ArgentumHHH

Thanks for raising this issue @ArgentumHHH!

Looking through the 1.120 changelog, I don't see anything obvious that may have broken polygon hole rendering. It would be helpful to do a git bisect to determine the commit which caused the regression.

@ArgentumHHH Is this something you would be able to try?

ggetz avatar Nov 13 '24 14:11 ggetz

When I encountered this issue, it was during version 1.123 update. In order to determine which version was causing the problem, I rolled back one version at a time and only found out that the issue did not occur at 1.119. Subsequent versions had this issue

ArgentumHHH avatar Nov 28 '24 06:11 ArgentumHHH

@ArgentumHHH Would you be able to perform a git-bisect in order to determine the problematic commit?

ggetz avatar Dec 10 '24 19:12 ggetz

@ArgentumHHH Would you be able to perform a git-bisect in order to determine the problematic commit?

I compared every change between version 1.119 and version 1.120 and determined that the reason for this situation is the version issue of the dependency library earcut in packages.engine. By reducing the version of earcut from 3.0.0 to the original 2.2.4, this situation no longer exists.

ArgentumHHH avatar Dec 24 '24 02:12 ArgentumHHH

@ArgentumHHH It looks like we have a potential fix in https://github.com/CesiumGS/cesium/pull/12412.

Would you please include the Sandcastle example that replicates the issue shown above? That would let us verify the fix. Thanks!

ggetz avatar Jan 06 '25 16:01 ggetz

I have a similar problem and I'm not sure if earcut 3.0 is the cause. I'm using an older version of cesium (I'm on 1.108.0 with earcut 2.2.4). I've been trying to figure this out for days. All the polygons are cut on the geographical south corner. Could this be related?

There are also weird interactions when polygons are drawn side by side, but I can't reproduce it every time. For example, if I draw 4 square polygons to create a larger square, some corners will fill in with the color of their neighbor, depending on the viewing angle.

Example of 2 polygons affected by the problem: image

Example of the viewing angle problem (visible on the green polygon, filling the missing part of the red one) : https://www.youtube.com/watch?v=WQyBPmldGGo

EDIT : Here's a sandcastle replicating the problem : https://sandcastle.cesium.com/#c=rVNda9swFP0rIk8OGMXWhy15SdgIhQ4GK6xsD8sYqqPEYopkJCXBG/3vkxOnCW0ZFOYH+Ur33uOjc49ra3wAeyUP0oEZMPIAFtKr3RZ+PZ4ly1F93C+sCUIZ6Zaj8bulqY99tZMiyDuru401Nyao0EWQxIitTEGjpBOubroxmM3Bn6UB8Tl9Ccq+VkkPxWqVDCkA+r7quKbno/aEXYGnInABri5heklvIyWnhK7ON1lYbR38dvvx/gYeVGg+6LYRSQYRHV+12V3Q8X4VWAvt5VWile7O+kjXmlupNk14XvI4RI+9MPEVVy1DpK5M8FGP71eqLoQLMRIGJwQzzgmGGeUsywuKUkApyRGHBHNKeIFKmgJCS8YxggVBjBU4w9ecB9n+AZ9DUpIMIUzyAT6DBWYI86Lg+RmewpyWJSsKRN4GTyHLCKWsKK/gI3lKWPZEPoM8LwjLccbfhl5CzlFkh/OLNhkjBaEYYTbAoxKykjPKGB3/6J350pPRxL2PfvpGtHI5SofR9OMa/FhHzzkB17q7t2c/rqQPyoh+7hX47yOMZhmlo6kPnZbzsyjv1ba1LoCd0wmEkyC3rY6X8ZOHXf1LBlh7f/IYANPJdet0pfZArWav/K2g1sL7mFnvtP6ifkcB5tNJrH/Rqq1YKbP5vJdOi64va/L5p9MhhHA6idvXO4O1+kG4Z8h/AQ

EDIT 2 : It only affects polygons when they are clamped to ground. If we set a height or an extrudedHeight, the polygon will always be complete.

EDIT 3 : From what I found, it could be related to #12246 , #12136 , #11883 and #11291 , I'm not yet sure if the problem is the same for this issue.

pvocat avatar Jan 16 '25 09:01 pvocat

@pvocat I don't think this is related to earcut. At least, your example does not appear to be affected by https://github.com/CesiumGS/cesium/pull/12412.

https://github.com/CesiumGS/cesium/issues/11291 appears to be the most relevant report. I'll add your report to that thread.

ggetz avatar Jan 27 '25 17:01 ggetz

@ArgentumHHH It looks like we have a potential fix in #12412.

Would you please include the Sandcastle example that replicates the issue shown above? That would let us verify the fix. Thanks!

The files provided below are administrative boundary data and example code.

district.json

fetch('district.json').then(response => response.json()).then(data => {
        let positions = [];
        let coordinates = data.coordinates;
        for (let i = 0; i < coordinates.length; i = i + 2) {
              positions.push(Cesium.Cartesian3.fromDegrees(coordinates[i], coordinates[i + 1]));  
        }

        const west = -74.13574219;
        const east = -70.90576172;
        const south = 42.19596878;
        const north = 45.47554027;
        const boundPositions = [
            Cesium.Cartesian3.fromDegrees(west, south),
            Cesium.Cartesian3.fromDegrees(east, south),
            Cesium.Cartesian3.fromDegrees(east, north),
            Cesium.Cartesian3.fromDegrees(west, north)
        ];
        
        let shape = viewer.entities.add({
            polygon: {
                hierarchy: new Cesium.PolygonHierarchy(boundPositions, [new Cesium.PolygonHierarchy(positions)]),
                material: Cesium.Color.RED.withAlpha(0.8),
                classificationType: Cesium.ClassificationType.BOTH,
                fill: true,
                stRotation: 0,
                perPositionHeight: true,
                outline: true,
                outlineColor: Cesium.Color.WHITE,
                shadows: Cesium.ShadowMode.DISABLED,
                height: 1,
                granularity: Cesium.Math.RADIANS_PER_DEGREE,
                closeBottom: true,
                closeTop: true
            }
        });
        viewer.zoomTo(shape);
    });

ArgentumHHH avatar Feb 09 '25 06:02 ArgentumHHH

This looks like the known issue with earcut 3.0.0, fixed in 3.0.1 https://github.com/mapbox/earcut/pull/177

jjhembd avatar May 22 '25 14:05 jjhembd

Also reported on the forum: https://community.cesium.com/t/distortion-with-polygon-entity-using-holes/39080

Here is a cleaned-up version of the Sandcastle from that thread.

jjhembd avatar May 22 '25 14:05 jjhembd

Update: earcut 3.0.1 does not resolve the problem.

@ArgentumHHH, as a workaround, you can supply the outer ring (the boundPositions in your code snippet) in clockwise order. See this local Sandcastle code.

This is clearly a bug, since the PolygonHierarchy doc says the positions should be supplied as a "linear ring", which should presumably follow the GeoJSON definition, which the spec says should be counter-clockwise for the exterior ring.

The bug could be somewhere in PolygonGeometryLibrary. The polygonsFromHierarchy method explicitly checks the winding order and reverses everything if necessary, so earcut shouldn't even see the order of your boundPositions array. We must be reading from two different versions of the array somewhere.

jjhembd avatar May 30 '25 21:05 jjhembd