2020-01-27 20:11:15 -05:00
|
|
|
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
|
|
|
|
|
|
#include "Selection/PolygonSelectionMechanic.h"
|
2022-10-26 12:57:32 -04:00
|
|
|
#include "Engine/World.h"
|
2022-09-14 15:25:19 -04:00
|
|
|
#include "Selection/GroupTopologySelector.h"
|
ModelingTools: replace StorableSelection mechanism with new UPersistentMeshSelection and UPersistentMeshSelectionManager context object.
- UPersistentMeshSelection is largely a port of UGroupTopologyStorableSelection, with the actual selection data moved to FGenericMeshSelection
- UPersistentMeshSelectionManager is meant to be used as a ContextObject in a ToolsContext, also contains utility functions to register/unregister/find context object
- Selection is no longer passed as part of FToolBuilderState. Instead Tools access the selection via ContextObject
- UPersistentMeshSelectionManager currently supports a single active selection. Selection changes are transacted via an FChange.
- When not inside a Tool, Selection is visualized with a pink border outline. Currently vertex selection is not visualized.
- Usage model is that on Tool Accept/Complete, prior to Tool Shutdown, any existing selection is cleared, and Tool may set a new Output selection which becomes the active selection
- StoredMeshSelectionUtil.h has utility functions to get current selection, set output selection, and clear it
- SingleSelectionMeshEditingTool already made input selection available to subclasses, port that capability to new architecture
- convert EditMeshPolygonsTool to be a SingleSelectionMeshEditingTool, use provided Input selection and set Output selection as appropriate
- ModelingToolsEditorMode clears active selection where appropriate, eg if selected object changes. However the behavior here will need further improvement, currently relies on questionable event handling from the TypedElement system
#rb semion.piskarev
#rnx
#jira none
#preflight 6136cbbfd9c85a0001fc3b56
#ROBOMERGE-AUTHOR: ryan.schmidt
#ROBOMERGE-SOURCE: CL 17441056 in //UE5/Main/...
#ROBOMERGE-BOT: STARSHIP (Main -> Release-Engine-Test) (v870-17433530)
[CL 17441061 by ryan schmidt in ue5-release-engine-test branch]
2021-09-06 23:05:07 -04:00
|
|
|
#include "Selection/PersistentMeshSelection.h"
|
ModelingMode: improve interop with new Selection System and existing Tools
Add support for Tools to provide an "output" selection. Add UGeometrySelectionManager::SetSelectionForComponent() which can set an explicit externally-provided selection. FBaseDynamicMeshSelector::UpdateSelectionFromSelection() now supports selection conversion when available and requested (is used to implement SetSelectionForComponent). New GeometrySelectionUtil functions InitializeSelectionFromTriangles() and ConvertSelection() are used to implement this (note: only Triangles->other conversion is currently supported). Add HaveAvailableGeometrySelection() and SetToolOutputGeometrySelectionForTarget() in StoredMeshSelectionUtil.h, this is the top-level function that Tools can use to set an Output selection.
ExtrudeMeshSelectionTool now emits output selection.
Update EditMeshPolygonsTool to use new Selection system and allow individual operations to be utilized as standalone Tools. Convert EditMeshPolygonsTool to be a USingleTargetWithSelectionTool, use FGeometrySelection to initialize selection. Add bTerminateOnPendingActionComplete flag, which is set when Tool is directly initialized to a specific operation, and forces tool to shut down when operation completes. This allows it to be used to more cleanly implement multiple action buttons in Modeling UI. When in this mode, selection panels are not shown. On Shutdown, now emits an "output" selection which GeometrySelectionManager can use to provide new selection to user. Update UPolygonSelectionMechanic Set/Get selection APIs to use FGeometrySelection instead of UPersistentMeshSelection.
port UVProjectionTool to derive from USingleTargetWithSelectionTool, use FGeometrySelection to initialize target ROI
deprecate UPersistentMeshSelection and related functions in StoredMeshSelectionUtil.h. Deprecate Tool Input Selection APIs in USingleSelectionMeshEditingTool and Builder.
Repurpose old ModelingMode-level PolyModel tab operations for new Selection Tools UI, now support Inset, Outset, Cut Faces, Insert Edge Loop, PushPull, and Bevel.
#rb none
#preflight 63c84fa2b065224750b9831f
[CL 23766643 by ryan schmidt in ue5-main branch]
2023-01-18 17:59:31 -05:00
|
|
|
#include "Selections/GeometrySelection.h"
|
2020-01-27 20:11:15 -05:00
|
|
|
|
2022-09-28 01:06:15 -04:00
|
|
|
#include UE_INLINE_GENERATED_CPP_BY_NAME(PolygonSelectionMechanic)
|
|
|
|
|
|
2021-03-09 19:33:56 -04:00
|
|
|
using namespace UE::Geometry;
|
|
|
|
|
|
2020-01-27 20:11:15 -05:00
|
|
|
#define LOCTEXT_NAMESPACE "UPolygonSelectionMechanic"
|
|
|
|
|
|
2022-09-14 15:25:19 -04:00
|
|
|
void UPolygonSelectionMechanic::Initialize(
|
|
|
|
|
const FDynamicMesh3* MeshIn,
|
|
|
|
|
FTransform3d TargetTransformIn,
|
|
|
|
|
UWorld* WorldIn,
|
|
|
|
|
const FGroupTopology* TopologyIn,
|
|
|
|
|
TFunction<FDynamicMeshAABBTree3* ()> GetSpatialSourceFuncIn)
|
2022-02-01 10:16:18 -05:00
|
|
|
{
|
2022-09-14 15:25:19 -04:00
|
|
|
Topology = TopologyIn;
|
|
|
|
|
TopoSelector = MakeShared<FGroupTopologySelector>(MeshIn, TopologyIn);
|
|
|
|
|
|
|
|
|
|
UMeshTopologySelectionMechanic::Initialize(MeshIn, TargetTransformIn, WorldIn, GetSpatialSourceFuncIn);
|
2022-02-01 10:16:18 -05:00
|
|
|
}
|
|
|
|
|
|
2022-09-14 15:25:19 -04:00
|
|
|
void UPolygonSelectionMechanic::Initialize(
|
|
|
|
|
UDynamicMeshComponent* MeshComponentIn,
|
|
|
|
|
const FGroupTopology* TopologyIn,
|
|
|
|
|
TFunction<FDynamicMeshAABBTree3* ()> GetSpatialSourceFuncIn)
|
2022-02-01 10:16:18 -05:00
|
|
|
{
|
2022-09-14 15:25:19 -04:00
|
|
|
Initialize(MeshComponentIn->GetMesh(),
|
|
|
|
|
(FTransform3d)MeshComponentIn->GetComponentTransform(),
|
|
|
|
|
MeshComponentIn->GetWorld(),
|
|
|
|
|
TopologyIn,
|
|
|
|
|
GetSpatialSourceFuncIn);
|
2020-06-23 18:40:00 -04:00
|
|
|
}
|
|
|
|
|
|
2022-09-14 15:25:19 -04:00
|
|
|
// TODO: Remove this function when Properties is removed after deprecation
|
2020-01-27 20:11:15 -05:00
|
|
|
void UPolygonSelectionMechanic::Setup(UInteractiveTool* ParentToolIn)
|
|
|
|
|
{
|
2022-09-14 15:25:19 -04:00
|
|
|
UMeshTopologySelectionMechanic::Setup(ParentToolIn);
|
2020-01-27 20:11:15 -05:00
|
|
|
|
2022-09-14 15:25:19 -04:00
|
|
|
PRAGMA_DISABLE_DEPRECATION_WARNINGS
|
|
|
|
|
Properties_DEPRECATED = NewObject<UDEPRECATED_PolygonSelectionMechanicProperties>(this);
|
|
|
|
|
Properties_DEPRECATED->Initialize(this);
|
|
|
|
|
Properties_DEPRECATED->WatchProperty(Properties_DEPRECATED->bSelectVertices, [this](bool bSelectVertices) {
|
2022-01-27 17:09:13 -05:00
|
|
|
UpdateMarqueeEnabled();
|
|
|
|
|
});
|
2022-09-14 15:25:19 -04:00
|
|
|
Properties_DEPRECATED->WatchProperty(Properties_DEPRECATED->bSelectEdges, [this](bool bSelectVertices) {
|
|
|
|
|
UpdateMarqueeEnabled();
|
2021-07-23 12:36:00 -04:00
|
|
|
});
|
2022-09-14 15:25:19 -04:00
|
|
|
Properties_DEPRECATED->WatchProperty(Properties_DEPRECATED->bSelectFaces, [this](bool bSelectFaces) {
|
|
|
|
|
UpdateMarqueeEnabled();
|
|
|
|
|
});
|
|
|
|
|
Properties_DEPRECATED->WatchProperty(Properties_DEPRECATED->bEnableMarquee, [this](bool bEnableMarquee) {
|
|
|
|
|
UpdateMarqueeEnabled();
|
|
|
|
|
});
|
|
|
|
|
PRAGMA_ENABLE_DEPRECATION_WARNINGS
|
2020-01-27 20:11:15 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
ModelingMode: improve interop with new Selection System and existing Tools
Add support for Tools to provide an "output" selection. Add UGeometrySelectionManager::SetSelectionForComponent() which can set an explicit externally-provided selection. FBaseDynamicMeshSelector::UpdateSelectionFromSelection() now supports selection conversion when available and requested (is used to implement SetSelectionForComponent). New GeometrySelectionUtil functions InitializeSelectionFromTriangles() and ConvertSelection() are used to implement this (note: only Triangles->other conversion is currently supported). Add HaveAvailableGeometrySelection() and SetToolOutputGeometrySelectionForTarget() in StoredMeshSelectionUtil.h, this is the top-level function that Tools can use to set an Output selection.
ExtrudeMeshSelectionTool now emits output selection.
Update EditMeshPolygonsTool to use new Selection system and allow individual operations to be utilized as standalone Tools. Convert EditMeshPolygonsTool to be a USingleTargetWithSelectionTool, use FGeometrySelection to initialize selection. Add bTerminateOnPendingActionComplete flag, which is set when Tool is directly initialized to a specific operation, and forces tool to shut down when operation completes. This allows it to be used to more cleanly implement multiple action buttons in Modeling UI. When in this mode, selection panels are not shown. On Shutdown, now emits an "output" selection which GeometrySelectionManager can use to provide new selection to user. Update UPolygonSelectionMechanic Set/Get selection APIs to use FGeometrySelection instead of UPersistentMeshSelection.
port UVProjectionTool to derive from USingleTargetWithSelectionTool, use FGeometrySelection to initialize target ROI
deprecate UPersistentMeshSelection and related functions in StoredMeshSelectionUtil.h. Deprecate Tool Input Selection APIs in USingleSelectionMeshEditingTool and Builder.
Repurpose old ModelingMode-level PolyModel tab operations for new Selection Tools UI, now support Inset, Outset, Cut Faces, Insert Edge Loop, PushPull, and Bevel.
#rb none
#preflight 63c84fa2b065224750b9831f
[CL 23766643 by ryan schmidt in ue5-main branch]
2023-01-18 17:59:31 -05:00
|
|
|
void UPolygonSelectionMechanic::GetSelection_AsGroupTopology(UE::Geometry::FGeometrySelection& SelectionOut, const FCompactMaps* CompactMapsToApply) const
|
2020-11-13 14:07:30 -04:00
|
|
|
{
|
ModelingMode: improve interop with new Selection System and existing Tools
Add support for Tools to provide an "output" selection. Add UGeometrySelectionManager::SetSelectionForComponent() which can set an explicit externally-provided selection. FBaseDynamicMeshSelector::UpdateSelectionFromSelection() now supports selection conversion when available and requested (is used to implement SetSelectionForComponent). New GeometrySelectionUtil functions InitializeSelectionFromTriangles() and ConvertSelection() are used to implement this (note: only Triangles->other conversion is currently supported). Add HaveAvailableGeometrySelection() and SetToolOutputGeometrySelectionForTarget() in StoredMeshSelectionUtil.h, this is the top-level function that Tools can use to set an Output selection.
ExtrudeMeshSelectionTool now emits output selection.
Update EditMeshPolygonsTool to use new Selection system and allow individual operations to be utilized as standalone Tools. Convert EditMeshPolygonsTool to be a USingleTargetWithSelectionTool, use FGeometrySelection to initialize selection. Add bTerminateOnPendingActionComplete flag, which is set when Tool is directly initialized to a specific operation, and forces tool to shut down when operation completes. This allows it to be used to more cleanly implement multiple action buttons in Modeling UI. When in this mode, selection panels are not shown. On Shutdown, now emits an "output" selection which GeometrySelectionManager can use to provide new selection to user. Update UPolygonSelectionMechanic Set/Get selection APIs to use FGeometrySelection instead of UPersistentMeshSelection.
port UVProjectionTool to derive from USingleTargetWithSelectionTool, use FGeometrySelection to initialize target ROI
deprecate UPersistentMeshSelection and related functions in StoredMeshSelectionUtil.h. Deprecate Tool Input Selection APIs in USingleSelectionMeshEditingTool and Builder.
Repurpose old ModelingMode-level PolyModel tab operations for new Selection Tools UI, now support Inset, Outset, Cut Faces, Insert Edge Loop, PushPull, and Bevel.
#rb none
#preflight 63c84fa2b065224750b9831f
[CL 23766643 by ryan schmidt in ue5-main branch]
2023-01-18 17:59:31 -05:00
|
|
|
const FGroupTopologySelection& CurSelection = PersistentSelection;
|
|
|
|
|
if (SelectionOut.TopologyType != EGeometryTopologyType::Polygroup)
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (SelectionOut.ElementType == EGeometryElementType::Vertex)
|
|
|
|
|
{
|
|
|
|
|
for (int32 CornerID : CurSelection.SelectedCornerIDs)
|
|
|
|
|
{
|
|
|
|
|
int32 VertexID = Topology->GetCornerVertexID(CornerID);
|
|
|
|
|
if (CompactMapsToApply != nullptr)
|
|
|
|
|
{
|
|
|
|
|
VertexID = CompactMapsToApply->GetVertexMapping(VertexID);
|
|
|
|
|
}
|
|
|
|
|
SelectionOut.Selection.Add( FGeoSelectionID(VertexID, CornerID).Encoded() );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (SelectionOut.ElementType == EGeometryElementType::Edge)
|
|
|
|
|
{
|
|
|
|
|
// TODO: not sure how we can apply compact maps here because mapping does not included compacted edges? are edges even compacted?
|
|
|
|
|
if ( CompactMapsToApply == nullptr )
|
|
|
|
|
{
|
|
|
|
|
for (int32 GroupEdgeID : CurSelection.SelectedEdgeIDs)
|
|
|
|
|
{
|
|
|
|
|
const TArray<int>& GroupEdge = Topology->GetGroupEdgeEdges(GroupEdgeID);
|
|
|
|
|
FMeshTriEdgeID TriEdgeID = Topology->GetMesh()->GetTriEdgeIDFromEdgeID(GroupEdge[0]);
|
|
|
|
|
SelectionOut.Selection.Add( FGeoSelectionID(TriEdgeID.Encoded(), GroupEdgeID).Encoded() );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (SelectionOut.ElementType == EGeometryElementType::Face)
|
|
|
|
|
{
|
|
|
|
|
for (int32 GroupID : CurSelection.SelectedGroupIDs)
|
|
|
|
|
{
|
|
|
|
|
const FGroupTopology::FGroup* GroupFace = Topology->FindGroupByID(GroupID);
|
|
|
|
|
if ( GroupFace )
|
|
|
|
|
{
|
|
|
|
|
FGeoSelectionID ID = FGeoSelectionID(GroupFace->Triangles[0], GroupFace->GroupID);
|
|
|
|
|
SelectionOut.Selection.Add(ID.Encoded());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-11-13 14:07:30 -04:00
|
|
|
}
|
|
|
|
|
|
ModelingMode: improve interop with new Selection System and existing Tools
Add support for Tools to provide an "output" selection. Add UGeometrySelectionManager::SetSelectionForComponent() which can set an explicit externally-provided selection. FBaseDynamicMeshSelector::UpdateSelectionFromSelection() now supports selection conversion when available and requested (is used to implement SetSelectionForComponent). New GeometrySelectionUtil functions InitializeSelectionFromTriangles() and ConvertSelection() are used to implement this (note: only Triangles->other conversion is currently supported). Add HaveAvailableGeometrySelection() and SetToolOutputGeometrySelectionForTarget() in StoredMeshSelectionUtil.h, this is the top-level function that Tools can use to set an Output selection.
ExtrudeMeshSelectionTool now emits output selection.
Update EditMeshPolygonsTool to use new Selection system and allow individual operations to be utilized as standalone Tools. Convert EditMeshPolygonsTool to be a USingleTargetWithSelectionTool, use FGeometrySelection to initialize selection. Add bTerminateOnPendingActionComplete flag, which is set when Tool is directly initialized to a specific operation, and forces tool to shut down when operation completes. This allows it to be used to more cleanly implement multiple action buttons in Modeling UI. When in this mode, selection panels are not shown. On Shutdown, now emits an "output" selection which GeometrySelectionManager can use to provide new selection to user. Update UPolygonSelectionMechanic Set/Get selection APIs to use FGeometrySelection instead of UPersistentMeshSelection.
port UVProjectionTool to derive from USingleTargetWithSelectionTool, use FGeometrySelection to initialize target ROI
deprecate UPersistentMeshSelection and related functions in StoredMeshSelectionUtil.h. Deprecate Tool Input Selection APIs in USingleSelectionMeshEditingTool and Builder.
Repurpose old ModelingMode-level PolyModel tab operations for new Selection Tools UI, now support Inset, Outset, Cut Faces, Insert Edge Loop, PushPull, and Bevel.
#rb none
#preflight 63c84fa2b065224750b9831f
[CL 23766643 by ryan schmidt in ue5-main branch]
2023-01-18 17:59:31 -05:00
|
|
|
|
|
|
|
|
void UPolygonSelectionMechanic::GetSelection_AsTriangleTopology(UE::Geometry::FGeometrySelection& SelectionOut, const FCompactMaps* CompactMapsToApply) const
|
2020-11-13 14:07:30 -04:00
|
|
|
{
|
ModelingMode: improve interop with new Selection System and existing Tools
Add support for Tools to provide an "output" selection. Add UGeometrySelectionManager::SetSelectionForComponent() which can set an explicit externally-provided selection. FBaseDynamicMeshSelector::UpdateSelectionFromSelection() now supports selection conversion when available and requested (is used to implement SetSelectionForComponent). New GeometrySelectionUtil functions InitializeSelectionFromTriangles() and ConvertSelection() are used to implement this (note: only Triangles->other conversion is currently supported). Add HaveAvailableGeometrySelection() and SetToolOutputGeometrySelectionForTarget() in StoredMeshSelectionUtil.h, this is the top-level function that Tools can use to set an Output selection.
ExtrudeMeshSelectionTool now emits output selection.
Update EditMeshPolygonsTool to use new Selection system and allow individual operations to be utilized as standalone Tools. Convert EditMeshPolygonsTool to be a USingleTargetWithSelectionTool, use FGeometrySelection to initialize selection. Add bTerminateOnPendingActionComplete flag, which is set when Tool is directly initialized to a specific operation, and forces tool to shut down when operation completes. This allows it to be used to more cleanly implement multiple action buttons in Modeling UI. When in this mode, selection panels are not shown. On Shutdown, now emits an "output" selection which GeometrySelectionManager can use to provide new selection to user. Update UPolygonSelectionMechanic Set/Get selection APIs to use FGeometrySelection instead of UPersistentMeshSelection.
port UVProjectionTool to derive from USingleTargetWithSelectionTool, use FGeometrySelection to initialize target ROI
deprecate UPersistentMeshSelection and related functions in StoredMeshSelectionUtil.h. Deprecate Tool Input Selection APIs in USingleSelectionMeshEditingTool and Builder.
Repurpose old ModelingMode-level PolyModel tab operations for new Selection Tools UI, now support Inset, Outset, Cut Faces, Insert Edge Loop, PushPull, and Bevel.
#rb none
#preflight 63c84fa2b065224750b9831f
[CL 23766643 by ryan schmidt in ue5-main branch]
2023-01-18 17:59:31 -05:00
|
|
|
// note: this is currently the same code as GetSelection_AsGroupTopology() except for the topology-type verification check
|
|
|
|
|
|
|
|
|
|
const FGroupTopologySelection& CurSelection = PersistentSelection;
|
|
|
|
|
if (SelectionOut.TopologyType != EGeometryTopologyType::Triangle)
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (SelectionOut.ElementType == EGeometryElementType::Vertex)
|
|
|
|
|
{
|
|
|
|
|
for (int32 CornerID : CurSelection.SelectedCornerIDs)
|
|
|
|
|
{
|
|
|
|
|
int32 VertexID = Topology->GetCornerVertexID(CornerID);
|
|
|
|
|
if (CompactMapsToApply != nullptr)
|
|
|
|
|
{
|
|
|
|
|
VertexID = CompactMapsToApply->GetVertexMapping(VertexID);
|
|
|
|
|
}
|
|
|
|
|
SelectionOut.Selection.Add( FGeoSelectionID::MeshVertex(VertexID).Encoded() );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (SelectionOut.ElementType == EGeometryElementType::Edge)
|
|
|
|
|
{
|
|
|
|
|
// TODO: not sure how we can apply compact maps here because mapping does not included compacted edges? are edges even compacted?
|
|
|
|
|
if ( CompactMapsToApply == nullptr )
|
|
|
|
|
{
|
|
|
|
|
for (int32 GroupEdgeID : CurSelection.SelectedEdgeIDs)
|
|
|
|
|
{
|
|
|
|
|
const TArray<int>& GroupEdge = Topology->GetGroupEdgeEdges(GroupEdgeID);
|
|
|
|
|
FMeshTriEdgeID TriEdgeID = Topology->GetMesh()->GetTriEdgeIDFromEdgeID(GroupEdge[0]);
|
|
|
|
|
SelectionOut.Selection.Add( FGeoSelectionID::MeshEdge(TriEdgeID).Encoded() );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (SelectionOut.ElementType == EGeometryElementType::Face)
|
|
|
|
|
{
|
|
|
|
|
for (int32 GroupID : CurSelection.SelectedGroupIDs)
|
|
|
|
|
{
|
|
|
|
|
const FGroupTopology::FGroup* GroupFace = Topology->FindGroupByID(GroupID);
|
|
|
|
|
if ( GroupFace )
|
|
|
|
|
{
|
|
|
|
|
SelectionOut.Selection.Add( FGeoSelectionID::MeshTriangle(GroupFace->Triangles[0]).Encoded() );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-11-13 14:07:30 -04:00
|
|
|
}
|
|
|
|
|
|
ModelingMode: improve interop with new Selection System and existing Tools
Add support for Tools to provide an "output" selection. Add UGeometrySelectionManager::SetSelectionForComponent() which can set an explicit externally-provided selection. FBaseDynamicMeshSelector::UpdateSelectionFromSelection() now supports selection conversion when available and requested (is used to implement SetSelectionForComponent). New GeometrySelectionUtil functions InitializeSelectionFromTriangles() and ConvertSelection() are used to implement this (note: only Triangles->other conversion is currently supported). Add HaveAvailableGeometrySelection() and SetToolOutputGeometrySelectionForTarget() in StoredMeshSelectionUtil.h, this is the top-level function that Tools can use to set an Output selection.
ExtrudeMeshSelectionTool now emits output selection.
Update EditMeshPolygonsTool to use new Selection system and allow individual operations to be utilized as standalone Tools. Convert EditMeshPolygonsTool to be a USingleTargetWithSelectionTool, use FGeometrySelection to initialize selection. Add bTerminateOnPendingActionComplete flag, which is set when Tool is directly initialized to a specific operation, and forces tool to shut down when operation completes. This allows it to be used to more cleanly implement multiple action buttons in Modeling UI. When in this mode, selection panels are not shown. On Shutdown, now emits an "output" selection which GeometrySelectionManager can use to provide new selection to user. Update UPolygonSelectionMechanic Set/Get selection APIs to use FGeometrySelection instead of UPersistentMeshSelection.
port UVProjectionTool to derive from USingleTargetWithSelectionTool, use FGeometrySelection to initialize target ROI
deprecate UPersistentMeshSelection and related functions in StoredMeshSelectionUtil.h. Deprecate Tool Input Selection APIs in USingleSelectionMeshEditingTool and Builder.
Repurpose old ModelingMode-level PolyModel tab operations for new Selection Tools UI, now support Inset, Outset, Cut Faces, Insert Edge Loop, PushPull, and Bevel.
#rb none
#preflight 63c84fa2b065224750b9831f
[CL 23766643 by ryan schmidt in ue5-main branch]
2023-01-18 17:59:31 -05:00
|
|
|
|
|
|
|
|
void UPolygonSelectionMechanic::SetSelection_AsGroupTopology(const UE::Geometry::FGeometrySelection& Selection)
|
|
|
|
|
{
|
|
|
|
|
if (Selection.TopologyType != EGeometryTopologyType::Polygroup)
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (Selection.ElementType == EGeometryElementType::Vertex)
|
|
|
|
|
{
|
|
|
|
|
for (uint64 ElementID : Selection.Selection)
|
|
|
|
|
{
|
|
|
|
|
int32 VertexID = FGeoSelectionID(ElementID).GeometryID;
|
|
|
|
|
int32 CornerID = Topology->GetCornerIDFromVertexID(VertexID);
|
|
|
|
|
if (CornerID != IndexConstants::InvalidID)
|
|
|
|
|
{
|
|
|
|
|
PersistentSelection.SelectedCornerIDs.Add(CornerID);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (Selection.ElementType == EGeometryElementType::Edge)
|
|
|
|
|
{
|
|
|
|
|
for (uint64 ElementID : Selection.Selection)
|
|
|
|
|
{
|
|
|
|
|
FMeshTriEdgeID TriEdgeID(FGeoSelectionID(ElementID).GeometryID);
|
|
|
|
|
int32 GroupEdgeID = Topology->FindGroupEdgeID(TriEdgeID);
|
|
|
|
|
if (GroupEdgeID != IndexConstants::InvalidID)
|
|
|
|
|
{
|
|
|
|
|
PersistentSelection.SelectedEdgeIDs.Add(GroupEdgeID);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (Selection.ElementType == EGeometryElementType::Face)
|
|
|
|
|
{
|
|
|
|
|
for (uint64 ElementID : Selection.Selection)
|
|
|
|
|
{
|
|
|
|
|
int32 TriangleID = FGeoSelectionID(ElementID).GeometryID;
|
|
|
|
|
int32 GroupID = Topology->GetGroupID(TriangleID);
|
|
|
|
|
if (Topology->FindGroupByID(GroupID) != nullptr)
|
|
|
|
|
{
|
|
|
|
|
PersistentSelection.SelectedGroupIDs.Add(GroupID);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void UPolygonSelectionMechanic::SetSelection_AsTriangleTopology(const UE::Geometry::FGeometrySelection& Selection)
|
|
|
|
|
{
|
|
|
|
|
if (Selection.TopologyType != EGeometryTopologyType::Triangle)
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (Selection.ElementType == EGeometryElementType::Vertex)
|
|
|
|
|
{
|
|
|
|
|
for (uint64 ElementID : Selection.Selection)
|
|
|
|
|
{
|
|
|
|
|
int32 VertexID = FGeoSelectionID(ElementID).GeometryID;
|
|
|
|
|
int32 CornerID = Topology->GetCornerIDFromVertexID(VertexID);
|
|
|
|
|
if (CornerID != IndexConstants::InvalidID)
|
|
|
|
|
{
|
|
|
|
|
PersistentSelection.SelectedCornerIDs.Add(CornerID);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (Selection.ElementType == EGeometryElementType::Edge)
|
|
|
|
|
{
|
|
|
|
|
for (uint64 ElementID : Selection.Selection)
|
|
|
|
|
{
|
|
|
|
|
FMeshTriEdgeID TriEdgeID(FGeoSelectionID(ElementID).GeometryID);
|
|
|
|
|
int32 GroupEdgeID = Topology->FindGroupEdgeID(TriEdgeID);
|
|
|
|
|
if (GroupEdgeID != IndexConstants::InvalidID)
|
|
|
|
|
{
|
|
|
|
|
PersistentSelection.SelectedEdgeIDs.Add(GroupEdgeID);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (Selection.ElementType == EGeometryElementType::Face)
|
|
|
|
|
{
|
|
|
|
|
for (uint64 ElementID : Selection.Selection)
|
|
|
|
|
{
|
|
|
|
|
int32 TriangleID = FGeoSelectionID(ElementID).GeometryID;
|
|
|
|
|
int32 GroupID = Topology->GetGroupID(TriangleID);
|
|
|
|
|
if (Topology->FindGroupByID(GroupID) != nullptr)
|
|
|
|
|
{
|
|
|
|
|
PersistentSelection.SelectedGroupIDs.Add(GroupID);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2020-01-27 20:11:15 -05:00
|
|
|
bool UPolygonSelectionMechanic::UpdateHighlight(const FRay& WorldRay)
|
|
|
|
|
{
|
2022-09-14 15:25:19 -04:00
|
|
|
checkf(DrawnTriangleSetComponent != nullptr, TEXT("Initialize() not called on UMeshTopologySelectionMechanic."));
|
2020-06-23 18:40:00 -04:00
|
|
|
|
2021-03-30 21:25:22 -04:00
|
|
|
FRay3d LocalRay(TargetTransform.InverseTransformPosition((FVector3d)WorldRay.Origin),
|
|
|
|
|
TargetTransform.InverseTransformVector((FVector3d)WorldRay.Direction));
|
2021-03-17 19:32:44 -04:00
|
|
|
UE::Geometry::Normalize(LocalRay.Direction);
|
2020-01-27 20:11:15 -05:00
|
|
|
|
|
|
|
|
HilightSelection.Clear();
|
|
|
|
|
FVector3d LocalPosition, LocalNormal;
|
2020-09-01 14:07:48 -04:00
|
|
|
FGroupTopologySelector::FSelectionSettings TopoSelectorSettings = GetTopoSelectorSettings(CameraState.bIsOrthographic);
|
2021-07-23 12:36:00 -04:00
|
|
|
bool bHit = TopoSelector->FindSelectedElement(TopoSelectorSettings, LocalRay, HilightSelection, LocalPosition, LocalNormal);
|
2020-09-01 14:07:48 -04:00
|
|
|
|
2022-09-14 15:25:19 -04:00
|
|
|
TSharedPtr<FGroupTopologySelector> GroupTopoSelector = StaticCastSharedPtr<FGroupTopologySelector>(TopoSelector);
|
|
|
|
|
|
2020-09-24 00:43:27 -04:00
|
|
|
if (HilightSelection.SelectedEdgeIDs.Num() > 0 && Properties->bSelectEdgeRings && ShouldSelectEdgeRingsFunc())
|
|
|
|
|
{
|
2022-09-14 15:25:19 -04:00
|
|
|
GroupTopoSelector->ExpandSelectionByEdgeRings(HilightSelection);
|
2020-09-24 00:43:27 -04:00
|
|
|
}
|
|
|
|
|
if (HilightSelection.SelectedEdgeIDs.Num() > 0 && Properties->bSelectEdgeLoops && ShouldSelectEdgeLoopsFunc())
|
2020-09-01 14:07:48 -04:00
|
|
|
{
|
2022-09-14 15:25:19 -04:00
|
|
|
GroupTopoSelector->ExpandSelectionByEdgeLoops(HilightSelection);
|
2020-09-01 14:07:48 -04:00
|
|
|
}
|
2020-06-23 18:40:00 -04:00
|
|
|
|
2020-11-13 12:09:55 -04:00
|
|
|
// Don't hover highlight a selection that we already selected, because people didn't like that
|
|
|
|
|
if (PersistentSelection.Contains(HilightSelection))
|
|
|
|
|
{
|
|
|
|
|
HilightSelection.Clear();
|
|
|
|
|
}
|
|
|
|
|
|
2020-06-23 18:40:00 -04:00
|
|
|
// Currently we draw highlighted edges/vertices differently from highlighted faces. Edges/vertices
|
|
|
|
|
// get drawn in the Render() call, so it is sufficient to just update HighlightSelection above.
|
|
|
|
|
// Faces, meanwhile, get placed into a Component that is rendered through the normal rendering system.
|
|
|
|
|
// So, we need to update the component when the highlighted selection changes.
|
|
|
|
|
|
|
|
|
|
// Put hovered groups in a set to easily compare to current
|
|
|
|
|
TSet<int> NewlyHighlightedGroups;
|
|
|
|
|
NewlyHighlightedGroups.Append(HilightSelection.SelectedGroupIDs);
|
|
|
|
|
|
|
|
|
|
// See if we're currently highlighting any groups that we're not supposed to
|
|
|
|
|
if (!NewlyHighlightedGroups.Includes(CurrentlyHighlightedGroups))
|
|
|
|
|
{
|
|
|
|
|
DrawnTriangleSetComponent->Clear();
|
|
|
|
|
CurrentlyHighlightedGroups.Empty();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// See if we need to add any groups
|
|
|
|
|
if (!CurrentlyHighlightedGroups.Includes(NewlyHighlightedGroups))
|
|
|
|
|
{
|
|
|
|
|
// Add triangles for each new group
|
|
|
|
|
for (int Gid : HilightSelection.SelectedGroupIDs)
|
|
|
|
|
{
|
|
|
|
|
if (!CurrentlyHighlightedGroups.Contains(Gid))
|
|
|
|
|
{
|
|
|
|
|
for (int32 Tid : Topology->GetGroupTriangles(Gid))
|
|
|
|
|
{
|
2020-08-11 01:36:57 -04:00
|
|
|
// We use the triangle normals because the normal overlay isn't guaranteed to be valid as we edit the mesh
|
|
|
|
|
FVector3d TriangleNormal = Mesh->GetTriNormal(Tid);
|
|
|
|
|
|
2021-09-27 11:20:58 -04:00
|
|
|
// The UV's and colors here don't currently get used by HighlightedFaceMaterial, but we set them anyway
|
2020-06-23 18:40:00 -04:00
|
|
|
FIndex3i VertIndices = Mesh->GetTriangle(Tid);
|
|
|
|
|
DrawnTriangleSetComponent->AddTriangle(FRenderableTriangle(HighlightedFaceMaterial,
|
2021-09-27 11:20:58 -04:00
|
|
|
FRenderableTriangleVertex((FVector)Mesh->GetVertex(VertIndices.A), (FVector2D)Mesh->GetVertexUV(VertIndices.A), (FVector)TriangleNormal, FLinearColor(Mesh->GetVertexColor(VertIndices.A)).ToFColor(true)),
|
|
|
|
|
FRenderableTriangleVertex((FVector)Mesh->GetVertex(VertIndices.B), (FVector2D)Mesh->GetVertexUV(VertIndices.B), (FVector)TriangleNormal, FLinearColor(Mesh->GetVertexColor(VertIndices.B)).ToFColor(true)),
|
2022-09-14 15:25:19 -04:00
|
|
|
FRenderableTriangleVertex((FVector)Mesh->GetVertex(VertIndices.C), (FVector2D)Mesh->GetVertexUV(VertIndices.C), (FVector)TriangleNormal, FLinearColor(Mesh->GetVertexColor(VertIndices.C)).ToFColor(true))));
|
2020-06-23 18:40:00 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CurrentlyHighlightedGroups.Add(Gid);
|
|
|
|
|
}
|
|
|
|
|
}//end iterating through groups
|
|
|
|
|
}//end if groups need to be added
|
|
|
|
|
|
2020-01-27 20:11:15 -05:00
|
|
|
return bHit;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool UPolygonSelectionMechanic::UpdateSelection(const FRay& WorldRay, FVector3d& LocalHitPositionOut, FVector3d& LocalHitNormalOut)
|
|
|
|
|
{
|
2021-03-30 21:25:22 -04:00
|
|
|
FRay3d LocalRay(TargetTransform.InverseTransformPosition((FVector3d)WorldRay.Origin),
|
|
|
|
|
TargetTransform.InverseTransformVector((FVector3d)WorldRay.Direction));
|
2021-03-17 19:32:44 -04:00
|
|
|
UE::Geometry::Normalize(LocalRay.Direction);
|
2020-01-27 20:11:15 -05:00
|
|
|
|
2021-09-27 11:20:58 -04:00
|
|
|
const FGroupTopologySelection PreviousSelection = PersistentSelection;
|
|
|
|
|
|
2020-01-27 20:11:15 -05:00
|
|
|
FVector3d LocalPosition, LocalNormal;
|
|
|
|
|
FGroupTopologySelection Selection;
|
2020-09-01 14:07:48 -04:00
|
|
|
FGroupTopologySelector::FSelectionSettings TopoSelectorSettings = GetTopoSelectorSettings(CameraState.bIsOrthographic);
|
2021-07-23 12:36:00 -04:00
|
|
|
if (TopoSelector->FindSelectedElement(TopoSelectorSettings, LocalRay, Selection, LocalPosition, LocalNormal))
|
2020-01-27 20:11:15 -05:00
|
|
|
{
|
|
|
|
|
LocalHitPositionOut = LocalPosition;
|
|
|
|
|
LocalHitNormalOut = LocalNormal;
|
2020-09-01 14:07:48 -04:00
|
|
|
|
2022-09-14 15:25:19 -04:00
|
|
|
TSharedPtr<FGroupTopologySelector> GroupTopoSelector = StaticCastSharedPtr<FGroupTopologySelector>(TopoSelector);
|
|
|
|
|
|
2020-09-24 00:43:27 -04:00
|
|
|
if (Selection.SelectedEdgeIDs.Num() > 0 && Properties->bSelectEdgeRings && ShouldSelectEdgeRingsFunc())
|
|
|
|
|
{
|
2022-09-14 15:25:19 -04:00
|
|
|
GroupTopoSelector->ExpandSelectionByEdgeRings(Selection);
|
2020-09-24 00:43:27 -04:00
|
|
|
}
|
|
|
|
|
if (Selection.SelectedEdgeIDs.Num() > 0 && Properties->bSelectEdgeLoops && ShouldSelectEdgeLoopsFunc())
|
2020-09-01 14:07:48 -04:00
|
|
|
{
|
2022-09-14 15:25:19 -04:00
|
|
|
GroupTopoSelector->ExpandSelectionByEdgeLoops(Selection);
|
2020-09-01 14:07:48 -04:00
|
|
|
}
|
2022-01-27 17:09:13 -05:00
|
|
|
}
|
2020-09-24 00:43:27 -04:00
|
|
|
|
2022-01-27 17:09:13 -05:00
|
|
|
if (ShouldAddToSelectionFunc())
|
|
|
|
|
{
|
|
|
|
|
if (ShouldRemoveFromSelectionFunc())
|
2020-01-27 20:11:15 -05:00
|
|
|
{
|
2022-01-27 17:09:13 -05:00
|
|
|
PersistentSelection.Toggle(Selection);
|
2020-11-13 12:09:55 -04:00
|
|
|
}
|
2020-01-27 20:11:15 -05:00
|
|
|
else
|
|
|
|
|
{
|
2022-01-27 17:09:13 -05:00
|
|
|
PersistentSelection.Append(Selection);
|
2020-01-27 20:11:15 -05:00
|
|
|
}
|
|
|
|
|
}
|
2022-01-27 17:09:13 -05:00
|
|
|
else if (ShouldRemoveFromSelectionFunc())
|
|
|
|
|
{
|
|
|
|
|
PersistentSelection.Remove(Selection);
|
|
|
|
|
}
|
2020-01-27 20:11:15 -05:00
|
|
|
else
|
|
|
|
|
{
|
2022-01-27 17:09:13 -05:00
|
|
|
PersistentSelection = Selection;
|
2020-01-27 20:11:15 -05:00
|
|
|
}
|
|
|
|
|
|
2021-09-27 11:20:58 -04:00
|
|
|
if (PersistentSelection != PreviousSelection)
|
2020-01-27 20:11:15 -05:00
|
|
|
{
|
|
|
|
|
SelectionTimestamp++;
|
|
|
|
|
OnSelectionChanged.Broadcast();
|
2021-09-27 11:20:58 -04:00
|
|
|
return true;
|
2020-01-27 20:11:15 -05:00
|
|
|
}
|
|
|
|
|
|
2021-09-27 11:20:58 -04:00
|
|
|
return false;
|
2020-01-27 20:11:15 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2022-09-14 15:25:19 -04:00
|
|
|
#undef LOCTEXT_NAMESPACE
|