Skip to content

Commit

Permalink
fix(Feature2Mesh): fix wrong computing of clockwise polygon.
Browse files Browse the repository at this point in the history
Compute clockwise in parser
  • Loading branch information
gchoqueux committed Mar 10, 2022
1 parent d3a0154 commit bad5e34
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 8 deletions.
22 changes: 15 additions & 7 deletions src/Converter/Feature2Mesh.js
Expand Up @@ -302,10 +302,10 @@ function featureToPolygon(feature, options) {

function area(contour, offset, count) {
offset *= 3;
const n = count * 3;
const n = offset + count * 3;
let a = 0.0;

for (let p = n + offset - 3, q = offset; q < n; p = q, q += 3) {
for (let p = n - 3, q = offset; q < n; p = q, q += 3) {
a += contour[p] * contour[q + 1] - contour[q] * contour[p + 1];
}

Expand All @@ -315,9 +315,6 @@ function area(contour, offset, count) {
const bottomColor = new THREE.Color();
function featureToExtrudedPolygon(feature, options) {
const ptsIn = feature.vertices;
const offset = feature.geometries[0].indices[0].offset;
const count = feature.geometries[0].indices[0].count;
const isClockWise = area(ptsIn, offset, count) < 0;

const normals = feature.normals;
const vertices = new Float32Array(ptsIn.length * 2);
Expand Down Expand Up @@ -345,6 +342,7 @@ function featureToExtrudedPolygon(feature, options) {
const lastIndice = geometry.indices.slice(-1)[0];
const end = lastIndice.offset + lastIndice.count;
const count = end - start;
const isClockWise = geometry.indices[0].ccw ?? (area(ptsIn, start, count) < 0);

coordinatesToVertices(ptsIn, normals, vertices, z, start, count);
fillColorArray(colors, count, bottomColor, start);
Expand All @@ -365,13 +363,23 @@ function featureToExtrudedPolygon(feature, options) {
indices[startIndice + i] = triangles[i] + startTop;
}

for (const indice of geometry.indices) {
// add extruded contour
addExtrudedPolygonSideFaces(
indices,
totalVertices,
geometry.indices[0].offset,
geometry.indices[0].count,
isClockWise);

// add extruded holes
for (let i = 1; i < geometry.indices.length; i++) {
const indice = geometry.indices[i];
addExtrudedPolygonSideFaces(
indices,
totalVertices,
indice.offset,
indice.count,
isClockWise);
!(indice.ccw ?? isClockWise));
}

if (batchIds) {
Expand Down
23 changes: 22 additions & 1 deletion src/Parser/GeoJsonParser.js
Expand Up @@ -25,6 +25,9 @@ function readCRS(json) {
}

const coord = new Coordinates('EPSG:4978', 0, 0, 0);
const last = new Coordinates('EPSG:4978', 0, 0, 0);
const first = new Coordinates('EPSG:4978', 0, 0, 0);

// filter with the first point
const firstPtIsOut = (extent, aCoords, crs) => {
coord.crs = crs;
Expand All @@ -43,6 +46,24 @@ const toFeature = {
}
geometry.updateExtent();
},
// compute clockwise polygon
populateGeometryWithCCW(crsIn, coordinates, geometry, feature) {
geometry.startSubGeometry(coordinates.length, feature);
coord.crs = crsIn;

let sum = 0;
first.setFromValues(coordinates[0][0], coordinates[0][1], coordinates[0][2]);
last.copy(first);
for (var i = 0; i < coordinates.length; i++) {
coord.setFromValues(coordinates[i][0], coordinates[i][1], coordinates[i][2]);
sum += (last.x - coord.x) * (last.y + coord.y);
last.copy(coord);
geometry.pushCoordinates(coord, feature);
}
sum += (last.x - first.x) * (last.y + first.y);
geometry.getLastSubGeometry().ccw = sum < 0;
geometry.updateExtent();
},
point(feature, crsIn, coordsIn, collection, properties) {
this.default(feature, crsIn, [coordsIn], collection, properties);
},
Expand All @@ -68,7 +89,7 @@ const toFeature = {

// Then read contour and holes
for (let i = 0; i < coordsIn.length; i++) {
this.populateGeometry(crsIn, coordsIn[i], geometry, feature);
this.populateGeometryWithCCW(crsIn, coordsIn[i], geometry, feature);
}
feature.updateExtent(geometry);
},
Expand Down

0 comments on commit bad5e34

Please sign in to comment.