// Copyright Epic Games, Inc. All Rights Reserved. #pragma once #include "CoreMinimal.h" #include "UObject/NoExportTypes.h" #include "Drawing/LineSetComponent.h" #include "BaseTools/BaseCreateFromSelectedTool.h" #include "CutMeshWithMeshTool.generated.h" #define UE_API MESHMODELINGTOOLS_API // Forward declarations class UPreviewMesh; PREDECLARE_USE_GEOMETRY_CLASS(FDynamicMesh3); /** * Standard properties of the CutMeshWithMesh operation */ UCLASS(MinimalAPI) class UCutMeshWithMeshToolProperties : public UInteractiveToolPropertySet { GENERATED_BODY() public: /** Try to fill holes created by the Boolean operation, e.g. due to numerical errors */ UPROPERTY(EditAnywhere, Category = Boolean) bool bTryFixHoles = false; /** Try to collapse extra edges created by the Boolean operation */ UPROPERTY(EditAnywhere, Category = Boolean) bool bTryCollapseEdges = true; /** Threshold to determine whether a triangle in one mesh is inside or outside of the other */ UPROPERTY(EditAnywhere, Category = Boolean, AdvancedDisplay, meta = (UIMin = "0", UIMax = "1")) float WindingThreshold = 0.5; /** Show boundary edges created by the Boolean operation, which might happen due to numerical errors */ UPROPERTY(EditAnywhere, Category = Display) bool bShowNewBoundaries = true; /** If true, only the first mesh will keep its material assignments, and all other faces will have the first material assigned */ UPROPERTY(EditAnywhere, Category = Materials) bool bUseFirstMeshMaterials = false; }; /** * UCutMeshWithMeshTool cuts an input mesh into two pieces based on a second input mesh. * Essentially this just both a Boolean Subtract and a Boolean Intersection. However * doing those as two separate operations involves quite a few steps, so this Tool * does it in a single step and with some improved efficiency. */ UCLASS(MinimalAPI) class UCutMeshWithMeshTool : public UBaseCreateFromSelectedTool { GENERATED_BODY() public: UCutMeshWithMeshTool() {} protected: UE_API virtual void OnPropertyModified(UObject* PropertySet, FProperty* Property) override; UE_API virtual void ConvertInputsAndSetPreviewMaterials(bool bSetPreviewMesh = true) override; UE_API virtual void SetupProperties() override; UE_API virtual void SaveProperties() override; UE_API virtual void SetPreviewCallbacks() override; UE_API virtual FString GetCreatedAssetName() const override; UE_API virtual FText GetActionName() const override; // IDynamicMeshOperatorFactory API UE_API virtual TUniquePtr MakeNewOperator() override; UE_API virtual void OnShutdown(EToolShutdownType ShutdownType) override; UE_API void UpdateVisualization(); UPROPERTY() TObjectPtr CutProperties; UPROPERTY() TObjectPtr IntersectPreviewMesh; TSharedPtr OriginalTargetMesh; TSharedPtr OriginalCuttingMesh; UPROPERTY() TObjectPtr DrawnLineSet; // for visualization of any errors in the currently-previewed CSG operation TArray CreatedSubtractBoundaryEdges; TArray CreatedIntersectBoundaryEdges; FDynamicMesh3 IntersectionMesh; }; UCLASS(MinimalAPI) class UCutMeshWithMeshToolBuilder : public UBaseCreateFromSelectedToolBuilder { GENERATED_BODY() public: virtual TOptional MaxComponentsSupported() const override { return TOptional(2); } virtual int32 MinComponentsSupported() const override { return 2; } virtual UMultiSelectionMeshEditingTool* CreateNewTool(const FToolBuilderState& SceneState) const override { return NewObject(SceneState.ToolManager); } }; #undef UE_API