116 lines
4.8 KiB
C++
116 lines
4.8 KiB
C++
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
#include "Properties/RevolveProperties.h"
|
|
|
|
#include "CompositionOps/CurveSweepOp.h"
|
|
#include "Properties/MeshMaterialProperties.h"
|
|
#include "Util/RevolveUtil.h"
|
|
|
|
#include UE_INLINE_GENERATED_CPP_BY_NAME(RevolveProperties)
|
|
|
|
using namespace UE::Geometry;
|
|
|
|
void URevolveProperties::ApplyToCurveSweepOp(const UNewMeshMaterialProperties& MaterialProperties,
|
|
const FVector3d& RevolutionAxisOrigin, const FVector3d& RevolutionAxisDirection,
|
|
FCurveSweepOp& CurveSweepOpOut) const
|
|
{
|
|
// Reversing the profile curve flips the mesh. This may need to be done if the curve wasn't drawn in the default
|
|
// (counterclockwise) direction or if we're not revolving in the default (counterclockwise) direction, or if
|
|
// the user asks.
|
|
bool bReverseProfileCurve = !RevolveUtil::ProfileIsCCWRelativeRevolve(CurveSweepOpOut.ProfileCurve,
|
|
RevolutionAxisOrigin, RevolutionAxisDirection, CurveSweepOpOut.bProfileCurveIsClosed);
|
|
bReverseProfileCurve = bReverseProfileCurve ^ bFlipMesh ^ bReverseRevolutionDirection;
|
|
if (bReverseProfileCurve)
|
|
{
|
|
for (int32 i = 0; i < CurveSweepOpOut.ProfileCurve.Num() / 2; ++i)
|
|
{
|
|
Swap(CurveSweepOpOut.ProfileCurve[i], CurveSweepOpOut.ProfileCurve[CurveSweepOpOut.ProfileCurve.Num() - 1 - i]);
|
|
}
|
|
}
|
|
|
|
const double TotalRevolutionDegrees = (HeightOffsetPerDegree == 0) ? RevolveDegreesClamped : RevolveDegrees;
|
|
|
|
const int32 Steps = bExplicitSteps ? NumExplicitSteps : FMath::CeilToInt(TotalRevolutionDegrees / StepsMaxDegrees);
|
|
|
|
double DegreesPerStep = TotalRevolutionDegrees / Steps;
|
|
double DegreesOffset = RevolveDegreesOffset;
|
|
if (bReverseRevolutionDirection)
|
|
{
|
|
DegreesPerStep *= -1;
|
|
DegreesOffset *= -1;
|
|
}
|
|
const double DownAxisOffsetPerStep = TotalRevolutionDegrees * HeightOffsetPerDegree / Steps;
|
|
|
|
if (bPathAtMidpointOfStep && DegreesPerStep != 0 && abs(DegreesPerStep) < 180)
|
|
{
|
|
RevolveUtil::MakeProfileCurveMidpointOfFirstStep(CurveSweepOpOut.ProfileCurve, DegreesPerStep, RevolutionAxisOrigin, RevolutionAxisDirection);
|
|
}
|
|
|
|
// Generate the sweep curve
|
|
CurveSweepOpOut.bSweepCurveIsClosed = bWeldFullRevolution && HeightOffsetPerDegree == 0 && TotalRevolutionDegrees == 360;
|
|
const int32 NumSweepFrames = CurveSweepOpOut.bSweepCurveIsClosed ? Steps : Steps + 1; // If closed, last sweep frame is also first
|
|
CurveSweepOpOut.SweepCurve.Reserve(NumSweepFrames);
|
|
RevolveUtil::GenerateSweepCurve(RevolutionAxisOrigin, RevolutionAxisDirection, DegreesOffset,
|
|
DegreesPerStep, DownAxisOffsetPerStep, NumSweepFrames, CurveSweepOpOut.SweepCurve);
|
|
|
|
// Weld any vertices that are on the axis
|
|
if (bWeldVertsOnAxis && DownAxisOffsetPerStep == 0)
|
|
{
|
|
RevolveUtil::WeldPointsOnAxis(CurveSweepOpOut.ProfileCurve, RevolutionAxisOrigin,
|
|
RevolutionAxisDirection, AxisWeldTolerance, CurveSweepOpOut.ProfileVerticesToWeld);
|
|
}
|
|
CurveSweepOpOut.bSharpNormals = bSharpNormals;
|
|
CurveSweepOpOut.SharpNormalAngleTolerance = SharpNormalsDegreeThreshold;
|
|
CurveSweepOpOut.DiagonalTolerance = QuadSplitCompactTolerance;
|
|
const double UVScale = MaterialProperties.UVScale;
|
|
CurveSweepOpOut.UVScale = FVector2d(UVScale, UVScale);
|
|
if (bReverseProfileCurve ^ bFlipVs)
|
|
{
|
|
CurveSweepOpOut.UVScale[1] *= -1;
|
|
CurveSweepOpOut.UVOffset = FVector2d(0, UVScale);
|
|
}
|
|
CurveSweepOpOut.bUVsSkipFullyWeldedEdges = bUVsSkipFullyWeldedEdges;
|
|
CurveSweepOpOut.bUVScaleRelativeWorld = MaterialProperties.bWorldSpaceUVScale;
|
|
CurveSweepOpOut.UnitUVInWorldCoordinates = 100; // This seems to be the case in the AddPrimitiveTool
|
|
switch (PolygroupMode)
|
|
{
|
|
case ERevolvePropertiesPolygroupMode::PerShape:
|
|
CurveSweepOpOut.PolygonGroupingMode = EProfileSweepPolygonGrouping::Single;
|
|
break;
|
|
case ERevolvePropertiesPolygroupMode::PerFace:
|
|
CurveSweepOpOut.PolygonGroupingMode = EProfileSweepPolygonGrouping::PerFace;
|
|
break;
|
|
case ERevolvePropertiesPolygroupMode::PerRevolveStep:
|
|
CurveSweepOpOut.PolygonGroupingMode = EProfileSweepPolygonGrouping::PerSweepSegment;
|
|
break;
|
|
case ERevolvePropertiesPolygroupMode::PerPathSegment:
|
|
CurveSweepOpOut.PolygonGroupingMode = EProfileSweepPolygonGrouping::PerProfileSegment;
|
|
break;
|
|
}
|
|
switch (QuadSplitMode)
|
|
{
|
|
case ERevolvePropertiesQuadSplit::Compact:
|
|
CurveSweepOpOut.QuadSplitMode = EProfileSweepQuadSplit::ShortestDiagonal;
|
|
break;
|
|
case ERevolvePropertiesQuadSplit::Uniform:
|
|
CurveSweepOpOut.QuadSplitMode = EProfileSweepQuadSplit::Uniform;
|
|
break;
|
|
}
|
|
switch (GetCapFillMode())
|
|
{
|
|
case ERevolvePropertiesCapFillMode::None:
|
|
CurveSweepOpOut.CapFillMode = FCurveSweepOp::ECapFillMode::None;
|
|
break;
|
|
case ERevolvePropertiesCapFillMode::Delaunay:
|
|
CurveSweepOpOut.CapFillMode = FCurveSweepOp::ECapFillMode::Delaunay;
|
|
break;
|
|
case ERevolvePropertiesCapFillMode::EarClipping:
|
|
CurveSweepOpOut.CapFillMode = FCurveSweepOp::ECapFillMode::EarClipping;
|
|
break;
|
|
case ERevolvePropertiesCapFillMode::CenterFan:
|
|
CurveSweepOpOut.CapFillMode = FCurveSweepOp::ECapFillMode::CenterFan;
|
|
break;
|
|
}
|
|
}
|
|
|