Files
UnrealEngineUWP/Engine/Plugins/Experimental/MeshModelingToolset/Source/ModelingComponents/Public/BaseTools/BaseCreateFromSelectedTool.h

213 lines
7.0 KiB
C
Raw Normal View History

// Copyright Epic Games, Inc. All Rights Reserved.
#pragma once
#include "CoreMinimal.h"
#include "MultiSelectionTool.h"
#include "InteractiveToolBuilder.h"
#include "MeshOpPreviewHelpers.h"
#include "PropertySets/OnAcceptProperties.h"
#include "PropertySets/CreateMeshObjectTypeProperties.h"
#include "BaseCreateFromSelectedTool.generated.h"
Gizmos: refactor Modeling Mode gizmo creation out of InteractiveGizmoManager. Editor will use other "default" transform gizmo implementations, and so the UTransformGizmo creation helper functions do not belong in GizmoManager. Instead a UTransformGizmoContextObject now provides this functionality. ModelingToolsEditorMode (and any other modes/systems that want to use these gizmo convenience functions) creates an instance of UTransformGizmoContextObject and registers it with the ContextObjectStore. Calling code can spawn a new UTransformGizmo by looking this object up in the ContextStore and calling it's helper functions. Static versions of the helper functions in the UE::TransformGizmoUtil:: namespace provide a single-line interface that replaces the previous GizmoManager call sites in the MeshModelingTools library. IntervalGizmo is now just registered and unregistered as needed by the MeshSpaceDeformerTool, as this is the only place it is currently used. Previous implementation in InteractiveGizmoManager is left intact as there are a few uses outside of MeshModelingTools that need to be cleaned up before it can be deleted. UTransformGizmo now requires it's Builder to tell it which sub-gizmo identifier strings to pass to the GizmoManager to create axis/plane/rotation sub-gizmos (and the code that registers the Builder must then provide these strings). This cleans up previous explicit references to UInteractiveGizmoManager static strings from UTransformGizmo. #rb Christina.TempelaarL, david.hill #rnx #jira none [CL 16409673 by Ryan Schmidt in ue5-main branch]
2021-05-20 16:39:39 -04:00
class UTransformGizmo;
class UTransformProxy;
/**
* ToolBuilder for UBaseCreateFromSelectedTool
*/
UCLASS()
class MODELINGCOMPONENTS_API UBaseCreateFromSelectedToolBuilder : public UInteractiveToolBuilder
{
GENERATED_BODY()
public:
virtual bool CanBuildTool(const FToolBuilderState& SceneState) const override;
virtual UInteractiveTool* BuildTool(const FToolBuilderState& SceneState) const override;
public:
virtual TOptional<int32> MaxComponentsSupported() const { return TOptional<int32>(); }
virtual int32 MinComponentsSupported() const { return 1; }
// subclass must override!
virtual UBaseCreateFromSelectedTool* MakeNewToolInstance(UObject* Outer) const { check(false); return nullptr; }
protected:
virtual const FToolTargetTypeRequirements& GetTargetRequirements() const override;
};
UENUM()
enum class EBaseCreateFromSelectedTargetType
{
/** Create a new asset containing the result mesh */
NewAsset,
/** Store the result mesh in the first selected input asset */
FirstInputAsset,
/** Store the result mesh in the last selected input asset */
LastInputAsset
};
UCLASS()
class MODELINGCOMPONENTS_API UBaseCreateFromSelectedHandleSourceProperties : public UOnAcceptHandleSourcesProperties
{
GENERATED_BODY()
public:
/** Where should the output mesh produced by this operation be stored */
UPROPERTY(EditAnywhere, Category = ToolOutputOptions)
EBaseCreateFromSelectedTargetType WriteOutputTo = EBaseCreateFromSelectedTargetType::NewAsset;
/** Base name for newly-generated asset */
UPROPERTY(EditAnywhere, Category = ToolOutputOptions, meta = (TransientToolProperty, EditCondition = "WriteOutputTo == EBaseCreateFromSelectedTargetType::NewAsset", EditConditionHides))
FString OutputName;
/** Name of asset that will be updated */
UPROPERTY(VisibleAnywhere, Category = ToolOutputOptions, meta = (TransientToolProperty, EditCondition = "WriteOutputTo != EBaseCreateFromSelectedTargetType::NewAsset", EditConditionHides))
FString OutputAsset;
};
/**
* Properties of UI to adjust input meshes
*/
UCLASS()
class MODELINGCOMPONENTS_API UTransformInputsToolProperties : public UInteractiveToolPropertySet
{
GENERATED_BODY()
public:
/** Show UI to allow changing translation, rotation and scale of input meshes */
UPROPERTY(EditAnywhere, Category = Transform)
bool bShowTransformUI = true;
/** Snap the cut plane to the world grid */
UPROPERTY(EditAnywhere, Category = Transform, meta = (EditCondition = "bShowTransformUI == true"))
bool bSnapToWorldGrid = false;
};
/**
* UBaseCreateFromSelectedTool is a base Tool (must be subclassed)
* that provides support for common functionality in tools that create a new mesh from a selection of one or more existing meshes
*/
UCLASS()
class MODELINGCOMPONENTS_API UBaseCreateFromSelectedTool : public UMultiSelectionTool, public UE::Geometry::IDynamicMeshOperatorFactory
{
GENERATED_BODY()
protected:
using FTransform3d = UE::Geometry::FTransform3d;
using FFrame3d = UE::Geometry::FFrame3d;
using FRay3d = UE::Geometry::FRay3d;
public:
UBaseCreateFromSelectedTool() = default;
virtual void SetWorld(UWorld* World);
//
// InteractiveTool API - generally does not need to be modified by subclasses
//
virtual void Setup() override;
virtual void Shutdown(EToolShutdownType ShutdownType) override;
virtual void OnTick(float DeltaTime) override;
virtual bool HasCancel() const override { return true; }
virtual bool HasAccept() const override { return true; }
virtual bool CanAccept() const override;
virtual void OnPropertyModified(UObject* PropertySet, FProperty* Property) override;
protected:
//
// UBaseCreateFromSelectedTool API - subclasses typically implement these functions
//
/**
* After preview is created, this is called to convert inputs and set preview materials
* (grouped together because materials may come from inputs)
* Subclasses should always implement this.
* @param bSetPreviewMesh If true, function may try to set an initial "early" preview mesh to have some initial surface on tool start. (Not all tools will actually create this.)
* This boolean is here in case a subclass needs to call this setup function again later (e.g. to change the materials used), when it won't need or want the preview surface to be created
*/
virtual void ConvertInputsAndSetPreviewMaterials(bool bSetPreviewMesh = true) { check(false); }
/** overload to initialize any added properties in subclasses; called during setup */
virtual void SetupProperties() {}
/** overload to save any added properties in the subclasses; called on shutdown */
virtual void SaveProperties() {}
/** optional overload to set callbacks on preview, e.g. to visualize results; called after preview is created. */
virtual void SetPreviewCallbacks() {}
/** Return the name to be used for generated assets. Note: Asset name will be prefixed by source actor name if only actor was selected. */
virtual FString GetCreatedAssetName() const { return TEXT("Generated"); }
/** Return the name of the action to be used in the Undo stack */
virtual FText GetActionName() const;
/** Return the materials to be used on the output mesh on tool accept; defaults to the materials set on the preview */
virtual TArray<UMaterialInterface*> GetOutputMaterials() const;
/**
* IDynamicMeshOperatorFactory implementation that subclass must override and implement
*/
virtual TUniquePtr<UE::Geometry::FDynamicMeshOperator> MakeNewOperator() override
{
check(false);
return TUniquePtr<UE::Geometry::FDynamicMeshOperator>();
}
protected:
/** Helper to build asset names */
FString PrefixWithSourceNameIfSingleSelection(const FString& AssetName) const;
// Helpers for managing transform gizoms; typically do not need to be overloaded
virtual void UpdateGizmoVisibility();
virtual void SetTransformGizmos();
virtual void TransformChanged(UTransformProxy* Proxy, FTransform Transform);
// Helper to generate assets when a result is accepted; typically does not need to be overloaded
virtual void GenerateAsset(const FDynamicMeshOpResult& Result);
// Helper to generate assets when a result is accepted; typically does not need to be overloaded
virtual void UpdateAsset(const FDynamicMeshOpResult& Result, UToolTarget* Target);
// Which of the transform gizmos to hide, or -1 if all gizmos can be shown
virtual int32 GetHiddenGizmoIndex() const;
protected:
UPROPERTY()
UTransformInputsToolProperties* TransformProperties;
UPROPERTY()
UCreateMeshObjectTypeProperties* OutputTypeProperties;
UPROPERTY()
UBaseCreateFromSelectedHandleSourceProperties* HandleSourcesProperties;
UPROPERTY()
UMeshOpPreviewWithBackgroundCompute* Preview;
UPROPERTY()
TArray<UTransformProxy*> TransformProxies;
UPROPERTY()
TArray<UTransformGizmo*> TransformGizmos;
UWorld* TargetWorld = nullptr;
};