Skip to content

Commit

Permalink
Merge branch 'dev' into update-progress-receive
Browse files Browse the repository at this point in the history
  • Loading branch information
oguzhankoral authored Jan 14, 2025
2 parents 4b154d5 + 2a508e6 commit 6d314d3
Show file tree
Hide file tree
Showing 7 changed files with 397 additions and 74 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ public static void AddNavisworks(this IServiceCollection serviceCollection)
>();

serviceCollection.AddScoped<NavisworksMaterialUnpacker>();
serviceCollection.AddScoped<NavisworksColorUnpacker>();

// Sending operations
serviceCollection.AddScoped<IRootObjectBuilder<NAV.ModelItem>, NavisworksRootObjectBuilder>();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
using Microsoft.Extensions.Logging;
using Speckle.Connector.Navisworks.Services;
using Speckle.Converter.Navisworks.Helpers;
using Speckle.Converter.Navisworks.Settings;
using Speckle.Converters.Common;
using Speckle.Sdk;
using Speckle.Sdk.Models.Proxies;
using ComApi = Autodesk.Navisworks.Api.Interop.ComApi;
using ComBridge = Autodesk.Navisworks.Api.ComApi.ComApiBridge;

namespace Speckle.Connector.Navisworks.HostApp;

public class NavisworksColorUnpacker(
ILogger<NavisworksColorUnpacker> logger,
IConverterSettingsStore<NavisworksConversionSettings> converterSettings,
IElementSelectionService selectionService
)
{
private static T Select<T>(RepresentationMode mode, T active, T permanent, T original, T defaultValue) =>
mode switch
{
RepresentationMode.Active => active,
RepresentationMode.Permanent => permanent,
RepresentationMode.Original => original,
_ => defaultValue,
};

internal List<ColorProxy> UnpackColor(
IReadOnlyList<NAV.ModelItem> navisworksObjects,
Dictionary<string, List<NAV.ModelItem>> groupedNodes
)
{
if (navisworksObjects == null)
{
throw new ArgumentNullException(nameof(navisworksObjects));
}

if (groupedNodes == null)
{
throw new ArgumentNullException(nameof(groupedNodes));
}

Dictionary<string, ColorProxy> colorProxies = [];
Dictionary<string, string> mergedIds = [];

// Build mergedIds map once
foreach (var group in groupedNodes)
{
foreach (var node in group.Value)
{
mergedIds[selectionService.GetModelItemPath(node)] = group.Key;
}
}

foreach (NAV.ModelItem navisworksObject in navisworksObjects)
{
try
{
// Skip non-2D elements
if (!Is2DElement(navisworksObject))
{
continue;
}

var navisworksObjectId = selectionService.GetModelItemPath(navisworksObject);
var finalId = mergedIds.TryGetValue(navisworksObjectId, out var mergedId) ? mergedId : navisworksObjectId;

var geometry = navisworksObject.Geometry;
var mode = converterSettings.Current.User.VisualRepresentationMode;

using var defaultColor = new NAV.Color(1.0, 1.0, 1.0);

var representationColor = Select(
mode,
geometry.ActiveColor,
geometry.PermanentColor,
geometry.OriginalColor,
defaultColor
);

var colorId = Select(
mode,
$"{geometry.ActiveColor.GetHashCode()}_{geometry.ActiveTransparency}".GetHashCode(),
$"{geometry.PermanentColor.GetHashCode()}_{geometry.PermanentTransparency}".GetHashCode(),
$"{geometry.OriginalColor.GetHashCode()}_{geometry.OriginalTransparency}".GetHashCode(),
0
);

var colorName = ColorConverter.NavisworksColorToColor(representationColor).Name;

if (colorProxies.TryGetValue(colorId.ToString(), out ColorProxy? colorProxy))
{
colorProxy.objects.Add(finalId);
}
else
{
colorProxies[colorId.ToString()] = new ColorProxy
{
value = ColorConverter.NavisworksColorToColor(representationColor).ToArgb(),
name = colorName,
applicationId = colorId.ToString(),
objects = [finalId]
};
}
}
catch (Exception ex) when (!ex.IsFatal())
{
logger.LogError(ex, "Failed to unpack color for Navisworks object");
}
}

return colorProxies.Values.ToList();
}

private static bool Is2DElement(NAV.ModelItem modelItem)
{
if (!modelItem.HasGeometry)
{
return false;
}

var primitiveChecker = new PrimitiveChecker();

var comSelection = ComBridge.ToInwOpSelection([modelItem]);
try
{
foreach (ComApi.InwOaPath path in comSelection.Paths())
{
GC.KeepAlive(path);

foreach (ComApi.InwOaFragment3 fragment in path.Fragments())
{
GC.KeepAlive(fragment);

fragment.GenerateSimplePrimitives(ComApi.nwEVertexProperty.eNORMAL, primitiveChecker);

// Exit early if triangles are found
if (primitiveChecker.HasTriangles)
{
return false;
}
}
}

// Return true if any 2D primitives are found
return primitiveChecker.HasLines || primitiveChecker.HasPoints || primitiveChecker.HasSnapPoints;
}
finally
{
System.Runtime.InteropServices.Marshal.ReleaseComObject(comSelection);
}
}
}

public class PrimitiveChecker : ComApi.InwSimplePrimitivesCB
{
public bool HasTriangles { get; private set; }
public bool HasLines { get; private set; }
public bool HasPoints { get; private set; }
public bool HasSnapPoints { get; private set; }

public void Line(ComApi.InwSimpleVertex v1, ComApi.InwSimpleVertex v2) => HasLines = true;

public void Point(ComApi.InwSimpleVertex v1) => HasPoints = true;

public void SnapPoint(ComApi.InwSimpleVertex v1) => HasSnapPoints = true;

public void Triangle(ComApi.InwSimpleVertex v1, ComApi.InwSimpleVertex v2, ComApi.InwSimpleVertex v3) =>
HasTriangles = true;
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using Microsoft.Extensions.Logging;
using Speckle.Connector.Navisworks.Services;
using Speckle.Converter.Navisworks.Helpers;
using Speckle.Converter.Navisworks.Settings;
using Speckle.Converters.Common;
using Speckle.Objects.Other;
Expand Down Expand Up @@ -92,7 +93,8 @@ internal List<RenderMaterialProxy> UnpackRenderMaterial(
0
);

var materialName = $"NavisworksMaterial_{Math.Abs(NavisworksColorToColor(renderColor).ToArgb())}";
var materialName =
$"NavisworksMaterial_{Math.Abs(ColorConverter.NavisworksColorToColor(renderColor).ToArgb())}";

// Check Item category for material name
var itemCategory = navisworksObject.PropertyCategories.FindCategoryByDisplayName("Item");
Expand Down Expand Up @@ -152,7 +154,7 @@ private static RenderMaterial ConvertRenderColorAndTransparencyToSpeckle(
int applicationId
)
{
var color = NavisworksColorToColor(navisworksColor);
var color = ColorConverter.NavisworksColorToColor(navisworksColor);

var speckleRenderMaterial = new RenderMaterial()
{
Expand All @@ -167,12 +169,4 @@ int applicationId

return speckleRenderMaterial;
}

private static System.Drawing.Color NavisworksColorToColor(NAV.Color color) =>
System.Drawing.Color.FromArgb(
alpha: 255,
red: Convert.ToInt32(color.R * 255),
green: Convert.ToInt32(color.G * 255),
blue: Convert.ToInt32(color.B * 255)
);
}
Loading

0 comments on commit 6d314d3

Please sign in to comment.