Skip to content

Commit

Permalink
Feat(Tekla) : receive instances in Tekla (#2774)
Browse files Browse the repository at this point in the history
receive instances in Tekla

Co-authored-by: Connor Ivy <[email protected]>
  • Loading branch information
connorivy and Connor Ivy authored Jul 16, 2023
1 parent 2143582 commit ff311bc
Show file tree
Hide file tree
Showing 5 changed files with 95 additions and 125 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using DesktopUI2;
using DesktopUI2;
using DesktopUI2.Models;
using DesktopUI2.Models.Settings;
using DesktopUI2.ViewModels;
Expand All @@ -14,6 +14,7 @@
using System.Linq;
using System.Threading.Tasks;
using Serilog;
using Speckle.Core.Models.GraphTraversal;

namespace Speckle.ConnectorTeklaStructures.UI
{
Expand Down Expand Up @@ -59,9 +60,7 @@ public override async Task<StreamState> ReceiveStream(StreamState state, Progres
progress.Update(conversionProgressDict);
};


var commitObjs = FlattenCommitObject(commitObject, converter);
foreach (var commitObj in commitObjs)
foreach (var commitObj in FlattenCommitObject(commitObject, converter))
{
BakeObject(commitObj, state, converter);
updateProgressAction?.Invoke();
Expand Down Expand Up @@ -94,53 +93,20 @@ private void BakeObject(Base obj, StreamState state, ISpeckleConverter converter
}

/// <summary>
/// Recurses through the commit object and flattens it.
/// Traverses the object graph, returning objects to be converted.
/// </summary>
/// <param name="obj"></param>
/// <param name="converter"></param>
/// <returns></returns>
private List<Base> FlattenCommitObject(object obj, ISpeckleConverter converter)
/// <param name="obj">The root <see cref="Base"/> object to traverse</param>
/// <param name="converter">The converter instance, used to define what objects are convertable</param>
/// <returns>A flattened list of objects to be converted ToNative</returns>
private IEnumerable<Base> FlattenCommitObject(Base obj, ISpeckleConverter converter)
{
List<Base> objects = new List<Base>();


if (obj is Base @base)
{
if (converter.CanConvertToNative(@base))
{
objects.Add(@base);

return objects;
}
else
{
foreach (var prop in @base.GetDynamicMembers())
{
objects.AddRange(FlattenCommitObject(@base[prop], converter));
}
return objects;
}
}

if (obj is List<object> list)
{
foreach (var listObj in list)
{
objects.AddRange(FlattenCommitObject(listObj, converter));
}
return objects;
}

if (obj is IDictionary dict)
{
foreach (DictionaryEntry kvp in dict)
{
objects.AddRange(FlattenCommitObject(kvp.Value, converter));
}
return objects;
}

return objects;
var traverseFunction = DefaultTraversal.CreateTraverseFunc(converter);

return traverseFunction.Traverse(obj)
.Select(tc => tc.current)
.Where(b => b != null)
.Where(converter.CanConvertToNative)
.Reverse();
}

#endregion
Expand Down
4 changes: 2 additions & 2 deletions Core/Core/Models/GraphTraversal/DefaultTraversal.cs
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ public static GraphTraversal CreateBIMTraverseFunc(ISpeckleConverter converter)
.When(o => o.speckle_type.Contains("Objects.Structural.Results"))
.ContinueTraversing(None);

private static readonly ITraversalRule DefaultRule = TraversalRule
public static readonly ITraversalRule DefaultRule = TraversalRule
.NewTraversalRule()
.When(_ => true)
.ContinueTraversing(Members());
Expand Down Expand Up @@ -132,7 +132,7 @@ public static bool HasGeometry(Base x)
}

[Pure]
internal static IEnumerable<string> None(Base _)
public static IEnumerable<string> None(Base _)
{
return Enumerable.Empty<string>();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,8 @@

<Import Project="..\ConverterTeklaStructuresShared\ConverterTeklaStructuresShared.projitems" Label="Shared" />

<Target Name="PostBuild" AfterTargets="PostBuildEvent">
<Exec Command="xcopy /Y /S &quot;$(TargetDir)$(AssemblyName).dll&quot; &quot;$(AppData)\Speckle\Kits\Objects\&quot;&#xD;&#xA;xcopy /Y /S &quot;$(TargetDir)$(AssemblyName).dll&quot; &quot;$(ALLUSERSPROFILE)\Speckle\Kits\Objects\&quot;&#xD;&#xA;xcopy /Y /S &quot;$(TargetDir)\Objects.dll&quot; &quot;$(ALLUSERSPROFILE)\Speckle\Kits\Objects\&quot;" />
</Target>

</Project>
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
using Speckle.Core.Kits;
using Objects.Geometry;
using Objects.Other;
using Speckle.Core.Kits;
using Speckle.Core.Logging;
using Speckle.Core.Models;
using Speckle.Core.Models;
using Speckle.Core.Models.Extensions;
using System;
using Speckle.Core.Models.GraphTraversal;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Tekla.Structures;
using Tekla.Structures.Model;
using BE = Objects.BuiltElements;
using GE = Objects.Geometry;
Expand Down Expand Up @@ -67,9 +64,13 @@ public void SetContextDocument(object doc)
public bool CanConvertToNative(Base @object)
{
Settings.TryGetValue("recieve-objects-mesh", out string recieveModelMesh);
if (bool.Parse(recieveModelMesh) == true)
if (bool.TryParse(recieveModelMesh, out var receiveAsMesh) && receiveAsMesh)
{
return true;
if (DefaultTraversal.HasDefinition(@object) || DefaultTraversal.HasDisplayValue(@object))
{
return true;
}
return false;
}

switch (@object)
Expand Down Expand Up @@ -128,33 +129,25 @@ public bool CanConvertToSpeckle(object @object)

public object ConvertToNative(Base @object)
{

Settings.TryGetValue("recieve-objects-mesh", out string recieveModelMesh);
if (bool.Parse(recieveModelMesh) == true)
if (bool.TryParse(recieveModelMesh, out var receiveAsMesh) && receiveAsMesh)
{
try
if (@object is Instance instance)
{
MeshToNative(instance, instance.GetTransformedGeometry().Where(t => t is Mesh).Cast<Mesh>().ToList());
}
else
{
var bases = BaseExtensions.Flatten(@object);
foreach (var @base in bases)
{
try
{
List<GE.Mesh> displayValues = new List<GE.Mesh> { };
var meshes = @base.GetType().GetProperty("displayValue").GetValue(@base) as List<GE.Mesh>;
//dynamic property = propInfo;
//List<GE.Mesh> meshes = (List<GE.Mesh>)property;
MeshToNative(@base, meshes);
}
catch
foreach (var displayAlias in DefaultTraversal.displayValuePropAliases)
{
if (@base[displayAlias] is not List<GE.Mesh> meshes) continue;

MeshToNative(@base, meshes);
}
}
return true;
}
catch
{

}
}

Expand Down
105 changes: 56 additions & 49 deletions Objects/Objects/Other/Instance.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using Objects.Geometry;
using Speckle.Core.Kits;
using Speckle.Core.Models;
using Speckle.Core.Models.GraphTraversal;
using Speckle.Newtonsoft.Json;

namespace Objects.Other
Expand Down Expand Up @@ -33,6 +34,52 @@ protected Instance() { }
/// The units of this Instance, should be the same as the instance transform units
/// </summary>
public string units { get; set; }

// helper method that scans an Instance for all transformable geometry and nested instances
protected virtual IEnumerable<Base> GetTransformableGeometry()
{
var displayValueRule = TraversalRule
.NewTraversalRule()
.When(DefaultTraversal.HasDisplayValue)
.ContinueTraversing(_ => DefaultTraversal.displayValueAndElementsPropAliases);

var instanceRule = TraversalRule.NewTraversalRule()
.When(b => b is Instance instance && instance != null)
.ContinueTraversing(DefaultTraversal.None);

var traversal = new GraphTraversal(instanceRule, displayValueRule, DefaultTraversal.DefaultRule);

return traversal
.Traverse(definition)
.Select(tc => tc.current)
.Where(b => b is ITransformable || b is Instance)
.Where(b => b != null);
}

[SchemaComputed("transformedGeometry")]
public virtual IEnumerable<ITransformable> GetTransformedGeometry()
{
return GetTransformableGeometry()
.SelectMany(b =>
{
switch (b)
{
case Instance i:
return i.GetTransformedGeometry()
.Select(b =>
{
b.TransformTo(transform, out var tranformed);
return tranformed;
});
case ITransformable bt:
var res = bt.TransformTo(transform, out var transformed);
return res ? new List<ITransformable> { transformed } : new();
default:
return new List<ITransformable>();
}
})
.Where(b => b != null);
}
}

/// <summary>
Expand Down Expand Up @@ -89,31 +136,9 @@ public BlockDefinition blockDefinition
set => typedDefinition = value;
}

[SchemaComputed("transformedGeometry")]
public List<ITransformable> GetTransformedGeometry()
protected override IEnumerable<Base> GetTransformableGeometry()
{
return typedDefinition.geometry
.SelectMany(b =>
{
switch (b)
{
case BlockInstance bi:
return bi.GetTransformedGeometry()
?.Select(b =>
{
ITransformable childTransformed = null;
b?.TransformTo(transform, out childTransformed);
return childTransformed;
});
case ITransformable bt:
var res = bt.TransformTo(transform, out var transformed);
return new List<ITransformable> { res ? transformed : null };
default:
return new List<ITransformable>();
}
})
.Where(b => b != null)
.ToList();
return typedDefinition.geometry;
}

/// <summary>
Expand Down Expand Up @@ -149,36 +174,18 @@ public class RevitInstance : Instance<RevitSymbolElementType>
public Base parameters { get; set; }
public string elementId { get; set; }

[SchemaComputed("transformedGeometry")]
public List<ITransformable> GetTransformedGeometry()
protected override IEnumerable<Base> GetTransformableGeometry()
{
var allChildren = typedDefinition.elements ?? new List<Base>();
if (typedDefinition.displayValue.Any())
allChildren.AddRange(typedDefinition.displayValue);
return allChildren;
}

// get transformed definition objs
var transformed = allChildren
.SelectMany(b =>
{
switch (b)
{
case RevitInstance ri:
return ri.GetTransformedGeometry()
?.Select(b =>
{
ITransformable childTransformed = null;
b?.TransformTo(transform, out childTransformed);
return childTransformed;
});
case ITransformable bt:
var res = bt.TransformTo(transform, out var transformed);
return new List<ITransformable> { res ? transformed : null };
default:
return new List<ITransformable>();
}
})
.Where(b => b != null)
.ToList();
[SchemaComputed("transformedGeometry")]
public override IEnumerable<ITransformable> GetTransformedGeometry()
{
var transformed = base.GetTransformedGeometry().ToList();

// add any dynamically attached elements on this instance
var elements = (this["elements"] ?? this["@elements"]) as List<object>;
Expand Down

0 comments on commit ff311bc

Please sign in to comment.