Skip to content

Commit

Permalink
adds teklamaterialcahce
Browse files Browse the repository at this point in the history
  • Loading branch information
dogukankaratas committed Nov 26, 2024
1 parent c5e14e7 commit 3fbba01
Show file tree
Hide file tree
Showing 4 changed files with 112 additions and 51 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
using Speckle.Objects.Other;

namespace Speckle.Connector.Tekla2024.HostApp;

public class TeklaMaterialCache
{
// cache of color -> RenderMaterial mappings
public Dictionary<string, RenderMaterial> MaterialCache { get; } = new();

// cache of object -> material proxy mappings
public Dictionary<string, Dictionary<string, RenderMaterialProxy>> ObjectProxyMap { get; } = new();

// clear caches
public void Clear()
{
MaterialCache.Clear();
ObjectProxyMap.Clear();
}

// returns the merged material proxy list for the given object ids
// use this to get post conversion a correct list of material proxies for setting on the root commit object
public List<RenderMaterialProxy> GetRenderMaterialProxyListForObjects(List<string> elementIds)
{
var proxiesToMerge = ObjectProxyMap
.Where(valuePair => elementIds.Contains(valuePair.Key))
.Select(valuePair => valuePair.Value);

var mergeTarget = new Dictionary<string, RenderMaterialProxy>();
foreach (var dictionary in proxiesToMerge)
{
foreach (var valuePair in dictionary)
{
if (!mergeTarget.TryGetValue(valuePair.Key, out RenderMaterialProxy? value))
{
value = valuePair.Value;
mergeTarget[valuePair.Key] = value;
continue;
}
value.objects.AddRange(valuePair.Value.objects);
}
}

foreach (var renderMaterialProxy in mergeTarget.Values)
{
renderMaterialProxy.objects = renderMaterialProxy.objects.Distinct().ToList();
}

return mergeTarget.Values.ToList();
}
}
Original file line number Diff line number Diff line change
@@ -1,80 +1,89 @@
using System.Drawing;
using Microsoft.Extensions.Logging;
using Speckle.Connector.Tekla2024.Extensions;
using Speckle.Objects.Other;

namespace Speckle.Connector.Tekla2024.HostApp;

