Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/DynamoCoreWpf/DynamoCoreWpf.csproj
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<UILib>true</UILib>
</PropertyGroup>
Expand Down Expand Up @@ -1308,6 +1308,7 @@
<Resource Include="UI\Images\closetab_hover.png" />
</ItemGroup>
<ItemGroup>
<Resource Include="UI\Images\cluster_32px.png" />
<Resource Include="UI\Images\gripper-default.png" />
<Resource Include="UI\Images\gripper-hover.png" />
<Resource Include="UI\Images\caret-left-disabled.png" />
Expand Down
Binary file added src/DynamoCoreWpf/UI/Images/cluster_32px.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using System.Windows.Media;

namespace Dynamo.NodeAutoComplete.ViewModels
{
public class DNADropdownViewModel
{
public string Description { get; set; }
public ImageSource SmallIcon { get; set; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@
using Dynamo.Core;
using Dynamo.Graph.Workspaces;
using Dynamo.Graph;
using System.Windows.Media;
using System.Windows.Media.Imaging;

namespace Dynamo.NodeAutoComplete.ViewModels
{
Expand Down Expand Up @@ -124,19 +126,19 @@ public bool HideAutocompleteMethodOptions
}
}

private IEnumerable<NodeAutoCompleteClusterResult> clusterResults;
private IEnumerable<DNADropdownViewModel> dropdownResults;
/// <summary>
/// Cluster autocomplete search results.
/// </summary>
public IEnumerable<NodeAutoCompleteClusterResult> DropdownResults
public IEnumerable<DNADropdownViewModel> DropdownResults
{
get
{
return clusterResults;
return dropdownResults;
}
set
{
clusterResults = value;
dropdownResults = value;
RaisePropertyChanged(nameof(DropdownResults));
RaisePropertyChanged(nameof(NthofTotal));
RaisePropertyChanged(nameof(ResultsLoaded));
Expand Down Expand Up @@ -346,6 +348,7 @@ public bool DisplayLowConfidence
internal event Action<NodeModel> ParentNodeRemoved;

internal MLNodeClusterAutoCompletionResponse FullResults { private set; get; }
internal List<SingleResultItem> FullSingleResults { set; get; }

/// <summary>
/// Constructor
Expand Down Expand Up @@ -472,14 +475,14 @@ internal MLNodeAutoCompletionRequest GenerateRequestForMLAutocomplete()
return request;
}

internal IEnumerable<NodeSearchElementViewModel> GetNodeAutocompleMLResults()
private IEnumerable<SingleResultItem> GetNodeAutocompleMLResults()
{
MLNodeAutoCompletionResponse MLresults = null;

// Get results from the ML API.
try
{
MLresults = GetMLNodeAutocompleteResults();
MLresults = GetGenericAutocompleteResult<MLNodeAutoCompletionResponse>(nodeAutocompleteMLEndpoint);
}
catch (Exception ex)
{
Expand All @@ -488,7 +491,7 @@ internal IEnumerable<NodeSearchElementViewModel> GetNodeAutocompleMLResults()
AutocompleteMLTitle = Resources.LoginNeededTitle;
AutocompleteMLMessage = Resources.LoginNeededMessage;
Analytics.TrackEvent(Actions.View, Categories.NodeAutoCompleteOperations, "UnabletoFetch");
return new List<NodeSearchElementViewModel>();
return new List<SingleResultItem>();
}

// no results
Expand All @@ -498,10 +501,10 @@ internal IEnumerable<NodeSearchElementViewModel> GetNodeAutocompleMLResults()
AutocompleteMLTitle = Resources.AutocompleteNoRecommendationsTitle;
AutocompleteMLMessage = Resources.AutocompleteNoRecommendationsMessage;
Analytics.TrackEvent(Actions.View, Categories.NodeAutoCompleteOperations, "NoRecommendation");
return new List<NodeSearchElementViewModel>();
return new List<SingleResultItem>();
}
ServiceVersion = MLresults.Version;
var results = new List<NodeSearchElementViewModel>();
var results = new List<SingleResultItem>();

var zeroTouchSearchElements = Model.Entries.OfType<ZeroTouchSearchElement>().Where(x => x.IsVisibleInSearch);
var nodeModelSearchElements = Model.Entries.OfType<NodeModelSearchElement>().Where(x => x.IsVisibleInSearch);
Expand All @@ -521,13 +524,10 @@ internal IEnumerable<NodeSearchElementViewModel> GetNodeAutocompleMLResults()
if (element != null)
{
nodeSearchElement = (NodeSearchElement)element.Clone();
}

// Set PortToConnect for each element based on port-index and port-name
if (nodeSearchElement != null)
{
// Set PortToConnect for each element based on port-index and port-name
nodeSearchElement.AutoCompletionNodeElementInfo = new AutoCompletionNodeElementInfo
{
{
PortToConnect = portIndex
};

Expand All @@ -539,13 +539,9 @@ internal IEnumerable<NodeSearchElementViewModel> GetNodeAutocompleMLResults()
break;
}
}
}

var viewModelElement = GetViewModelForNodeSearchElement(nodeSearchElement);
var viewModelElement = new SingleResultItem(nodeSearchElement, result.Score);

if (viewModelElement != null)
{
viewModelElement.AutoCompletionNodeMachineLearningInfo = new AutoCompletionNodeMachineLearningInfo(true, true, Math.Round(result.Score * 100));
results.Add(viewModelElement);
}
}
Expand All @@ -564,29 +560,21 @@ internal IEnumerable<NodeSearchElementViewModel> GetNodeAutocompleMLResults()
if (element != null)
{
nodeSearchElement = (NodeSearchElement)element.Clone();
}

if (nodeSearchElement != null)
{
nodeSearchElement.AutoCompletionNodeElementInfo = new AutoCompletionNodeElementInfo
{
PortToConnect = portIndex
};
}

var viewModelElement = GetViewModelForNodeSearchElement(nodeSearchElement);

if (viewModelElement != null)
{
viewModelElement.AutoCompletionNodeMachineLearningInfo = new AutoCompletionNodeMachineLearningInfo(true, true, Math.Round(result.Score * 100));
var viewModelElement = new SingleResultItem(nodeSearchElement, result.Score);
results.Add(viewModelElement);
}
}
}

