UStaticMesh几何数据相关(UE5.2)

UStaticMesh相关类图

8f663eb4989e48579fd3d47252243c43.png

 

UStaticMesh的数据构成

 

UStaticMesh的FStaticMeshSourceModel

UStaticMesh的Mesh几何元数据来自于FStaticMeshSourceModel, 一级Lod就存在一个FStaticMeshSourceModel. FStaticMeshSourceModel几何数据大致包含以下几类:

Vertex(点), VertexInstance(顶点), Edge(边),   Triangle(三角形),   Polygon(多边形)

总体上概念和Houdini的一些几何概念相似,每种几何元素都可以附带属性,比如点的“Position”, 顶点的“Normal,UV”等等。

下面介绍下如何获取Mesh元数据和相关属性

void AMyActor::TestMeshInfo() const
{
	if(!Mesh)
		return;

	// SourceModel
	const TArray<FStaticMeshSourceModel>& SourceModels = Mesh->GetSourceModels();
	for(int32 Index = 0; Index < SourceModels.Num(); Index++)
	{
		FMeshDescription* MeshDesc = Mesh->GetMeshDescription(Index);
		if(MeshDesc)
		{
			const FVertexArray& VertexArray =  MeshDesc->Vertices();

			// TVertexAttributesRef<FVector3f> VertexPositions = MeshDesc->VertexAttributes().GetAttributesRef<FVector3f>(MeshAttribute::Vertex::Position);
			TVertexAttributesRef<FVector3f> VertexPositions = MeshDesc->GetVertexPositions();

			//loop vertex postion
			for(const FVertexID VertexID : VertexArray.GetElementIDs())
			{
				FVector3f& Pos = VertexPositions[VertexID];
			}

			UE_LOG(LogTemp, Warning, TEXT("Vertex num = %d"), VertexArray.Num());


			//loop vertex instance attribute
			const FVertexInstanceArray& VertexInstanceArray = MeshDesc->VertexInstances();
			TVertexInstanceAttributesRef<FVector4f> VertexInstanceColors = MeshDesc->VertexInstanceAttributes().GetAttributesRef<FVector4f>(MeshAttribute::VertexInstance::Color);
			for(const FVertexInstanceID VertxInstanceId : VertexInstanceArray.GetElementIDs())
			{
				
			}

			UE_LOG(LogTemp, Warning, TEXT("VertexInstanceArray num = %d"), VertexInstanceArray.Num());

			//loop vertex edge attribute
			const FEdgeArray& EdgeArray = MeshDesc->Edges();
			TEdgeAttributesRef<bool> EdgeHardness = MeshDesc->EdgeAttributes().GetAttributesRef<bool>(MeshAttribute::Edge::IsHard);
			for (FEdgeID EdgeID : EdgeArray.GetElementIDs())
			{
				
			}

			UE_LOG(LogTemp, Warning, TEXT("EdgeArray num = %d"), EdgeArray.Num());

			// loop triangle attribute
			const FTriangleArray& TriangleArray = MeshDesc->Triangles();
			TTriangleAttributesRef<FVector3f> TriangleNormals = MeshDesc->TriangleAttributes().GetAttributesRef<FVector3f>(MeshAttribute::Triangle::Normal);
			for (FTriangleID TriangleID : TriangleArray.GetElementIDs())
			{
				
			}

			UE_LOG(LogTemp, Warning, TEXT("TriangleArray num = %d"), TriangleArray.Num());
			
			// loop polygon
			const FPolygonArray& PolygonArray =  MeshDesc->Polygons();
			TPolygonAttributesRef<int32> PatchGroups = MeshDesc->PolygonAttributes().GetAttributesRef<int32>(MeshAttribute::Polygon::PolygonGroupIndex);

			UE_LOG(LogTemp, Warning, TEXT("PolygonArray num = %d"), PolygonArray.Num());
		}


		if(Mesh->GetRenderData()->LODResources.Num() > Index)
		{
			TArray<FVector3f> Vertexs;
			auto& LodResource = Mesh->GetRenderData()->LODResources[Index];
			int32 VertexNum = LodResource.GetNumVertices();
			for(int32 I = 0; I < VertexNum; I++)
			{
				Vertexs.Add(LodResource.VertexBuffers.PositionVertexBuffer.VertexPosition(I));
			}

			int32 TriangleNum = LodResource.GetNumTriangles();
			TArray<uint32> Indexs;
			for(int32 I = 0; I < TriangleNum; I++)
			{
				Indexs.Add(LodResource.IndexBuffer.GetIndex(I * 3 + 0));
				Indexs.Add(LodResource.IndexBuffer.GetIndex(I * 3 + 1));
				Indexs.Add(LodResource.IndexBuffer.GetIndex(I * 3 + 2));
			}
			
		}
	}
}

 

 