public class TeklaMaterialUnpacker
{
private readonly ILogger<TeklaMaterialUnpacker> _logger;
private readonly TeklaMaterialCache _materialCache;

public TeklaMaterialUnpacker(ILogger<TeklaMaterialUnpacker> logger)
public TeklaMaterialUnpacker(TeklaMaterialCache materialCache)
{
_logger = logger;
_materialCache = materialCache;
}

public List<RenderMaterialProxy> UnpackRenderMaterial(List<TSM.ModelObject> atomicObjects)
{
var renderMaterialProxies = new Dictionary<string, RenderMaterialProxy>();
var processedObjects = new HashSet<string>();
Dictionary<string, RenderMaterialProxy> renderMaterialProxies = new();

var flattenedAtomicObjects = new List<TSM.ModelObject>();

// flatten objects and their children
foreach (var atomicObject in atomicObjects)
{
ProcessModelObject(atomicObject, renderMaterialProxies, processedObjects);
flattenedAtomicObjects.Add(atomicObject);
flattenedAtomicObjects.AddRange(atomicObject.GetSupportedChildren().ToList());
}

return renderMaterialProxies.Values.ToList();
}
// process each object
foreach (TSM.ModelObject obj in flattenedAtomicObjects)
{
var color = new TSMUI.Color();
TSMUI.ModelObjectVisualization.GetRepresentation(obj, ref color);

private void ProcessModelObject(
TSM.ModelObject modelObject,
Dictionary<string, RenderMaterialProxy> renderMaterialProxies,
HashSet<string> processedObjects
)
{
var objectId = modelObject.GetSpeckleApplicationId();
// create ARGB value consistently
int r = (int)(color.Red * 255);
int g = (int)(color.Green * 255);
int b = (int)(color.Blue * 255);
int a = (int)(color.Transparency * 255);
int argb = (a << 24) | (r << 16) | (g << 8) | b;

// NOTE: Related to CNX 798, processing of BooleanPart led to renderMaterial overwrites. Hence, it was excluded
// If duplicate objectIds are still appearing, there is another type causing issues.
if (processedObjects.Contains(objectId))
{
_logger.LogError(
$"The objectId {objectId} had already been processed. Check ModelObjectExtension.cs for nested object circular references."
);
}
// create consistent color ID
string colorId = color.GetSpeckleApplicationId();
string objectId = obj.GetSpeckleApplicationId();

processedObjects.Add(objectId);
// get or create proxy
if (!renderMaterialProxies.TryGetValue(colorId, out RenderMaterialProxy? proxy))
{
RenderMaterial renderMaterial;
if (_materialCache.MaterialCache.TryGetValue(colorId, out RenderMaterial? cachedMaterial))
{
renderMaterial = cachedMaterial;
}
else
{
var systemColor = Color.FromArgb(argb);
renderMaterial = new RenderMaterial
{
name = $"Color_{colorId}",
diffuse = systemColor.ToArgb(),
opacity = 1,
applicationId = colorId
};
_materialCache.MaterialCache[colorId] = renderMaterial;
}

var color = new TSMUI.Color();
TSMUI.ModelObjectVisualization.GetRepresentation(modelObject, ref color);
int r = (int)(color.Red * 255);
int g = (int)(color.Green * 255);
int b = (int)(color.Blue * 255);
int a = (int)(color.Transparency * 255);
int argb = (a << 24) | (r << 16) | (g << 8) | b;
proxy = new RenderMaterialProxy
{
value = renderMaterial,
objects = new List<string>(),
applicationId = colorId
};
renderMaterialProxies[colorId] = proxy;
}

Color systemColor = Color.FromArgb(argb);
var colorId = color.GetSpeckleApplicationId();
proxy.objects.Add(objectId);

// Ensure unique RenderMaterialProxy for each color
if (!renderMaterialProxies.TryGetValue(colorId, out RenderMaterialProxy? renderMaterialProxy))
{
renderMaterialProxy = new RenderMaterialProxy
// update object -> proxy mapping
if (!_materialCache.ObjectProxyMap.TryGetValue(objectId, out var proxyMap))
{
value = new RenderMaterial { name = colorId, diffuse = systemColor.ToArgb() },
objects = new List<string>(),
applicationId = colorId
};
renderMaterialProxies[colorId] = renderMaterialProxy;
proxyMap = new Dictionary<string, RenderMaterialProxy>();
_materialCache.ObjectProxyMap[objectId] = proxyMap;
}
proxyMap[colorId] = proxy;
}

renderMaterialProxy.objects.Add(objectId);

// Recursively process children (not included in s_excludedTypes)
foreach (var child in modelObject.GetSupportedChildren())
{
ProcessModelObject(child, renderMaterialProxies, processedObjects);
}
return renderMaterialProxies.Values.ToList();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,9 @@ public static IServiceCollection AddTekla(this IServiceCollection services)
ConverterSettingsStore<TeklaConversionSettings>
>();

// Register unpackers and bakers
// register unpackers and cache
services.AddScoped<TeklaMaterialUnpacker>();
services.AddSingleton<TeklaMaterialCache>();

services.AddMatchingInterfacesAsTransient(converterAssembly);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
<Compile Include="$(MSBuildThisFileDirectory)HostApp\SendCollectionManager.cs" />
<Compile Include="$(MSBuildThisFileDirectory)HostApp\TeklaDocumentModelStore.cs" />
<Compile Include="$(MSBuildThisFileDirectory)HostApp\TeklaIdleManager.cs" />
<Compile Include="$(MSBuildThisFileDirectory)HostApp\TeklaMaterialCache.cs" />
<Compile Include="$(MSBuildThisFileDirectory)HostApp\TeklaMaterialUnpacker.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Operations\Send\Settings\SendRebarsAsSolidSetting.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Operations\Send\Settings\ToSpeckleSettingsManager.cs" />
Expand Down

0 comments on commit 3fbba01

Please sign in to comment.