From 09e877b9108f41980793b82350815710d2dd6761 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B3zsef=20L=2E=20Kiss?= <50739844+jozseflkiss@users.noreply.github.com> Date: Tue, 21 Nov 2023 14:48:40 +0100 Subject: [PATCH] fix(Archicad): Timeout after 100s when sending large models #3 (#3052) timeout error Co-authored-by: Alan Rynne --- .../AddOn/Commands/GetModelForElements.cpp | 4 +- .../ConnectorArchicad/ConnectorBinding.cs | 61 ++++++++++++--- .../Converters/Converters/BeamConverter.cs | 30 ++++---- .../Converters/Converters/ColumnConverter.cs | 24 +++--- .../Converters/DirectShapeConverter.cs | 14 ++-- .../Converters/Converters/DoorConverter.cs | 14 ++-- .../Converters/Converters/FloorConverter.cs | 28 ++++--- .../Converters/GridLineConverter.cs | 68 +++++++++-------- .../Converters/Converters/RoofConverter.cs | 72 ++++++++++-------- .../Converters/Converters/RoomConverter.cs | 74 ++++++++++--------- .../Converters/SkylightConverter.cs | 14 ++-- .../Converters/Converters/WallConverter.cs | 24 +++--- .../Converters/Converters/WindowConverter.cs | 14 ++-- .../Converters/ModelConverter.cs | 30 ++++---- .../ConnectorArchicad/Helpers/Timer.cs | 7 +- .../OperationNameTemplates.Designer.cs | 47 +++++++++++- .../Properties/OperationNameTemplates.resx | 12 +++ .../Properties/launchSettings.json | 8 ++ 18 files changed, 350 insertions(+), 195 deletions(-) create mode 100644 ConnectorArchicad/ConnectorArchicad/Properties/launchSettings.json diff --git a/ConnectorArchicad/AddOn/Sources/AddOn/Commands/GetModelForElements.cpp b/ConnectorArchicad/AddOn/Sources/AddOn/Commands/GetModelForElements.cpp index dd5c4587ef..025dfea734 100644 --- a/ConnectorArchicad/AddOn/Sources/AddOn/Commands/GetModelForElements.cpp +++ b/ConnectorArchicad/AddOn/Sources/AddOn/Commands/GetModelForElements.cpp @@ -79,7 +79,9 @@ static void GetModelInfoForElement (const Modeler::Elem& elem, // edges for (ULong edgeIdx = 0; edgeIdx < body.GetEdgeCount (); ++edgeIdx) { const EDGE& edge = body.GetConstEdge (edgeIdx); - modelInfo.AddEdge (ModelInfo::EdgeId (edge.vert1 + vetrexOffset, edge.vert2 + vetrexOffset), ModelInfo::EdgeData (ModelInfo::VisibleEdge, edge.pgon1, edge.pgon2)); + // send only edges which have no polygons (only 3D lines) + if (edge.pgon1 == Brep::MeshBrep::Edge::InvalidPgonIdx && edge.pgon2 == Brep::MeshBrep::Edge::InvalidPgonIdx) + modelInfo.AddEdge (ModelInfo::EdgeId (edge.vert1 + vetrexOffset, edge.vert2 + vetrexOffset), ModelInfo::EdgeData (ModelInfo::VisibleEdge, edge.pgon1, edge.pgon2)); } // polygons diff --git a/ConnectorArchicad/ConnectorArchicad/ConnectorBinding.cs b/ConnectorArchicad/ConnectorArchicad/ConnectorBinding.cs index 95182d9c0d..58c0600f93 100644 --- a/ConnectorArchicad/ConnectorArchicad/ConnectorBinding.cs +++ b/ConnectorArchicad/ConnectorArchicad/ConnectorBinding.cs @@ -152,7 +152,14 @@ public override async Task ReceiveStream(StreamState state, Progres { using (var timer = Archicad.Helpers.Timer.CreateReceive(state.StreamId)) { - Base commitObject = await Speckle.Core.Api.Helpers.Receive(IdentifyStream(state)); + Base commitObject; + + var context = Archicad.Helpers.Timer.Context.Peek; + using (context?.cumulativeTimer?.Begin(ConnectorArchicad.Properties.OperationNameTemplates.SendToServer)) + { + commitObject = await Speckle.Core.Api.Helpers.Receive(IdentifyStream(state)); + } + if (commitObject is not null) await ElementConverterManager.Instance.ConvertToNative(state, commitObject, progress); @@ -193,20 +200,50 @@ public override void PreviewSend(StreamState state, ProgressViewModel progress) public override async Task SendStream(StreamState state, ProgressViewModel progress) { - if (state.Filter == null) - throw new InvalidOperationException("Expected selection filter to be non-null"); + try + { + using (var timer = Archicad.Helpers.Timer.CreateSend(state.StreamId)) + { + if (state.Filter == null) + { + throw new InvalidOperationException("Expected selection filter to be non-null"); + } - var commitObject = await ElementConverterManager.Instance.ConvertToSpeckle(state.Filter, progress); + var commitObject = await ElementConverterManager.Instance.ConvertToSpeckle(state.Filter, progress); - if (commitObject == null) - throw new SpeckleException("Failed to convert objects to speckle: conversion returned null"); + if (commitObject == null) + { + timer.Cancel(); + throw new SpeckleException("Failed to convert objects to Speckle"); + } + + var context = Archicad.Helpers.Timer.Context.Peek; + using (context?.cumulativeTimer?.Begin(ConnectorArchicad.Properties.OperationNameTemplates.SendToServer)) + { + return await Speckle.Core.Api.Helpers.Send( + IdentifyStream(state), + commitObject, + state.CommitMessage, + HostApplications.Archicad.Name + ); + } + } + } + catch (Exception ex) + { + // log + if (ex is not OperationCanceledException) + SpeckleLog.Logger.Error("Conversion to Speckle failed."); - return await Speckle.Core.Api.Helpers.Send( - IdentifyStream(state), - commitObject, - state.CommitMessage, - HostApplications.Archicad.Name - ); + // throw + switch (ex) + { + case OperationCanceledException: + throw new OperationCanceledException(ex.Message); + default: + throw new SpeckleException(ex.Message, ex); + } + } } public override void WriteStreamsToFile(List streams) { } diff --git a/ConnectorArchicad/ConnectorArchicad/Converters/Converters/BeamConverter.cs b/ConnectorArchicad/ConnectorArchicad/Converters/Converters/BeamConverter.cs index 55fba21649..27e29d4327 100644 --- a/ConnectorArchicad/ConnectorArchicad/Converters/Converters/BeamConverter.cs +++ b/ConnectorArchicad/ConnectorArchicad/Converters/Converters/BeamConverter.cs @@ -81,22 +81,26 @@ CancellationToken token if (jArray is null) return beams; - foreach (Speckle.Newtonsoft.Json.Linq.JToken jToken in jArray) + var context = Archicad.Helpers.Timer.Context.Peek; + using (context?.cumulativeTimer?.Begin(ConnectorArchicad.Properties.OperationNameTemplates.ConvertToSpeckle, Type.Name)) { - // convert between DTOs - Objects.BuiltElements.Archicad.ArchicadBeam beam = - Archicad.Converters.Utils.ConvertDTOs(jToken); - - // downgrade (always): Objects.BuiltElements.Archicad.ArchicadBeam --> Objects.BuiltElements.Beam + foreach (Speckle.Newtonsoft.Json.Linq.JToken jToken in jArray) { - beam.units = Units.Meters; - beam.displayValue = Operations.ModelConverter.MeshesToSpeckle( - elementModels.First(e => e.applicationId == beam.applicationId).model - ); - beam.baseLine = new Line(beam.begC, beam.endC); - } + // convert between DTOs + Objects.BuiltElements.Archicad.ArchicadBeam beam = + Archicad.Converters.Utils.ConvertDTOs(jToken); - beams.Add(beam); + // downgrade (always): Objects.BuiltElements.Archicad.ArchicadBeam --> Objects.BuiltElements.Beam + { + beam.units = Units.Meters; + beam.displayValue = Operations.ModelConverter.MeshesToSpeckle( + elementModels.First(e => e.applicationId == beam.applicationId).model + ); + beam.baseLine = new Line(beam.begC, beam.endC); + } + + beams.Add(beam); + } } return beams; diff --git a/ConnectorArchicad/ConnectorArchicad/Converters/Converters/ColumnConverter.cs b/ConnectorArchicad/ConnectorArchicad/Converters/Converters/ColumnConverter.cs index 98e16f8f46..20414eb44d 100644 --- a/ConnectorArchicad/ConnectorArchicad/Converters/Converters/ColumnConverter.cs +++ b/ConnectorArchicad/ConnectorArchicad/Converters/Converters/ColumnConverter.cs @@ -78,18 +78,22 @@ CancellationToken token if (jArray is null) return columns; - foreach (Speckle.Newtonsoft.Json.Linq.JToken jToken in jArray) + var context = Archicad.Helpers.Timer.Context.Peek; + using (context?.cumulativeTimer?.Begin(ConnectorArchicad.Properties.OperationNameTemplates.ConvertToSpeckle, Type.Name)) { - // convert between DTOs - Objects.BuiltElements.Archicad.ArchicadColumn column = - Archicad.Converters.Utils.ConvertDTOs(jToken); + foreach (Speckle.Newtonsoft.Json.Linq.JToken jToken in jArray) + { + // convert between DTOs + Objects.BuiltElements.Archicad.ArchicadColumn column = + Archicad.Converters.Utils.ConvertDTOs(jToken); - column.units = Units.Meters; - column.displayValue = Operations.ModelConverter.MeshesToSpeckle( - elementModels.First(e => e.applicationId == column.applicationId).model - ); - column.baseLine = new Line(column.origoPos, column.origoPos + new Point(0, 0, column.height)); - columns.Add(column); + column.units = Units.Meters; + column.displayValue = Operations.ModelConverter.MeshesToSpeckle( + elementModels.First(e => e.applicationId == column.applicationId).model + ); + column.baseLine = new Line(column.origoPos, column.origoPos + new Point(0, 0, column.height)); + columns.Add(column); + } } return columns; diff --git a/ConnectorArchicad/ConnectorArchicad/Converters/Converters/DirectShapeConverter.cs b/ConnectorArchicad/ConnectorArchicad/Converters/Converters/DirectShapeConverter.cs index 006bc15bfb..2ae21e6294 100644 --- a/ConnectorArchicad/ConnectorArchicad/Converters/Converters/DirectShapeConverter.cs +++ b/ConnectorArchicad/ConnectorArchicad/Converters/Converters/DirectShapeConverter.cs @@ -88,13 +88,17 @@ CancellationToken token if (data is null) return directShapes; - foreach (Objects.BuiltElements.Archicad.DirectShape directShape in data) + var context = Archicad.Helpers.Timer.Context.Peek; + using (context?.cumulativeTimer?.Begin(ConnectorArchicad.Properties.OperationNameTemplates.ConvertToSpeckle, Type.Name)) { + foreach (Objects.BuiltElements.Archicad.DirectShape directShape in data) { - directShape.displayValue = Operations.ModelConverter.MeshesToSpeckle( - elementModels.First(e => e.applicationId == directShape.applicationId).model - ); - directShapes.Add(directShape); + { + directShape.displayValue = Operations.ModelConverter.MeshesToSpeckle( + elementModels.First(e => e.applicationId == directShape.applicationId).model + ); + directShapes.Add(directShape); + } } } diff --git a/ConnectorArchicad/ConnectorArchicad/Converters/Converters/DoorConverter.cs b/ConnectorArchicad/ConnectorArchicad/Converters/Converters/DoorConverter.cs index 40ac47e076..79e3e1f6df 100644 --- a/ConnectorArchicad/ConnectorArchicad/Converters/Converters/DoorConverter.cs +++ b/ConnectorArchicad/ConnectorArchicad/Converters/Converters/DoorConverter.cs @@ -71,12 +71,16 @@ CancellationToken token if (data is null) return openings; - foreach (Objects.BuiltElements.Archicad.ArchicadDoor subelement in data) + var context = Archicad.Helpers.Timer.Context.Peek; + using (context?.cumulativeTimer?.Begin(ConnectorArchicad.Properties.OperationNameTemplates.ConvertToSpeckle, Type.Name)) { - subelement.displayValue = Operations.ModelConverter.MeshesToSpeckle( - elementModels.First(e => e.applicationId == subelement.applicationId).model - ); - openings.Add(subelement); + foreach (Objects.BuiltElements.Archicad.ArchicadDoor subelement in data) + { + subelement.displayValue = Operations.ModelConverter.MeshesToSpeckle( + elementModels.First(e => e.applicationId == subelement.applicationId).model + ); + openings.Add(subelement); + } } return openings; diff --git a/ConnectorArchicad/ConnectorArchicad/Converters/Converters/FloorConverter.cs b/ConnectorArchicad/ConnectorArchicad/Converters/Converters/FloorConverter.cs index c669a46567..99e9b2829f 100644 --- a/ConnectorArchicad/ConnectorArchicad/Converters/Converters/FloorConverter.cs +++ b/ConnectorArchicad/ConnectorArchicad/Converters/Converters/FloorConverter.cs @@ -73,20 +73,24 @@ CancellationToken token if (jArray is null) return floors; - foreach (Speckle.Newtonsoft.Json.Linq.JToken jToken in jArray) + var context = Archicad.Helpers.Timer.Context.Peek; + using (context?.cumulativeTimer?.Begin(ConnectorArchicad.Properties.OperationNameTemplates.ConvertToSpeckle, Type.Name)) { - // convert between DTOs - Objects.BuiltElements.Archicad.ArchicadFloor slab = - Archicad.Converters.Utils.ConvertDTOs(jToken); + foreach (Speckle.Newtonsoft.Json.Linq.JToken jToken in jArray) + { + // convert between DTOs + Objects.BuiltElements.Archicad.ArchicadFloor slab = + Archicad.Converters.Utils.ConvertDTOs(jToken); - slab.units = Units.Meters; - slab.displayValue = Operations.ModelConverter.MeshesToSpeckle( - elements.First(e => e.applicationId == slab.applicationId).model - ); - slab.outline = Utils.PolycurveToSpeckle(slab.shape.contourPolyline); - if (slab.shape.holePolylines?.Count > 0) - slab.voids = new List(slab.shape.holePolylines.Select(Utils.PolycurveToSpeckle)); - floors.Add(slab); + slab.units = Units.Meters; + slab.displayValue = Operations.ModelConverter.MeshesToSpeckle( + elements.First(e => e.applicationId == slab.applicationId).model + ); + slab.outline = Utils.PolycurveToSpeckle(slab.shape.contourPolyline); + if (slab.shape.holePolylines?.Count > 0) + slab.voids = new List(slab.shape.holePolylines.Select(Utils.PolycurveToSpeckle)); + floors.Add(slab); + } } return floors; diff --git a/ConnectorArchicad/ConnectorArchicad/Converters/Converters/GridLineConverter.cs b/ConnectorArchicad/ConnectorArchicad/Converters/Converters/GridLineConverter.cs index c195093cdb..4b5c923516 100644 --- a/ConnectorArchicad/ConnectorArchicad/Converters/Converters/GridLineConverter.cs +++ b/ConnectorArchicad/ConnectorArchicad/Converters/Converters/GridLineConverter.cs @@ -89,45 +89,49 @@ CancellationToken token return new List(); } - List gridlines = new List(); - foreach (Archicad.GridElement archicadGridElement in data) + var context = Archicad.Helpers.Timer.Context.Peek; + using (context?.cumulativeTimer?.Begin(ConnectorArchicad.Properties.OperationNameTemplates.ConvertToSpeckle, Type.Name)) { - Objects.BuiltElements.GridLine speckleGridLine = new Objects.BuiltElements.GridLine(); + List gridlines = new List(); + foreach (Archicad.GridElement archicadGridElement in data) + { + Objects.BuiltElements.GridLine speckleGridLine = new Objects.BuiltElements.GridLine(); - // convert from Archicad to Speckle data structure - // Speckle base properties - speckleGridLine.id = archicadGridElement.id; - speckleGridLine.applicationId = archicadGridElement.applicationId; - speckleGridLine.label = archicadGridElement.markerText; - speckleGridLine.units = Units.Meters; + // convert from Archicad to Speckle data structure + // Speckle base properties + speckleGridLine.id = archicadGridElement.id; + speckleGridLine.applicationId = archicadGridElement.applicationId; + speckleGridLine.label = archicadGridElement.markerText; + speckleGridLine.units = Units.Meters; - // Archicad properties - // elementType and classifications do not exist in Objects.BuiltElements.GridLine - //speckleGrid.elementType = archicadGridElement.elementType; - //speckleGrid.classifications = archicadGridElement.classifications; + // Archicad properties + // elementType and classifications do not exist in Objects.BuiltElements.GridLine + //speckleGrid.elementType = archicadGridElement.elementType; + //speckleGrid.classifications = archicadGridElement.classifications; - if (!archicadGridElement.isArc) - { - speckleGridLine.baseLine = new Line(archicadGridElement.begin, archicadGridElement.end); - } - else - { - speckleGridLine.baseLine = new Arc( - archicadGridElement.begin, - archicadGridElement.end, - archicadGridElement.arcAngle - ); - } + if (!archicadGridElement.isArc) + { + speckleGridLine.baseLine = new Line(archicadGridElement.begin, archicadGridElement.end); + } + else + { + speckleGridLine.baseLine = new Arc( + archicadGridElement.begin, + archicadGridElement.end, + archicadGridElement.arcAngle + ); + } - speckleGridLine.displayValue = Operations.ModelConverter - .MeshesAndLinesToSpeckle(elementModels.First(e => e.applicationId == archicadGridElement.applicationId).model) - .Cast() - .ToList(); + speckleGridLine.displayValue = Operations.ModelConverter + .MeshesAndLinesToSpeckle(elementModels.First(e => e.applicationId == archicadGridElement.applicationId).model) + .Cast() + .ToList(); - gridlines.Add(speckleGridLine); - } + gridlines.Add(speckleGridLine); + } - return gridlines; + return gridlines; + } } } } diff --git a/ConnectorArchicad/ConnectorArchicad/Converters/Converters/RoofConverter.cs b/ConnectorArchicad/ConnectorArchicad/Converters/Converters/RoofConverter.cs index 09e357daad..8e02eb8ea6 100644 --- a/ConnectorArchicad/ConnectorArchicad/Converters/Converters/RoofConverter.cs +++ b/ConnectorArchicad/ConnectorArchicad/Converters/Converters/RoofConverter.cs @@ -88,25 +88,29 @@ CancellationToken token var roofs = new List(); if (jArray is not null) { - foreach (Speckle.Newtonsoft.Json.Linq.JToken jToken in jArray) + var context = Archicad.Helpers.Timer.Context.Peek; + using (context?.cumulativeTimer?.Begin(ConnectorArchicad.Properties.OperationNameTemplates.ConvertToSpeckle, Type.Name)) { - // convert between DTOs - Objects.BuiltElements.Archicad.ArchicadRoof roof = - Archicad.Converters.Utils.ConvertDTOs(jToken); - - roof.units = Units.Meters; - roof.displayValue = Operations.ModelConverter.MeshesToSpeckle( - elements.First(e => e.applicationId == roof.applicationId).model - ); - - if (roof.shape != null) + foreach (Speckle.Newtonsoft.Json.Linq.JToken jToken in jArray) { - roof.outline = Utils.PolycurveToSpeckle(roof.shape.contourPolyline); - if (roof.shape.holePolylines?.Count > 0) - roof.voids = new List(roof.shape.holePolylines.Select(Utils.PolycurveToSpeckle)); + // convert between DTOs + Objects.BuiltElements.Archicad.ArchicadRoof roof = + Archicad.Converters.Utils.ConvertDTOs(jToken); + + roof.units = Units.Meters; + roof.displayValue = Operations.ModelConverter.MeshesToSpeckle( + elements.First(e => e.applicationId == roof.applicationId).model + ); + + if (roof.shape != null) + { + roof.outline = Utils.PolycurveToSpeckle(roof.shape.contourPolyline); + if (roof.shape.holePolylines?.Count > 0) + roof.voids = new List(roof.shape.holePolylines.Select(Utils.PolycurveToSpeckle)); + } + + roofs.Add(roof); } - - roofs.Add(roof); } } @@ -118,25 +122,29 @@ CancellationToken token var shells = new List(); if (jArray is not null) { - foreach (Speckle.Newtonsoft.Json.Linq.JToken jToken in jArray) + var context = Archicad.Helpers.Timer.Context.Peek; + using (context?.cumulativeTimer?.Begin(ConnectorArchicad.Properties.OperationNameTemplates.ConvertToSpeckle, Type.Name)) { - // convert between DTOs - Objects.BuiltElements.Archicad.ArchicadShell shell = - Archicad.Converters.Utils.ConvertDTOs(jToken); - - shell.units = Units.Meters; - shell.displayValue = Operations.ModelConverter.MeshesToSpeckle( - elements.First(e => e.applicationId == shell.applicationId).model - ); - - if (shell.shape != null) + foreach (Speckle.Newtonsoft.Json.Linq.JToken jToken in jArray) { - shell.outline = Utils.PolycurveToSpeckle(shell.shape.contourPolyline); - if (shell.shape.holePolylines?.Count > 0) - shell.voids = new List(shell.shape.holePolylines.Select(Utils.PolycurveToSpeckle)); + // convert between DTOs + Objects.BuiltElements.Archicad.ArchicadShell shell = + Archicad.Converters.Utils.ConvertDTOs(jToken); + + shell.units = Units.Meters; + shell.displayValue = Operations.ModelConverter.MeshesToSpeckle( + elements.First(e => e.applicationId == shell.applicationId).model + ); + + if (shell.shape != null) + { + shell.outline = Utils.PolycurveToSpeckle(shell.shape.contourPolyline); + if (shell.shape.holePolylines?.Count > 0) + shell.voids = new List(shell.shape.holePolylines.Select(Utils.PolycurveToSpeckle)); + } + + shells.Add(shell); } - - shells.Add(shell); } } diff --git a/ConnectorArchicad/ConnectorArchicad/Converters/Converters/RoomConverter.cs b/ConnectorArchicad/ConnectorArchicad/Converters/Converters/RoomConverter.cs index 81bf3fcbc2..01cbcc64e4 100644 --- a/ConnectorArchicad/ConnectorArchicad/Converters/Converters/RoomConverter.cs +++ b/ConnectorArchicad/ConnectorArchicad/Converters/Converters/RoomConverter.cs @@ -104,42 +104,46 @@ CancellationToken token if (data is null) return rooms; - foreach (Archicad.Room archicadRoom in data) + var context = Archicad.Helpers.Timer.Context.Peek; + using (context?.cumulativeTimer?.Begin(ConnectorArchicad.Properties.OperationNameTemplates.ConvertToSpeckle, Type.Name)) { - Objects.BuiltElements.Archicad.ArchicadRoom speckleRoom = new Objects.BuiltElements.Archicad.ArchicadRoom(); - - // convert from Archicad to Speckle data structure - // Speckle base properties - speckleRoom.id = archicadRoom.id; - speckleRoom.applicationId = archicadRoom.applicationId; - speckleRoom.displayValue = Operations.ModelConverter.MeshesToSpeckle( - elementModels.First(e => e.applicationId == archicadRoom.applicationId).model - ); - speckleRoom.units = Units.Meters; - - // Archicad properties - speckleRoom.elementType = archicadRoom.elementType; - speckleRoom.classifications = archicadRoom.classifications; - speckleRoom.archicadLevel = archicadRoom.level; - speckleRoom.height = archicadRoom.height ?? .0; - speckleRoom.shape = archicadRoom.shape; - - // downdgrade - speckleRoom.name = archicadRoom.name; - speckleRoom.number = archicadRoom.number; - speckleRoom.area = archicadRoom.area ?? .0; - speckleRoom.volume = archicadRoom.volume ?? .0; - - ElementShape.Polyline polyLine = archicadRoom.shape.contourPolyline; - Polycurve polycurve = Utils.PolycurveToSpeckle(polyLine); - speckleRoom.outline = polycurve; - if (archicadRoom.shape.holePolylines?.Count > 0) - speckleRoom.voids = new List(archicadRoom.shape.holePolylines.Select(Utils.PolycurveToSpeckle)); - - // calculate base point - speckleRoom.basePoint = archicadRoom.basePoint; - - rooms.Add(speckleRoom); + foreach (Archicad.Room archicadRoom in data) + { + Objects.BuiltElements.Archicad.ArchicadRoom speckleRoom = new Objects.BuiltElements.Archicad.ArchicadRoom(); + + // convert from Archicad to Speckle data structure + // Speckle base properties + speckleRoom.id = archicadRoom.id; + speckleRoom.applicationId = archicadRoom.applicationId; + speckleRoom.displayValue = Operations.ModelConverter.MeshesToSpeckle( + elementModels.First(e => e.applicationId == archicadRoom.applicationId).model + ); + speckleRoom.units = Units.Meters; + + // Archicad properties + speckleRoom.elementType = archicadRoom.elementType; + speckleRoom.classifications = archicadRoom.classifications; + speckleRoom.archicadLevel = archicadRoom.level; + speckleRoom.height = archicadRoom.height ?? .0; + speckleRoom.shape = archicadRoom.shape; + + // downdgrade + speckleRoom.name = archicadRoom.name; + speckleRoom.number = archicadRoom.number; + speckleRoom.area = archicadRoom.area ?? .0; + speckleRoom.volume = archicadRoom.volume ?? .0; + + ElementShape.Polyline polyLine = archicadRoom.shape.contourPolyline; + Polycurve polycurve = Utils.PolycurveToSpeckle(polyLine); + speckleRoom.outline = polycurve; + if (archicadRoom.shape.holePolylines?.Count > 0) + speckleRoom.voids = new List(archicadRoom.shape.holePolylines.Select(Utils.PolycurveToSpeckle)); + + // calculate base point + speckleRoom.basePoint = archicadRoom.basePoint; + + rooms.Add(speckleRoom); + } } return rooms; diff --git a/ConnectorArchicad/ConnectorArchicad/Converters/Converters/SkylightConverter.cs b/ConnectorArchicad/ConnectorArchicad/Converters/Converters/SkylightConverter.cs index 13ae5309cc..4ce5effa85 100644 --- a/ConnectorArchicad/ConnectorArchicad/Converters/Converters/SkylightConverter.cs +++ b/ConnectorArchicad/ConnectorArchicad/Converters/Converters/SkylightConverter.cs @@ -71,12 +71,16 @@ CancellationToken token if (data is null) return openings; - foreach (Objects.BuiltElements.Archicad.ArchicadSkylight subelement in data) + var context = Archicad.Helpers.Timer.Context.Peek; + using (context?.cumulativeTimer?.Begin(ConnectorArchicad.Properties.OperationNameTemplates.ConvertToSpeckle, Type.Name)) { - subelement.displayValue = Operations.ModelConverter.MeshesToSpeckle( - elementModels.First(e => e.applicationId == subelement.applicationId).model - ); - openings.Add(subelement); + foreach (Objects.BuiltElements.Archicad.ArchicadSkylight subelement in data) + { + subelement.displayValue = Operations.ModelConverter.MeshesToSpeckle( + elementModels.First(e => e.applicationId == subelement.applicationId).model + ); + openings.Add(subelement); + } } return openings; diff --git a/ConnectorArchicad/ConnectorArchicad/Converters/Converters/WallConverter.cs b/ConnectorArchicad/ConnectorArchicad/Converters/Converters/WallConverter.cs index ca10a79bfb..e0c7c8dfe9 100644 --- a/ConnectorArchicad/ConnectorArchicad/Converters/Converters/WallConverter.cs +++ b/ConnectorArchicad/ConnectorArchicad/Converters/Converters/WallConverter.cs @@ -81,18 +81,22 @@ CancellationToken token if (jArray is null) return walls; - foreach (Speckle.Newtonsoft.Json.Linq.JToken jToken in jArray) + var context = Archicad.Helpers.Timer.Context.Peek; + using (context?.cumulativeTimer?.Begin(ConnectorArchicad.Properties.OperationNameTemplates.ConvertToSpeckle, Type.Name)) { - // convert between DTOs - Objects.BuiltElements.Archicad.ArchicadWall wall = - Archicad.Converters.Utils.ConvertDTOs(jToken); + foreach (Speckle.Newtonsoft.Json.Linq.JToken jToken in jArray) + { + // convert between DTOs + Objects.BuiltElements.Archicad.ArchicadWall wall = + Archicad.Converters.Utils.ConvertDTOs(jToken); - wall.units = Units.Meters; - wall.displayValue = Operations.ModelConverter.MeshesToSpeckle( - elementModels.First(e => e.applicationId == wall.applicationId).model - ); - wall.baseLine = new Line(wall.startPoint, wall.endPoint); - walls.Add(wall); + wall.units = Units.Meters; + wall.displayValue = Operations.ModelConverter.MeshesToSpeckle( + elementModels.First(e => e.applicationId == wall.applicationId).model + ); + wall.baseLine = new Line(wall.startPoint, wall.endPoint); + walls.Add(wall); + } } return walls; diff --git a/ConnectorArchicad/ConnectorArchicad/Converters/Converters/WindowConverter.cs b/ConnectorArchicad/ConnectorArchicad/Converters/Converters/WindowConverter.cs index accd107a00..d2ccc0c693 100644 --- a/ConnectorArchicad/ConnectorArchicad/Converters/Converters/WindowConverter.cs +++ b/ConnectorArchicad/ConnectorArchicad/Converters/Converters/WindowConverter.cs @@ -71,12 +71,16 @@ CancellationToken token if (data is null) return openings; - foreach (Objects.BuiltElements.Archicad.ArchicadWindow subelement in data) + var context = Archicad.Helpers.Timer.Context.Peek; + using (context?.cumulativeTimer?.Begin(ConnectorArchicad.Properties.OperationNameTemplates.ConvertToSpeckle, Type.Name)) { - subelement.displayValue = Operations.ModelConverter.MeshesToSpeckle( - elementModels.First(e => e.applicationId == subelement.applicationId).model - ); - openings.Add(subelement); + foreach (Objects.BuiltElements.Archicad.ArchicadWindow subelement in data) + { + subelement.displayValue = Operations.ModelConverter.MeshesToSpeckle( + elementModels.First(e => e.applicationId == subelement.applicationId).model + ); + openings.Add(subelement); + } } return openings; diff --git a/ConnectorArchicad/ConnectorArchicad/Converters/ModelConverter.cs b/ConnectorArchicad/ConnectorArchicad/Converters/ModelConverter.cs index 95346128b2..32f9767214 100644 --- a/ConnectorArchicad/ConnectorArchicad/Converters/ModelConverter.cs +++ b/ConnectorArchicad/ConnectorArchicad/Converters/ModelConverter.cs @@ -17,21 +17,25 @@ public static class ModelConverter public static List MeshesToSpeckle(MeshModel meshModel) { - var materials = meshModel.materials.Select(MaterialToSpeckle).ToList(); - var meshes = materials.Select(m => new Mesh { units = Units.Meters, ["renderMaterial"] = m }).ToList(); - var vertCount = new int[materials.Count]; - - foreach (var poly in meshModel.polygons) + var context = Archicad.Helpers.Timer.Context.Peek; + using (context?.cumulativeTimer?.Begin(ConnectorArchicad.Properties.OperationNameTemplates.MeshToSpeckle)) { - var meshIndex = poly.material; - meshes[meshIndex].vertices.AddRange( - poly.pointIds.SelectMany(id => FlattenPoint(meshModel.vertices[id])).ToList() - ); - meshes[meshIndex].faces.AddRange(PolygonToSpeckle(poly, vertCount[meshIndex])); - vertCount[meshIndex] += poly.pointIds.Count; - } + var materials = meshModel.materials.Select(MaterialToSpeckle).ToList(); + var meshes = materials.Select(m => new Mesh { units = Units.Meters, ["renderMaterial"] = m }).ToList(); + var vertCount = new int[materials.Count]; - return meshes; + foreach (var poly in meshModel.polygons) + { + var meshIndex = poly.material; + meshes[meshIndex].vertices.AddRange( + poly.pointIds.SelectMany(id => FlattenPoint(meshModel.vertices[id])).ToList() + ); + meshes[meshIndex].faces.AddRange(PolygonToSpeckle(poly, vertCount[meshIndex])); + vertCount[meshIndex] += poly.pointIds.Count; + } + + return meshes; + } } public static List MeshesAndLinesToSpeckle(MeshModel meshModel) diff --git a/ConnectorArchicad/ConnectorArchicad/Helpers/Timer.cs b/ConnectorArchicad/ConnectorArchicad/Helpers/Timer.cs index a51af7f118..659ca9b725 100755 --- a/ConnectorArchicad/ConnectorArchicad/Helpers/Timer.cs +++ b/ConnectorArchicad/ConnectorArchicad/Helpers/Timer.cs @@ -12,11 +12,16 @@ internal sealed class Context : Speckle.Core.Helpers.State private SerilogTimings.Operation serilogOperation = null; - public static Timer CreateReceive (string streamId) + public static Timer CreateReceive(string streamId) { return new Timer("Receive stream {streamId}", streamId); } + public static Timer CreateSend(string streamId) + { + return new Timer("Send stream {streamId}", streamId); + } + public Timer(string messageTemplate, params object[] args) { Context context = Context.Push(); diff --git a/ConnectorArchicad/ConnectorArchicad/Properties/OperationNameTemplates.Designer.cs b/ConnectorArchicad/ConnectorArchicad/Properties/OperationNameTemplates.Designer.cs index 63ea5bcec8..24b919ee7a 100644 --- a/ConnectorArchicad/ConnectorArchicad/Properties/OperationNameTemplates.Designer.cs +++ b/ConnectorArchicad/ConnectorArchicad/Properties/OperationNameTemplates.Designer.cs @@ -1,6 +1,7 @@ -//------------------------------------------------------------------------------ +//------------------------------------------------------------------------------ // // This code was generated by a tool. +// Runtime Version:4.0.30319.42000 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. @@ -13,10 +14,12 @@ namespace ConnectorArchicad.Properties { /// /// A strongly-typed resource class, for looking up localized strings, etc. - /// This class was generated by MSBuild using the GenerateResource task. - /// To add or remove a member, edit your .resx file then rerun MSBuild. /// - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Build.Tasks.StronglyTypedResourceBuilder", "15.1.0.0")] + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] internal class OperationNameTemplates { @@ -66,6 +69,15 @@ internal static string ConvertToNative { } } + /// + /// Looks up a localized string similar to Time: Convert to Speckle: {0}. + /// + internal static string ConvertToSpeckle { + get { + return ResourceManager.GetString("ConvertToSpeckle", resourceCulture); + } + } + /// /// Looks up a localized string similar to Time: HTTP command API: {0}. /// @@ -92,5 +104,32 @@ internal static string MeshToNative { return ResourceManager.GetString("MeshToNative", resourceCulture); } } + + /// + /// Looks up a localized string similar to Time: Mesh to Speckle. + /// + internal static string MeshToSpeckle { + get { + return ResourceManager.GetString("MeshToSpeckle", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Time: Receive From Server. + /// + internal static string ReceiveFromServer { + get { + return ResourceManager.GetString("ReceiveFromServer", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Time: Send To Server. + /// + internal static string SendToServer { + get { + return ResourceManager.GetString("SendToServer", resourceCulture); + } + } } } diff --git a/ConnectorArchicad/ConnectorArchicad/Properties/OperationNameTemplates.resx b/ConnectorArchicad/ConnectorArchicad/Properties/OperationNameTemplates.resx index 9ec24a7703..517b37ef4b 100644 --- a/ConnectorArchicad/ConnectorArchicad/Properties/OperationNameTemplates.resx +++ b/ConnectorArchicad/ConnectorArchicad/Properties/OperationNameTemplates.resx @@ -129,4 +129,16 @@ Time: Mesh to native + + Time: Convert to Speckle: {0} + + + Time: Mesh to Speckle + + + Time: Receive From Server + + + Time: Send To Server + \ No newline at end of file diff --git a/ConnectorArchicad/ConnectorArchicad/Properties/launchSettings.json b/ConnectorArchicad/ConnectorArchicad/Properties/launchSettings.json new file mode 100644 index 0000000000..62a4b9dda8 --- /dev/null +++ b/ConnectorArchicad/ConnectorArchicad/Properties/launchSettings.json @@ -0,0 +1,8 @@ +{ + "profiles": { + "ConnectorArchicad": { + "commandName": "Project", + "commandLineArgs": "19723 888" + } + } +} \ No newline at end of file