332ab25e64
* Use Sets and Freezing to make conversions faster * fmt * move class to own file
82 lines
2.9 KiB
C#
82 lines
2.9 KiB
C#
using Autodesk.AutoCAD.DatabaseServices;
|
|
using Microsoft.Extensions.Logging;
|
|
using Speckle.Connectors.Common.Conversion;
|
|
using Speckle.Sdk;
|
|
using Speckle.Sdk.Dependencies;
|
|
using Speckle.Sdk.Models.Proxies;
|
|
|
|
namespace Speckle.Connectors.Autocad.HostApp;
|
|
|
|
/// <summary>
|
|
/// This resource expects to be injected "fresh" in each receive operation (scoped lifetime).
|
|
/// Extracts group information from a set of objects into proxies in send operations; also creates groups from a set of proxies in receive operations.
|
|
/// TODO: Oguzhan! Check whats happening on second receive unless purge groups? naming etc..
|
|
/// </summary>
|
|
public class AutocadGroupBaker
|
|
{
|
|
private readonly ILogger<AutocadGroupBaker> _logger;
|
|
private readonly AutocadContext _autocadContext;
|
|
|
|
public AutocadGroupBaker(AutocadContext autocadContext, ILogger<AutocadGroupBaker> logger)
|
|
{
|
|
_autocadContext = autocadContext;
|
|
_logger = logger;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Creates groups in the host app from a set of group proxies. Can be called after the bake operation of all atomic objects (including instances) is complete.
|
|
/// </summary>
|
|
/// <param name="groupProxies"></param>
|
|
/// <param name="applicationIdMap"></param>
|
|
/// <returns></returns>
|
|
// TODO: Oguzhan! Do not report here too! But this is TBD that we don't know the shape of the report yet.
|
|
public IReadOnlyCollection<ReceiveConversionResult> CreateGroups(
|
|
IEnumerable<GroupProxy> groupProxies,
|
|
Dictionary<string, IReadOnlyCollection<Entity>> applicationIdMap
|
|
)
|
|
{
|
|
HashSet<ReceiveConversionResult> results = new();
|
|
|
|
using var groupCreationTransaction =
|
|
Application.DocumentManager.CurrentDocument.Database.TransactionManager.StartTransaction();
|
|
|
|
var groupDictionary = (DBDictionary)
|
|
groupCreationTransaction.GetObject(
|
|
Application.DocumentManager.CurrentDocument.Database.GroupDictionaryId,
|
|
OpenMode.ForWrite
|
|
);
|
|
|
|
foreach (var gp in groupProxies.OrderBy(group => group.objects.Count))
|
|
{
|
|
try
|
|
{
|
|
var entities = gp.objects.SelectMany(oldObjId => applicationIdMap[oldObjId]);
|
|
var ids = new ObjectIdCollection();
|
|
|
|
foreach (var entity in entities)
|
|
{
|
|
ids.Add(entity.ObjectId);
|
|
}
|
|
|
|
var groupName = _autocadContext.RemoveInvalidChars(gp.name);
|
|
var newGroup = new Group(groupName, true); // NOTE: this constructor sets both the description (as it says) but also the name at the same time
|
|
newGroup.Append(ids);
|
|
|
|
groupDictionary.UpgradeOpen();
|
|
groupDictionary.SetAt(groupName, newGroup);
|
|
|
|
groupCreationTransaction.AddNewlyCreatedDBObject(newGroup, true);
|
|
}
|
|
catch (Exception ex) when (!ex.IsFatal())
|
|
{
|
|
results.Add(new ReceiveConversionResult(Status.ERROR, gp, null, null, ex));
|
|
_logger.LogError(ex, "Failed to bake Autocad Group");
|
|
}
|
|
}
|
|
|
|
groupCreationTransaction.Commit();
|
|
|
|
return results.Freeze();
|
|
}
|
|
}
|