return results;
}
internal T GetGenericAutocompleteResult<T>(string endpoint)
private T GetGenericAutocompleteResult<T>(string endpoint)
{
var requestDTO = GenerateRequestForMLAutocomplete();
var jsonRequest = JsonConvert.SerializeObject(requestDTO);
Expand Down Expand Up @@ -642,16 +630,6 @@ internal T GetGenericAutocompleteResult<T>(string endpoint)
return results;
}

private MLNodeAutoCompletionResponse GetMLNodeAutocompleteResults()
{
return GetGenericAutocompleteResult<MLNodeAutoCompletionResponse>(nodeAutocompleteMLEndpoint);
}

private MLNodeClusterAutoCompletionResponse GetMLNodeClusterAutocompleteResults()
{
return GetGenericAutocompleteResult<MLNodeClusterAutoCompletionResponse>(nodeClusterAutocompleteMLEndpoint);
}

/// <summary>
/// Show the low confidence ML results.
/// </summary>
Expand Down Expand Up @@ -708,7 +686,7 @@ internal HostNames GetHostNameEnum(string HostName)
/// <summary>
/// Key function to populate node autocomplete results to display
/// </summary>
internal IEnumerable<NodeSearchElementViewModel> GetSingleAutocompleteResults()
internal IEnumerable<SingleResultItem> GetSingleAutocompleteResults()
{
if (PortViewModel == null) return null;

Expand All @@ -734,11 +712,11 @@ internal IEnumerable<NodeSearchElementViewModel> GetSingleAutocompleteResults()
// These default suggestions will be populated based on the port type.
if (!objectTypeMatchingElements.Any())
{
return DefaultAutoCompleteCandidates();
return DefaultAutoCompleteCandidates().Select(x => new SingleResultItem(x));
}
else
{
return GetViewModelForNodeSearchElements(objectTypeMatchingElements);
return objectTypeMatchingElements.Select(x => new SingleResultItem(x));
}
}
}
Expand Down Expand Up @@ -894,38 +872,37 @@ internal void PopulateAutoComplete()
{
DropdownResults = null;
}

