您最多选择25个主题
主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
396 行
14 KiB
396 行
14 KiB
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Reflection;
|
|
using UnityEditor.UIElements;
|
|
using UnityEngine;
|
|
using UnityEngine.Perception.GroundTruth;
|
|
using UnityEngine.UIElements;
|
|
using Object = UnityEngine.Object;
|
|
using Random = UnityEngine.Random;
|
|
|
|
namespace UnityEditor.Perception.GroundTruth
|
|
{
|
|
class AddToConfigWindow : EditorWindow
|
|
{
|
|
VisualElement m_Root;
|
|
|
|
const string k_UxmlDir = "Packages/com.unity.perception/Editor/GroundTruth/Uxml/";
|
|
string m_UxmlPath;
|
|
|
|
static List<string> s_LabelValues = new List<string>();
|
|
static Label s_TitleLabel;
|
|
static Label s_Status;
|
|
|
|
public void SetStatus(string status)
|
|
{
|
|
s_Status.text = status;
|
|
s_Status.style.display = DisplayStyle.Flex;
|
|
}
|
|
|
|
List<string> m_AllLabelConfigGuids = new List<string>();
|
|
List<ScriptableObject> m_ConfigsContainingLabel = new List<ScriptableObject>();
|
|
List<ScriptableObject> m_ConfigsNotContainingLabel = new List<ScriptableObject>();
|
|
|
|
static ListView s_PresentConfigsListview;
|
|
static ListView s_NonPresentConfigsListview;
|
|
static ListView s_SelectedLabelsListview;
|
|
static Label s_CurrentlyPresentTitle;
|
|
static Label s_OtherConfigsTitle;
|
|
|
|
List<Type> m_LabelConfigTypes = new List<Type>();
|
|
public static void ShowWindow(string labelValue)
|
|
{
|
|
s_LabelValues.Clear();
|
|
s_LabelValues.Add(labelValue);
|
|
ShowWindow(s_LabelValues);
|
|
}
|
|
|
|
public static void ShowWindow(List<string> labelValues)
|
|
{
|
|
s_LabelValues = new List<string>(labelValues);
|
|
var window = GetWindow<AddToConfigWindow>();
|
|
|
|
if (s_Status != null)
|
|
{
|
|
s_Status.style.display = DisplayStyle.None;
|
|
}
|
|
|
|
if (labelValues.Count == 1)
|
|
{
|
|
|
|
if(s_TitleLabel != null)
|
|
s_TitleLabel.text = "Label: \"" + s_LabelValues.First() + "\"";
|
|
|
|
if (s_PresentConfigsListview != null)
|
|
{
|
|
s_PresentConfigsListview.style.display = DisplayStyle.Flex;
|
|
}
|
|
|
|
if (s_CurrentlyPresentTitle != null)
|
|
{
|
|
s_CurrentlyPresentTitle.style.display = DisplayStyle.Flex;
|
|
}
|
|
|
|
if (s_OtherConfigsTitle != null)
|
|
{
|
|
s_OtherConfigsTitle.text = "Other Label Configs in Project";
|
|
}
|
|
|
|
if (s_NonPresentConfigsListview != null)
|
|
{
|
|
s_NonPresentConfigsListview.style.height = 150;
|
|
}
|
|
|
|
if (s_SelectedLabelsListview != null)
|
|
{
|
|
s_SelectedLabelsListview.style.display = DisplayStyle.None;
|
|
}
|
|
|
|
window.titleContent = new GUIContent("Manage Label");
|
|
window.minSize = new Vector2(400, 390);
|
|
window.maxSize = new Vector2(700, 390);
|
|
}
|
|
else
|
|
{
|
|
if(s_TitleLabel != null)
|
|
s_TitleLabel.text = "Labels to Add";
|
|
|
|
if (s_PresentConfigsListview != null)
|
|
{
|
|
s_PresentConfigsListview.style.display = DisplayStyle.None;
|
|
}
|
|
|
|
if (s_CurrentlyPresentTitle != null)
|
|
{
|
|
s_CurrentlyPresentTitle.style.display = DisplayStyle.None;
|
|
}
|
|
|
|
if (s_OtherConfigsTitle != null)
|
|
{
|
|
s_OtherConfigsTitle.text = "All Label Configurations in Project";
|
|
}
|
|
|
|
if (s_NonPresentConfigsListview != null)
|
|
{
|
|
s_NonPresentConfigsListview.style.height = 250;
|
|
}
|
|
|
|
if (s_SelectedLabelsListview != null)
|
|
{
|
|
s_SelectedLabelsListview.style.display = DisplayStyle.Flex;
|
|
|
|
}
|
|
|
|
window.titleContent = new GUIContent("Manage Labels");
|
|
window.minSize = new Vector2(400, 370);
|
|
window.maxSize = new Vector2(700, 1000);
|
|
}
|
|
|
|
window.Init();
|
|
}
|
|
|
|
|
|
void Init()
|
|
{
|
|
Show();
|
|
|
|
m_ConfigsContainingLabel.Clear();
|
|
|
|
m_LabelConfigTypes = FindAllSubTypes(typeof(LabelConfig<>));
|
|
|
|
RefreshConfigAssets();
|
|
CheckInclusionInConfigs(m_AllLabelConfigGuids, s_LabelValues.Count == 1? s_LabelValues.First() : null);
|
|
SetupListViews();
|
|
}
|
|
|
|
void RefreshConfigAssets()
|
|
{
|
|
AssetDatabase.Refresh();
|
|
|
|
m_AllLabelConfigGuids.Clear();
|
|
foreach (var type in m_LabelConfigTypes)
|
|
{
|
|
m_AllLabelConfigGuids.AddRange(AssetDatabase.FindAssets("t:"+type.Name));
|
|
}
|
|
}
|
|
|
|
void SetupListViews()
|
|
{
|
|
//configs containing label
|
|
if (s_LabelValues.Count == 1)
|
|
{
|
|
//we are dealing with only one label
|
|
|
|
s_PresentConfigsListview.itemsSource = m_ConfigsContainingLabel;
|
|
VisualElement MakeItem1() => new ConfigElementLabelPresent(this, s_LabelValues.First());
|
|
|
|
void BindItem1(VisualElement e, int i)
|
|
{
|
|
if (e is ConfigElementLabelPresent element)
|
|
{
|
|
element.labelElement.text = m_ConfigsContainingLabel[i].name;
|
|
element.labelConfig = m_ConfigsContainingLabel[i];
|
|
}
|
|
}
|
|
|
|
s_PresentConfigsListview.itemHeight = 30;
|
|
s_PresentConfigsListview.bindItem = BindItem1;
|
|
s_PresentConfigsListview.makeItem = MakeItem1;
|
|
s_PresentConfigsListview.selectionType = SelectionType.None;
|
|
}
|
|
|
|
|
|
//Configs not containing label
|
|
s_NonPresentConfigsListview.itemsSource = m_ConfigsNotContainingLabel;
|
|
VisualElement MakeItem2() => new ConfigElementLabelNotPresent(this, s_LabelValues);
|
|
|
|
void BindItem2(VisualElement e, int i)
|
|
{
|
|
if (e is ConfigElementLabelNotPresent element)
|
|
{
|
|
element.labelElement.text = m_ConfigsNotContainingLabel[i].name;
|
|
element.labelConfig = m_ConfigsNotContainingLabel[i];
|
|
}
|
|
}
|
|
|
|
s_NonPresentConfigsListview.itemHeight = 30;
|
|
s_NonPresentConfigsListview.bindItem = BindItem2;
|
|
s_NonPresentConfigsListview.makeItem = MakeItem2;
|
|
s_NonPresentConfigsListview.selectionType = SelectionType.None;
|
|
|
|
|
|
//Selected labels
|
|
s_SelectedLabelsListview.itemsSource = s_LabelValues;
|
|
|
|
VisualElement MakeItem3() => new Label();
|
|
void BindItem3(VisualElement e, int i)
|
|
{
|
|
if (e is Label label)
|
|
{
|
|
label.text = s_LabelValues[i];
|
|
label.style.marginLeft = 2;
|
|
label.style.marginRight = 2;
|
|
}
|
|
}
|
|
|
|
s_SelectedLabelsListview.itemHeight = 20;
|
|
s_SelectedLabelsListview.bindItem = BindItem3;
|
|
s_SelectedLabelsListview.makeItem = MakeItem3;
|
|
s_SelectedLabelsListview.selectionType = SelectionType.None;
|
|
}
|
|
|
|
public void RefreshLists()
|
|
{
|
|
CheckInclusionInConfigs(m_AllLabelConfigGuids, s_LabelValues.Count == 1? s_LabelValues.First() : null);
|
|
s_PresentConfigsListview.Refresh();
|
|
s_NonPresentConfigsListview.Refresh();
|
|
}
|
|
void OnEnable()
|
|
{
|
|
m_UxmlPath = k_UxmlDir + "AddToConfigWindow.uxml";
|
|
|
|
m_Root = rootVisualElement;
|
|
AssetDatabase.LoadAssetAtPath<VisualTreeAsset>(m_UxmlPath).CloneTree(m_Root);
|
|
|
|
s_TitleLabel = m_Root.Q<Label>("title");
|
|
s_CurrentlyPresentTitle = m_Root.Q<Label>("currently-present-label");
|
|
s_OtherConfigsTitle = m_Root.Q<Label>("other-configs-label");
|
|
s_PresentConfigsListview = m_Root.Q<ListView>("current-configs-listview");
|
|
s_NonPresentConfigsListview = m_Root.Q<ListView>("other-configs-listview");
|
|
s_SelectedLabelsListview = m_Root.Q<ListView>("selected-labels-list");
|
|
s_Status = m_Root.Q<Label>("status");
|
|
s_Status.style.display = DisplayStyle.None;
|
|
}
|
|
|
|
void CheckInclusionInConfigs(List<string> configGuids, string label = null)
|
|
{
|
|
m_ConfigsContainingLabel.Clear();
|
|
m_ConfigsNotContainingLabel.Clear();
|
|
|
|
foreach (var configGuid in configGuids)
|
|
{
|
|
var asset = AssetDatabase.LoadAssetAtPath<ScriptableObject>(AssetDatabase.GUIDToAssetPath(configGuid));
|
|
if (label != null)
|
|
{
|
|
//means we are dealing with only one label not a set
|
|
var methodInfo = asset.GetType().GetMethod(IdLabelConfig.DoesLabelMatchAnEntryName);
|
|
|
|
if (methodInfo == null)
|
|
continue;
|
|
|
|
object[] parametersArray = new object[1];
|
|
parametersArray[0] = label;
|
|
|
|
var labelExistsInConfig = (bool) methodInfo.Invoke(asset, parametersArray);
|
|
|
|
if (labelExistsInConfig)
|
|
{
|
|
m_ConfigsContainingLabel.Add(asset);
|
|
}
|
|
else
|
|
{
|
|
m_ConfigsNotContainingLabel.Add(asset);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
m_ConfigsNotContainingLabel.Add(asset);
|
|
}
|
|
}
|
|
}
|
|
|
|
public static List<Type> FindAllSubTypes(Type superType)
|
|
{
|
|
Assembly assembly = Assembly.GetAssembly(superType);
|
|
Type[] types = assembly.GetTypes();
|
|
List<Type> subclasses = types.Where(t => IsSubclassOfRawGeneric(superType, t)).ToList();
|
|
return subclasses;
|
|
|
|
|
|
bool IsSubclassOfRawGeneric(Type generic, Type toCheck) {
|
|
while (toCheck != null && toCheck != typeof(object)) {
|
|
var cur = toCheck.IsGenericType ? toCheck.GetGenericTypeDefinition() : toCheck;
|
|
if (generic == cur) {
|
|
return true;
|
|
}
|
|
toCheck = toCheck.BaseType;
|
|
}
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
|
|
class ConfigElementLabelPresent : VisualElement
|
|
{
|
|
const string k_UxmlDir = "Packages/com.unity.perception/Editor/GroundTruth/Uxml/";
|
|
VisualElement m_Root;
|
|
ObjectField m_ConfigObjectField;
|
|
|
|
public Label labelElement;
|
|
public ScriptableObject labelConfig;
|
|
|
|
public ConfigElementLabelPresent(AddToConfigWindow window, string targetLabel)
|
|
{
|
|
var uxmlPath = k_UxmlDir + "ConfigElementLabelPresent.uxml";
|
|
AssetDatabase.LoadAssetAtPath<VisualTreeAsset>(uxmlPath).CloneTree(this);
|
|
labelElement = this.Q<Label>("config-name");
|
|
var removeButton = this.Q<Button>("remove-from-config-button");
|
|
removeButton.text = "Remove Label";
|
|
|
|
var openButton = this.Q<Button>("open-config-button");
|
|
openButton.clicked += () =>
|
|
{
|
|
Selection.SetActiveObjectWithContext(labelConfig, null);
|
|
};
|
|
|
|
removeButton.clicked += () =>
|
|
{
|
|
var editor = Editor.CreateEditor(labelConfig);
|
|
if (editor is SemanticSegmentationLabelConfigEditor semanticEditor)
|
|
{
|
|
semanticEditor.RemoveLabel(targetLabel);
|
|
}
|
|
else if (editor is IdLabelConfigEditor idEditor)
|
|
{
|
|
idEditor.RemoveLabel(targetLabel);
|
|
}
|
|
|
|
window.RefreshLists();
|
|
Object.DestroyImmediate(editor);
|
|
};
|
|
}
|
|
}
|
|
|
|
|
|
class ConfigElementLabelNotPresent : VisualElement
|
|
{
|
|
const string k_UxmlDir = "Packages/com.unity.perception/Editor/GroundTruth/Uxml/";
|
|
VisualElement m_Root;
|
|
ObjectField m_ConfigObjectField;
|
|
public Label labelElement;
|
|
public ScriptableObject labelConfig;
|
|
|
|
public ConfigElementLabelNotPresent(AddToConfigWindow window, List<string> targetLabels)
|
|
{
|
|
var uxmlPath = k_UxmlDir + "ConfigElementLabelPresent.uxml";
|
|
AssetDatabase.LoadAssetAtPath<VisualTreeAsset>(uxmlPath).CloneTree(this);
|
|
labelElement = this.Q<Label>("config-name");
|
|
var addButton = this.Q<Button>("remove-from-config-button");
|
|
addButton.text = targetLabels.Count ==1 ? "Add Label" : "Add All Labels";
|
|
|
|
var openButton = this.Q<Button>("open-config-button");
|
|
openButton.clicked += () =>
|
|
{
|
|
Selection.SetActiveObjectWithContext(labelConfig, null);
|
|
};
|
|
|
|
addButton.clicked += () =>
|
|
{
|
|
var editor = Editor.CreateEditor(labelConfig);
|
|
if (editor is SemanticSegmentationLabelConfigEditor semanticEditor)
|
|
{
|
|
foreach (var label in targetLabels)
|
|
{
|
|
semanticEditor.AddLabel(label);
|
|
}
|
|
}
|
|
else if (editor is IdLabelConfigEditor idEditor)
|
|
{
|
|
foreach (var label in targetLabels)
|
|
{
|
|
idEditor.AddLabel(label);
|
|
}
|
|
}
|
|
|
|
if (targetLabels.Count > 1)
|
|
{
|
|
window.SetStatus("All Labels Added to " + labelConfig.name);
|
|
}
|
|
|
|
window.RefreshLists();
|
|
Object.DestroyImmediate(editor);
|
|
};
|
|
}
|
|
}
|
|
}
|