如何填充数据生成一个UStaticMesh

主要是通过填充FMeshDescription的各种图元数据(Vertex, VertexInstance, Polygon, PolygonGroup等等)

void AMyActor::TestCreateStaticMesh()
{
	const FString ObjectName = "TestStaticMesh";
	const FString GameFoldPath = "/Game";
	const FString PackageName = FString::Printf(TEXT("%s/%s"), *GameFoldPath, *ObjectName);

	UPackage* Package = CreatePackage(*PackageName);
	UStaticMesh* MyMesh = NewObject<UStaticMesh>(Package, *ObjectName, RF_Standalone | RF_Public);
	FMeshDescription MeshDescription;
	FStaticMeshAttributes MeshAttribute(MeshDescription);
	MeshAttribute.Register();

	TArray<FDynamicMeshVertex> Vertices;
	Vertices.Add(FDynamicMeshVertex(FVector3f(500.0f, 500.0f, 200)));
	Vertices.Add(FDynamicMeshVertex(FVector3f(-500.0f, 500.0f, 200)));
	Vertices.Add(FDynamicMeshVertex(FVector3f(-500.0f, -500.0f, 200)));
	Vertices.Add(FDynamicMeshVertex(FVector3f(500.0f, -500.0f, 200)));

	TArray<int32> Indexs;
	Indexs.Add(0);
	Indexs.Add(3);
	Indexs.Add(1);

	Indexs.Add(1);
	Indexs.Add(3);
	Indexs.Add(2);
	
	MeshDescription.Empty();
	MeshDescription.ReserveNewVertices(Vertices.Num());
	MeshDescription.ReserveNewTriangles(Indexs.Num() / 3);
	MeshDescription.ReserveNewVertexInstances(Indexs.Num());

	TVertexAttributesRef<FVector3f> VertexPositions = MeshAttribute.GetVertexPositions();
	TVertexInstanceAttributesRef<FVector2f>	VertexInstanceUVs = MeshAttribute.GetVertexInstanceUVs();
	TVertexInstanceAttributesRef<FVector3f>	VertexInstanceNormals = MeshAttribute.GetVertexInstanceNormals();
	TVertexInstanceAttributesRef<FVector3f>	VertexInstanceTangents = MeshAttribute.GetVertexInstanceTangents();
	TPolygonGroupAttributesRef<FName> MaterialSlotNames = MeshAttribute.GetPolygonGroupMaterialSlotNames();
	TArray<UMaterialInterface*> MaterialInterfaces = {UMaterial::GetDefaultMaterial(MD_Surface)};
	for(int32 Index = 0; Index < MaterialInterfaces.Num(); Index++)
	{
		FPolygonGroupID PolygonGroupID = MeshDescription.CreatePolygonGroup();
		FStaticMaterial StaticMaterial = MaterialInterfaces[Index];
		MaterialSlotNames[PolygonGroupID] = StaticMaterial.MaterialSlotName;
	}

	//create vertex
	for(int32 Index = 0; Index < Vertices.Num(); Index++)
	{
		FVertexID VertexId = MeshDescription.CreateVertex();
		VertexPositions.Set(VertexId, Vertices[Index].Position);
	}

	//create vertex instance
	for(int32 Index = 0; Index < Indexs.Num(); Index++)
	{
		FVertexInstanceID VertexInstanceId = FVertexInstanceID(Index);
		FVertexID VertexID = FVertexID(Indexs[Index]);
		MeshDescription.CreateVertexInstanceWithID(VertexInstanceId, VertexID);
	}

	// set vertex instance normal/tangent/uv
	FPolygonGroupID PolygonGroupID(0);
	TArray<FVertexInstanceID> InstanceIds;
	for(int32 Index = 0; Index < Indexs.Num(); Index++)
	{
		FVertexInstanceID VertexInstanceId = FVertexInstanceID(Index);
		InstanceIds.Add(VertexInstanceId);
		const FDynamicMeshVertex& DynamicVertex = Vertices[Indexs[Index]];
		VertexInstanceUVs.Set(VertexInstanceId, DynamicVertex.TextureCoordinate[0]);
		VertexInstanceNormals.Set(VertexInstanceId, DynamicVertex.TangentX.ToFVector3f());
		VertexInstanceTangents.Set(VertexInstanceId, DynamicVertex.TangentZ.ToFVector3f());

		if(InstanceIds.Num() == 3)
		{
			TArray<FEdgeID> EdgeIds;
			MeshDescription.CreatePolygon(PolygonGroupID, InstanceIds, &EdgeIds);
			InstanceIds.Empty();
		}
	}

	// create source model lod0 and commit mesh desc
	const int32 LodIndex = 0;
	if(!MyMesh->IsSourceModelValid(LodIndex))
	{
		FStaticMeshSourceModel& SourceModel = MyMesh->AddSourceModel();
		SourceModel.BuildSettings.bRecomputeNormals = false;
		SourceModel.BuildSettings.bRecomputeTangents = false;
		SourceModel.BuildSettings.bGenerateLightmapUVs = false;
	}

	MyMesh->CreateMeshDescription(LodIndex, MeshDescription);
	MyMesh->CommitMeshDescription(LodIndex);

	MyMesh->ImportVersion = EImportStaticMeshVersion::LastVersion;
	MyMesh->CreateBodySetup();
	MyMesh->GetBodySetup()->CollisionReponse = EBodyCollisionResponse::BodyCollision_Disabled;
	MyMesh->Build(true);
	
	MyMesh->PostEditChange();
	MyMesh->MarkPackageDirty();
	FAssetRegistryModule::AssetCreated(MyMesh);
}

