Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Revit receive first pass: reference geometry workflow (CNX-403) #254

Merged
merged 37 commits into from
Sep 19, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
54a3a45
feat(dui3): re-enables receive binding
didimitrie Sep 9, 2024
0af84a8
chore(revit): drastic cleanup
didimitrie Sep 9, 2024
bdbb20e
feat(revit): starts scaffolding revit root to host converter
didimitrie Sep 9, 2024
24f86ce
RenderMaterialToHostConverter added back
kekesidavid Sep 10, 2024
a4abd26
casting to GeometryObject instead of GeometryElement
kekesidavid Sep 10, 2024
8f84a9e
feat(dui3): fallback display values and refactors out material converter
didimitrie Sep 10, 2024
807d9ff
feat(dui3): creates DS and adds point support
didimitrie Sep 10, 2024
05f30e3
feat(dui3): closed nurbs fallback to display values
didimitrie Sep 10, 2024
cfb20de
David/cnx 443 selection (#231)
kekesidavid Sep 10, 2024
7f1e00e
wip
kekesidavid Sep 12, 2024
71f857f
Merge branch 'dev' into grouping-sandbox
didimitrie Sep 12, 2024
9823cec
feat(revit): wraps receive in correct context
didimitrie Sep 12, 2024
92bbddb
wip
didimitrie Sep 12, 2024
5d8d572
feat(dui3): adds prototype grouping by collection
didimitrie Sep 12, 2024
18c8d44
remove invalid characters from group name
kekesidavid Sep 12, 2024
7ce34d6
hide warnings preprocessor
kekesidavid Sep 12, 2024
38ed784
exception handling and error log
kekesidavid Sep 12, 2024
e1b0832
added cancellation and progress reporting
kekesidavid Sep 12, 2024
81f35f6
chore: comments and minor cleanup
didimitrie Sep 12, 2024
0cc0897
Merge pull request #237 from specklesystems/grouping-sandbox
didimitrie Sep 12, 2024
0e87060
David/cnx 409 2 add rendermaterial and color manager to connector (#242)
kekesidavid Sep 16, 2024
e77b2e4
Minor cleanup
oguzhankoral Sep 16, 2024
10d0988
Add object application id into objects of its layer render material p…
oguzhankoral Sep 16, 2024
90834bd
feat(dui3): adds compatibility for objects with display values
didimitrie Sep 16, 2024
1de58a3
Merge pull request #243 from specklesystems/oguzhan/cnx-470-add-suppo…
didimitrie Sep 16, 2024
57407d4
Use LocalToGlobal logic for revit receive
oguzhankoral Sep 16, 2024
e1053df
Use common local to global util for arcgis too
oguzhankoral Sep 16, 2024
206524a
Remove unnecessary registration
oguzhankoral Sep 16, 2024
70e43dd
Remove using
oguzhankoral Sep 16, 2024
4e523ac
Remove unnecessart ToList
oguzhankoral Sep 16, 2024
b8b9355
Register LocalToGlobalConverterUtils for connectors not as common
oguzhankoral Sep 17, 2024
f74f9bc
Merge pull request #244 from specklesystems/oguzhan/cnx-442-handle-in…
didimitrie Sep 17, 2024
5caf403
purge materials and groups in Revit before update (#245)
kekesidavid Sep 18, 2024
5e52cdd
assign categories to DirectShapes after receive, updated revit invali…
kekesidavid Sep 18, 2024
2fa3477
Merge remote-tracking branch 'origin/dev' into revit-receive
oguzhankoral Sep 19, 2024
dc394fa
Post conflict resolving problems
oguzhankoral Sep 19, 2024
7a42a10
minor changes, logging, comments (#257)
kekesidavid Sep 19, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Use LocalToGlobal logic for revit receive
  • Loading branch information
oguzhankoral committed Sep 16, 2024
commit 57407d4e2196b4e3511ef0401ffec35130691e94
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using Speckle.Connectors.Revit.HostApp;
using Speckle.Connectors.Utils.Builders;
using Speckle.Connectors.Utils.Conversion;
using Speckle.Connectors.Utils.Instances;
using Speckle.Connectors.Utils.Operations.Receive;
using Speckle.Converters.Common;
using Speckle.Converters.RevitShared.Helpers;
Expand All @@ -20,6 +21,8 @@ internal sealed class RevitHostObjectBuilder : IHostObjectBuilder, IDisposable
private readonly IRevitConversionContextStack _contextStack;
private readonly GraphTraversal _traverseFunction;
private readonly ITransactionManager _transactionManager;
private readonly ILocalToGlobalUnpacker _localToGlobalUnpacker;
private readonly LocalToGlobalConverterUtils _localToGlobalConverterUtils;
private readonly RevitGroupBaker _groupManager;
private readonly RevitMaterialBaker _materialBaker;
private readonly ILogger<RevitHostObjectBuilder> _logger;
Expand All @@ -31,6 +34,8 @@ public RevitHostObjectBuilder(
IRevitConversionContextStack contextStack,
GraphTraversal traverseFunction,
ITransactionManager transactionManager,
ILocalToGlobalUnpacker localToGlobalUnpacker,
LocalToGlobalConverterUtils localToGlobalConverterUtils,
RevitGroupBaker groupManager,
RevitMaterialBaker materialBaker,
RootObjectUnpacker rootObjectUnpacker,
Expand All @@ -41,6 +46,8 @@ ILogger<RevitHostObjectBuilder> logger
_contextStack = contextStack;
_traverseFunction = traverseFunction;
_transactionManager = transactionManager;
_localToGlobalUnpacker = localToGlobalUnpacker;
_localToGlobalConverterUtils = localToGlobalConverterUtils;
_groupManager = groupManager;
_materialBaker = materialBaker;
_rootObjectUnpacker = rootObjectUnpacker;
Expand Down Expand Up @@ -70,6 +77,10 @@ CancellationToken cancellationToken

// 1 - Unpack objects and proxies from root commit object
var unpackedRoot = _rootObjectUnpacker.Unpack(rootObject);
var localToGlobalMaps = _localToGlobalUnpacker.Unpack(
unpackedRoot.DefinitionProxies,
unpackedRoot.ObjectsToConvert.ToList()
);

using var activity = SpeckleActivityFactory.Start("Build");

Expand All @@ -88,7 +99,7 @@ CancellationToken cancellationToken
}
}

var conversionResults = BakeObjects(unpackedRoot.ObjectsToConvert, onOperationProgressed, cancellationToken);
var conversionResults = BakeObjects(localToGlobalMaps, onOperationProgressed, cancellationToken);

using (var _ = SpeckleActivityFactory.Start("Commit"))
{
Expand Down Expand Up @@ -122,48 +133,50 @@ CancellationToken cancellationToken
}

private HostObjectBuilderResult BakeObjects(
IEnumerable<TraversalContext> objectsGraph,
List<LocalToGlobalMap> localToGlobalMaps,
Action<string, double?>? onOperationProgressed,
CancellationToken cancellationToken
)
{
using (var _ = SpeckleActivityFactory.Start("BakeObjects"))
{
var conversionResults = new List<ReceiveConversionResult>();
var bakedObjectIds = new List<string>();
using var _ = SpeckleActivityFactory.Start("BakeObjects");
var conversionResults = new List<ReceiveConversionResult>();
var bakedObjectIds = new List<string>();

// is this a dumb idea?
var objectList = objectsGraph.ToList();
int count = 0;
// is this a dumb idea?
var objectList = localToGlobalMaps.ToList();
int count = 0;

foreach (TraversalContext tc in objectList)
foreach (LocalToGlobalMap localToGlobalMap in localToGlobalMaps)
{
cancellationToken.ThrowIfCancellationRequested();
try
{
cancellationToken.ThrowIfCancellationRequested();
try
using var activity = SpeckleActivityFactory.Start("BakeObject");
var atomicObject = _localToGlobalConverterUtils.TransformObjects(
localToGlobalMap.AtomicObject,
localToGlobalMap.Matrix
);
var result = _converter.Convert(atomicObject);
onOperationProgressed?.Invoke("Converting", (double)++count / objectList.Count);

// Note: our current converter always returns a DS for now
if (result is DirectShape ds)
{
using var activity = SpeckleActivityFactory.Start("BakeObject");
var result = _converter.Convert(tc.Current);
onOperationProgressed?.Invoke("Converting", (double)++count / objectList.Count);

// Note: our current converter always returns a DS for now
if (result is DirectShape ds)
{
bakedObjectIds.Add(ds.UniqueId.ToString());
_groupManager.AddToGroupMapping(tc, ds);
}
else
{
throw new SpeckleConversionException($"Failed to cast {result.GetType()} to Direct Shape.");
}
conversionResults.Add(new(Status.SUCCESS, tc.Current, ds.UniqueId, "Direct Shape"));
bakedObjectIds.Add(ds.UniqueId.ToString());
_groupManager.AddToGroupMapping(localToGlobalMap.TraversalContext, ds);
}
catch (Exception ex) when (!ex.IsFatal())
else
{
conversionResults.Add(new(Status.ERROR, tc.Current, null, null, ex));
throw new SpeckleConversionException($"Failed to cast {result.GetType()} to Direct Shape.");
}
conversionResults.Add(new(Status.SUCCESS, atomicObject, ds.UniqueId, "Direct Shape"));
}
catch (Exception ex) when (!ex.IsFatal())
{
conversionResults.Add(new(Status.ERROR, localToGlobalMap.AtomicObject, null, null, ex));
}
return new(bakedObjectIds, conversionResults);
}
return new(bakedObjectIds, conversionResults);
}

public void Dispose()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ This will require consolidating across other connectors.
builder.AddScoped<IFactory<IToHostTopLevelConverter>, Factory<IToHostTopLevelConverter>>();
builder.AddScoped<IConverterResolver<IToHostTopLevelConverter>, ConverterResolver<IToHostTopLevelConverter>>();

builder.AddScoped<LocalToGlobalConverterUtils>();
builder.AddScoped<IRootToHostConverter, ConverterWithFallback>();
builder.AddScoped<ConverterWithoutFallback>(); //Register as self, only the `ConverterWithFallback` needs it

Expand Down
71 changes: 71 additions & 0 deletions Sdk/Speckle.Converters.Common/LocalToGlobalConverterUtils.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
using Speckle.DoubleNumerics;
using Speckle.Objects;
using Speckle.Sdk.Models;

namespace Speckle.Converters.Common;

// POC: We could pass transformation matrices to converters by default and evaluate there instead as utils.
public class LocalToGlobalConverterUtils
{
private Vector3 TransformPt(Vector3 vector, Matrix4x4 matrix)
{
var divisor = matrix.M41 + matrix.M42 + matrix.M43 + matrix.M44;
var x = (vector.X * matrix.M11 + vector.Y * matrix.M12 + vector.Z * matrix.M13 + matrix.M14) / divisor;
var y = (vector.X * matrix.M21 + vector.Y * matrix.M22 + vector.Z * matrix.M23 + matrix.M24) / divisor;
var z = (vector.X * matrix.M31 + vector.Y * matrix.M32 + vector.Z * matrix.M33 + matrix.M34) / divisor;

return new Vector3(x, y, z);
}

// POC: This could move to converters instead handling all cases like this.
public Base TransformObjects(Base atomicObject, List<Matrix4x4> matrix)
{
if (matrix.Count == 0)
{
return atomicObject;
}

List<Speckle.Objects.Other.Transform> transforms = matrix
.Select(x => new Speckle.Objects.Other.Transform(x, "none"))
.ToList();

if (atomicObject is ITransformable c)
{
foreach (var transform in transforms)
{
c.TransformTo(transform, out ITransformable newObj);
c = newObj;
}

if (c is not Base)
{
throw new SpeckleConversionException(
$"Blocks transformation of type {atomicObject.speckle_type} did not return a valid object"
);
}

string id = atomicObject.id;
atomicObject = (Base)c;
atomicObject.id = id;

// .TransformTo only transfers typed properties, we need to add back the dynamic ones:
foreach (var prop in atomicObject.GetMembers(DynamicBaseMemberType.Dynamic))
{
if (prop.Value is not Base)
{
atomicObject[prop.Key] = prop.Value;
}
else
{
// TODO: add more granular warnings if needed that the property was skipped for blocks
}
}

return atomicObject;
}

throw new SpeckleConversionException(
$"{atomicObject.speckle_type} is not supported for local to global coordinate transformation"
);
}
}