Task.Run(() =>
{
IEnumerable<NodeAutoCompleteClusterResult> comboboxResults;
if (IsSingleAutocomplete)
{
var fullSingleResults = GetSingleAutocompleteResults().ToList();
FullSingleResults = GetSingleAutocompleteResults().ToList();
FullResults = new MLNodeClusterAutoCompletionResponse
{
Version = "0.0",
NumberOfResults = fullSingleResults.Count,
Results = fullSingleResults.Select(x => new ClusterResultItem
NumberOfResults = FullSingleResults.Count,
Results = FullSingleResults.Select(x => new ClusterResultItem
{
Description = x.Description,
Title = x.Description,
Probability = (x.AutoCompletionNodeMachineLearningInfo.ConfidenceScore / 100).ToString(),
Title = x.Description,
Probability = x.Score.ToString(),
EntryNodeIndex = 0,
EntryNodeInPort = x.Model.AutoCompletionNodeElementInfo.PortToConnect,
EntryNodeInPort = x.PortToConnect,
Topology = new TopologyItem
{
Nodes = new List<NodeItem> { new NodeItem {
Id = new Guid().ToString(),
Type = new NodeType { Id = x.Model.CreationName } } },
Type = new NodeType { Id = x.CreationName } } },
Connections = new List<ConnectionItem>()
}
})
};
}
else
{
FullResults = GetMLNodeClusterAutocompleteResults();
FullResults = GetGenericAutocompleteResult<MLNodeClusterAutoCompletionResponse>(nodeClusterAutocompleteMLEndpoint);
}
comboboxResults = QualifiedResults.Select(x => new NodeAutoCompleteClusterResult { Description = x.Description });

dynamoViewModel.UIDispatcher.BeginInvoke(() =>
{
Expand All @@ -936,6 +913,35 @@ internal void PopulateAutoComplete()
return;
}

IEnumerable<DNADropdownViewModel> comboboxResults;
if (IsSingleAutocomplete)
{
//getting bitmaps from resources necessarily has to be done in the UI thread
Dictionary<string, ImageSource> dict = [];
foreach (var singleResult in FullSingleResults)
{
if (dict.ContainsKey(singleResult.CreationName))
{
continue;
}
var iconRequest = new IconRequestEventArgs(singleResult.Assembly, singleResult.IconName + Configurations.SmallIconPostfix);
SearchViewModelRequestBitmapSource(iconRequest);
dict[singleResult.CreationName] = iconRequest.Icon;
}
comboboxResults = QualifiedResults.Select(x => new DNADropdownViewModel
{
Description = x.Description,
SmallIcon = dict[x.Topology.Nodes.First().Type.Id],
});
}
else
{
comboboxResults = QualifiedResults.Select(x => new DNADropdownViewModel
{
Description = x.Description
//default icon (cluster) is set in the xaml view
});
}
// this runs synchronously on the UI thread, so the UI can't disappear during execution
DropdownResults = comboboxResults;
SelectedIndex = 0;
Expand Down Expand Up @@ -992,84 +998,6 @@ internal void NodeViewModel_Removed(NodeModel node)
ParentNodeRemoved?.Invoke(node);
}

/// <summary>
/// Returns a IEnumberable of NodeSearchElementViewModel for respective NodeSearchElements.
/// </summary>
private IEnumerable<NodeSearchElementViewModel> GetViewModelForNodeSearchElements(List<NodeSearchElement> searchElementsCache)
{
return searchElementsCache.Select(e =>
{
var vm = new NodeSearchElementViewModel(e, this);
vm.RequestBitmapSource += SearchViewModelRequestBitmapSource;
return vm;
});
}

/// <summary>
/// Returns a NodeSearchElementViewModel for a NodeSearchElement
/// </summary>
private NodeSearchElementViewModel GetViewModelForNodeSearchElement(NodeSearchElement nodeSearchElement)
{
if (nodeSearchElement != null)
{
var vm = new NodeSearchElementViewModel(nodeSearchElement, this);
vm.RequestBitmapSource += SearchViewModelRequestBitmapSource;
return vm;
}
return null;
}


/// <summary>
/// Performs a search using the given string as query and subset, if provided.
/// </summary>
/// <returns> Returns a list with a maximum MaxNumSearchResults elements.</returns>
/// <param name="search"> The search query </param>
internal IEnumerable<NodeSearchElementViewModel> SearchNodeAutocomplete(string search)
{
if (LuceneUtility != null)
{
//The DirectoryReader and IndexSearcher have to be assigned after commiting indexing changes and before executing the Searcher.Search() method, otherwise new indexed info won't be reflected
LuceneUtility.dirReader = LuceneUtility.writer?.GetReader(applyAllDeletes: true);
if (LuceneUtility.dirReader == null) return null;

LuceneUtility.Searcher = new IndexSearcher(LuceneUtility.dirReader);

string searchTerm = search.Trim();
var candidates = new List<NodeSearchElementViewModel>();
var parser = new MultiFieldQueryParser(LuceneConfig.LuceneNetVersion, LuceneConfig.NodeIndexFields, LuceneUtility.Analyzer)
{
AllowLeadingWildcard = true,
DefaultOperator = LuceneConfig.DefaultOperator,
FuzzyMinSim = LuceneConfig.MinimumSimilarity
};

Query query = parser.Parse(LuceneUtility.CreateSearchQuery(LuceneConfig.NodeIndexFields, searchTerm));
TopDocs topDocs = LuceneUtility.Searcher.Search(query, n: LuceneConfig.DefaultResultsCount);

for (int i = 0; i < topDocs.ScoreDocs.Length; i++)
{
// read back a Lucene doc from results
Document resultDoc = LuceneUtility.Searcher.Doc(topDocs.ScoreDocs[i].Doc);

string name = resultDoc.Get(nameof(LuceneConfig.NodeFieldsEnum.Name));
string docName = resultDoc.Get(nameof(LuceneConfig.NodeFieldsEnum.DocName));
string cat = resultDoc.Get(nameof(LuceneConfig.NodeFieldsEnum.FullCategoryName));
string parameters = resultDoc.Get(nameof(LuceneConfig.NodeFieldsEnum.Parameters));


var foundNode = FindViewModelForNodeNameAndCategory(name, cat, parameters);
if (foundNode != null)
{
candidates.Add(foundNode);
}
}

return candidates;
}
return null;
}

/// <summary>
/// Returns a collection of node search elements for nodes
/// that output a type compatible with the port type if it's an input port.
Expand Down

This file was deleted.

Loading
Loading