Files
UnrealEngineUWP/Engine/Plugins/Runtime/GeometryProcessing/Source/DynamicMesh/Private/Operations/QuadGridPatchUtil.cpp

108 lines
3.4 KiB
C++
Raw Normal View History

GeometryProcessing: OffsetMeshRegion improvements Refactor core of FDynamicMeshEditor::DisconnectTriangles into an overload that takes precomputed triangle TSet and BoundaryLoops array, as some call sites already have computed this info Refactor new-polygroup computation out of OffsetMeshRegion into UE::Geometry::ComputeNewGroupIDsAlongEdgeLoop util function in PolyEditingEdgeUtil.h/cpp Add new function UE::Geometry::ComputeAverageUVScaleRatioAlongVertexPath in PolyEditingUVUtil.h/cpp Introduce new type FQuadGridPatch, this is a book-keeping data structure for keeping track of "grid of quads" subregion of a triangle mesh, that provides easy access to vertex and quad/trainagle rows/columns Add util functions ComputeNormalsForQuadPatch() and ComputeUVIslandForQuadPatch() in QuadGridPatchUtil.h Add new version of OffsetMeshRegion geometric operation, inside FOffsetMeshRegion class. EVersion parameter determines which version of operation to run. Code for the "Legacy" version has not been modified, so back-compat is maintained. New implementation supports variable number of subdivisions along the Offset (via .NumSubdivisions), and computes normal/UV-islands "per group" in extrusion region, instead of per-quad. New version also splits bowties in extrude region before any additional processing, which simplifies some of the book-keeping/etc. FExtrudeOp currently hardcoded to use use the FOffsetMeshRegion implementation #rb none #preflight 639762350a67152550ee9a18 [CL 23481550 by ryan schmidt in ue5-main branch]
2022-12-12 15:09:02 -05:00
// Copyright Epic Games, Inc. All Rights Reserved.
#include "Operations/QuadGridPatchUtil.h"
#include "DynamicMesh/DynamicMesh3.h"
#include "DynamicMeshEditor.h"
#include "Parameterization/DynamicMeshUVEditor.h"
#include "Operations/PolyEditingUVUtil.h"
using namespace UE::Geometry;
void UE::Geometry::ComputeNormalsForQuadPatch(
FDynamicMesh3& Mesh,
const FQuadGridPatch& QuadPatch )
{
TArray<int32> PatchTriangles;
QuadPatch.GetAllTriangles(PatchTriangles);
FDynamicMeshEditor Editor(&Mesh);
Editor.SetTriangleNormals(PatchTriangles);
}
bool UE::Geometry::ComputeUVIslandForQuadPatch(
FDynamicMesh3& Mesh,
const FQuadGridPatch& QuadPatch,
double UVScaleFactor,
int UVOverlayIndex )
{
FDynamicMeshUVEditor UVEditor(&Mesh, UVOverlayIndex, false);
FDynamicMeshUVOverlay* UVOverlay = UVEditor.GetOverlay();
if (!UVOverlay)
{
return false;
}
TArray<int32> AllTriangles;
QuadPatch.GetAllTriangles(AllTriangles);
UVEditor.ResetUVs(AllTriangles);
// compute UV scale factor that tries to keep UV dimensions roughly consistent with connected area
double UVLengthScale = 0, UVLengthWeight = 0;
for (int32 k = 0; k < 2; ++k)
{
const TArray<int32>& VertexSpan = (k == 0) ? QuadPatch.VertexSpans[0] : QuadPatch.VertexSpans.Last();
double PathLength = 0;
double UVLengthScaleTmp = UE::Geometry::ComputeAverageUVScaleRatioAlongVertexPath(Mesh, *UVOverlay, VertexSpan, &PathLength);
if (PathLength > 0)
{
UVLengthScale += UVLengthScaleTmp;
UVLengthWeight += 1.0;
}
}
UVLengthScale = (UVLengthWeight == 0 || UVLengthScale == 0) ? 1.0 : (UVLengthScale / UVLengthWeight);
GeometryProcessing: OffsetMeshRegion improvements Refactor core of FDynamicMeshEditor::DisconnectTriangles into an overload that takes precomputed triangle TSet and BoundaryLoops array, as some call sites already have computed this info Refactor new-polygroup computation out of OffsetMeshRegion into UE::Geometry::ComputeNewGroupIDsAlongEdgeLoop util function in PolyEditingEdgeUtil.h/cpp Add new function UE::Geometry::ComputeAverageUVScaleRatioAlongVertexPath in PolyEditingUVUtil.h/cpp Introduce new type FQuadGridPatch, this is a book-keeping data structure for keeping track of "grid of quads" subregion of a triangle mesh, that provides easy access to vertex and quad/trainagle rows/columns Add util functions ComputeNormalsForQuadPatch() and ComputeUVIslandForQuadPatch() in QuadGridPatchUtil.h Add new version of OffsetMeshRegion geometric operation, inside FOffsetMeshRegion class. EVersion parameter determines which version of operation to run. Code for the "Legacy" version has not been modified, so back-compat is maintained. New implementation supports variable number of subdivisions along the Offset (via .NumSubdivisions), and computes normal/UV-islands "per group" in extrusion region, instead of per-quad. New version also splits bowties in extrude region before any additional processing, which simplifies some of the book-keeping/etc. FExtrudeOp currently hardcoded to use use the FOffsetMeshRegion implementation #rb none #preflight 639762350a67152550ee9a18 [CL 23481550 by ryan schmidt in ue5-main branch]
2022-12-12 15:09:02 -05:00
TArray<TArray<int32>> UVElementSpans;
UVElementSpans.SetNum( QuadPatch.NumVertexRowsV );
const TArray<int32>& StartVertexSpan = QuadPatch.VertexSpans[0];
const TArray<int32>& EndVertexSpan = QuadPatch.VertexSpans.Last();
TArray<int32>& StartUVSpan = UVElementSpans[0];
TArray<int32>& EndUVSpan = UVElementSpans.Last();
// generate new UV elements along the two vertex spans
// note even in the case of a closed loop, we have a span here, so we will get an 'unwrapped' cylinder etc
double AccumDistU = 0;
int32 NumU = QuadPatch.NumVertexColsU;
int32 NumV = QuadPatch.NumVertexRowsV;
for ( int32 k = 0; k < NumU; ++k )
{
double DistV = Distance( Mesh.GetVertex(StartVertexSpan[k]), Mesh.GetVertex(EndVertexSpan[k]) );
//double DistV = Distance( Mesh.GetVertex(StartVertexSpan[0]), Mesh.GetVertex(EndVertexSpan[0]) );
float UseU = (float)(UVLengthScale * AccumDistU * UVScaleFactor);
float EndV = (float)(UVLengthScale * DistV * UVScaleFactor);
for ( int32 j = 0; j < NumV; ++j )
{
float t = (float)j / (float)(NumV-1);
int32 NewElemID = UVOverlay->AppendElement( FVector2f(UseU, (float)(t * EndV)) );
UVElementSpans[j].Add(NewElemID);
}
if ( k < NumU-1 )
{
AccumDistU += Distance( Mesh.GetVertex(StartVertexSpan[k]), Mesh.GetVertex(StartVertexSpan[k+1]) );
}
}
QuadPatch.ForEachQuad( [&](int32 Row, int32 QuadIndex, FIndex2i QuadTris)
{
for (int32 TriIdx = 0; TriIdx < 2; ++TriIdx)
{
int32 TriangleID = QuadTris[TriIdx];
FIndex3i IndicesTri = QuadPatch.GetQuadTriMappedToSpanIndices(Mesh, Row, QuadIndex, TriIdx);
FIndex3i UVTri;
for ( int32 j = 0; j < 3; ++j )
{
FIndex2i VertexSpanIndex = QuadPatch.DecodeRowColumnIndex(IndicesTri[j]);
UVTri[j] = UVElementSpans[VertexSpanIndex.A][VertexSpanIndex.B];
}
UVOverlay->SetTriangle(TriangleID, UVTri);
}
});
return true;
}