2020-01-27 20:11:15 -05:00
// Copyright Epic Games, Inc. All Rights Reserved.
# pragma once
# include "CoreMinimal.h"
# include "UObject/NoExportTypes.h"
# include "BaseTools/MeshSurfacePointTool.h"
# include "Mechanics/PlaneDistanceFromHitMechanic.h"
# include "Mechanics/SpatialCurveDistanceMechanic.h"
# include "Mechanics/CollectSurfacePathMechanic.h"
# include "Mechanics/ConstructionPlaneMechanic.h"
# include "Drawing/PolyEditPreviewMesh.h"
2021-06-23 22:14:55 -04:00
# include "PropertySets/CreateMeshObjectTypeProperties.h"
2020-01-27 20:11:15 -05:00
# include "Properties/MeshMaterialProperties.h"
# include "DrawPolyPathTool.generated.h"
class FMeshVertexChangeBuilder ;
class UTransformProxy ;
/**
* ToolBuilder
*/
UCLASS ( )
2021-07-29 20:08:48 -04:00
class MESHMODELINGTOOLSEXP_API UDrawPolyPathToolBuilder : public UMeshSurfacePointToolBuilder
2020-01-27 20:11:15 -05:00
{
GENERATED_BODY ( )
public :
virtual bool CanBuildTool ( const FToolBuilderState & SceneState ) const override ;
virtual UInteractiveTool * BuildTool ( const FToolBuilderState & SceneState ) const override ;
} ;
UENUM ( )
enum class EDrawPolyPathWidthMode
{
2021-10-21 17:57:49 -04:00
/** Fixed width along the drawn path determined by the Width property */
Fixed ,
/** Extrude drawn path to height set via additional mouse input after finishing the path */
Interactive
2020-01-27 20:11:15 -05:00
} ;
2022-01-10 15:56:01 -05:00
UENUM ( )
enum class EDrawPolyPathRadiusMode
{
/** Fixed radius determined by the CornerRadius property. */
Fixed ,
/** Set the radius interactively by clicking in the viewport. */
Interactive
} ;
2020-01-27 20:11:15 -05:00
UENUM ( )
2021-10-21 17:57:49 -04:00
enum class EDrawPolyPathExtrudeMode
2020-01-27 20:11:15 -05:00
{
2021-10-21 17:57:49 -04:00
/** Flat path without extrusion */
Flat ,
2020-01-27 20:11:15 -05:00
2021-10-21 17:57:49 -04:00
/** Extrude drawn path to a fixed height determined by the Extrude Height property */
Fixed ,
/** Extrude drawn path to height set via additional mouse input after finishing the path */
Interactive ,
/** Extrude with increasing height along the drawn path. The height at the start and the end of the ramp is determined by the Extrude Height and Ramp Start Ratio properties .*/
RampFixed ,
/** Extrude with increasing height along the drawn path. The height is set via additional mouse input after finishing the path. */
RampInteractive
} ;
2020-01-27 20:11:15 -05:00
UCLASS ( )
2021-07-29 20:08:48 -04:00
class MESHMODELINGTOOLSEXP_API UDrawPolyPathProperties : public UInteractiveToolPropertySet
2020-01-27 20:11:15 -05:00
{
GENERATED_BODY ( )
public :
2021-10-21 17:57:49 -04:00
/** How the drawn path width gets set */
UPROPERTY ( EditAnywhere , Category = Path )
2020-01-27 20:11:15 -05:00
EDrawPolyPathWidthMode WidthMode = EDrawPolyPathWidthMode : : Interactive ;
2021-10-21 17:57:49 -04:00
/** Width of the drawn path when using Fixed width mode; also shows the width in Interactive width mode */
2022-01-10 15:56:01 -05:00
UPROPERTY ( EditAnywhere , Category = Path , meta = ( EditCondition = " WidthMode == EDrawPolyPathWidthMode::Fixed " ,
UIMin = " 0.0001 " , UIMax = " 1000 " , ClampMin = " 0.0001 " , ClampMax = " 999999 " ) )
2020-01-27 20:11:15 -05:00
float Width = 10.0f ;
2021-12-10 18:05:44 -05:00
/** Use arc segments instead of straight lines in corners */
UPROPERTY ( EditAnywhere , Category = Path )
bool bRoundedCorners = false ;
2022-01-10 15:56:01 -05:00
/** How the rounded corner radius gets set */
UPROPERTY ( EditAnywhere , Category = Path , meta = ( EditCondition = " bRoundedCorners " ) )
EDrawPolyPathRadiusMode RadiusMode = EDrawPolyPathRadiusMode : : Interactive ;
/** Radius of the corner arcs, as a fraction of path width. This is only available if Rounded Corners is enabled. */
UPROPERTY ( EditAnywhere , Category = Path , meta = (
EditCondition = " RadiusMode == EDrawPolyPathRadiusMode::Fixed && bRoundedCorners " ,
UIMin = " 0 " , UIMax = " 2.0 " , ClampMin = " 0 " , ClampMax = " 999999 " ) )
float CornerRadius = 0.5f ;
2021-12-10 18:05:44 -05:00
/** Number of radial subdivisions for rounded corners */
UPROPERTY ( EditAnywhere , NonTransactional , Category = Path , meta = ( UIMin = " 3 " , UIMax = " 100 " , ClampMin = " 3 " , ClampMax = " 10000 " ,
EditCondition = " bRoundedCorners " ) )
int RadialSlices = 16 ;
2021-11-18 14:37:34 -05:00
/** If true, all quads on the path will belong to the same polygon. If false, each quad gets its own polygon. */
UPROPERTY ( EditAnywhere , Category = Path )
bool bSinglePolyGroup = false ;
2021-10-21 17:57:49 -04:00
/** If and how the drawn path gets extruded */
UPROPERTY ( EditAnywhere , Category = Extrude )
EDrawPolyPathExtrudeMode ExtrudeMode = EDrawPolyPathExtrudeMode : : Interactive ;
2020-01-27 20:11:15 -05:00
2021-10-21 17:57:49 -04:00
/** Extrusion distance when using the Fixed extrude modes; also shows the distance in Interactive extrude modes */
UPROPERTY ( EditAnywhere , Category = Extrude , meta = (
EditCondition = " ExtrudeMode == EDrawPolyPathExtrudeMode::Fixed || ExtrudeMode == EDrawPolyPathExtrudeMode::RampFixed " ,
UIMin = " -1000 " , UIMax = " 1000 " , ClampMin = " -10000 " , ClampMax = " 10000 " ) )
float ExtrudeHeight = 10.0f ;
2020-01-27 20:11:15 -05:00
2021-10-21 17:57:49 -04:00
/** Height of the start of the ramp as a fraction of the Extrude Height property */
UPROPERTY ( EditAnywhere , Category = Extrude , meta = (
EditCondition = " ExtrudeMode == EDrawPolyPathExtrudeMode::RampFixed || ExtrudeMode == EDrawPolyPathExtrudeMode::RampInteractive " ,
UIMin = " 0.0 " , UIMax = " 1.0 " , ClampMin = " 0.0 " , ClampMax = " 100.0 " ) )
2020-03-03 16:57:38 -05:00
float RampStartRatio = 0.05f ;
2020-01-27 20:11:15 -05:00
} ;
UENUM ( )
enum class EDrawPolyPathExtrudeDirection
{
SelectionNormal ,
WorldX ,
WorldY ,
WorldZ ,
LocalX ,
LocalY ,
LocalZ
} ;
UCLASS ( )
2021-07-29 20:08:48 -04:00
class MESHMODELINGTOOLSEXP_API UDrawPolyPathExtrudeProperties : public UInteractiveToolPropertySet
2020-01-27 20:11:15 -05:00
{
GENERATED_BODY ( )
public :
UPROPERTY ( EditAnywhere , Category = Extrude )
EDrawPolyPathExtrudeDirection Direction = EDrawPolyPathExtrudeDirection : : SelectionNormal ;
} ;
/**
*
*/
UCLASS ( )
2021-07-29 20:08:48 -04:00
class MESHMODELINGTOOLSEXP_API UDrawPolyPathTool : public UInteractiveTool , public IClickBehaviorTarget , public IHoverBehaviorTarget
2020-01-27 20:11:15 -05:00
{
GENERATED_BODY ( )
public :
virtual void SetWorld ( UWorld * World ) ;
virtual void Setup ( ) override ;
virtual void Shutdown ( EToolShutdownType ShutdownType ) override ;
2022-01-10 15:56:01 -05:00
virtual void OnPropertyModified ( UObject * PropertySet , FProperty * Property ) override ;
2020-04-18 18:42:59 -04:00
virtual void OnTick ( float DeltaTime ) override ;
2020-01-27 20:11:15 -05:00
virtual void Render ( IToolsContextRenderAPI * RenderAPI ) override ;
virtual bool HasCancel ( ) const override { return false ; }
virtual bool HasAccept ( ) const override { return false ; }
virtual bool CanAccept ( ) const override { return false ; }
virtual bool HitTest ( const FRay & Ray , FHitResult & OutHit ) ;
// IClickBehaviorTarget API
virtual FInputRayHit IsHitByClick ( const FInputDeviceRay & ClickPos ) override ;
virtual void OnClicked ( const FInputDeviceRay & ClickPos ) override ;
// IHoverBehaviorTarget API
virtual FInputRayHit BeginHoverSequenceHitTest ( const FInputDeviceRay & PressPos ) override ;
virtual void OnBeginHover ( const FInputDeviceRay & DevicePos ) override { }
virtual bool OnUpdateHover ( const FInputDeviceRay & DevicePos ) override ;
virtual void OnEndHover ( ) override { }
2022-01-10 15:56:01 -05:00
// IModifierToggleBehaviorTarget
virtual void OnUpdateModifierState ( int ModifierID , bool bIsOn ) override ;
2020-01-27 20:11:15 -05:00
protected :
UWorld * TargetWorld ;
ModelingTools: add support for creating Volumes directly from DrawPolygon, DrawRevolve, DrawPolyPath, and AddPrimitive, CombineMeshes, CutMeshWithMesh, PlaneCut, BaseCreateFromSelected Tools. Improve support for Editing volumes, eg handling mesh/volume interactions, and add configurable auto-simplification for volumes to avoid painful Editor hangs.
- Move ToolTarget implementations, DynamicMeshToVolume to ModelingComponentsEditorOnly module
- move VolumeToDynamicMesh, DynamicMeshProvider/Commiter interfaces to ModelingComponents module
- Add UCreateMeshObjectTypeProperties property set to expose mesh/volume options
- Add FCreateMeshObjectParams::TypeHintClass to allow AVolume type (or other UClass hints) to be passed to creation APIs
- Add UE::ToolTarget::ConfigureCreateMeshObjectParams() util function in ModelingToolTargetUtil, tries to determine output type in a FCreateMeshObjectParams based on input ToolTarget
- Add UEditorModelingObjectsCreationAPI::CreateVolume() implementation
- Add UEditorModelingObjectsCreationAPI::FilterMaterials() that strips out any internal materials and replaces with WorldGridMaterial. This occurs when (eg) subtracting a Volume from a StaticMesh, because the temporary volume mesh gets assigned internal materials, but the Tools don't know this. Use in EditorModelingObjectsCreationAPI when creating new objects. UStaticMeshComponentToolTarget also does this filtering in ::CommitMaterialSetUpdate().
- Add ::ComponentTypeSupportsCollision() function to ComponentCollisionUtil, use to avoid checks/ensures for Volume targets
- Add support for automatic mesh simplification in DynamicMeshToVolume. Add CVar to VolumeDynamicMeshToolTarget.h to control max triangle count (default 500). Apply auto-simplify when creating or updating an AVolume. This prevents the Editor from blocking for long periods on meshes that are too high-res for volumes (even 500 is quite high).
- DynamicMeshToVolume now emits polygroup-faces that contain holes (ie multiple boundary loops) as a set of triangles, rather than emitting separate overlapping faces for each boundary loop
#rb none
#rnx
#jira none
#preflight 60ba50632c42ea0001cb54c5
[CL 16561742 by Ryan Schmidt in ue5-main branch]
2021-06-04 16:04:03 -04:00
/** Property set for type of output object (StaticMesh, Volume, etc) */
UPROPERTY ( )
2021-07-20 00:24:38 -04:00
TObjectPtr < UCreateMeshObjectTypeProperties > OutputTypeProperties ;
ModelingTools: add support for creating Volumes directly from DrawPolygon, DrawRevolve, DrawPolyPath, and AddPrimitive, CombineMeshes, CutMeshWithMesh, PlaneCut, BaseCreateFromSelected Tools. Improve support for Editing volumes, eg handling mesh/volume interactions, and add configurable auto-simplification for volumes to avoid painful Editor hangs.
- Move ToolTarget implementations, DynamicMeshToVolume to ModelingComponentsEditorOnly module
- move VolumeToDynamicMesh, DynamicMeshProvider/Commiter interfaces to ModelingComponents module
- Add UCreateMeshObjectTypeProperties property set to expose mesh/volume options
- Add FCreateMeshObjectParams::TypeHintClass to allow AVolume type (or other UClass hints) to be passed to creation APIs
- Add UE::ToolTarget::ConfigureCreateMeshObjectParams() util function in ModelingToolTargetUtil, tries to determine output type in a FCreateMeshObjectParams based on input ToolTarget
- Add UEditorModelingObjectsCreationAPI::CreateVolume() implementation
- Add UEditorModelingObjectsCreationAPI::FilterMaterials() that strips out any internal materials and replaces with WorldGridMaterial. This occurs when (eg) subtracting a Volume from a StaticMesh, because the temporary volume mesh gets assigned internal materials, but the Tools don't know this. Use in EditorModelingObjectsCreationAPI when creating new objects. UStaticMeshComponentToolTarget also does this filtering in ::CommitMaterialSetUpdate().
- Add ::ComponentTypeSupportsCollision() function to ComponentCollisionUtil, use to avoid checks/ensures for Volume targets
- Add support for automatic mesh simplification in DynamicMeshToVolume. Add CVar to VolumeDynamicMeshToolTarget.h to control max triangle count (default 500). Apply auto-simplify when creating or updating an AVolume. This prevents the Editor from blocking for long periods on meshes that are too high-res for volumes (even 500 is quite high).
- DynamicMeshToVolume now emits polygroup-faces that contain holes (ie multiple boundary loops) as a set of triangles, rather than emitting separate overlapping faces for each boundary loop
#rb none
#rnx
#jira none
#preflight 60ba50632c42ea0001cb54c5
[CL 16561742 by Ryan Schmidt in ue5-main branch]
2021-06-04 16:04:03 -04:00
2020-01-27 20:11:15 -05:00
UPROPERTY ( )
2021-07-20 00:24:38 -04:00
TObjectPtr < UDrawPolyPathProperties > TransformProps ;
2020-01-27 20:11:15 -05:00
UPROPERTY ( )
2021-07-20 00:24:38 -04:00
TObjectPtr < UDrawPolyPathExtrudeProperties > ExtrudeProperties ;
2020-01-27 20:11:15 -05:00
UPROPERTY ( )
2021-07-20 00:24:38 -04:00
TObjectPtr < UNewMeshMaterialProperties > MaterialProperties ;
2020-01-27 20:11:15 -05:00
protected :
2022-01-10 15:56:01 -05:00
enum class EState
{
DrawingPath ,
SettingWidth ,
SettingRadius ,
SettingHeight
} ;
EState State = EState : : DrawingPath ;
2020-01-27 20:11:15 -05:00
// camera state at last render
2022-01-29 14:37:53 -05:00
FTransform3d WorldTransform ;
2020-01-27 20:11:15 -05:00
FViewCameraState CameraState ;
// drawing plane and gizmo
UPROPERTY ( )
2021-07-20 00:24:38 -04:00
TObjectPtr < UConstructionPlaneMechanic > PlaneMechanic = nullptr ;
2020-01-27 20:11:15 -05:00
2021-03-09 19:33:56 -04:00
UE : : Geometry : : FFrame3d DrawPlaneWorld ;
2020-01-27 20:11:15 -05:00
bool CanUpdateDrawPlane ( ) const ;
// UV Scale factor to apply to texturing on any new geometry (e.g. new faces added by extrude)
float UVScaleFactor = 1.0f ;
2021-03-09 19:33:56 -04:00
TArray < UE : : Geometry : : FFrame3d > CurPathPoints ;
2020-01-27 20:11:15 -05:00
TArray < double > OffsetScaleFactors ;
2021-03-17 21:45:29 -04:00
TArray < FVector3d > CurPolyLine ;
2020-01-27 20:11:15 -05:00
double CurPathLength ;
double CurHeight ;
2021-11-23 10:39:20 -05:00
bool bHasSavedWidth = false ;
float SavedWidth ;
2022-01-10 15:56:01 -05:00
bool bHasSavedRadius = false ;
float SavedRadius ;
2021-11-23 10:39:20 -05:00
bool bHasSavedExtrudeHeight = false ;
float SavedExtrudeHeight ;
2020-03-09 13:52:38 -04:00
bool bPathIsClosed = false ; // If true, CurPathPoints are assumed to define a closed path
2020-01-27 20:11:15 -05:00
2022-01-10 15:56:01 -05:00
static const int ShiftModifierID = 1 ;
bool bIgnoreSnappingToggle = false ; // toggled by hotkey (shift)
2021-10-13 12:32:03 -04:00
TArray < FVector3d > CurPolyLoop ;
TArray < FVector3d > SecondPolyLoop ;
2020-01-27 20:11:15 -05:00
UPROPERTY ( )
2021-07-20 00:24:38 -04:00
TObjectPtr < UPolyEditPreviewMesh > EditPreview ;
2020-01-27 20:11:15 -05:00
UPROPERTY ( )
2021-07-20 00:24:38 -04:00
TObjectPtr < UPlaneDistanceFromHitMechanic > ExtrudeHeightMechanic = nullptr ;
2020-01-27 20:11:15 -05:00
UPROPERTY ( )
2021-07-20 00:24:38 -04:00
TObjectPtr < USpatialCurveDistanceMechanic > CurveDistMechanic = nullptr ;
2020-01-27 20:11:15 -05:00
UPROPERTY ( )
2021-07-20 00:24:38 -04:00
TObjectPtr < UCollectSurfacePathMechanic > SurfacePathMechanic = nullptr ;
2020-01-27 20:11:15 -05:00
2021-12-10 18:05:44 -05:00
bool bSpecifyingRadius = false ;
2020-01-27 20:11:15 -05:00
void InitializeNewSurfacePath ( ) ;
void UpdateSurfacePathPlane ( ) ;
void OnCompleteSurfacePath ( ) ;
2022-01-10 15:56:01 -05:00
void BeginSettingWidth ( ) ;
2021-12-10 18:05:44 -05:00
void OnCompleteWidth ( ) ;
2022-01-10 15:56:01 -05:00
void BeginSettingRadius ( ) ;
2021-12-10 18:05:44 -05:00
void OnCompleteRadius ( ) ;
2022-01-10 15:56:01 -05:00
void BeginSettingHeight ( ) ;
2020-01-27 20:11:15 -05:00
void BeginInteractiveExtrudeHeight ( ) ;
2022-01-10 15:56:01 -05:00
void BeginConstantExtrudeHeight ( ) ;
2020-01-27 20:11:15 -05:00
void UpdateExtrudePreview ( ) ;
2021-12-10 18:05:44 -05:00
void OnCompleteExtrudeHeight ( ) ;
void UpdatePathPreview ( ) ;
2020-01-27 20:11:15 -05:00
void InitializePreviewMesh ( ) ;
void ClearPreview ( ) ;
2021-12-10 18:05:44 -05:00
2021-03-09 19:33:56 -04:00
void GeneratePathMesh ( UE : : Geometry : : FDynamicMesh3 & Mesh ) ;
void GenerateExtrudeMesh ( UE : : Geometry : : FDynamicMesh3 & PathMesh ) ;
2021-11-23 10:39:20 -05:00
void EmitNewObject ( ) ;
2020-01-27 20:11:15 -05:00
2020-03-10 14:00:36 -04:00
// user feedback messages
void ShowStartupMessage ( ) ;
void ShowExtrudeMessage ( ) ;
void ShowOffsetMessage ( ) ;
2020-01-27 20:11:15 -05:00
friend class FDrawPolyPathStateChange ;
int32 CurrentCurveTimestamp = 1 ;
2022-01-10 15:56:01 -05:00
void UndoCurrentOperation ( EState DestinationState ) ;
2020-01-27 20:11:15 -05:00
bool CheckInCurve ( int32 Timestamp ) const { return CurrentCurveTimestamp = = Timestamp ; }
} ;
2021-07-29 20:08:48 -04:00
class MESHMODELINGTOOLSEXP_API FDrawPolyPathStateChange : public FToolCommandChange
2020-01-27 20:11:15 -05:00
{
public :
bool bHaveDoneUndo = false ;
int32 CurveTimestamp = 0 ;
2022-01-10 15:56:01 -05:00
UDrawPolyPathTool : : EState PreviousState = UDrawPolyPathTool : : EState : : DrawingPath ;
FDrawPolyPathStateChange ( int32 CurveTimestampIn , UDrawPolyPathTool : : EState PreviousStateIn )
: CurveTimestamp ( CurveTimestampIn )
, PreviousState ( PreviousStateIn )
2020-01-27 20:11:15 -05:00
{
}
virtual void Apply ( UObject * Object ) override { }
virtual void Revert ( UObject * Object ) override ;
virtual bool HasExpired ( UObject * Object ) const override ;
virtual FString ToString ( ) const override ;
2020-03-09 13:52:38 -04:00
} ;