From 532adb855f31d7efd98b97466108a39e3758e999 Mon Sep 17 00:00:00 2001
From: Jedd Morgan <45512892+JR-Morgan@users.noreply.github.com>
Date: Wed, 4 Feb 2026 12:24:24 +0000
Subject: [PATCH 01/11] feat(deployment)!: autocad bundle (#1247)
* autocad bundle
* civil3d
* correct paths
* fuck ai
* fix civil local
---
.github/workflows/release.yml | 2 +-
Connectors/Autocad/Directory.Build.targets | 10 ++-
.../Plugin/BundleAutoCAD/PackageContents.xml | 79 +++++++++++++++++++
.../Plugin/BundleCivil3D/PackageContents.xml | 79 +++++++++++++++++++
...Speckle.Connectors.AutocadShared.projitems | 8 ++
5 files changed, 173 insertions(+), 5 deletions(-)
create mode 100644 Connectors/Autocad/Speckle.Connectors.AutocadShared/Plugin/BundleAutoCAD/PackageContents.xml
create mode 100644 Connectors/Autocad/Speckle.Connectors.AutocadShared/Plugin/BundleCivil3D/PackageContents.xml
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 16206296c..0f0208ff2 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -68,7 +68,7 @@ jobs:
"repo": "${{ github.repository }}",
"is_public_release": ${{ env.IS_PUBLIC_RELEASE }}
}'
- ref: main
+ ref: jedd/cnx-1358-autocad-and-civil3d-installations-are-blocked-by-pre #todo: revert back to main before PR is merged
wait-for-completion: true
wait-for-completion-interval: 10s
wait-for-completion-timeout: 10m
diff --git a/Connectors/Autocad/Directory.Build.targets b/Connectors/Autocad/Directory.Build.targets
index 5afa22167..5d93d9f50 100644
--- a/Connectors/Autocad/Directory.Build.targets
+++ b/Connectors/Autocad/Directory.Build.targets
@@ -1,7 +1,7 @@
-
+
@@ -9,11 +9,12 @@
-
+
+
-
+
@@ -21,7 +22,8 @@
-
+
+
diff --git a/Connectors/Autocad/Speckle.Connectors.AutocadShared/Plugin/BundleAutoCAD/PackageContents.xml b/Connectors/Autocad/Speckle.Connectors.AutocadShared/Plugin/BundleAutoCAD/PackageContents.xml
new file mode 100644
index 000000000..5285a6d3f
--- /dev/null
+++ b/Connectors/Autocad/Speckle.Connectors.AutocadShared/Plugin/BundleAutoCAD/PackageContents.xml
@@ -0,0 +1,79 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Connectors/Autocad/Speckle.Connectors.AutocadShared/Plugin/BundleCivil3D/PackageContents.xml b/Connectors/Autocad/Speckle.Connectors.AutocadShared/Plugin/BundleCivil3D/PackageContents.xml
new file mode 100644
index 000000000..c193b44b6
--- /dev/null
+++ b/Connectors/Autocad/Speckle.Connectors.AutocadShared/Plugin/BundleCivil3D/PackageContents.xml
@@ -0,0 +1,79 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Connectors/Autocad/Speckle.Connectors.AutocadShared/Speckle.Connectors.AutocadShared.projitems b/Connectors/Autocad/Speckle.Connectors.AutocadShared/Speckle.Connectors.AutocadShared.projitems
index 04d739257..1c3a680cd 100644
--- a/Connectors/Autocad/Speckle.Connectors.AutocadShared/Speckle.Connectors.AutocadShared.projitems
+++ b/Connectors/Autocad/Speckle.Connectors.AutocadShared/Speckle.Connectors.AutocadShared.projitems
@@ -53,4 +53,12 @@
+
+
+ Always
+
+
+ Always
+
+
\ No newline at end of file
From 882358e22a3d113308e209234523bc806e6755d3 Mon Sep 17 00:00:00 2001
From: Jedd Morgan <45512892+JR-Morgan@users.noreply.github.com>
Date: Wed, 4 Feb 2026 14:39:49 +0000
Subject: [PATCH 02/11] Merge pull request #1248 from
specklesystems/jrm/update-codeowners
chore: Updated CODEOWNERS
---
.github/CODEOWNERS | 28 ++++++++++++++--------------
1 file changed, 14 insertions(+), 14 deletions(-)
diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
index 2a239e563..737852fb6 100644
--- a/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
@@ -6,34 +6,34 @@
# Connectors
-/Connectors/ArcGIS/* @KatKatKateryna
-/Connectors/Autocad/* @clairekuang @oguzhankoral @didimitrie
-/Connectors/Civil3d/* @clairekuang @oguzhankoral @didimitrie
+/Connectors/Autocad/* @oguzhankoral @JR-Morgan @dogukankaratas
+/Connectors/Civil3d/* @oguzhankoral @JR-Morgan @dogukankaratas
/Connectors/CSi/* @bjoernsteinhagen @dogukankaratas
/Connectors/Navisworks/* @jsdbroughton
-/Connectors/Revit/* @clairekuang @oguzhankoral @didimitrie
-/Connectors/Rhino/* @clairekuang @oguzhankoral @didimitrie
+/Connectors/Revit/* @oguzhankoral
+/Connectors/Rhino/* @oguzhankoral @JR-Morgan
/Connectors/Tekla/* @bjoernsteinhagen @dogukankaratas
# Converters
-/Convertors/ArcGIS/* @KatKatKateryna
-/Convertors/Autocad/* @clairekuang @oguzhankoral @didimitrie
-/Convertors/Civil3d/* @clairekuang @oguzhankoral @didimitrie
+/Convertors/Autocad/* @oguzhankoral @JR-Morgan @dogukankaratas
+/Convertors/Civil3d/* @oguzhankoral @JR-Morgan @dogukankaratas
/Convertors/CSi/* @bjoernsteinhagen @dogukankaratas
/Convertors/Navisworks/* @jsdbroughton
-/Convertors/Revit/* @clairekuang @oguzhankoral @didimitrie
-/Convertors/Rhino/* @clairekuang @oguzhankoral @didimitrie
+/Convertors/Revit/* @oguzhankoral
+/Convertors/Rhino/* @oguzhankoral @JR-Morgan
/Convertors/Tekla/* @bjoernsteinhagen @dogukankaratas
# DUI
-/DUI3/* @clairekuang @oguzhankoral @didimitrie
+/DUI3/* @oguzhankoral
# Importers
-/Importers/* @JR-Morgan @didimitrie @oguzhankoral @adamhathcock
+/Importers/* @JR-Morgan @oguzhankoral
# SDK
-/SDK/* @JR-Morgan @clairekuang @didimitrie @oguzhankoral @adamhathcock
+/SDK/* @JR-Morgan @oguzhankoral
# Build
-/Build/* @JR-Morgan @oguzhankoral @adamhathcock
+/Build/* @JR-Morgan @oguzhankoral
+/.github/* @JR-Morgan @oguzhankoral
+/.config/* @JR-Morgan @oguzhankoral
From c5deaf484467f12f3ea7b13588897fcaec9ba70c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?O=C4=9Fuzhan=20Koral?=
<45078678+oguzhankoral@users.noreply.github.com>
Date: Wed, 4 Feb 2026 17:59:11 +0300
Subject: [PATCH 03/11] Add nullable cloud file id to check against on our
server (#1221)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Co-authored-by: Björn Steinhagen <88777268+bjoernsteinhagen@users.noreply.github.com>
---
.../Bindings/BasicConnectorBindingRevit.cs | 7 ++++++-
DUI3/Speckle.Connectors.DUI/Models/DocumentInfo.cs | 2 +-
2 files changed, 7 insertions(+), 2 deletions(-)
diff --git a/Connectors/Revit/Speckle.Connectors.RevitShared/Bindings/BasicConnectorBindingRevit.cs b/Connectors/Revit/Speckle.Connectors.RevitShared/Bindings/BasicConnectorBindingRevit.cs
index 034eff0b9..9013f4080 100644
--- a/Connectors/Revit/Speckle.Connectors.RevitShared/Bindings/BasicConnectorBindingRevit.cs
+++ b/Connectors/Revit/Speckle.Connectors.RevitShared/Bindings/BasicConnectorBindingRevit.cs
@@ -73,7 +73,12 @@ internal sealed class BasicConnectorBindingRevit : IBasicConnectorBinding
}
//should this use the Hashcode of the document instead of something like CreationGUID?
- var info = new DocumentInfo(doc.PathName, doc.Title, doc.GetHashCode().ToString());
+ var info = new DocumentInfo(
+ doc.PathName,
+ doc.Title,
+ doc.GetHashCode().ToString(),
+ doc.IsModelInCloud ? doc.GetCloudModelUrn() : null
+ );
return info;
}
diff --git a/DUI3/Speckle.Connectors.DUI/Models/DocumentInfo.cs b/DUI3/Speckle.Connectors.DUI/Models/DocumentInfo.cs
index b15a76c27..a2286e87b 100644
--- a/DUI3/Speckle.Connectors.DUI/Models/DocumentInfo.cs
+++ b/DUI3/Speckle.Connectors.DUI/Models/DocumentInfo.cs
@@ -1,6 +1,6 @@
namespace Speckle.Connectors.DUI.Models;
-public record DocumentInfo(string Location, string Name, string Id)
+public record DocumentInfo(string Location, string Name, string Id, string? CloudFileId = null)
{
//?.Replace("\\", "\\\\"); // for some reason, when returning variables from a direct binding call
//we don't need this. nevertheless, after switching to a post response back to the ui,
From e87eebefd1b263040d02ba3f0785ea451ebcdb85 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn=20Steinhagen?=
<88777268+bjoernsteinhagen@users.noreply.github.com>
Date: Wed, 4 Feb 2026 17:13:17 +0200
Subject: [PATCH 04/11] fix(revit): prevent unpacking of internal unexpected
elements in groups (#1266)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* feat(revit): filter out sketch lines from grouped elements
* fix(revit): exclude internal definitions (types/masses) from group unpacking
* perf(revit): optimize group unpacking with FilteredElementCollector
* chore(revit): remove unused method after refactor
---------
Co-authored-by: Oğuzhan Koral <45078678+oguzhankoral@users.noreply.github.com>
---
.../HostApp/ElementUnpacker.cs | 35 +++++++++++++++----
1 file changed, 28 insertions(+), 7 deletions(-)
diff --git a/Connectors/Revit/Speckle.Connectors.RevitShared/HostApp/ElementUnpacker.cs b/Connectors/Revit/Speckle.Connectors.RevitShared/HostApp/ElementUnpacker.cs
index f78622879..fd7e2eb73 100644
--- a/Connectors/Revit/Speckle.Connectors.RevitShared/HostApp/ElementUnpacker.cs
+++ b/Connectors/Revit/Speckle.Connectors.RevitShared/HostApp/ElementUnpacker.cs
@@ -9,8 +9,19 @@ namespace Speckle.Connectors.Revit.HostApp;
///
public class ElementUnpacker
{
+ private static readonly List s_skippedCategories =
+ [
+ BuiltInCategory.OST_SketchLines,
+ BuiltInCategory.OST_MassForm,
+ BuiltInCategory.OST_StairsSketchBoundaryLines,
+ BuiltInCategory.OST_StairsSketchLandingCenterLines,
+ BuiltInCategory.OST_StairsSketchRiserLines,
+ BuiltInCategory.OST_RebarSketchLines,
+ BuiltInCategory.OST_StairsSketchRunLines
+ ];
+
///
- /// Unpacks a random set of revit objects into atomic objects. It currently unpacks groups recurisvely, nested families into atomic family instances.
+ /// Unpacks a random set of revit objects into atomic objects. It currently unpacks groups recursively, nested families into atomic family instances.
/// This method will also "pack" curtain walls if necessary (ie, if mullions or panels are selected without their parent curtain wall, they are sent independently; if the parent curtain wall is selected, they will be removed out as the curtain wall will include all its children).
///
///
@@ -32,7 +43,7 @@ public class ElementUnpacker
}
///
- /// Unpacks input element ids into their subelements, eg groups and nested family instances
+ /// Unpacks input element ids into their sub-elements, eg groups and nested family instances
///
///
///
@@ -57,11 +68,21 @@ public class ElementUnpacker
// UNPACK: Groups
if (element is Group g)
{
- // When a group is from a linked model, GetMemberIds may behave differently
- // We add null checks to handle cases where elements can't be properly resolved
- // POC: this might screw up generating hosting rel generation here, because nested families in groups get flattened out by GetMemberIds().
- var groupElements = g.GetMemberIds().Select(doc.GetElement).Where(el => el != null);
- unpackedElements.AddRange(UnpackElements(groupElements, doc));
+ var memberIds = g.GetMemberIds();
+
+ if (memberIds.Count <= 0)
+ {
+ continue;
+ }
+
+ // using a collector more efficient
+ using var collector = new FilteredElementCollector(doc, memberIds);
+ collector.WhereElementIsNotElementType(); // exclude "Type" elements (FamilySymbols)
+ var filter = new ElementMulticategoryFilter(s_skippedCategories, inverted: true); // exclude "Sketch/Form" categories
+ collector.WherePasses(filter);
+
+ // recursively unpack the valid results
+ unpackedElements.AddRange(UnpackElements(collector, doc));
}
else if (element is BaseArray baseArray)
{
From 9b9c3831286dc390f089e8f1b0cac9530ff566ee Mon Sep 17 00:00:00 2001
From: Mucahit Bilal GOKER <51519350+bimgeek@users.noreply.github.com>
Date: Tue, 10 Feb 2026 12:08:39 +0300
Subject: [PATCH 05/11] fix unplaced rooms (#1274)
---
.../Helpers/DisplayValueExtractor.cs | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/Converters/Revit/Speckle.Converters.RevitShared/Helpers/DisplayValueExtractor.cs b/Converters/Revit/Speckle.Converters.RevitShared/Helpers/DisplayValueExtractor.cs
index fe7aa1f79..0f193f587 100644
--- a/Converters/Revit/Speckle.Converters.RevitShared/Helpers/DisplayValueExtractor.cs
+++ b/Converters/Revit/Speckle.Converters.RevitShared/Helpers/DisplayValueExtractor.cs
@@ -68,6 +68,14 @@ public sealed class DisplayValueExtractor
return [DisplayValueResult.WithoutTransform(GetCurveDisplayValue(modelCurve.GeometryCurve))];
case DB.Grid grid:
return [DisplayValueResult.WithoutTransform(GetCurveDisplayValue(grid.Curve))];
+ case DB.Architecture.Room room:
+ // api still returns geometry for unplaced rooms.
+ // return empty list so room object is sent but with null display value
+ if (room.Volume == 0)
+ {
+ return new List();
+ }
+ return GetGeometryDisplayValue(room);
case DB.Area area:
return _converterSettings.Current.SendAreasAsMesh
? GetAreaMeshDisplayValue(area)
From cd30370654dab2741d6479d5d8aae18933cd283b Mon Sep 17 00:00:00 2001
From: Claire Kuang
Date: Tue, 10 Feb 2026 13:16:27 +0000
Subject: [PATCH 06/11] feat(autocad/civil): add reference point behavior
(#1126)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* adds reference point transform to publish
* only send reference point if not identity
* first pass at adding reference point transform to publish
* fixes transform matrix
* fixes autocad to system matrix conversion
* fixes text transforms
* removes bboxs
* removes to internal reference point (send only for now)
* fix nullability
* adds instance handling
* adds converter settings to civil
* refactors instance unpacker and polyline to speckle conversion
* fixes blocks and some polyline receive conversions
* removes transform on root
* feat(autocad): adds event tracking for change of ucs/wcs settings (#1164)
* feat: track ucs changes and invalidate cache
* chore: redundant qualifier
* fixes polyline conversions
time to cry
* fix(autocad): fixes polyline2d conversion with non-standard normals (#1169)
* fix: polyline2d like polyline
* refactor: coordinate system extension
* refactor: extension for pt3d to ocs
* renames reference point methods
* moves logic to reference point converter
* Update AutocadPolycurveToHostConverter.cs (#1175)
---------
Co-authored-by: Björn Steinhagen <88777268+bjoernsteinhagen@users.noreply.github.com>
Co-authored-by: Oğuzhan Koral <45078678+oguzhankoral@users.noreply.github.com>
Co-authored-by: bimgeek
Co-authored-by: Mucahit Bilal GOKER <51519350+bimgeek@users.noreply.github.com>
---
.../Bindings/AutocadSendBaseBinding.cs | 70 ++++++++++++++-
.../HostApp/AutocadInstanceUnpacker.cs | 10 +--
.../HostApp/AutocadMaterialUnpacker.cs | 12 +++
.../Send/AutocadRootObjectBaseBuilder.cs | 68 +++++++++++++--
.../Send/AutocadRootObjectBuilder.cs | 3 +
.../Send/Civil3dRootObjectBuilder.cs | 3 +
.../Operations/Send/RhinoRootObjectBuilder.cs | 2 +-
.../AutocadConversionSettings.cs | 4 +-
.../AutocadConversionSettingsFactory.cs | 12 ++-
.../Extensions/ListExtensions.cs | 42 +++------
.../Helpers/ReferencePointHelper.cs | 42 +++++++++
.../Helpers/TransformHelper.cs | 73 ++++++++++++++++
.../IReferencePointConverter.cs | 33 +++++++
.../ReferencePointConverter.cs | 74 ++++++++++++++++
.../ServiceRegistration.cs | 2 +
...Speckle.Converters.AutocadShared.projitems | 15 +++-
.../AutocadPolycurveToHostConverter.cs | 32 ++++++-
...adPolycurveToHostPolyline2dRawConverter.cs | 14 +--
...ocadPolycurveToHostPolylineRawConverter.cs | 14 +--
.../PolyfaceMeshToSpeckleConverter.cs | 27 ++----
.../Geometry/Polyline2dToSpeckleConverter.cs | 42 ++++-----
.../Geometry/Polyline3dToSpeckleConverter.cs | 32 +++----
.../Geometry/PolylineToSpeckleConverter.cs | 27 +++---
.../Geometry/SubDMeshToSpeckleConverter.cs | 79 ++---------------
.../Raw/BrepToSpeckleRawConverter.cs | 9 +-
.../Raw/CircularArc2dToSpeckleRawConverter.cs | 27 ++----
.../Raw/DBArcToSpeckleRawConverter.cs | 5 --
.../Raw/DBCircleToSpeckleRawConverter.cs | 7 +-
.../Raw/DBCurveToSpeckleRawConverter.cs | 6 +-
.../Raw/DBEllipseToSpeckleRawConverter.cs | 26 +++---
.../Raw/DBLineToSpeckleRawConverter.cs | 6 +-
.../Raw/DBSplineToSpeckleRawConverter.cs | 16 ++--
.../Raw/DBSubDMeshToSpeckleRawConverter.cs | 86 +++++++++++++++++++
.../Raw/DBTextToSpeckleRawConverter.cs | 28 ++++--
.../DoublesToSpecklePolylineRawConverter.cs | 32 +++++++
.../Raw/MTextToSpeckleRawConverter.cs | 30 +++++--
.../Raw/PlaneToSpeckleRawConverter.cs | 11 ++-
.../Raw/Point2dToSpeckleRawConverter.cs | 26 ++++++
.../Raw/Point3dToSpeckleRawConverter.cs | 25 ++++++
.../Raw/PointToSpeckleRawConverter.cs | 16 ----
.../Raw/Vector3dToSpeckleRawConverter.cs | 25 ++++++
.../Raw/VectorToSpeckleRawConverter.cs | 17 ----
.../ServiceRegistration.cs | 1 +
...gnmentSubentityArcToSpeckleRawConverter.cs | 27 ++----
...nmentSubentityLineToSpeckleRawConverter.cs | 26 ++----
...entSubentitySpiralToSpeckleRawConverter.cs | 10 ++-
.../GridSurfaceToSpeckleMeshRawConverter.cs | 17 ++--
.../Point3dCollectionToSpeckleRawConverter.cs | 10 ++-
.../TinSurfaceToSpeckleMeshRawConverter.cs | 10 ++-
.../Instances/IInstanceObjectsManager.cs | 3 +-
.../Instances/InstanceObjectsManager.cs | 9 +-
.../Instances/UnpackResult.cs | 1 +
52 files changed, 866 insertions(+), 378 deletions(-)
create mode 100644 Converters/Autocad/Speckle.Converters.AutocadShared/Helpers/ReferencePointHelper.cs
create mode 100644 Converters/Autocad/Speckle.Converters.AutocadShared/Helpers/TransformHelper.cs
create mode 100644 Converters/Autocad/Speckle.Converters.AutocadShared/IReferencePointConverter.cs
create mode 100644 Converters/Autocad/Speckle.Converters.AutocadShared/ReferencePointConverter.cs
create mode 100644 Converters/Autocad/Speckle.Converters.AutocadShared/ToSpeckle/Raw/DBSubDMeshToSpeckleRawConverter.cs
create mode 100644 Converters/Autocad/Speckle.Converters.AutocadShared/ToSpeckle/Raw/DoublesToSpecklePolylineRawConverter.cs
create mode 100644 Converters/Autocad/Speckle.Converters.AutocadShared/ToSpeckle/Raw/Point2dToSpeckleRawConverter.cs
create mode 100644 Converters/Autocad/Speckle.Converters.AutocadShared/ToSpeckle/Raw/Point3dToSpeckleRawConverter.cs
delete mode 100644 Converters/Autocad/Speckle.Converters.AutocadShared/ToSpeckle/Raw/PointToSpeckleRawConverter.cs
create mode 100644 Converters/Autocad/Speckle.Converters.AutocadShared/ToSpeckle/Raw/Vector3dToSpeckleRawConverter.cs
delete mode 100644 Converters/Autocad/Speckle.Converters.AutocadShared/ToSpeckle/Raw/VectorToSpeckleRawConverter.cs
diff --git a/Connectors/Autocad/Speckle.Connectors.AutocadShared/Bindings/AutocadSendBaseBinding.cs b/Connectors/Autocad/Speckle.Connectors.AutocadShared/Bindings/AutocadSendBaseBinding.cs
index f30544012..9c23996ed 100644
--- a/Connectors/Autocad/Speckle.Connectors.AutocadShared/Bindings/AutocadSendBaseBinding.cs
+++ b/Connectors/Autocad/Speckle.Connectors.AutocadShared/Bindings/AutocadSendBaseBinding.cs
@@ -1,6 +1,7 @@
using System.Collections.Concurrent;
using System.Diagnostics.CodeAnalysis;
using Autodesk.AutoCAD.DatabaseServices;
+using Autodesk.AutoCAD.Geometry;
using Speckle.Connectors.Autocad.HostApp.Extensions;
using Speckle.Connectors.Common.Caching;
using Speckle.Connectors.Common.Cancellation;
@@ -40,6 +41,9 @@ public abstract class AutocadSendBaseBinding : ISendBinding
///
private ConcurrentBag ChangedObjectIds { get; set; } = new();
+ private readonly List _docSubsTracker = new();
+ private readonly Dictionary _docUcsTracker = new();
+
protected AutocadSendBaseBinding(
DocumentModelStore store,
IBrowserBridge parent,
@@ -71,6 +75,10 @@ public abstract class AutocadSendBaseBinding : ISendBinding
// catches the case when autocad just opens up with a blank new doc
SubscribeToObjectChanges(Application.DocumentManager.CurrentDocument);
}
+
+ Application.SystemVariableChanged += (_, e) =>
+ _topLevelExceptionHandler.CatchUnhandled(() => OnSystemVariableChanged(e));
+
// Since ids of the objects generates from same seed, we should clear the cache always whenever doc swapped.
_store.DocumentChanged += (_, _) =>
{
@@ -78,8 +86,6 @@ public abstract class AutocadSendBaseBinding : ISendBinding
};
}
- private readonly List _docSubsTracker = new();
-
private void SubscribeToObjectChanges(Document doc)
{
if (doc == null || doc.Database == null || _docSubsTracker.Contains(doc.Name))
@@ -88,11 +94,58 @@ public abstract class AutocadSendBaseBinding : ISendBinding
}
_docSubsTracker.Add(doc.Name);
+ _docUcsTracker[doc.Name] = doc.Editor.CurrentUserCoordinateSystem;
+
doc.Database.ObjectAppended += (_, e) => OnObjectChanged(e.DBObject);
doc.Database.ObjectErased += (_, e) => OnObjectChanged(e.DBObject);
doc.Database.ObjectModified += (_, e) => OnObjectChanged(e.DBObject);
}
+ ///
+ /// Handles system variable changes to detect UCS modifications.
+ /// When UCS changes, clears the conversion cache and expires all sender model cards.
+ ///
+ private void OnSystemVariableChanged(Autodesk.AutoCAD.ApplicationServices.SystemVariableChangedEventArgs e)
+ {
+ // check if this is a UCS-defining system variable
+ string varName = e.Name.ToUpperInvariant();
+ bool isUcsChange = varName == "UCSNAME" || varName == "UCSORG" || varName == "UCSXDIR" || varName == "UCSYDIR";
+
+ if (!isUcsChange)
+ {
+ return;
+ }
+
+ // get the currently active document
+ Document doc = Application.DocumentManager.MdiActiveDocument;
+ if (doc == null)
+ {
+ return;
+ }
+
+ var currentUcs = doc.Editor.CurrentUserCoordinateSystem;
+
+ // first time tracking this document's UCS
+ if (!_docUcsTracker.TryGetValue(doc.Name, out Matrix3d storedUcs))
+ {
+ _docUcsTracker[doc.Name] = currentUcs;
+ return;
+ }
+
+ // ucs hasn't actually changed (multiple variables fire for single UCS change)
+ if (currentUcs.IsEqualTo(storedUcs))
+ {
+ return;
+ }
+
+ // ucs has changed - all cached conversions invalid
+ _sendConversionCache.ClearCache();
+ _docUcsTracker[doc.Name] = currentUcs;
+
+ // expire all sender model cards
+ _idleManager.SubscribeToIdle(nameof(ExpireAllSenders), async () => await ExpireAllSenders());
+ }
+
private void OnObjectChanged(DBObject dbObject) =>
_topLevelExceptionHandler.CatchUnhandled(() => OnChangeChangedObjectIds(dbObject));
@@ -123,6 +176,19 @@ public abstract class AutocadSendBaseBinding : ISendBinding
ChangedObjectIds = new();
}
+ ///
+ /// Expires all sender model cards when a global change occurs (like UCS change).
+ ///
+ private async Task ExpireAllSenders()
+ {
+ var senders = _store.GetSenders();
+ var expiredSenderIds = senders.Select(s => s.ModelCardId.NotNull()).ToList();
+ if (expiredSenderIds.Count > 0)
+ {
+ await Commands.SetModelsExpired(expiredSenderIds);
+ }
+ }
+
public List GetSendFilters() => _sendFilters;
public List GetSendSettings() => [];
diff --git a/Connectors/Autocad/Speckle.Connectors.AutocadShared/HostApp/AutocadInstanceUnpacker.cs b/Connectors/Autocad/Speckle.Connectors.AutocadShared/HostApp/AutocadInstanceUnpacker.cs
index d38ebca41..3b9611c84 100644
--- a/Connectors/Autocad/Speckle.Connectors.AutocadShared/HostApp/AutocadInstanceUnpacker.cs
+++ b/Connectors/Autocad/Speckle.Connectors.AutocadShared/HostApp/AutocadInstanceUnpacker.cs
@@ -3,9 +3,9 @@ using Microsoft.Extensions.Logging;
using Speckle.Connectors.Autocad.HostApp.Extensions;
using Speckle.Connectors.Autocad.Operations.Send;
using Speckle.Connectors.Common.Instances;
+using Speckle.Converters.Autocad.Helpers;
using Speckle.Converters.AutocadShared.ToSpeckle;
using Speckle.Converters.Common;
-using Speckle.DoubleNumerics;
using Speckle.Sdk;
using Speckle.Sdk.Models.Instances;
@@ -46,6 +46,7 @@ public class AutocadInstanceUnpacker : IInstanceUnpacker
{
UnpackInstance(blockReference, 0, transaction);
}
+
_instanceObjectsManager.AddAtomicObject(obj.ApplicationId, obj);
}
return _instanceObjectsManager.GetUnpackResult();
@@ -66,13 +67,14 @@ public class AutocadInstanceUnpacker : IInstanceUnpacker
? instance.AnonymousBlockTableRecord
: instance.BlockTableRecord;
+ // transforms on instances are always stored in WCS
InstanceProxy instanceProxy =
new()
{
applicationId = instanceId,
definitionId = definitionId.ToString(),
maxDepth = depth,
- transform = GetMatrix(instance.BlockTransform.ToArray()),
+ transform = TransformHelper.ConvertToInstanceMatrix4x4(instance.BlockTransform),
units = _unitsConverter.ConvertOrThrow(Application.DocumentManager.CurrentDocument.Database.Insunits)
};
@@ -173,6 +175,7 @@ public class AutocadInstanceUnpacker : IInstanceUnpacker
UnpackInstance(blockReference, depth + 1, transaction);
}
+ _instanceObjectsManager.AddAtomicDefinitionObjectId(appId);
_instanceObjectsManager.AddAtomicObject(appId, new(obj, appId));
}
@@ -183,7 +186,4 @@ public class AutocadInstanceUnpacker : IInstanceUnpacker
_logger.LogError(ex, "Failed unpacking Autocad instance");
}
}
-
- private Matrix4x4 GetMatrix(double[] t) =>
- new(t[0], t[1], t[2], t[3], t[4], t[5], t[6], t[7], t[8], t[9], t[10], t[11], t[12], t[13], t[14], t[15]);
}
diff --git a/Connectors/Autocad/Speckle.Connectors.AutocadShared/HostApp/AutocadMaterialUnpacker.cs b/Connectors/Autocad/Speckle.Connectors.AutocadShared/HostApp/AutocadMaterialUnpacker.cs
index 9b1f843b3..0f87df9a5 100644
--- a/Connectors/Autocad/Speckle.Connectors.AutocadShared/HostApp/AutocadMaterialUnpacker.cs
+++ b/Connectors/Autocad/Speckle.Connectors.AutocadShared/HostApp/AutocadMaterialUnpacker.cs
@@ -51,6 +51,12 @@ public class AutocadMaterialUnpacker
if (transaction.GetObject(entity.MaterialId, OpenMode.ForRead) is Material material)
{
+ // skip default material
+ if (material.Name == "Global")
+ {
+ continue;
+ }
+
string materialId = material.GetSpeckleApplicationId();
if (materialProxies.TryGetValue(materialId, out RenderMaterialProxy? value))
{
@@ -77,6 +83,12 @@ public class AutocadMaterialUnpacker
{
if (transaction.GetObject(layer.MaterialId, OpenMode.ForRead) is Material material)
{
+ // skip default material
+ if (material.Name == "Global")
+ {
+ continue;
+ }
+
string materialId = material.GetSpeckleApplicationId();
string layerId = layer.GetSpeckleApplicationId(); // Do not use handle directly, see note in the 'GetSpeckleApplicationId' method
if (materialProxies.TryGetValue(materialId, out RenderMaterialProxy? value))
diff --git a/Connectors/Autocad/Speckle.Connectors.AutocadShared/Operations/Send/AutocadRootObjectBaseBuilder.cs b/Connectors/Autocad/Speckle.Connectors.AutocadShared/Operations/Send/AutocadRootObjectBaseBuilder.cs
index 0434dcc35..20b5660d2 100644
--- a/Connectors/Autocad/Speckle.Connectors.AutocadShared/Operations/Send/AutocadRootObjectBaseBuilder.cs
+++ b/Connectors/Autocad/Speckle.Connectors.AutocadShared/Operations/Send/AutocadRootObjectBaseBuilder.cs
@@ -1,5 +1,6 @@
using System.Diagnostics.CodeAnalysis;
using Autodesk.AutoCAD.DatabaseServices;
+using Autodesk.AutoCAD.Geometry;
using Microsoft.Extensions.Logging;
using Speckle.Connectors.Autocad.HostApp;
using Speckle.Connectors.Common.Builders;
@@ -7,6 +8,8 @@ using Speckle.Connectors.Common.Caching;
using Speckle.Connectors.Common.Conversion;
using Speckle.Connectors.Common.Extensions;
using Speckle.Connectors.Common.Operations;
+using Speckle.Converters.Autocad;
+using Speckle.Converters.Autocad.Helpers;
using Speckle.Converters.Common;
using Speckle.Sdk;
using Speckle.Sdk.Logging;
@@ -19,6 +22,7 @@ namespace Speckle.Connectors.Autocad.Operations.Send;
public abstract class AutocadRootObjectBaseBuilder : IRootObjectBuilder
{
private readonly IRootToSpeckleConverter _converter;
+ private readonly IConverterSettingsStore _converterSettings;
private readonly string[] _documentPathSeparator = ["\\"];
private readonly ISendConversionCache _sendConversionCache;
private readonly AutocadInstanceUnpacker _instanceUnpacker;
@@ -30,6 +34,7 @@ public abstract class AutocadRootObjectBaseBuilder : IRootObjectBuilder converterSettings,
ISendConversionCache sendConversionCache,
AutocadInstanceUnpacker instanceObjectManager,
AutocadMaterialUnpacker materialUnpacker,
@@ -40,6 +45,7 @@ public abstract class AutocadRootObjectBaseBuilder : IRootObjectBuilder usedAcadLayers = new(); // Keeps track of autocad layers used, so we can pass them on later to the material and color unpacker.
List results = new();
int count = 0;
+
+ // 4 - Convert atomic objects
foreach (var (entity, applicationId) in atomicObjects)
{
cancellationToken.ThrowIfCancellationRequested();
@@ -104,9 +128,28 @@ public abstract class AutocadRootObjectBaseBuilder : IRootObjectBuilder currentSettings with { ReferencePointTransform = null }))
+ {
+ result = ConvertAutocadEntity(entity, applicationId, objectCollection, instanceProxies, projectId);
+ }
+ }
+ else // this is a selected atomic object (not part of definition)
+ {
+ result = ConvertAutocadEntity(
+ entity,
+ applicationId,
+ objectCollection,
+ instanceProxies,
+ projectId,
+ referenceTransform // set this for top level instance proxies to use if needed
+ );
+ }
+ results.Add(result);
onOperationProgressed.Report(new("Converting", (double)++count / atomicObjects.Count));
}
@@ -115,10 +158,10 @@ public abstract class AutocadRootObjectBaseBuilder : IRootObjectBuilder instanceProxies,
- string projectId
+ string projectId,
+ Matrix3d? transform = null
)
{
string sourceType = entity.GetType().ToString();
try
{
Base converted;
- if (entity is BlockReference && instanceProxies.TryGetValue(applicationId, out InstanceProxy? instanceProxy))
+ if (entity is BlockReference br && instanceProxies.TryGetValue(applicationId, out InstanceProxy? instanceProxy))
{
+ // modify transform by reference point this if it is top level
+ if (instanceProxy.maxDepth == 0 && transform is Matrix3d validTransform)
+ {
+ instanceProxy.transform = TransformHelper.ConvertToInstanceMatrix4x4(
+ br.BlockTransform.PreMultiplyBy(validTransform)
+ );
+ }
+
converted = instanceProxy;
}
else if (_sendConversionCache.TryGetValue(projectId, applicationId, out ObjectReference? value))
diff --git a/Connectors/Autocad/Speckle.Connectors.AutocadShared/Operations/Send/AutocadRootObjectBuilder.cs b/Connectors/Autocad/Speckle.Connectors.AutocadShared/Operations/Send/AutocadRootObjectBuilder.cs
index 7278ecae6..a356d6960 100644
--- a/Connectors/Autocad/Speckle.Connectors.AutocadShared/Operations/Send/AutocadRootObjectBuilder.cs
+++ b/Connectors/Autocad/Speckle.Connectors.AutocadShared/Operations/Send/AutocadRootObjectBuilder.cs
@@ -2,6 +2,7 @@ using Autodesk.AutoCAD.DatabaseServices;
using Microsoft.Extensions.Logging;
using Speckle.Connectors.Autocad.HostApp;
using Speckle.Connectors.Common.Caching;
+using Speckle.Converters.Autocad;
using Speckle.Converters.Common;
using Speckle.Sdk.Logging;
using Speckle.Sdk.Models.Collections;
@@ -15,6 +16,7 @@ public sealed class AutocadRootObjectBuilder : AutocadRootObjectBaseBuilder
public AutocadRootObjectBuilder(
AutocadLayerUnpacker layerUnpacker,
IRootToSpeckleConverter converter,
+ IConverterSettingsStore converterSettings,
ISendConversionCache sendConversionCache,
AutocadInstanceUnpacker instanceObjectManager,
AutocadMaterialUnpacker materialUnpacker,
@@ -25,6 +27,7 @@ public sealed class AutocadRootObjectBuilder : AutocadRootObjectBaseBuilder
)
: base(
converter,
+ converterSettings,
sendConversionCache,
instanceObjectManager,
materialUnpacker,
diff --git a/Connectors/Autocad/Speckle.Connectors.Civil3dShared/Operations/Send/Civil3dRootObjectBuilder.cs b/Connectors/Autocad/Speckle.Connectors.Civil3dShared/Operations/Send/Civil3dRootObjectBuilder.cs
index 9f17bd7e0..c1a629415 100644
--- a/Connectors/Autocad/Speckle.Connectors.Civil3dShared/Operations/Send/Civil3dRootObjectBuilder.cs
+++ b/Connectors/Autocad/Speckle.Connectors.Civil3dShared/Operations/Send/Civil3dRootObjectBuilder.cs
@@ -4,6 +4,7 @@ using Speckle.Connectors.Autocad.HostApp;
using Speckle.Connectors.Autocad.Operations.Send;
using Speckle.Connectors.Common.Caching;
using Speckle.Connectors.Common.Operations;
+using Speckle.Converters.Autocad;
using Speckle.Converters.Civil3dShared.ToSpeckle;
using Speckle.Converters.Common;
using Speckle.Sdk.Logging;
@@ -20,6 +21,7 @@ public sealed class Civil3dRootObjectBuilder : AutocadRootObjectBaseBuilder
AutocadLayerUnpacker layerUnpacker,
PropertySetDefinitionHandler propertySetDefinitionHandler,
IRootToSpeckleConverter converter,
+ IConverterSettingsStore converterSettings,
ISendConversionCache sendConversionCache,
AutocadInstanceUnpacker instanceObjectManager,
AutocadMaterialUnpacker materialUnpacker,
@@ -30,6 +32,7 @@ public sealed class Civil3dRootObjectBuilder : AutocadRootObjectBaseBuilder
)
: base(
converter,
+ converterSettings,
sendConversionCache,
instanceObjectManager,
materialUnpacker,
diff --git a/Connectors/Rhino/Speckle.Connectors.RhinoShared/Operations/Send/RhinoRootObjectBuilder.cs b/Connectors/Rhino/Speckle.Connectors.RhinoShared/Operations/Send/RhinoRootObjectBuilder.cs
index 491c06c12..8394ec6c5 100644
--- a/Connectors/Rhino/Speckle.Connectors.RhinoShared/Operations/Send/RhinoRootObjectBuilder.cs
+++ b/Connectors/Rhino/Speckle.Connectors.RhinoShared/Operations/Send/RhinoRootObjectBuilder.cs
@@ -86,7 +86,7 @@ public class RhinoRootObjectBuilder : IRootObjectBuilder
unpackResults = _instanceUnpacker.UnpackSelection(rhinoObjects);
}
- var (atomicObjects, instanceProxies, instanceDefinitionProxies) = unpackResults;
+ var (atomicObjects, atomicDefinitionObjectIds, instanceProxies, instanceDefinitionProxies) = unpackResults;
// POC: we should formalise this, sooner or later - or somehow fix it a bit more
rootObjectCollection[ProxyKeys.INSTANCE_DEFINITION] = instanceDefinitionProxies; // this won't work re traversal on receive
diff --git a/Converters/Autocad/Speckle.Converters.AutocadShared/AutocadConversionSettings.cs b/Converters/Autocad/Speckle.Converters.AutocadShared/AutocadConversionSettings.cs
index 093f92e9b..7add8edff 100644
--- a/Converters/Autocad/Speckle.Converters.AutocadShared/AutocadConversionSettings.cs
+++ b/Converters/Autocad/Speckle.Converters.AutocadShared/AutocadConversionSettings.cs
@@ -1,3 +1,3 @@
-namespace Speckle.Converters.Autocad;
+namespace Speckle.Converters.Autocad;
-public record AutocadConversionSettings(Document Document, string SpeckleUnits);
+public record AutocadConversionSettings(Document Document, AG.Matrix3d? ReferencePointTransform, string SpeckleUnits);
diff --git a/Converters/Autocad/Speckle.Converters.AutocadShared/AutocadConversionSettingsFactory.cs b/Converters/Autocad/Speckle.Converters.AutocadShared/AutocadConversionSettingsFactory.cs
index 08b4d4a68..433139174 100644
--- a/Converters/Autocad/Speckle.Converters.AutocadShared/AutocadConversionSettingsFactory.cs
+++ b/Converters/Autocad/Speckle.Converters.AutocadShared/AutocadConversionSettingsFactory.cs
@@ -1,4 +1,4 @@
-using Speckle.Converters.Common;
+using Speckle.Converters.Common;
using Speckle.InterfaceGenerator;
namespace Speckle.Converters.Autocad;
@@ -7,6 +7,12 @@ namespace Speckle.Converters.Autocad;
public class AutocadConversionSettingsFactory(IHostToSpeckleUnitConverter unitsConverter)
: IAutocadConversionSettingsFactory
{
- public AutocadConversionSettings Create(Document document) =>
- new(document, unitsConverter.ConvertOrThrow(document.Database.Insunits));
+ public AutocadConversionSettings Create(Document document)
+ {
+ AG.Matrix3d? m =
+ document.Editor.CurrentUserCoordinateSystem == AG.Matrix3d.Identity
+ ? null
+ : document.Editor.CurrentUserCoordinateSystem;
+ return new(document, m, unitsConverter.ConvertOrThrow(document.Database.Insunits));
+ }
}
diff --git a/Converters/Autocad/Speckle.Converters.AutocadShared/Extensions/ListExtensions.cs b/Converters/Autocad/Speckle.Converters.AutocadShared/Extensions/ListExtensions.cs
index 99595f357..add433011 100644
--- a/Converters/Autocad/Speckle.Converters.AutocadShared/Extensions/ListExtensions.cs
+++ b/Converters/Autocad/Speckle.Converters.AutocadShared/Extensions/ListExtensions.cs
@@ -2,34 +2,6 @@ namespace Speckle.Converters.Autocad.Extensions;
public static class ListExtensions
{
- public static SOG.Polyline ConvertToSpecklePolyline(this List pointList, string speckleUnits)
- {
- // throw if list is malformed
- if (pointList.Count % 3 != 0)
- {
- throw new ArgumentException("Point list of xyz values is malformed", nameof(pointList));
- }
-
- return new() { value = pointList, units = speckleUnits };
- }
-
- public static List ConvertToPoint2d(this List pointList, double conversionFactor = 1)
- {
- // throw if list is malformed
- if (pointList.Count % 2 != 0)
- {
- throw new ArgumentException("Point list of xy values is malformed", nameof(pointList));
- }
-
- List points2d = new(pointList.Count / 2);
- for (int i = 1; i < pointList.Count; i += 2)
- {
- points2d.Add(new AG.Point2d(pointList[i - 1] * conversionFactor, pointList[i] * conversionFactor));
- }
-
- return points2d;
- }
-
public static List ConvertToPoint3d(this List pointList, double conversionFactor = 1)
{
// throw if list is malformed
@@ -52,4 +24,18 @@ public static class ListExtensions
return points3d;
}
+
+ ///
+ /// Converts a list of doubles to Point3d objects and transforms them to OCS (Object Coordinate System)
+ /// based on the provided normal vector
+ ///
+ public static List ConvertToPoint3dInOcs(
+ this List pointList,
+ AG.Vector3d normal,
+ double conversionFactor = 1
+ )
+ {
+ AG.Matrix3d matrixOcs = AG.Matrix3d.WorldToPlane(normal);
+ return pointList.ConvertToPoint3d(conversionFactor).Select(p => p.TransformBy(matrixOcs)).ToList();
+ }
}
diff --git a/Converters/Autocad/Speckle.Converters.AutocadShared/Helpers/ReferencePointHelper.cs b/Converters/Autocad/Speckle.Converters.AutocadShared/Helpers/ReferencePointHelper.cs
new file mode 100644
index 000000000..c0b34a98b
--- /dev/null
+++ b/Converters/Autocad/Speckle.Converters.AutocadShared/Helpers/ReferencePointHelper.cs
@@ -0,0 +1,42 @@
+namespace Speckle.Converters.Autocad.Helpers;
+
+///
+/// Helper class for working with reference points
+///
+public static class ReferencePointHelper
+{
+ public const string REFERENCE_POINT_TRANSFORM_KEY = "referencePointTransform";
+
+ ///
+ /// Changes Autocad Matrix3d Transform to a double array.
+ /// Uses a 16-element column-major matrix representation. See https://speckle.guide/dev/objects.html
+ ///
+ public static Dictionary CreateTransformDataForRootObject(AG.Matrix3d transform)
+ {
+ return new Dictionary
+ {
+ {
+ "transform", // TODO: it would also be nice to include the key-value pair for reference point type as a string
+ new[]
+ {
+ transform.CoordinateSystem3d.Xaxis.X,
+ transform.CoordinateSystem3d.Xaxis.Y,
+ transform.CoordinateSystem3d.Xaxis.Z,
+ 0,
+ transform.CoordinateSystem3d.Yaxis.X,
+ transform.CoordinateSystem3d.Yaxis.Y,
+ transform.CoordinateSystem3d.Yaxis.Z,
+ 0,
+ transform.CoordinateSystem3d.Zaxis.X,
+ transform.CoordinateSystem3d.Zaxis.Y,
+ transform.CoordinateSystem3d.Zaxis.Z,
+ 0,
+ transform.CoordinateSystem3d.Origin.X,
+ transform.CoordinateSystem3d.Origin.Y,
+ transform.CoordinateSystem3d.Origin.Z,
+ 1
+ }
+ }
+ };
+ }
+}
diff --git a/Converters/Autocad/Speckle.Converters.AutocadShared/Helpers/TransformHelper.cs b/Converters/Autocad/Speckle.Converters.AutocadShared/Helpers/TransformHelper.cs
new file mode 100644
index 000000000..9a2d48237
--- /dev/null
+++ b/Converters/Autocad/Speckle.Converters.AutocadShared/Helpers/TransformHelper.cs
@@ -0,0 +1,73 @@
+using Speckle.DoubleNumerics;
+
+namespace Speckle.Converters.Autocad.Helpers;
+
+///
+/// Helper class for working with transforms
+///
+public static class TransformHelper
+{
+ ///
+ /// Converts an AutoCAD matrix3d to a row-dominant Speckle Matrix4x4
+ ///
+ ///
+ ///
+ ///
+ /// Use for System Numerics operations, eg matrix and vector multiplication
+ ///
+ public static Matrix4x4 ConvertToMatrix4x4(AG.Matrix3d m) =>
+ new(
+ m[0, 0],
+ m[1, 0],
+ m[2, 0],
+ m[3, 0],
+ m[0, 1],
+ m[1, 1],
+ m[2, 1],
+ m[3, 1],
+ m[0, 2],
+ m[1, 2],
+ m[2, 2],
+ m[3, 2],
+ m[0, 3],
+ m[1, 3],
+ m[2, 3],
+ m[3, 3]
+ );
+
+ ///
+ /// Speckle Instances use a transform that is column-dominant, not row dominant.
+ ///
+ ///
+ ///
+ /// Use only for Speckle Instance object transforms.
+ public static Matrix4x4 ConvertToInstanceMatrix4x4(AG.Matrix3d m) =>
+ new(
+ m[0, 0],
+ m[0, 1],
+ m[0, 2],
+ m[0, 3],
+ m[1, 0],
+ m[1, 1],
+ m[1, 2],
+ m[1, 3],
+ m[2, 0],
+ m[2, 1],
+ m[2, 2],
+ m[2, 3],
+ m[3, 0],
+ m[3, 1],
+ m[3, 2],
+ m[3, 3]
+ );
+
+ ///
+ /// Get the transform matrix from an entity's OCS to the WCS
+ ///
+ ///
+ ///
+ ///
+ /// Use this method for certain properties or methods on entities that return values in OCS
+ ///
+ public static AG.Matrix3d GetTransformFromOCSToWCS(AG.Vector3d normal) => AG.Matrix3d.WorldToPlane(normal);
+}
diff --git a/Converters/Autocad/Speckle.Converters.AutocadShared/IReferencePointConverter.cs b/Converters/Autocad/Speckle.Converters.AutocadShared/IReferencePointConverter.cs
new file mode 100644
index 000000000..d114b5ced
--- /dev/null
+++ b/Converters/Autocad/Speckle.Converters.AutocadShared/IReferencePointConverter.cs
@@ -0,0 +1,33 @@
+namespace Speckle.Converters.Autocad;
+
+public interface IReferencePointConverter
+{
+ ///
+ /// Converts a list of doubles representing point3ds in WCS coordinates to the current active coordinate system
+ ///
+ ///
+ ///
+ List ConvertWCSDoublesToExternalCoordinates(List d);
+
+ ///
+ /// Converts a Point in WCS coordinates to the current active coordinate system
+ ///
+ ///
+ ///
+ AG.Point3d ConvertWCSPointToExternalCoordinates(AG.Point3d p);
+
+ ///
+ /// Converts a Vector in WCS coordinates to the current active coordinate system
+ ///
+ ///
+ ///
+ AG.Vector3d ConvertWCSVectorToExternalCoordinates(AG.Vector3d v);
+
+ ///
+ /// Converts an elevation in OCS coordinates to the current active coordinate system
+ ///
+ /// elevation in OCS
+ /// OCS plane normal in WCS
+ ///
+ double ConvertOCSElevationDoubleToExternalCoordinates(double e, AG.Vector3d normal);
+}
diff --git a/Converters/Autocad/Speckle.Converters.AutocadShared/ReferencePointConverter.cs b/Converters/Autocad/Speckle.Converters.AutocadShared/ReferencePointConverter.cs
new file mode 100644
index 000000000..33fef2814
--- /dev/null
+++ b/Converters/Autocad/Speckle.Converters.AutocadShared/ReferencePointConverter.cs
@@ -0,0 +1,74 @@
+using Speckle.Converters.Autocad.Helpers;
+using Speckle.Converters.Common;
+using Speckle.DoubleNumerics;
+
+namespace Speckle.Converters.Autocad;
+
+///
+/// POC: reference point functionality needs to be revisited (we are currently baking in these transforms into all geometry using the point and vector converters, and losing the transform).
+/// This converter uses the transform from the converter settings (from the current doc)
+///
+public class ReferencePointConverter(IConverterSettingsStore converterSettings)
+ : IReferencePointConverter
+{
+ public List ConvertWCSDoublesToExternalCoordinates(List d)
+ {
+ if (d.Count % 3 != 0)
+ {
+ throw new ArgumentException("Point list of xyz values is malformed", nameof(d));
+ }
+
+ if (converterSettings.Current.ReferencePointTransform is AG.Matrix3d m)
+ {
+ Matrix4x4 transform = TransformHelper.ConvertToMatrix4x4(m.Inverse());
+
+ var transformed = new List(d.Count);
+
+ for (int i = 0; i < d.Count; i += 3)
+ {
+ Vector3 p = Vector3.Transform(new(d[i], d[i + 1], d[i + 2]), transform);
+
+ transformed.Add(p.X);
+ transformed.Add(p.Y);
+ transformed.Add(p.Z);
+ }
+
+ return transformed;
+ }
+
+ return d;
+ }
+
+ public AG.Point3d ConvertWCSPointToExternalCoordinates(AG.Point3d p)
+ {
+ if (converterSettings.Current.ReferencePointTransform is AG.Matrix3d transform)
+ {
+ return p.TransformBy(transform.Inverse());
+ }
+
+ return p;
+ }
+
+ public AG.Vector3d ConvertWCSVectorToExternalCoordinates(AG.Vector3d v)
+ {
+ if (converterSettings.Current.ReferencePointTransform is AG.Matrix3d transform)
+ {
+ return v.TransformBy(transform.Inverse());
+ }
+
+ return v;
+ }
+
+ public double ConvertOCSElevationDoubleToExternalCoordinates(double elevation, AG.Vector3d normal)
+ {
+ // get a point on the plane in WCS
+ AG.Point3d wcsPoint = AG.Point3d.Origin + normal * elevation;
+
+ // transform to external coords
+ AG.Point3d extPoint = ConvertWCSPointToExternalCoordinates(wcsPoint);
+ AG.Vector3d extNormal = ConvertWCSVectorToExternalCoordinates(normal);
+
+ // calculate elevation as perpendicular distance in external coords
+ return extPoint.GetAsVector().DotProduct(extNormal);
+ }
+}
diff --git a/Converters/Autocad/Speckle.Converters.AutocadShared/ServiceRegistration.cs b/Converters/Autocad/Speckle.Converters.AutocadShared/ServiceRegistration.cs
index e748b49a4..adc447336 100644
--- a/Converters/Autocad/Speckle.Converters.AutocadShared/ServiceRegistration.cs
+++ b/Converters/Autocad/Speckle.Converters.AutocadShared/ServiceRegistration.cs
@@ -26,6 +26,8 @@ public static class ServiceRegistration
>();
serviceCollection.AddMatchingInterfacesAsTransient(Assembly.GetExecutingAssembly());
+ serviceCollection.AddScoped();
+
// add other classes
serviceCollection.AddScoped();
serviceCollection.AddScoped();
diff --git a/Converters/Autocad/Speckle.Converters.AutocadShared/Speckle.Converters.AutocadShared.projitems b/Converters/Autocad/Speckle.Converters.AutocadShared/Speckle.Converters.AutocadShared.projitems
index cfe3ceade..2808e48d3 100644
--- a/Converters/Autocad/Speckle.Converters.AutocadShared/Speckle.Converters.AutocadShared.projitems
+++ b/Converters/Autocad/Speckle.Converters.AutocadShared/Speckle.Converters.AutocadShared.projitems
@@ -1,4 +1,4 @@
-
+
$(MSBuildAllProjects);$(MSBuildThisFileFullPath)
@@ -16,6 +16,10 @@
+
+
+
+
@@ -54,6 +58,7 @@
+
@@ -62,6 +67,7 @@
+
@@ -80,7 +86,6 @@
-
@@ -88,9 +93,11 @@
-
+
+
+
-
+
diff --git a/Converters/Autocad/Speckle.Converters.AutocadShared/ToHost/Geometry/AutocadPolycurveToHostConverter.cs b/Converters/Autocad/Speckle.Converters.AutocadShared/ToHost/Geometry/AutocadPolycurveToHostConverter.cs
index 65a3028b5..96df3782b 100644
--- a/Converters/Autocad/Speckle.Converters.AutocadShared/ToHost/Geometry/AutocadPolycurveToHostConverter.cs
+++ b/Converters/Autocad/Speckle.Converters.AutocadShared/ToHost/Geometry/AutocadPolycurveToHostConverter.cs
@@ -11,16 +11,19 @@ public class AutocadPolycurveToHostConverter : IToHostTopLevelConverter
private readonly ITypedConverter _polylineConverter;
private readonly ITypedConverter _polyline2dConverter;
private readonly ITypedConverter _polyline3dConverter;
+ private readonly ITypedConverter> _polycurveConverter;
public AutocadPolycurveToHostConverter(
ITypedConverter polylineConverter,
ITypedConverter polyline2dConverter,
- ITypedConverter polyline3dConverter
+ ITypedConverter polyline3dConverter,
+ ITypedConverter> polycurveConverter
)
{
_polylineConverter = polylineConverter;
_polyline2dConverter = polyline2dConverter;
_polyline3dConverter = polyline3dConverter;
+ _polycurveConverter = polycurveConverter;
}
public object Convert(Base target)
@@ -30,7 +33,7 @@ public class AutocadPolycurveToHostConverter : IToHostTopLevelConverter
switch (polycurve.polyType)
{
case SOG.Autocad.AutocadPolyType.Light:
- return _polylineConverter.Convert(polycurve);
+ return Has2DValue(polycurve) ? _polycurveConverter.Convert(polycurve) : _polylineConverter.Convert(polycurve);
case SOG.Autocad.AutocadPolyType.Simple2d:
case SOG.Autocad.AutocadPolyType.FitCurve2d:
@@ -47,4 +50,29 @@ public class AutocadPolycurveToHostConverter : IToHostTopLevelConverter
throw new ValidationException("Unknown poly type for AutocadPolycurve");
}
}
+
+ // Method for backwards compatibility: polylines from 3.10 and before had point2d values in OCS instead of point3d values in WCS/UCS
+ private bool Has2DValue(SOG.Autocad.AutocadPolycurve polycurve)
+ {
+ int pointListCount = polycurve.value.Count;
+ if (pointListCount % 3 == 0 && pointListCount % 2 != 0)
+ {
+ return false;
+ }
+
+ if (pointListCount % 2 != 0)
+ {
+ throw new ValidationException(
+ "Polycurve value list was deformed, could not translate into 2d or 3d coordinates."
+ );
+ }
+
+ int segmentVertexCount = polycurve.closed ? polycurve.segments.Count : polycurve.segments.Count + 1;
+ if (pointListCount / 2 == segmentVertexCount)
+ {
+ return true;
+ }
+
+ return false;
+ }
}
diff --git a/Converters/Autocad/Speckle.Converters.AutocadShared/ToHost/Raw/AutocadPolycurveToHostPolyline2dRawConverter.cs b/Converters/Autocad/Speckle.Converters.AutocadShared/ToHost/Raw/AutocadPolycurveToHostPolyline2dRawConverter.cs
index b3ad64154..6c986d336 100644
--- a/Converters/Autocad/Speckle.Converters.AutocadShared/ToHost/Raw/AutocadPolycurveToHostPolyline2dRawConverter.cs
+++ b/Converters/Autocad/Speckle.Converters.AutocadShared/ToHost/Raw/AutocadPolycurveToHostPolyline2dRawConverter.cs
@@ -26,33 +26,33 @@ public class AutocadPolycurveToHostPolyline2dRawConverter
// check for normal
if (target.normal is not SOG.Vector normal)
{
- throw new System.ArgumentException($"Autocad polycurve of type {target.polyType} did not have a normal");
+ throw new ArgumentException($"Autocad polycurve of type {target.polyType} did not have a normal");
}
// check for elevation
if (target.elevation is not double elevation)
{
- throw new System.ArgumentException($"Autocad polycurve of type {target.polyType} did not have an elevation");
+ throw new ArgumentException($"Autocad polycurve of type {target.polyType} did not have an elevation");
}
- // get vertices
+ // convert the normal, get vertices and transform them to ocs
+ var convertedNormal = _vectorConverter.Convert(normal);
double f = Units.GetConversionFactor(target.units, _settingsStore.Current.SpeckleUnits);
- List points = target.value.ConvertToPoint3d(f);
+ List points = target.value.ConvertToPoint3dInOcs(convertedNormal, f);
// check for invalid bulges
if (target.bulges is null || target.bulges.Count < points.Count)
{
- throw new System.ArgumentException($"Autocad polycurve of type {target.polyType} had null or malformed bulges");
+ throw new ArgumentException($"Autocad polycurve of type {target.polyType} had null or malformed bulges");
}
// check for invalid tangents
if (target.tangents is null || target.tangents.Count < points.Count)
{
- throw new System.ArgumentException($"Autocad polycurve of type {target.polyType} had null or malformed tangents");
+ throw new ArgumentException($"Autocad polycurve of type {target.polyType} had null or malformed tangents");
}
// create the polyline2d using the empty constructor
- AG.Vector3d convertedNormal = _vectorConverter.Convert(normal);
double convertedElevation = elevation * f;
ADB.Polyline2d polyline =
new()
diff --git a/Converters/Autocad/Speckle.Converters.AutocadShared/ToHost/Raw/AutocadPolycurveToHostPolylineRawConverter.cs b/Converters/Autocad/Speckle.Converters.AutocadShared/ToHost/Raw/AutocadPolycurveToHostPolylineRawConverter.cs
index dff137087..e05430e6f 100644
--- a/Converters/Autocad/Speckle.Converters.AutocadShared/ToHost/Raw/AutocadPolycurveToHostPolylineRawConverter.cs
+++ b/Converters/Autocad/Speckle.Converters.AutocadShared/ToHost/Raw/AutocadPolycurveToHostPolylineRawConverter.cs
@@ -24,26 +24,26 @@ public class AutocadPolycurveToHostPolylineRawConverter : ITypedConverter points2d = target.value.ConvertToPoint2d(f);
+ List points3d = target.value.ConvertToPoint3dInOcs(normal, f);
ADB.Polyline polyline =
new()
{
- Normal = _vectorConverter.Convert(target.normal),
+ Normal = normal,
Elevation = (double)target.elevation * f,
Closed = target.closed
};
- for (int i = 0; i < points2d.Count; i++)
+ for (int i = 0; i < points3d.Count; i++)
{
var bulge = target.bulges is null ? 0 : target.bulges[i];
- polyline.AddVertexAt(i, points2d[i], bulge, 0, 0);
+ polyline.AddVertexAt(i, new(points3d[i].X, points3d[i].Y), bulge, 0, 0);
}
return polyline;
diff --git a/Converters/Autocad/Speckle.Converters.AutocadShared/ToSpeckle/Geometry/PolyfaceMeshToSpeckleConverter.cs b/Converters/Autocad/Speckle.Converters.AutocadShared/ToSpeckle/Geometry/PolyfaceMeshToSpeckleConverter.cs
index a8d23bbef..679498076 100644
--- a/Converters/Autocad/Speckle.Converters.AutocadShared/ToSpeckle/Geometry/PolyfaceMeshToSpeckleConverter.cs
+++ b/Converters/Autocad/Speckle.Converters.AutocadShared/ToSpeckle/Geometry/PolyfaceMeshToSpeckleConverter.cs
@@ -1,4 +1,3 @@
-using Autodesk.AutoCAD.Geometry;
using Speckle.Converters.Common;
using Speckle.Converters.Common.Objects;
using Speckle.Sdk.Models;
@@ -14,18 +13,15 @@ namespace Speckle.Converters.Autocad.Geometry;
[NameAndRankValue(typeof(ADB.PolyFaceMesh), NameAndRankValueAttribute.SPECKLE_DEFAULT_RANK)]
public class DBPolyfaceMeshToSpeckleConverter : IToSpeckleTopLevelConverter
{
- private readonly ITypedConverter _pointConverter;
- private readonly ITypedConverter _boxConverter;
+ private readonly IReferencePointConverter _referencePointConverter;
private readonly IConverterSettingsStore _settingsStore;
public DBPolyfaceMeshToSpeckleConverter(
- ITypedConverter pointConverter,
- ITypedConverter boxConverter,
+ IReferencePointConverter referencePointConverter,
IConverterSettingsStore settingsStore
)
{
- _pointConverter = pointConverter;
- _boxConverter = boxConverter;
+ _referencePointConverter = referencePointConverter;
_settingsStore = settingsStore;
}
@@ -33,7 +29,7 @@ public class DBPolyfaceMeshToSpeckleConverter : IToSpeckleTopLevelConverter
public SOG.Mesh RawConvert(ADB.PolyFaceMesh target)
{
- List dbVertices = new();
+ List vertices = new();
List faces = new();
List faceVisibility = new();
List colors = new();
@@ -45,7 +41,9 @@ public class DBPolyfaceMeshToSpeckleConverter : IToSpeckleTopLevelConverter
switch (obj)
{
case ADB.PolyFaceMeshVertex o:
- dbVertices.Add(o.Position);
+ vertices.Add(o.Position.X);
+ vertices.Add(o.Position.Y);
+ vertices.Add(o.Position.Z);
colors.Add(o.Color.ColorValue.ToArgb());
break;
case ADB.FaceRecord o:
@@ -84,22 +82,13 @@ public class DBPolyfaceMeshToSpeckleConverter : IToSpeckleTopLevelConverter
tr.Commit();
}
- List vertices = new(dbVertices.Count * 3);
- foreach (Point3d vert in dbVertices)
- {
- vertices.AddRange(_pointConverter.Convert(vert).ToList());
- }
-
- SOG.Box bbox = _boxConverter.Convert(target.GeometricExtents);
-
SOG.Mesh speckleMesh =
new()
{
- vertices = vertices,
+ vertices = _referencePointConverter.ConvertWCSDoublesToExternalCoordinates(vertices), // transform by reference point
faces = faces,
colors = colors,
units = _settingsStore.Current.SpeckleUnits,
- bbox = bbox,
["faceVisibility"] = faceVisibility
};
diff --git a/Converters/Autocad/Speckle.Converters.AutocadShared/ToSpeckle/Geometry/Polyline2dToSpeckleConverter.cs b/Converters/Autocad/Speckle.Converters.AutocadShared/ToSpeckle/Geometry/Polyline2dToSpeckleConverter.cs
index e6cdfe890..1b73a5a50 100644
--- a/Converters/Autocad/Speckle.Converters.AutocadShared/ToSpeckle/Geometry/Polyline2dToSpeckleConverter.cs
+++ b/Converters/Autocad/Speckle.Converters.AutocadShared/ToSpeckle/Geometry/Polyline2dToSpeckleConverter.cs
@@ -19,30 +19,30 @@ public class Polyline2dToSpeckleConverter
: IToSpeckleTopLevelConverter,
ITypedConverter
{
+ private readonly ITypedConverter, SOG.Polyline> _doublesConverter;
private readonly ITypedConverter _arcConverter;
private readonly ITypedConverter _lineConverter;
- private readonly ITypedConverter _polylineConverter;
private readonly ITypedConverter _splineConverter;
private readonly ITypedConverter _vectorConverter;
- private readonly ITypedConverter _boxConverter;
+ private readonly IReferencePointConverter _referencePointConverter;
private readonly IConverterSettingsStore _settingsStore;
public Polyline2dToSpeckleConverter(
+ ITypedConverter, SOG.Polyline> doublesConverter,
ITypedConverter arcConverter,
ITypedConverter lineConverter,
- ITypedConverter polylineConverter,
ITypedConverter splineConverter,
ITypedConverter vectorConverter,
- ITypedConverter boxConverter,
+ IReferencePointConverter referencePointConverter,
IConverterSettingsStore settingsStore
)
{
+ _doublesConverter = doublesConverter;
_arcConverter = arcConverter;
_lineConverter = lineConverter;
- _polylineConverter = polylineConverter;
_splineConverter = splineConverter;
_vectorConverter = vectorConverter;
- _boxConverter = boxConverter;
+ _referencePointConverter = referencePointConverter;
_settingsStore = settingsStore;
}
@@ -85,11 +85,13 @@ public class Polyline2dToSpeckleConverter
for (int i = 0; i < vertices.Count; i++)
{
- ADB.Vertex2d vertex = vertices[i];
+ ADB.Vertex2d vertex = vertices[i]; // this is in OCS
// get vertex value in the Global Coordinate System (GCS).
- // NOTE: for some reason, the z value of the position for rotated polyline2ds doesn't seem to match the exploded segment endpoint values
- value.AddRange(vertex.Position.ToArray());
+ AG.Point3d vertexGCS = target.VertexPosition(vertex);
+ value.Add(vertexGCS.X);
+ value.Add(vertexGCS.Y);
+ value.Add(vertexGCS.Z);
// get the bulge and tangent
bulges.Add(vertex.Bulge);
@@ -160,31 +162,31 @@ public class Polyline2dToSpeckleConverter
if (isSpline)
{
SOG.Curve spline = _splineConverter.Convert(target.Spline);
- SOG.Polyline displayValue = segmentValues.ConvertToSpecklePolyline(_settingsStore.Current.SpeckleUnits);
- if (displayValue != null)
- {
- spline.displayValue = displayValue;
- }
-
+ spline.displayValue = _doublesConverter.Convert(segmentValues);
segments.Add(spline);
}
- SOG.Vector normal = _vectorConverter.Convert(target.Normal);
- SOG.Box bbox = _boxConverter.Convert(target.GeometricExtents);
+ SOG.Vector normal = _vectorConverter.Convert(target.Normal); // wcs
+
+ // get the elevation transformed by ucs
+ double elevation = _referencePointConverter.ConvertOCSElevationDoubleToExternalCoordinates(
+ target.Elevation,
+ target.Normal
+ );
+
SOG.Autocad.AutocadPolycurve polycurve =
new()
{
segments = segments,
- value = value,
+ value = _referencePointConverter.ConvertWCSDoublesToExternalCoordinates(value), // convert with reference point
bulges = bulges,
tangents = tangents,
normal = normal,
- elevation = target.Elevation,
+ elevation = elevation,
polyType = polyType,
closed = target.Closed,
length = target.Length,
area = target.Area,
- bbox = bbox,
units = _settingsStore.Current.SpeckleUnits
};
diff --git a/Converters/Autocad/Speckle.Converters.AutocadShared/ToSpeckle/Geometry/Polyline3dToSpeckleConverter.cs b/Converters/Autocad/Speckle.Converters.AutocadShared/ToSpeckle/Geometry/Polyline3dToSpeckleConverter.cs
index 76218142d..43a8e00ab 100644
--- a/Converters/Autocad/Speckle.Converters.AutocadShared/ToSpeckle/Geometry/Polyline3dToSpeckleConverter.cs
+++ b/Converters/Autocad/Speckle.Converters.AutocadShared/ToSpeckle/Geometry/Polyline3dToSpeckleConverter.cs
@@ -18,21 +18,21 @@ public class Polyline3dToSpeckleConverter
: IToSpeckleTopLevelConverter,
ITypedConverter
{
- private readonly ITypedConverter _pointConverter;
+ private readonly ITypedConverter, SOG.Polyline> _doublesConverter;
private readonly ITypedConverter _splineConverter;
- private readonly ITypedConverter _boxConverter;
+ private readonly IReferencePointConverter _referencePointConverter;
private readonly IConverterSettingsStore _settingsStore;
public Polyline3dToSpeckleConverter(
- ITypedConverter pointConverter,
+ ITypedConverter, SOG.Polyline> doublesConverter,
ITypedConverter splineConverter,
- ITypedConverter boxConverter,
+ IReferencePointConverter referencePointConverter,
IConverterSettingsStore settingsStore
)
{
- _pointConverter = pointConverter;
+ _doublesConverter = doublesConverter;
_splineConverter = splineConverter;
- _boxConverter = boxConverter;
+ _referencePointConverter = referencePointConverter;
_settingsStore = settingsStore;
}
@@ -56,7 +56,6 @@ public class Polyline3dToSpeckleConverter
}
// get all vertex data except control vertices
- List value = new();
List vertices = target
.GetSubEntities(
ADB.OpenMode.ForRead,
@@ -64,10 +63,13 @@ public class Polyline3dToSpeckleConverter
)
.Where(e => e.VertexType != ADB.Vertex3dType.FitVertex) // Do not collect fit vertex points, they are not used for creation
.ToList();
+ List value = new(vertices.Count * 3);
for (int i = 0; i < vertices.Count; i++)
{
// vertex value is in the Global Coordinate System (GCS).
- value.AddRange(vertices[i].Position.ToArray());
+ value.Add(vertices[i].Position.X);
+ value.Add(vertices[i].Position.Y);
+ value.Add(vertices[i].Position.Z);
}
List segments = new();
@@ -94,18 +96,15 @@ public class Polyline3dToSpeckleConverter
}
}
- SOG.Polyline displayValue = segmentValues.ConvertToSpecklePolyline(_settingsStore.Current.SpeckleUnits);
- if (displayValue != null)
- {
- spline.displayValue = displayValue;
- }
+ // set displayValue of spline
+ spline.displayValue = _doublesConverter.Convert(segmentValues);
segments.Add(spline);
}
// for simple polyline3ds just get the polyline segment from the value
else
{
- SOG.Polyline polyline = value.ConvertToSpecklePolyline(_settingsStore.Current.SpeckleUnits);
+ SOG.Polyline polyline = _doublesConverter.Convert(value);
if (target.Closed)
{
polyline.closed = true;
@@ -114,8 +113,6 @@ public class Polyline3dToSpeckleConverter
segments.Add(polyline);
}
- SOG.Box bbox = _boxConverter.Convert(target.GeometricExtents);
-
SOG.Autocad.AutocadPolycurve polycurve =
new()
{
@@ -123,11 +120,10 @@ public class Polyline3dToSpeckleConverter
bulges = null,
tangents = null,
normal = null,
- value = value,
+ value = _referencePointConverter.ConvertWCSDoublesToExternalCoordinates(value), // convert with reference point
polyType = polyType,
closed = target.Closed,
length = target.Length,
- bbox = bbox,
units = _settingsStore.Current.SpeckleUnits
};
diff --git a/Converters/Autocad/Speckle.Converters.AutocadShared/ToSpeckle/Geometry/PolylineToSpeckleConverter.cs b/Converters/Autocad/Speckle.Converters.AutocadShared/ToSpeckle/Geometry/PolylineToSpeckleConverter.cs
index da89a945b..6ad5630bd 100644
--- a/Converters/Autocad/Speckle.Converters.AutocadShared/ToSpeckle/Geometry/PolylineToSpeckleConverter.cs
+++ b/Converters/Autocad/Speckle.Converters.AutocadShared/ToSpeckle/Geometry/PolylineToSpeckleConverter.cs
@@ -17,22 +17,23 @@ public class PolylineToSpeckleConverter
{
private readonly ITypedConverter _lineConverter;
private readonly ITypedConverter _arcConverter;
+
private readonly ITypedConverter _vectorConverter;
- private readonly ITypedConverter _boxConverter;
+ private readonly IReferencePointConverter _referencePointConverter;
private readonly IConverterSettingsStore _settingsStore;
public PolylineToSpeckleConverter(
ITypedConverter lineConverter,
ITypedConverter arcConverter,
ITypedConverter vectorConverter,
- ITypedConverter boxConverter,
+ IReferencePointConverter referencePointConverter,
IConverterSettingsStore settingsStore
)
{
_lineConverter = lineConverter;
_arcConverter = arcConverter;
_vectorConverter = vectorConverter;
- _boxConverter = boxConverter;
+ _referencePointConverter = referencePointConverter;
_settingsStore = settingsStore;
}
@@ -45,9 +46,11 @@ public class PolylineToSpeckleConverter
List segments = new();
for (int i = 0; i < target.NumberOfVertices; i++)
{
- // get vertex value in the Object Coordinate System (OCS)
- AG.Point2d vertex = target.GetPoint2dAt(i);
- value.AddRange(vertex.ToArray());
+ // get vertex value in the World Coordinate System (WCS)
+ AG.Point3d vertex = target.GetPoint3dAt(i);
+ value.Add(vertex.X);
+ value.Add(vertex.Y);
+ value.Add(vertex.Z);
// get the bulge
bulges.Add(target.GetBulgeAt(i));
@@ -71,22 +74,26 @@ public class PolylineToSpeckleConverter
}
SOG.Vector normal = _vectorConverter.Convert(target.Normal);
- SOG.Box bbox = _boxConverter.Convert(target.GeometricExtents);
+
+ // get the elevation transformed by ucs
+ double elevation = _referencePointConverter.ConvertOCSElevationDoubleToExternalCoordinates(
+ target.Elevation,
+ target.Normal
+ );
SOG.Autocad.AutocadPolycurve polycurve =
new()
{
segments = segments,
- value = value,
+ value = _referencePointConverter.ConvertWCSDoublesToExternalCoordinates(value), // convert with reference point
bulges = bulges,
normal = normal,
tangents = null,
- elevation = target.Elevation,
+ elevation = elevation,
polyType = SOG.Autocad.AutocadPolyType.Light,
closed = target.Closed,
length = target.Length,
area = target.Area,
- bbox = bbox,
units = _settingsStore.Current.SpeckleUnits
};
diff --git a/Converters/Autocad/Speckle.Converters.AutocadShared/ToSpeckle/Geometry/SubDMeshToSpeckleConverter.cs b/Converters/Autocad/Speckle.Converters.AutocadShared/ToSpeckle/Geometry/SubDMeshToSpeckleConverter.cs
index 608c31243..8514f4c93 100644
--- a/Converters/Autocad/Speckle.Converters.AutocadShared/ToSpeckle/Geometry/SubDMeshToSpeckleConverter.cs
+++ b/Converters/Autocad/Speckle.Converters.AutocadShared/ToSpeckle/Geometry/SubDMeshToSpeckleConverter.cs
@@ -1,85 +1,20 @@
using Speckle.Converters.Common;
using Speckle.Converters.Common.Objects;
-using Speckle.Sdk;
using Speckle.Sdk.Models;
-namespace Speckle.Converters.Autocad.Geometry;
+namespace Speckle.Converters.Autocad.ToSpeckle.Geometry;
[NameAndRankValue(typeof(ADB.SubDMesh), NameAndRankValueAttribute.SPECKLE_DEFAULT_RANK)]
-public class DBSubDMeshToSpeckleConverter : IToSpeckleTopLevelConverter
+public class SubDMeshToSpeckleConverter : IToSpeckleTopLevelConverter
{
- private readonly IConverterSettingsStore _settingsStore;
+ private readonly ITypedConverter _subDMeshConverter;
- public DBSubDMeshToSpeckleConverter(IConverterSettingsStore settingsStore)
+ public SubDMeshToSpeckleConverter(ITypedConverter subDMeshConverter)
{
- _settingsStore = settingsStore;
+ _subDMeshConverter = subDMeshConverter;
}
- public Base Convert(object target) => RawConvert((ADB.SubDMesh)target);
+ public Base Convert(object target) => Convert((ADB.SubDMesh)target);
- public SOG.Mesh RawConvert(ADB.SubDMesh target)
- {
- //vertices
- var vertices = new List(target.Vertices.Count * 3);
- foreach (AG.Point3d vert in target.Vertices)
- {
- vertices.Add(vert.X);
- vertices.Add(vert.Y);
- vertices.Add(vert.Z);
- }
-
- // faces
- var faces = new List();
- int[] faceArr = target.FaceArray.ToArray(); // contains vertex indices
- int edgeCount = 0;
- for (int i = 0; i < faceArr.Length; i = i + edgeCount + 1)
- {
- List faceVertices = new();
- edgeCount = faceArr[i];
- for (int j = i + 1; j <= i + edgeCount; j++)
- {
- faceVertices.Add(faceArr[j]);
- }
-
- if (edgeCount == 4) // quad face
- {
- faces.AddRange(new List { 4, faceVertices[0], faceVertices[1], faceVertices[2], faceVertices[3] });
- }
- else // triangle face
- {
- faces.AddRange(new List { 3, faceVertices[0], faceVertices[1], faceVertices[2] });
- }
- }
-
- // colors
- var colors = target
- .VertexColorArray.Select(o =>
- System
- .Drawing.Color.FromArgb(
- System.Convert.ToInt32(o.Red),
- System.Convert.ToInt32(o.Green),
- System.Convert.ToInt32(o.Blue)
- )
- .ToArgb()
- )
- .ToList();
-
- SOG.Mesh speckleMesh =
- new()
- {
- vertices = vertices,
- faces = faces,
- colors = colors,
- units = _settingsStore.Current.SpeckleUnits,
- area = target.ComputeSurfaceArea()
- };
-
- try
- {
- speckleMesh.volume = target.ComputeVolume();
- }
- catch (Exception e) when (!e.IsFatal()) { } // for non-volumetric meshes
-
- return speckleMesh;
- }
+ public SOG.Mesh Convert(ADB.SubDMesh target) => _subDMeshConverter.Convert(target);
}
diff --git a/Converters/Autocad/Speckle.Converters.AutocadShared/ToSpeckle/Raw/BrepToSpeckleRawConverter.cs b/Converters/Autocad/Speckle.Converters.AutocadShared/ToSpeckle/Raw/BrepToSpeckleRawConverter.cs
index b97ed7727..fda77d849 100644
--- a/Converters/Autocad/Speckle.Converters.AutocadShared/ToSpeckle/Raw/BrepToSpeckleRawConverter.cs
+++ b/Converters/Autocad/Speckle.Converters.AutocadShared/ToSpeckle/Raw/BrepToSpeckleRawConverter.cs
@@ -7,10 +7,15 @@ namespace Speckle.Converters.Autocad.ToSpeckle.Raw;
public class BrepToSpeckleRawConverter : ITypedConverter
{
+ private readonly IReferencePointConverter _referencePointConverter;
private readonly IConverterSettingsStore _settingsStore;
- public BrepToSpeckleRawConverter(IConverterSettingsStore settingsStore)
+ public BrepToSpeckleRawConverter(
+ IReferencePointConverter referencePointConverter,
+ IConverterSettingsStore settingsStore
+ )
{
+ _referencePointConverter = referencePointConverter;
_settingsStore = settingsStore;
}
@@ -65,7 +70,7 @@ public class BrepToSpeckleRawConverter : ITypedConverter
new()
{
faces = faces,
- vertices = vertices,
+ vertices = _referencePointConverter.ConvertWCSDoublesToExternalCoordinates(vertices), // transform by reference point
units = _settingsStore.Current.SpeckleUnits,
area = target.GetSurfaceArea()
};
diff --git a/Converters/Autocad/Speckle.Converters.AutocadShared/ToSpeckle/Raw/CircularArc2dToSpeckleRawConverter.cs b/Converters/Autocad/Speckle.Converters.AutocadShared/ToSpeckle/Raw/CircularArc2dToSpeckleRawConverter.cs
index 5b16e80f6..39c474736 100644
--- a/Converters/Autocad/Speckle.Converters.AutocadShared/ToSpeckle/Raw/CircularArc2dToSpeckleRawConverter.cs
+++ b/Converters/Autocad/Speckle.Converters.AutocadShared/ToSpeckle/Raw/CircularArc2dToSpeckleRawConverter.cs
@@ -5,14 +5,17 @@ namespace Speckle.Converters.Autocad.ToSpeckle.Raw;
public class CircularArc2dToSpeckleRawConverter : ITypedConverter
{
+ private readonly ITypedConverter _pointConverter;
private readonly ITypedConverter _planeConverter;
private readonly IConverterSettingsStore _settingsStore;
public CircularArc2dToSpeckleRawConverter(
+ ITypedConverter pointConverter,
ITypedConverter planeConverter,
IConverterSettingsStore settingsStore
)
{
+ _pointConverter = pointConverter;
_planeConverter = planeConverter;
_settingsStore = settingsStore;
}
@@ -35,27 +38,9 @@ public class CircularArc2dToSpeckleRawConverter : ITypedConverter
{
private readonly ITypedConverter _pointConverter;
private readonly ITypedConverter _planeConverter;
- private readonly ITypedConverter _boxConverter;
private readonly IConverterSettingsStore _settingsStore;
public DBArcToSpeckleRawConverter(
ITypedConverter pointConverter,
ITypedConverter planeConverter,
- ITypedConverter boxConverter,
IConverterSettingsStore settingsStore
)
{
_pointConverter = pointConverter;
_planeConverter = planeConverter;
- _boxConverter = boxConverter;
_settingsStore = settingsStore;
}
@@ -33,7 +30,6 @@ public class DBArcToSpeckleRawConverter : ITypedConverter
SOG.Point end = _pointConverter.Convert(target.EndPoint);
SOG.Point mid = _pointConverter.Convert(target.GetPointAtDist(target.Length / 2.0));
SOP.Interval domain = new() { start = target.StartParam, end = target.EndParam };
- SOG.Box bbox = _boxConverter.Convert(target.GeometricExtents);
SOG.Arc arc =
new()
@@ -43,7 +39,6 @@ public class DBArcToSpeckleRawConverter : ITypedConverter
endPoint = end,
midPoint = mid,
domain = domain,
- bbox = bbox,
units = _settingsStore.Current.SpeckleUnits
};
diff --git a/Converters/Autocad/Speckle.Converters.AutocadShared/ToSpeckle/Raw/DBCircleToSpeckleRawConverter.cs b/Converters/Autocad/Speckle.Converters.AutocadShared/ToSpeckle/Raw/DBCircleToSpeckleRawConverter.cs
index 7d63f6ee8..b84bd4e9b 100644
--- a/Converters/Autocad/Speckle.Converters.AutocadShared/ToSpeckle/Raw/DBCircleToSpeckleRawConverter.cs
+++ b/Converters/Autocad/Speckle.Converters.AutocadShared/ToSpeckle/Raw/DBCircleToSpeckleRawConverter.cs
@@ -7,17 +7,14 @@ namespace Speckle.Converters.Autocad.ToSpeckle.Raw;
public class DBCircleToSpeckleRawConverter : ITypedConverter
{
private readonly ITypedConverter _planeConverter;
- private readonly ITypedConverter _boxConverter;
private readonly IConverterSettingsStore _settingsStore;
public DBCircleToSpeckleRawConverter(
ITypedConverter planeConverter,
- ITypedConverter boxConverter,
IConverterSettingsStore settingsStore
)
{
_planeConverter = planeConverter;
- _boxConverter = boxConverter;
_settingsStore = settingsStore;
}
@@ -26,14 +23,12 @@ public class DBCircleToSpeckleRawConverter : ITypedConverter _circleConverter;
private readonly ITypedConverter _ellipseConverter;
private readonly ITypedConverter _splineConverter;
- private readonly IConverterSettingsStore _settingsStore;
public DBCurveToSpeckleRawConverter(
ITypedConverter lineConverter,
@@ -25,8 +23,7 @@ public class DBCurveToSpeckleRawConverter : ITypedConverter arcConverter,
ITypedConverter circleConverter,
ITypedConverter ellipseConverter,
- ITypedConverter splineConverter,
- IConverterSettingsStore settingsStore
+ ITypedConverter splineConverter
)
{
_lineConverter = lineConverter;
@@ -37,7 +34,6 @@ public class DBCurveToSpeckleRawConverter : ITypedConverter
diff --git a/Converters/Autocad/Speckle.Converters.AutocadShared/ToSpeckle/Raw/DBEllipseToSpeckleRawConverter.cs b/Converters/Autocad/Speckle.Converters.AutocadShared/ToSpeckle/Raw/DBEllipseToSpeckleRawConverter.cs
index 39acc0a66..9dc8ac5bd 100644
--- a/Converters/Autocad/Speckle.Converters.AutocadShared/ToSpeckle/Raw/DBEllipseToSpeckleRawConverter.cs
+++ b/Converters/Autocad/Speckle.Converters.AutocadShared/ToSpeckle/Raw/DBEllipseToSpeckleRawConverter.cs
@@ -6,18 +6,18 @@ namespace Speckle.Converters.Autocad.ToSpeckle.Raw;
public class DBEllipseToSpeckleRawConverter : ITypedConverter
{
- private readonly ITypedConverter _planeConverter;
- private readonly ITypedConverter _boxConverter;
+ private readonly ITypedConverter _pointConverter;
+ private readonly ITypedConverter _vectorConverter;
private readonly IConverterSettingsStore _settingsStore;
public DBEllipseToSpeckleRawConverter(
- ITypedConverter planeConverter,
- ITypedConverter boxConverter,
+ ITypedConverter pointConverter,
+ ITypedConverter vectorConverter,
IConverterSettingsStore settingsStore
)
{
- _planeConverter = planeConverter;
- _boxConverter = boxConverter;
+ _pointConverter = pointConverter;
+ _vectorConverter = vectorConverter;
_settingsStore = settingsStore;
}
@@ -25,8 +25,15 @@ public class DBEllipseToSpeckleRawConverter : ITypedConverter
{
private readonly ITypedConverter _pointConverter;
- private readonly ITypedConverter _boxConverter;
private readonly IConverterSettingsStore _settingsStore;
public DBLineToSpeckleRawConverter(
ITypedConverter pointConverter,
- ITypedConverter boxConverter,
IConverterSettingsStore settingsStore
)
{
_pointConverter = pointConverter;
- _boxConverter = boxConverter;
_settingsStore = settingsStore;
}
@@ -28,8 +25,7 @@ public class DBLineToSpeckleRawConverter : ITypedConverter
{
start = _pointConverter.Convert(target.StartPoint),
end = _pointConverter.Convert(target.EndPoint),
- units = _settingsStore.Current.SpeckleUnits,
domain = new SOP.Interval { start = 0, end = target.Length },
- bbox = _boxConverter.Convert(target.GeometricExtents)
+ units = _settingsStore.Current.SpeckleUnits
};
}
diff --git a/Converters/Autocad/Speckle.Converters.AutocadShared/ToSpeckle/Raw/DBSplineToSpeckleRawConverter.cs b/Converters/Autocad/Speckle.Converters.AutocadShared/ToSpeckle/Raw/DBSplineToSpeckleRawConverter.cs
index 608da74b8..41d5bb5dc 100644
--- a/Converters/Autocad/Speckle.Converters.AutocadShared/ToSpeckle/Raw/DBSplineToSpeckleRawConverter.cs
+++ b/Converters/Autocad/Speckle.Converters.AutocadShared/ToSpeckle/Raw/DBSplineToSpeckleRawConverter.cs
@@ -8,18 +8,21 @@ namespace Speckle.Converters.Autocad.ToSpeckle.Raw;
public class DBSplineToSpeckleRawConverter : ITypedConverter
{
+ private readonly ITypedConverter, SOG.Polyline> _doublesConverter;
private readonly ITypedConverter _intervalConverter;
- private readonly ITypedConverter _boxConverter;
+ private readonly IReferencePointConverter _referencePointConverter;
private readonly IConverterSettingsStore _settingsStore;
public DBSplineToSpeckleRawConverter(
+ ITypedConverter, SOG.Polyline> doublesConverter,
ITypedConverter intervalConverter,
- ITypedConverter boxConverter,
+ IReferencePointConverter referencePointConverter,
IConverterSettingsStore settingsStore
)
{
+ _doublesConverter = doublesConverter;
_intervalConverter = intervalConverter;
- _boxConverter = boxConverter;
+ _referencePointConverter = referencePointConverter;
_settingsStore = settingsStore;
}
@@ -44,11 +47,11 @@ public class DBSplineToSpeckleRawConverter : ITypedConverter points = new();
foreach (Point3d point in data.GetControlPoints().OfType())
{
- points.Add(point);
+ points.Add(_referencePointConverter.ConvertWCSPointToExternalCoordinates(point));
}
// NOTE: for closed periodic splines, autocad does not track last #degree points.
@@ -108,7 +111,6 @@ public class DBSplineToSpeckleRawConverter : ITypedConverter
+{
+ private readonly IReferencePointConverter _referencePointConverter;
+ private readonly IConverterSettingsStore _settingsStore;
+
+ public DBSubDMeshToSpeckleRawConverter(
+ IReferencePointConverter referencePointConverter,
+ IConverterSettingsStore settingsStore
+ )
+ {
+ _referencePointConverter = referencePointConverter;
+ _settingsStore = settingsStore;
+ }
+
+ public SOG.Mesh Convert(ADB.SubDMesh target)
+ {
+ // vertices
+ List vertices = new(target.Vertices.Count * 3);
+ foreach (AG.Point3d vert in target.Vertices)
+ {
+ vertices.Add(vert.X);
+ vertices.Add(vert.Y);
+ vertices.Add(vert.Z);
+ }
+
+ // faces
+ List faces = new();
+ int[] faceArr = target.FaceArray.ToArray(); // contains vertex indices
+ int edgeCount = 0;
+ for (int i = 0; i < faceArr.Length; i = i + edgeCount + 1)
+ {
+ List faceVertices = new();
+ edgeCount = faceArr[i];
+ for (int j = i + 1; j <= i + edgeCount; j++)
+ {
+ faceVertices.Add(faceArr[j]);
+ }
+
+ if (edgeCount == 4) // quad face
+ {
+ faces.AddRange(new List { 4, faceVertices[0], faceVertices[1], faceVertices[2], faceVertices[3] });
+ }
+ else // triangle face
+ {
+ faces.AddRange(new List { 3, faceVertices[0], faceVertices[1], faceVertices[2] });
+ }
+ }
+
+ // colors
+ var colors = target
+ .VertexColorArray.Select(o =>
+ System
+ .Drawing.Color.FromArgb(
+ System.Convert.ToInt32(o.Red),
+ System.Convert.ToInt32(o.Green),
+ System.Convert.ToInt32(o.Blue)
+ )
+ .ToArgb()
+ )
+ .ToList();
+
+ SOG.Mesh speckleMesh =
+ new()
+ {
+ vertices = _referencePointConverter.ConvertWCSDoublesToExternalCoordinates(vertices), // transform with reference point
+ faces = faces,
+ colors = colors,
+ units = _settingsStore.Current.SpeckleUnits,
+ area = target.ComputeSurfaceArea()
+ };
+
+ try
+ {
+ speckleMesh.volume = target.ComputeVolume();
+ }
+ catch (Exception e) when (!e.IsFatal()) { } // for non-volumetric meshes
+
+ return speckleMesh;
+ }
+}
diff --git a/Converters/Autocad/Speckle.Converters.AutocadShared/ToSpeckle/Raw/DBTextToSpeckleRawConverter.cs b/Converters/Autocad/Speckle.Converters.AutocadShared/ToSpeckle/Raw/DBTextToSpeckleRawConverter.cs
index e245808f3..f14fb7e41 100644
--- a/Converters/Autocad/Speckle.Converters.AutocadShared/ToSpeckle/Raw/DBTextToSpeckleRawConverter.cs
+++ b/Converters/Autocad/Speckle.Converters.AutocadShared/ToSpeckle/Raw/DBTextToSpeckleRawConverter.cs
@@ -1,3 +1,4 @@
+using Speckle.Converters.Autocad.Helpers;
using Speckle.Converters.Common;
using Speckle.Converters.Common.Objects;
using Speckle.Objects.Annotation;
@@ -7,17 +8,17 @@ namespace Speckle.Converters.Autocad.ToSpeckle.Raw;
public class DBTextToSpeckleRawConverter : ITypedConverter
{
private readonly ITypedConverter _pointConverter;
- private readonly ITypedConverter _planeConverter;
+ private readonly ITypedConverter _vectorConverter;
private readonly IConverterSettingsStore _settingsStore;
public DBTextToSpeckleRawConverter(
ITypedConverter pointConverter,
- ITypedConverter planeConverter,
+ ITypedConverter vectorConverter,
IConverterSettingsStore settingsStore
)
{
_pointConverter = pointConverter;
- _planeConverter = planeConverter;
+ _vectorConverter = vectorConverter;
_settingsStore = settingsStore;
}
@@ -41,15 +42,24 @@ public class DBTextToSpeckleRawConverter : ITypedConverter
units = _settingsStore.Current.SpeckleUnits
};
+ // For DBText, the following properties are stored in:
+ // - Position: WCS
+ // - Normal: WCS
+ // - Rotation: OCS -> WCS https://help.autodesk.com/view/OARX/2020/ENU/?guid=OARX-ManagedRefGuide-Autodesk_AutoCAD_DatabaseServices_DBText_Rotation
private SOG.Plane GetTextPlane(ADB.DBText target)
{
- AG.Plane plane = new(target.Position, target.Normal);
+ // Rotation prop is in OCS: calculate the x and y axis based in WCS
+ AG.Matrix3d transform = TransformHelper.GetTransformFromOCSToWCS(target.Normal).Inverse();
+ AG.Vector3d xDir = AG.Vector3d.XAxis.RotateBy(target.Rotation, target.Normal).TransformBy(transform);
+ AG.Vector3d yDir = AG.Vector3d.YAxis.RotateBy(target.Rotation, target.Normal).TransformBy(transform);
- if (target.Rotation != 0)
+ return new()
{
- plane.RotateBy(target.Rotation, target.Normal, target.Position);
- }
-
- return _planeConverter.Convert(plane);
+ origin = _pointConverter.Convert(target.Position),
+ normal = _vectorConverter.Convert(target.Normal),
+ xdir = _vectorConverter.Convert(xDir),
+ ydir = _vectorConverter.Convert(yDir),
+ units = _settingsStore.Current.SpeckleUnits,
+ };
}
}
diff --git a/Converters/Autocad/Speckle.Converters.AutocadShared/ToSpeckle/Raw/DoublesToSpecklePolylineRawConverter.cs b/Converters/Autocad/Speckle.Converters.AutocadShared/ToSpeckle/Raw/DoublesToSpecklePolylineRawConverter.cs
new file mode 100644
index 000000000..c041ff39d
--- /dev/null
+++ b/Converters/Autocad/Speckle.Converters.AutocadShared/ToSpeckle/Raw/DoublesToSpecklePolylineRawConverter.cs
@@ -0,0 +1,32 @@
+using Speckle.Converters.Common;
+using Speckle.Converters.Common.Objects;
+
+namespace Speckle.Converters.Autocad.ToSpeckle.Raw;
+
+public class DoublesToSpeckleRawConverter : ITypedConverter, SOG.Polyline>
+{
+ private readonly IReferencePointConverter _referencePointConverter;
+ private readonly IConverterSettingsStore _settingsStore;
+
+ public DoublesToSpeckleRawConverter(
+ IConverterSettingsStore settingsStore,
+ IReferencePointConverter referencePointConverter
+ )
+ {
+ _settingsStore = settingsStore;
+ _referencePointConverter = referencePointConverter;
+ }
+
+ public SOG.Polyline Convert(List target)
+ {
+ // throw if list is malformed
+ if (target.Count % 3 != 0)
+ {
+ throw new ArgumentException("Point list of xyz values is malformed", nameof(target));
+ }
+
+ List value = _referencePointConverter.ConvertWCSDoublesToExternalCoordinates(target);
+
+ return new() { value = value, units = _settingsStore.Current.SpeckleUnits };
+ }
+}
diff --git a/Converters/Autocad/Speckle.Converters.AutocadShared/ToSpeckle/Raw/MTextToSpeckleRawConverter.cs b/Converters/Autocad/Speckle.Converters.AutocadShared/ToSpeckle/Raw/MTextToSpeckleRawConverter.cs
index d4a55addc..e163f39c0 100644
--- a/Converters/Autocad/Speckle.Converters.AutocadShared/ToSpeckle/Raw/MTextToSpeckleRawConverter.cs
+++ b/Converters/Autocad/Speckle.Converters.AutocadShared/ToSpeckle/Raw/MTextToSpeckleRawConverter.cs
@@ -6,17 +6,17 @@ namespace Speckle.Converters.Autocad.ToSpeckle.Raw;
public class MTextToSpeckleRawConverter : ITypedConverter
{
private readonly ITypedConverter _pointConverter;
- private readonly ITypedConverter _planeConverter;
+ private readonly ITypedConverter _vectorConverter;
private readonly IConverterSettingsStore _settingsStore;
public MTextToSpeckleRawConverter(
ITypedConverter pointConverter,
- ITypedConverter planeConverter,
+ ITypedConverter vectorConverter,
IConverterSettingsStore settingsStore
)
{
_pointConverter = pointConverter;
- _planeConverter = planeConverter;
+ _vectorConverter = vectorConverter;
_settingsStore = settingsStore;
}
@@ -38,16 +38,28 @@ public class MTextToSpeckleRawConverter : ITypedConverter
units = _settingsStore.Current.SpeckleUnits
};
+ // For MText, the following properties are stored in:
+ // - Position: WCS
+ // - Normal: WCS??
+ // - Rotation: OCS -> UCS?? https://help.autodesk.com/view/OARX/2020/ENU/?guid=OARX-ManagedRefGuide-Autodesk_AutoCAD_DatabaseServices_MText_Rotation
+ // "Accesses the angle between the X axis of the OCS for the normal vector of the current AutoCAD editor's UCS
+ // and the projection of the MText object's direction vector onto the plane of the AutoCAD editor's current UCS."
+ // - Direction: WCS
+ // "Note that the direction vector need not be orthogonal to the normal vector." <- do not use FML
private SOG.Plane GetTextPlane(ADB.MText target)
{
- AG.Plane plane = new(target.Location, target.Normal);
+ // Rotation prop is in UCS already: do NOT use vector converter or it will transform again!
+ AG.Vector3d xDir = AG.Vector3d.XAxis.RotateBy(target.Rotation, target.Normal);
+ AG.Vector3d yDir = AG.Vector3d.YAxis.RotateBy(target.Rotation, target.Normal);
- if (target.Rotation != 0)
+ return new()
{
- plane.RotateBy(target.Rotation, target.Normal, target.Location);
- }
-
- return _planeConverter.Convert(plane);
+ origin = _pointConverter.Convert(target.Location),
+ normal = _vectorConverter.Convert(target.Normal),
+ xdir = new(xDir.X, xDir.Y, xDir.Z, _settingsStore.Current.SpeckleUnits),
+ ydir = new(yDir.X, yDir.Y, yDir.Z, _settingsStore.Current.SpeckleUnits),
+ units = _settingsStore.Current.SpeckleUnits,
+ };
}
///
diff --git a/Converters/Autocad/Speckle.Converters.AutocadShared/ToSpeckle/Raw/PlaneToSpeckleRawConverter.cs b/Converters/Autocad/Speckle.Converters.AutocadShared/ToSpeckle/Raw/PlaneToSpeckleRawConverter.cs
index 6a24731ed..1b1377d1e 100644
--- a/Converters/Autocad/Speckle.Converters.AutocadShared/ToSpeckle/Raw/PlaneToSpeckleRawConverter.cs
+++ b/Converters/Autocad/Speckle.Converters.AutocadShared/ToSpeckle/Raw/PlaneToSpeckleRawConverter.cs
@@ -23,13 +23,16 @@ public class PlaneToSpeckleRawConverter : ITypedConverter
public Base Convert(object target) => Convert((AG.Plane)target);
- public SOG.Plane Convert(AG.Plane target) =>
- new()
+ public SOG.Plane Convert(AG.Plane target)
+ {
+ AG.CoordinateSystem3d cs = target.GetCoordinateSystem(); // TODO: validate if this returns the coordinate system in GCS or already transformed
+ return new()
{
origin = _pointConverter.Convert(target.PointOnPlane),
normal = _vectorConverter.Convert(target.Normal),
- xdir = _vectorConverter.Convert(target.GetCoordinateSystem().Xaxis),
- ydir = _vectorConverter.Convert(target.GetCoordinateSystem().Yaxis),
+ xdir = _vectorConverter.Convert(cs.Xaxis),
+ ydir = _vectorConverter.Convert(cs.Yaxis),
units = _settingsStore.Current.SpeckleUnits,
};
+ }
}
diff --git a/Converters/Autocad/Speckle.Converters.AutocadShared/ToSpeckle/Raw/Point2dToSpeckleRawConverter.cs b/Converters/Autocad/Speckle.Converters.AutocadShared/ToSpeckle/Raw/Point2dToSpeckleRawConverter.cs
new file mode 100644
index 000000000..dd450d2b2
--- /dev/null
+++ b/Converters/Autocad/Speckle.Converters.AutocadShared/ToSpeckle/Raw/Point2dToSpeckleRawConverter.cs
@@ -0,0 +1,26 @@
+using Speckle.Converters.Common;
+using Speckle.Converters.Common.Objects;
+
+namespace Speckle.Converters.Autocad.ToSpeckle.Raw;
+
+public class Point2dToSpeckleRawConverter : ITypedConverter
+{
+ private readonly IConverterSettingsStore _settingsStore;
+ private readonly IReferencePointConverter _referencePointConverter;
+
+ public Point2dToSpeckleRawConverter(
+ IConverterSettingsStore settingsStore,
+ IReferencePointConverter referencePointConverter
+ )
+ {
+ _settingsStore = settingsStore;
+ _referencePointConverter = referencePointConverter;
+ }
+
+ public SOG.Point Convert(AG.Point2d target)
+ {
+ var extPt = _referencePointConverter.ConvertWCSDoublesToExternalCoordinates(new(3) { target.X, target.Y, 0 });
+
+ return new(extPt[0], extPt[1], extPt[2], _settingsStore.Current.SpeckleUnits);
+ }
+}
diff --git a/Converters/Autocad/Speckle.Converters.AutocadShared/ToSpeckle/Raw/Point3dToSpeckleRawConverter.cs b/Converters/Autocad/Speckle.Converters.AutocadShared/ToSpeckle/Raw/Point3dToSpeckleRawConverter.cs
new file mode 100644
index 000000000..10118ea7e
--- /dev/null
+++ b/Converters/Autocad/Speckle.Converters.AutocadShared/ToSpeckle/Raw/Point3dToSpeckleRawConverter.cs
@@ -0,0 +1,25 @@
+using Speckle.Converters.Common;
+using Speckle.Converters.Common.Objects;
+
+namespace Speckle.Converters.Autocad.ToSpeckle.Raw;
+
+public class Point3dToSpeckleRawConverter : ITypedConverter
+{
+ private readonly IConverterSettingsStore _settingsStore;
+ private readonly IReferencePointConverter _referencePointConverter;
+
+ public Point3dToSpeckleRawConverter(
+ IConverterSettingsStore settingsStore,
+ IReferencePointConverter referencePointConverter
+ )
+ {
+ _settingsStore = settingsStore;
+ _referencePointConverter = referencePointConverter;
+ }
+
+ public SOG.Point Convert(AG.Point3d target)
+ {
+ AG.Point3d extPt = _referencePointConverter.ConvertWCSPointToExternalCoordinates(target);
+ return new(extPt.X, extPt.Y, extPt.Z, _settingsStore.Current.SpeckleUnits);
+ }
+}
diff --git a/Converters/Autocad/Speckle.Converters.AutocadShared/ToSpeckle/Raw/PointToSpeckleRawConverter.cs b/Converters/Autocad/Speckle.Converters.AutocadShared/ToSpeckle/Raw/PointToSpeckleRawConverter.cs
deleted file mode 100644
index a1e71fc87..000000000
--- a/Converters/Autocad/Speckle.Converters.AutocadShared/ToSpeckle/Raw/PointToSpeckleRawConverter.cs
+++ /dev/null
@@ -1,16 +0,0 @@
-using Speckle.Converters.Common;
-using Speckle.Converters.Common.Objects;
-
-namespace Speckle.Converters.Autocad.ToSpeckle.Raw;
-
-public class PointToSpeckleRawConverter : ITypedConverter
-{
- private readonly IConverterSettingsStore _settingsStore;
-
- public PointToSpeckleRawConverter(IConverterSettingsStore settingsStore)
- {
- _settingsStore = settingsStore;
- }
-
- public SOG.Point Convert(AG.Point3d target) => new(target.X, target.Y, target.Z, _settingsStore.Current.SpeckleUnits);
-}
diff --git a/Converters/Autocad/Speckle.Converters.AutocadShared/ToSpeckle/Raw/Vector3dToSpeckleRawConverter.cs b/Converters/Autocad/Speckle.Converters.AutocadShared/ToSpeckle/Raw/Vector3dToSpeckleRawConverter.cs
new file mode 100644
index 000000000..817bcbcea
--- /dev/null
+++ b/Converters/Autocad/Speckle.Converters.AutocadShared/ToSpeckle/Raw/Vector3dToSpeckleRawConverter.cs
@@ -0,0 +1,25 @@
+using Speckle.Converters.Common;
+using Speckle.Converters.Common.Objects;
+
+namespace Speckle.Converters.Autocad.ToSpeckle.Raw;
+
+public class Vector3dToSpeckleRawConverter : ITypedConverter
+{
+ private readonly IConverterSettingsStore _settingsStore;
+ private readonly IReferencePointConverter _referencePointConverter;
+
+ public Vector3dToSpeckleRawConverter(
+ IConverterSettingsStore settingsStore,
+ IReferencePointConverter referencePointConverter
+ )
+ {
+ _settingsStore = settingsStore;
+ _referencePointConverter = referencePointConverter;
+ }
+
+ public SOG.Vector Convert(AG.Vector3d target)
+ {
+ AG.Vector3d extVector = _referencePointConverter.ConvertWCSVectorToExternalCoordinates(target);
+ return new(extVector.X, extVector.Y, extVector.Z, _settingsStore.Current.SpeckleUnits);
+ }
+}
diff --git a/Converters/Autocad/Speckle.Converters.AutocadShared/ToSpeckle/Raw/VectorToSpeckleRawConverter.cs b/Converters/Autocad/Speckle.Converters.AutocadShared/ToSpeckle/Raw/VectorToSpeckleRawConverter.cs
deleted file mode 100644
index 6c9dddf68..000000000
--- a/Converters/Autocad/Speckle.Converters.AutocadShared/ToSpeckle/Raw/VectorToSpeckleRawConverter.cs
+++ /dev/null
@@ -1,17 +0,0 @@
-using Speckle.Converters.Common;
-using Speckle.Converters.Common.Objects;
-
-namespace Speckle.Converters.Autocad.ToSpeckle.Raw;
-
-public class VectorToSpeckleRawConverter : ITypedConverter
-{
- private readonly IConverterSettingsStore _settingsStore;
-
- public VectorToSpeckleRawConverter(IConverterSettingsStore settingsStore)
- {
- _settingsStore = settingsStore;
- }
-
- public SOG.Vector Convert(AG.Vector3d target) =>
- new(target.X, target.Y, target.Z, _settingsStore.Current.SpeckleUnits);
-}
diff --git a/Converters/Civil3d/Speckle.Converters.Civil3dShared/ServiceRegistration.cs b/Converters/Civil3d/Speckle.Converters.Civil3dShared/ServiceRegistration.cs
index ef33264a0..bfcd4cfa1 100644
--- a/Converters/Civil3d/Speckle.Converters.Civil3dShared/ServiceRegistration.cs
+++ b/Converters/Civil3d/Speckle.Converters.Civil3dShared/ServiceRegistration.cs
@@ -34,6 +34,7 @@ public static class ServiceRegistration
IConverterSettingsStore,
ConverterSettingsStore
>();
+ serviceCollection.AddScoped();
// add other classes
serviceCollection.AddScoped(); // for civil
diff --git a/Converters/Civil3d/Speckle.Converters.Civil3dShared/ToSpeckle/Raw/AlignmentSubentityArcToSpeckleRawConverter.cs b/Converters/Civil3d/Speckle.Converters.Civil3dShared/ToSpeckle/Raw/AlignmentSubentityArcToSpeckleRawConverter.cs
index 1bb7a4a4e..ca00e4bc4 100644
--- a/Converters/Civil3d/Speckle.Converters.Civil3dShared/ToSpeckle/Raw/AlignmentSubentityArcToSpeckleRawConverter.cs
+++ b/Converters/Civil3d/Speckle.Converters.Civil3dShared/ToSpeckle/Raw/AlignmentSubentityArcToSpeckleRawConverter.cs
@@ -6,14 +6,17 @@ namespace Speckle.Converters.Civil3dShared.ToSpeckle.Raw;
public class AlignmentSubentityArcToSpeckleRawConverter : ITypedConverter
{
+ private readonly ITypedConverter _pointConverter;
private readonly ITypedConverter _planeConverter;
private readonly IConverterSettingsStore