143 lines
3.4 KiB
C++
143 lines
3.4 KiB
C++
#include "AdjacentInfo.h"
|
|
|
|
// 索引相同的顶点是同一个点
|
|
bool operator==(const FAdjacentVertex& left, const FAdjacentVertex& right)
|
|
{
|
|
return left.Index() == right.Index();
|
|
}
|
|
|
|
// 只要边连接的两个顶点相同(顺序可以相反)就是同一个边
|
|
bool operator==(const FAdjacentEdge& left, const FAdjacentEdge& right)
|
|
{
|
|
return (left.V1() == right.V1() && left.V2() == right.V2()) || (left.V1() == right.V2() && left.V2() == right.V1());
|
|
}
|
|
|
|
void FAdjacentVertex::CalculateType()
|
|
{
|
|
// 是边界点
|
|
if (inBorder)
|
|
{
|
|
if (angle > 1.5f * PI)
|
|
{
|
|
type = 2.0f;
|
|
}
|
|
else if (angle < 0.5f * PI)
|
|
{
|
|
type = 3.0f;
|
|
}
|
|
else
|
|
{
|
|
type = 1.0f;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
type = 0.0f;
|
|
}
|
|
}
|
|
|
|
void FAdjacentVertex::CalculateSoftNormalByAdjVertice()
|
|
{
|
|
if (!inBorder)
|
|
return;
|
|
uint32 innerAdjVerticeCount = 0;
|
|
for (FAdjacentVertex* v: adjVertice)
|
|
if (!v->inBorder)
|
|
++innerAdjVerticeCount;
|
|
|
|
softNormal = FVector::ZeroVector;
|
|
// 如果相邻顶点有内部顶点,使用内部顶点方向
|
|
if (innerAdjVerticeCount)
|
|
{
|
|
for (FAdjacentVertex* v: adjVertice)
|
|
{
|
|
if (!v->inBorder)
|
|
{
|
|
FVector dir = pos - v->pos;
|
|
dir.Normalize();
|
|
softNormal += dir;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for (FAdjacentVertex* v: adjVertice)
|
|
{
|
|
FVector dir = pos - v->pos;
|
|
dir.Normalize();
|
|
softNormal += dir;
|
|
}
|
|
}
|
|
softNormal.Normalize();
|
|
}
|
|
|
|
void FAdjacentVertex::ProjectSoftNormalOnNormalPlane()
|
|
{
|
|
normal.Normalize();
|
|
if (inBorder)
|
|
{
|
|
softNormal.Normalize();
|
|
softNormal -= FVector::DotProduct(normal, softNormal) * normal;
|
|
softNormal.Normalize();
|
|
}
|
|
}
|
|
|
|
FAdjacentEdge::FAdjacentEdge(FAdjacentVertex& v1, FAdjacentVertex& v2): v1(v1), v2(v2), count(1)
|
|
{
|
|
length = (v1.Pos() - v2.Pos()).Size();
|
|
}
|
|
|
|
void FAdjacentEdge::SetInBorder()
|
|
{
|
|
v1.InBorder() = true;
|
|
v2.InBorder() = true;
|
|
}
|
|
|
|
void FAdjacentEdge::AddVertexToEdge()
|
|
{
|
|
v1.AdjVertice().Add(&v2);
|
|
v2.AdjVertice().Add(&v1);
|
|
}
|
|
|
|
FAdjacentPolygon::FAdjacentPolygon(const TArray<FAdjacentVertex*>& Vertices, const TArray<FAdjacentEdge*>& Edges, int32 N)
|
|
: v(Vertices), e(Edges), n(N)
|
|
{
|
|
// 计算面法线
|
|
FVector dirAB = V(1).Pos() - V(0).Pos();
|
|
FVector dirBC = V(2).Pos() - V(1).Pos();
|
|
normal = FVector::CrossProduct(dirAB, dirBC);
|
|
normal.Normalize();
|
|
}
|
|
|
|
void FAdjacentPolygon::CalculateVertexNormal()
|
|
{
|
|
// 对于三角形的每个顶点,计算该顶点角度和方向
|
|
for (int i = 0; i < n; ++i)
|
|
{
|
|
// 顶点
|
|
FAdjacentVertex& A = V(i);
|
|
FAdjacentVertex& B = V((i - 1 + n) % n);
|
|
FAdjacentVertex& C = V((i + 1) % n);
|
|
|
|
FVector dirBA = A.Pos() - B.Pos();
|
|
FVector dirCA = A.Pos() - C.Pos();
|
|
|
|
dirBA.Normalize();
|
|
dirCA.Normalize();
|
|
|
|
float cosA = FVector::DotProduct(dirBA, dirCA);
|
|
// 顶点A的角度
|
|
float angle = FMath::Acos(cosA);
|
|
|
|
FVector vNormal = normal * angle;
|
|
|
|
A.Normal() += vNormal;
|
|
|
|
if (A.InBorder()) // 边界顶点 计算边界延伸方向
|
|
{
|
|
// angle为权重
|
|
A.SoftNormal() += (dirBA + dirCA).GetUnsafeNormal() * angle;
|
|
}
|
|
A.Angle() += angle;
|
|
}
|
|
} |