Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 25 additions & 16 deletions src/3d/qf3dgeometryutils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,19 @@ bool Qf3DGeometryUtils::polygonIsEar( const QVector<QVector3D> &ring, const QVec
return true;
}

bool Qf3DGeometryUtils::polygonIsCounterClockwise( const QVector<QVector3D> &ring )
{
// Shoelace winding
double area2 = 0;
const int n = ring.size();
for ( int i = 0; i < n; ++i )
{
const int j = ( i + 1 ) % n;
area2 += static_cast<double>( ring[i].x() ) * ring[j].z() - static_cast<double>( ring[j].x() ) * ring[i].z();
}
return area2 > 0;
}

void Qf3DGeometryUtils::generatePolygonWalls( const QVector<QVector3D> &vertices,
float extrusion,
float r, float g, float b, float a,
Expand All @@ -225,10 +238,11 @@ void Qf3DGeometryUtils::generatePolygonWalls( const QVector<QVector3D> &vertices
return;
}

const bool ccw = polygonIsCounterClockwise( ring );
for ( int i = 0; i < n; ++i )
{
const QVector3D &edgeStart = ring[i];
const QVector3D &edgeEnd = ring[( i + 1 ) % n];
const QVector3D &edgeStart = ccw ? ring[i] : ring[( i + 1 ) % n];
const QVector3D &edgeEnd = ccw ? ring[( i + 1 ) % n] : ring[i];
const QVector3D edgeStartTop = edgeStart + QVector3D( 0, extrusion, 0 );
const QVector3D edgeEndTop = edgeEnd + QVector3D( 0, extrusion, 0 );

Expand Down Expand Up @@ -309,14 +323,13 @@ void Qf3DGeometryUtils::generatePolygonFill( const QVector<QVector3D> &vertices,
indices.append( i );
}

// Shoelace winding
double area2 = 0;
for ( int i = 0; i < n; ++i )
{
const int j = ( i + 1 ) % n;
area2 += static_cast<double>( ring[i].x() ) * ring[j].z() - static_cast<double>( ring[j].x() ) * ring[i].z();
}
const bool ccw = area2 > 0;
const bool ccw = polygonIsCounterClockwise( ring );

const auto writeTriangle = [&iptr, baseVertex, ccw]( int first, int second, int third ) {
*iptr++ = baseVertex + first;
*iptr++ = baseVertex + ( ccw ? third : second );
*iptr++ = baseVertex + ( ccw ? second : third );
};

const int expectedTriangles = n - 2;
int trianglesWritten = 0;
Expand All @@ -333,9 +346,7 @@ void Qf3DGeometryUtils::generatePolygonFill( const QVector<QVector3D> &vertices,

if ( polygonIsEar( ring, indices, eps, ccw, prev, i, next ) )
{
*iptr++ = baseVertex + indices[prev];
*iptr++ = baseVertex + indices[i];
*iptr++ = baseVertex + indices[next];
writeTriangle( indices[prev], indices[i], indices[next] );
indices.remove( i );
earFound = true;
++trianglesWritten;
Expand All @@ -351,9 +362,7 @@ void Qf3DGeometryUtils::generatePolygonFill( const QVector<QVector3D> &vertices,
// Fan fallback for the unprocessed remainder
for ( int i = 1; i < indices.size() - 1 && trianglesWritten < expectedTriangles; ++i )
{
*iptr++ = baseVertex + indices[0];
*iptr++ = baseVertex + indices[i];
*iptr++ = baseVertex + indices[i + 1];
writeTriangle( indices[0], indices[i], indices[i + 1] );
++trianglesWritten;
}
while ( trianglesWritten < expectedTriangles )
Expand Down
3 changes: 3 additions & 0 deletions src/3d/qf3dgeometryutils.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,9 @@ class QFIELD_3D_EXPORT Qf3DGeometryUtils
private:
//! Returns true if the triangle ( prev, cur, next ) of \a indices is an ear of \a ring on the XZ plane.
static bool polygonIsEar( const QVector<QVector3D> &ring, const QVector<int> &indices, float eps, bool ccw, int prev, int cur, int next );

//! Returns true if \a ring has a positive shoelace area on the XZ plane.
static bool polygonIsCounterClockwise( const QVector<QVector3D> &ring );
};

#endif // QF3DGEOMETRYUTILS_H
1 change: 0 additions & 1 deletion src/3d/qml/QfFeatureListSelectionHighlight3D.qml
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ Node {
alphaMode: model.extrusion > 0 ? PrincipledMaterial.Opaque : PrincipledMaterial.Blend
depthDrawMode: Material.OpaqueOnlyDepthDraw
cullMode: PrincipledMaterial.NoCulling
lighting: PrincipledMaterial.NoLighting
}
]
}
Expand Down
1 change: 0 additions & 1 deletion src/3d/qml/QfMapCanvas3D.qml
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,6 @@ Item {
alphaMode: PrincipledMaterial.Blend
depthDrawMode: Material.OpaqueOnlyDepthDraw
cullMode: PrincipledMaterial.NoCulling
lighting: PrincipledMaterial.NoLighting
}
}
}
Expand Down
Loading