-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
c5e14e7
commit 3fbba01
Showing
4 changed files
with
112 additions
and
51 deletions.
There are no files selected for viewing
50 changes: 50 additions & 0 deletions
50
Connectors/Tekla/Speckle.Connector.TeklaShared/HostApp/TeklaMaterialCache.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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(); | ||
} | ||
} |
109 changes: 59 additions & 50 deletions
109
Connectors/Tekla/Speckle.Connector.TeklaShared/HostApp/TeklaMaterialUnpacker.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters