Files
UnrealEngine/Engine/Plugins/Experimental/MeshModelingToolsetExp/Source/MeshModelingToolsExp/Public/SplitMeshesTool.h
2025-05-18 13:04:45 +08:00

123 lines
3.5 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
#pragma once
#include "CoreMinimal.h"
#include "BaseTools/MultiTargetWithSelectionTool.h"
#include "InteractiveToolBuilder.h"
#include "PropertySets/CreateMeshObjectTypeProperties.h"
#include "SplitMeshesTool.generated.h"
#define UE_API MESHMODELINGTOOLSEXP_API
class UMaterialInterface;
UCLASS(MinimalAPI)
class USplitMeshesToolBuilder : public UMultiTargetWithSelectionToolBuilder
{
GENERATED_BODY()
public:
UE_API virtual UMultiTargetWithSelectionTool* CreateNewTool(const FToolBuilderState& SceneState) const override;
virtual bool RequiresInputSelection() const override { return false; }
protected:
UE_API virtual const FToolTargetTypeRequirements& GetTargetRequirements() const override;
};
// Methods for splitting meshes
UENUM()
enum class ESplitMeshesMethod : uint8
{
// Split meshes based on the triangle-connected regions of the mesh
ByMeshTopology,
// Split meshes based on triangle-connected regions, and consider vertices to be connected if they are within a tolerance distance
ByVertexOverlap,
// Split meshes based on material ID
ByMaterialID,
// Split meshes based on PolyGroup ID
ByPolyGroup
};
UCLASS(MinimalAPI)
class USplitMeshesToolProperties : public UInteractiveToolPropertySet
{
GENERATED_BODY()
public:
// Method to use to split the input(s) into output meshes
UPROPERTY(EditAnywhere, Category = Options, meta = (EditCondition = "!bIsInSelectionMode", EditConditionHides, HideEditConditionToggle))
ESplitMeshesMethod SplitMethod = ESplitMeshesMethod::ByMeshTopology;
// Vertices as close as this distance will be treated as overlapping, and kept in the same output mesh
UPROPERTY(EditAnywhere, Category = Options, meta = (ClampMin = .0001, UIMax = 1.0, EditCondition = "!bIsInSelectionMode && SplitMethod == ESplitMeshesMethod::ByVertexOverlap", EditConditionHides, HideEditConditionToggle))
double ConnectVerticesThreshold = 0.01;
// Whether to transfer materials to the output meshes
UPROPERTY(EditAnywhere, Category = Options)
bool bTransferMaterials = true;
// Whether to color mesh faces based on how they will be split into output meshes
UPROPERTY(EditAnywhere, Category = Options)
bool bShowPreview = true;
UPROPERTY()
bool bIsInSelectionMode = false;
};
UCLASS(MinimalAPI)
class USplitMeshesTool : public UMultiTargetWithSelectionTool
{
GENERATED_BODY()
public:
UE_API virtual void Setup() override;
UE_API virtual void OnShutdown(EToolShutdownType ShutdownType) override;
virtual bool HasCancel() const override { return true; }
virtual bool HasAccept() const override { return true; }
UE_API virtual bool CanAccept() const override;
UPROPERTY()
TObjectPtr<USplitMeshesToolProperties> BasicProperties;
UPROPERTY()
TObjectPtr<UCreateMeshObjectTypeProperties> OutputTypeProperties;
protected:
struct FSourceMeshInfo
{
UE::Geometry::FDynamicMesh3 Mesh;
TArray<UMaterialInterface*> Materials;
};
TArray<FSourceMeshInfo> SourceMeshes;
struct FComponentsInfo
{
bool bNoComponents;
TArray<UE::Geometry::FDynamicMesh3> Meshes;
TArray<TArray<UMaterialInterface*>> Materials;
TArray<FVector3d> Origins;
};
TArray<FComponentsInfo> SplitMeshes;
int32 NoSplitCount = 0;
UE_API void UpdateSplitMeshes();
private:
// Preview how the meshes are to be split
UPROPERTY()
TArray<TObjectPtr<UPreviewGeometry>> PerTargetPreviews;
UPROPERTY()
TObjectPtr<UMaterialInterface> PreviewMaterial = nullptr;
UE_API void UpdatePreviewVisibility(bool bShowPreview);
};
#undef UE_API