4cf12657eaea4f30b908fbb25d410d6f.png

 

  • 9
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Parasolid几何引擎是一种用于构建和处理三维几何模型的软件工具。它采用一种特定的数据结构来表示几何对象,并提供一系列算法和操作用于编辑、转换和分析这些对象。下面是对Parasolid几何引擎数据结构的技术分析: 1. 边界表示(B-rep):Parasolid使用边界表示法来存储几何对象。B-rep是一种常用的数据结构,它将几何对象表示为边界面、顶点和边的集合。每个面由一个或多个有向边界曲线组成,这些边界曲线以一定的方向排列,形成了一个封闭的边界。这种数据结构能够准确地描述几何对象的形状和拓扑关系。 2. 嵌套结构:Parasolid的数据结构支持嵌套,即一个几何对象可以包含其他几何对象。这种嵌套结构使得可以构建复杂的几何模型,例如装配体、部件和子组件等。每个对象都有一个唯一的标识符,可以通过标识符来查找和操作对象。 3. 参数化特征:Parasolid支持参数化特征,即可以通过参数来定义和控制几何对象的形状。参数可以是数值、几何对象或其他属性,可以用于控制尺寸、位置、曲率等。这种参数化的特性使得可以轻松地修改和调整几何模型,提高了设计的灵活性和效率。 4. 拓扑关系:Parasolid的数据结构能够维护几何对象之间的拓扑关系,例如相邻关系、相交关系、包含关系等。这些拓扑关系对于进行几何操作和分析非常重要,例如求交、求并、求差等。 总的来说,Parasolid几何引擎采用边界表示法的数据结构,支持嵌套结构、参数化特征和拓扑关系,能够准确地描述和操作三维几何模型。这种数据结构使得Parasolid成为一款强大的几何建模工具,在计算机辅助设计和工程分析领域得到广泛应用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值