[CustomEditor(typeof(Labeling)), CanEditMultipleObjects]
class LabelingEditor : Editor
{
class MyBinding : IBinding
{
private LabelingEditor m_Editor ;
public MyBinding ( LabelingEditor editor )
{
m_Editor = editor ;
}
public void PreUpdate ( )
{
}
public void Update ( )
{
m_Editor . RefreshUi ( ) ;
}
public void Release ( )
{
}
}
private Labeling m_Labeling ;
private SerializedProperty m_SerializedLabelsArray ;
private VisualElement m_Root ;
private string m_UxmlDir = "Packages/com.unity.perception/Editor/GroundTruth/Uxml/" ;
private string m_UxmlPath ;
private string [ ] nameSeparators = { "." , "-" , "_" } ;
private string [ ] pathSeparators = { "/" } ;
private string [ ] m_NameSeparators = { "." , "-" , "_" } ;
private string [ ] m_PathSeparators = { "/" } ;
public List < string > suggestedLabelsBasedOnName = new List < string > ( ) ;
public List < string > suggestedLabelsBasedOnPath = new List < string > ( ) ;
private List < string > m_SuggestedLabelsBasedOnName = new List < string > ( ) ;
private List < string > m_SuggestedLabelsBasedOnPath = new List < string > ( ) ;
public List < string > CommonLabels = > m_CommonLabels ;
public Dictionary < int , int > CommonsIndexToLabelsIndex = > m_CommonsIndexToLabelsIndex ;
private void OnEnable ( )
{
var mySerializedObject = new SerializedObject ( serializedObject . targetObjects [ 0 ] ) ;
m_UxmlPath = m_UxmlDir + "Labeling_Main.uxml" ;
m_Root = AssetDatabase . LoadAssetAtPath < VisualTreeAsset > ( m_UxmlPath ) . CloneTree ( ) ;
//m_OuterElement = m_Root.Q<BindableElement>("outer-container");
//m_OuterElement.binding = new MyBinding(this);
//m_OuterElement.bindingPath = "labels";
m_CurrentLabelsListView = m_Root . Q < ListView > ( "current-labels-listview" ) ;
m_SuggestLabelsListView_FromName = m_Root . Q < ListView > ( "suggested-labels-name-listview" ) ;
}
}
RefreshData ( ) ;
RefreshUi ( ) ;
//RefreshUi();
} ;
}
m_Labeling = serializedObject . targetObject as Labeling ;
m_SerializedLabelsArray = mySerializedObject . FindProperty ( "labels" ) ;
RefreshCommonLabels ( ) ;
Update SuggestedLabelLists( ) ;
Refresh SuggestedLabelLists( ) ;
SetupListViews ( ) ;
return m_Root ;
}
suggestedLabelsBasedOnName . RemoveAll ( s = > m_CommonLabels . Contains ( s ) ) ;
suggestedLabelsBasedOnPath . RemoveAll ( s = > m_CommonLabels . Contains ( s ) ) ;
m_SuggestedLabelsBasedOnName . RemoveAll ( s = > m_CommonLabels . Contains ( s ) ) ;
m_SuggestedLabelsBasedOnPath . RemoveAll ( s = > m_CommonLabels . Contains ( s ) ) ;
public void UpdateSuggestedLabelLists ( )
public void RefreshSuggestedLabelLists ( )
suggestedLabelsBasedOnName . Clear ( ) ;
suggestedLabelsBasedOnPath . Clear ( ) ;
m_SuggestedLabelsBasedOnName . Clear ( ) ;
m_SuggestedLabelsBasedOnPath . Clear ( ) ;
suggestedLabelsBasedOnName . Add ( assetName ) ;
suggestedLabelsBasedOnName . AddRange ( assetName . Split ( nameSeparators , StringSplitOptions . RemoveEmptyEntries ) . ToList ( ) ) ;
m_SuggestedLabelsBasedOnName . Add ( assetName ) ;
m_SuggestedLabelsBasedOnName . AddRange ( assetName . Split ( m_NameSeparators , StringSplitOptions . RemoveEmptyEntries ) . ToList ( ) ) ;
var stringList = assetPath . Split ( pathSeparators , StringSplitOptions . RemoveEmptyEntries ) . ToList ( ) ;
var stringList = assetPath . Split ( m_PathSeparators , StringSplitOptions . RemoveEmptyEntries ) . ToList ( ) ;
suggestedLabelsBasedOnPath . AddRange ( stringList ) ;
m_SuggestedLabelsBasedOnPath . AddRange ( stringList ) ;
}
foreach ( var targetObject in targets )
if ( prefabObject )
{
string assetPath = AssetDatabase . GetAssetPath ( prefabObject ) ;
var stringList = assetPath . Split ( pathSeparators , StringSplitOptions . RemoveEmptyEntries ) . ToList ( ) ;
suggestedLabelsBasedOnPath = suggestedLabelsBasedOnPath . Intersect ( stringList ) . ToList ( ) ;
var stringList = assetPath . Split ( m_PathSeparators , StringSplitOptions . RemoveEmptyEntries ) . ToList ( ) ;
m_SuggestedLabelsBasedOnPath = m_SuggestedLabelsBasedOnPath . Intersect ( stringList ) . ToList ( ) ;
RemoveAddedLabelsFromSuggestedLists ( ) ;
RemoveAddedLabelsFromSuggestedLists ( ) ;
Debug . Log ( "list update, source list count is:" + m_SuggestedLabelsBasedOnPath . Count ) ;
}
public void RefreshData ( )
var mySerializedObject = new SerializedObject ( serializedObject . targetObjects [ 0 ] ) ;
m_SerializedLabelsArray = mySerializedObject . FindProperty ( "labels" ) ;
//m_Labeling = serializedObject.targetObject as Labeling;
RefreshSuggestedLabelLists ( ) ;
SetupSuggestedLabelsListViews ( ) ;
}
public void RefreshUi ( )
{
m_CurrentLabelsListView . Refresh ( ) ;
m_SuggestLabelsListView_FromName . Refresh ( ) ;
m_SuggestLabelsListView_FromPath . Refresh ( ) ;
m_SuggestLabelsListView_FromDB . Refresh ( ) ;
}
void SetupListViews ( )
}
Debug . Log ( "-----------------------------" ) ;
Debug . Log ( "common labels count: " + m_CommonLabels . Count ) ;
m_CommonsIndexToLabelsIndex . Clear ( ) ;
for ( int i = 0 ; i < m_Labeling . labels . Count ; i + + )
{
// }
}
//to know which index in the asset
Dictionary < int , int > CreateCommonLabelsToAssetsLabelsIndex ( )
{
return null ;
}
void SetupCurrentLabelsListView ( )
{
m_CurrentLabelsListView . itemsSource = m_CommonLabels ;
if ( e is AddedLabelEditor addedLabel )
{
addedLabel . m_IndexInList = i ;
addedLabel . m_LabelTextField . BindProperty ( m_SerializedLabelsArray . GetArrayElementAtIndex ( m_CommonsIndexToLabelsIndex [ i ] ) ) ;
addedLabel . m_LabelTextField . value = m_SerializedLabelsArray . GetArrayElementAtIndex ( m_CommonsIndexToLabelsIndex [ i ] ) . stringValue ;
}
}
void SetupSuggestedLabelsListViews ( )
{
SetupSuggestedLabelsBasedOnFlatList ( m_SuggestLabelsListView_FromName , s uggestedLabelsBasedOnName) ;
SetupSuggestedLabelsBasedOnFlatList ( m_SuggestLabelsListView_FromPath , s uggestedLabelsBasedOnPath) ;
//SetupSuggestedLabelsBasedOnFlatList(m_SuggestLabelsListView_FromDB, );
SetupSuggestedLabelsBasedOnFlatList ( m_SuggestLabelsListView_FromName , m_S uggestedLabelsBasedOnName) ;
SetupSuggestedLabelsBasedOnFlatList ( m_SuggestLabelsListView_FromPath , m_S uggestedLabelsBasedOnPath) ;
//SetupSuggestedBasedOnNameLabelsListView( );
//SetupSuggestedBasedOnPathLabelsListView();
var mySerializedObject = new SerializedObject ( serializedObject . targetObjects [ 0 ] ) ;
labelsListView . itemsSource = stringList ;
VisualElement MakeItem ( ) = > new SuggestedLabelElement ( this , labelsListView ,
m_CurrentLabelsListView , m_SerializedLabelsArray , mySerializedObject ) ;
VisualElement MakeItem ( ) = > new SuggestedLabelElement ( this ) ;
void BindItem ( VisualElement e , int i )
{
labelsListView . bindItem = BindItem ;
labelsListView . makeItem = MakeItem ;
labelsListView . itemHeight = itemHeight ;
labelsListView . itemsSource = stringList ;
// void SetupSuggestedBasedOnPathLabelsListView()
// {
// m_SuggestLabelsListView_FromPath.itemsSource = m_SuggestedLabelsBasedOnPath;
//
// VisualElement MakeItem() => new SuggestedLabelElement(this);
//
// void BindItem(VisualElement e, int i)
// {
// if (e is SuggestedLabelElement suggestedLabel)
// {
// Debug.Log("bind, source list count is:" + m_SuggestedLabelsBasedOnPath.Count);
// suggestedLabel.m_Label.text = m_SuggestedLabelsBasedOnPath[i];
// }
// }
//
// const int itemHeight = 32;
//
// m_SuggestLabelsListView_FromPath.bindItem = BindItem;
// m_SuggestLabelsListView_FromPath.makeItem = MakeItem;
// m_SuggestLabelsListView_FromPath.itemHeight = itemHeight;
// m_SuggestLabelsListView_FromPath.selectionType = SelectionType.None;
// }
//
// void SetupSuggestedBasedOnNameLabelsListView()
// {
// VisualElement MakeItem() => new SuggestedLabelElement(this);
//
// void BindItem(VisualElement e, int i)
// {
// if (e is SuggestedLabelElement suggestedLabel)
// {
// suggestedLabel.m_Label.text = m_SuggestedLabelsBasedOnName[i];
// }
// }
//
// const int itemHeight = 32;
//
// m_SuggestLabelsListView_FromName.bindItem = BindItem;
// m_SuggestLabelsListView_FromName.makeItem = MakeItem;
// m_SuggestLabelsListView_FromName.itemHeight = itemHeight;
// m_SuggestLabelsListView_FromName.itemsSource = m_SuggestedLabelsBasedOnName;
// m_SuggestLabelsListView_FromName.selectionType = SelectionType.None;
// }
}
//The listview of added labels in the editor is only bound to the top target object, se we need to apply label modifications to other selected objects too
m_LabelTextField . RegisterValueChangedCallback < string > ( ( cEvent ) = >
{
List < string > m_CommonLabels = new List < string > ( ) ;
m_CommonLabels . Clear ( ) ;
var firstTarget = editor . targets [ 0 ] as Labeling ;
m_CommonLabels . AddRange ( firstTarget . labels ) ;
foreach ( var obj in editor . targets )
{
m_CommonLabels = m_CommonLabels . Intersect ( ( ( Labeling ) obj ) . labels ) . ToList ( ) ;
}
// List<string> m_CommonLabels = new List<string>();
//
// m_CommonLabels.Clear();
// var firstTarget = editor.targets[0] as Labeling;
// m_CommonLabels.AddRange(firstTarget.labels);
//
// foreach (var obj in editor.targets)
// {
// m_CommonLabels = m_CommonLabels.Intersect(((Labeling) obj).labels).ToList();
// }
if ( targetObject ! = editor . targets [ 0 ] & & targetObject is Labeling labeling )
if ( targetObject is Labeling labeling )
Dictionary < int , int > commonsIndexToLabelsIndex = new Dictionary < int , int > ( ) ;
// Dictionary<int, int> commonsIndexToLabelsIndex = new Dictionary<int, int>();
//
// for (int i = 0; i < labeling.labels.Count; i++)
// {
// string label = labeling.labels[i];
//
// for (int j = 0; j < editor.CommonLabels.Count; j++)
// {
// string label2 = editor.CommonLabels[j];
//
// if (String.Equals(label, label2) && !commonsIndexToLabelsIndex.ContainsKey(j))
// {
// commonsIndexToLabelsIndex.Add(j, i);
// }
// }
// }
for ( int i = 0 ; i < labeling . labels . Count ; i + + )
{
string label = labeling . labels [ i ] ;
for ( int j = 0 ; j < m_CommonLabels . Count ; j + + )
{
string label2 = m_CommonLabels [ j ] ;
if ( String . Equals ( label , label2 ) & & ! commonsIndexToLabelsIndex . ContainsKey ( j ) )
{
commonsIndexToLabelsIndex . Add ( j , i ) ;
}
}
}
var indexToModifyInTargetLabelList =
labeling . labels . IndexOf ( editor . CommonLabels [ m_IndexInList ] ) ;
serializedLabelArray2 . GetArrayElementAtIndex ( commonsIndexToLabelsIndex [ m_IndexInList ] ) . stringValue = cEvent . newValue ;
serializedLabelArray2 . GetArrayElementAtIndex ( indexToModifyInTargetLabelList ) . stringValue = cEvent . newValue ;
editor . RefreshData ( ) ;
} ) ;
m_AddToConfigButton . clicked + = ( ) = >
}
}
editor . serializedObject . SetIsDifferentCacheDirty ( ) ;
editor . RemoveAddedLabelsFromSuggestedLists ( ) ;
editor . RefreshUi ( ) ;
//editor.RefreshUi();
} ;
}
private Button m_AddButton ;
public Label m_Label ;
public SuggestedLabelElement ( LabelingEditor editor , ListView suggestedLabelsListView , ListView currentLabelsListView , SerializedProperty serializedLabelArray , SerializedObject serializedLabelingObject )
public SuggestedLabelElement ( LabelingEditor editor )
{
m_UxmlPath = m_UxmlDir + "SuggestedLabelElement.uxml" ;
AssetDatabase . LoadAssetAtPath < VisualTreeAsset > ( m_UxmlPath ) . CloneTree ( this ) ;
{
if ( targetObject is Labeling labeling )
{
//if (labeling.labels.Contains(m_Label.text))
// continue; //Do not allow duplicate labels in one asset. Duplicate labels have no use and cause other operations (especially mutlt asset editing) to get messed up
if ( labeling . labels . Contains ( m_Label . text ) )
continue ; //Do not allow duplicate labels in one asset. Duplicate labels have no use and cause other operations (especially mutlt asset editing) to get messed up
var serializedLabelingObject2 = new SerializedObject ( targetObject ) ;
var serializedLabelArray2 = serializedLabelingObject2 . FindProperty ( "labels" ) ;
serializedLabelArray2 . InsertArrayElementAtIndex ( serializedLabelArray2 . arraySize ) ;
editor . serializedObject . SetIsDifferentCacheDirty ( ) ;
}
}
editor . RemoveAddedLabelsFromSuggestedLists ( ) ;
editor . RefreshUi ( ) ;
//editor.RefreshUi();
} ;
}
}