From 8f5b2d0b55c88495282c692950bf952ea750f5dd Mon Sep 17 00:00:00 2001 From: Matteo Cominetti Date: Fri, 31 Mar 2023 09:48:35 +0100 Subject: [PATCH] Linked models & shared coords improvements (#2368) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * wip: attempting to improve the support for linked models and shared coordinates * fixes linked doc transforms * chore: 💅 --------- Co-authored-by: Claire Kuang --- ConnectorRevit/ConnectorRevit.sln | 32 +++--- .../ConverterRevitShared/ConversionUtils.cs | 101 ++++++++---------- 2 files changed, 64 insertions(+), 69 deletions(-) diff --git a/ConnectorRevit/ConnectorRevit.sln b/ConnectorRevit/ConnectorRevit.sln index b755788343..be34230965 100644 --- a/ConnectorRevit/ConnectorRevit.sln +++ b/ConnectorRevit/ConnectorRevit.sln @@ -44,18 +44,6 @@ EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConverterDxf", "..\Objects\Converters\ConverterDxf\ConverterDxf\ConverterDxf.csproj", "{64A2BFC9-8711-4C9D-A1B4-BEE678C8E640}" EndProject Global - GlobalSection(SharedMSBuildProjectFiles) = preSolution - ..\Objects\Converters\ConverterRevit\ConverterRevitShared\ConverterRevitShared.projitems*{236cff40-7dda-4cc5-84a9-b1df6f0985ef}*SharedItemsImports = 5 - ..\Objects\Converters\ConverterRevit\ConverterRevitShared\ConverterRevitShared.projitems*{240ead7e-ef10-482a-b299-3b85b64b032f}*SharedItemsImports = 5 - ConnectorRevit\ConnectorRevit.projitems*{27a79aca-7ea8-4406-8bb8-216578cc3ab7}*SharedItemsImports = 4 - ..\Objects\Converters\ConverterRevit\ConverterRevitShared\ConverterRevitShared.projitems*{2dcd648d-dca5-4d2a-8b14-ad2cb85d24b0}*SharedItemsImports = 13 - ConnectorRevit\ConnectorRevit.projitems*{586a5a37-93f6-427e-8df8-c10db4d6822a}*SharedItemsImports = 4 - ConnectorRevit\ConnectorRevit.projitems*{5fd0d810-03e9-4fd2-93e4-b1b51e5d82c5}*SharedItemsImports = 13 - ConnectorRevit\ConnectorRevit.projitems*{8a53b084-20d8-48f6-9591-9d53cfa74130}*SharedItemsImports = 4 - ..\Objects\Converters\ConverterRevit\ConverterRevitShared\ConverterRevitShared.projitems*{c74e4c61-ca68-47f9-825e-91b7a5c4546d}*SharedItemsImports = 5 - ..\Objects\Converters\ConverterRevit\ConverterRevitShared\ConverterRevitShared.projitems*{cfbd9a83-5aa2-4849-8735-28d4f73f4f56}*SharedItemsImports = 5 - ConnectorRevit\ConnectorRevit.projitems*{dfdfdbb8-018b-4dcb-a012-54227abf53a7}*SharedItemsImports = 4 - EndGlobalSection GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU Debug|x64 = Debug|x64 @@ -79,6 +67,10 @@ Global {BE852BE3-37B8-4B62-AC2C-0872C41A2542}.Release|Any CPU.Build.0 = Release|Any CPU {BE852BE3-37B8-4B62-AC2C-0872C41A2542}.Release|x64.ActiveCfg = Release|Any CPU {BE852BE3-37B8-4B62-AC2C-0872C41A2542}.Release|x64.Build.0 = Release|Any CPU + {2DCD648D-DCA5-4D2A-8B14-AD2CB85D24B0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2DCD648D-DCA5-4D2A-8B14-AD2CB85D24B0}.Debug|x64.ActiveCfg = Debug|Any CPU + {2DCD648D-DCA5-4D2A-8B14-AD2CB85D24B0}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2DCD648D-DCA5-4D2A-8B14-AD2CB85D24B0}.Release|x64.ActiveCfg = Release|Any CPU {240EAD7E-EF10-482A-B299-3B85B64B032F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {240EAD7E-EF10-482A-B299-3B85B64B032F}.Debug|Any CPU.Build.0 = Debug|Any CPU {240EAD7E-EF10-482A-B299-3B85B64B032F}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -95,6 +87,10 @@ Global {CFBD9A83-5AA2-4849-8735-28D4F73F4F56}.Release|Any CPU.Build.0 = Release|Any CPU {CFBD9A83-5AA2-4849-8735-28D4F73F4F56}.Release|x64.ActiveCfg = Release|Any CPU {CFBD9A83-5AA2-4849-8735-28D4F73F4F56}.Release|x64.Build.0 = Release|Any CPU + {5FD0D810-03E9-4FD2-93E4-B1B51E5D82C5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {5FD0D810-03E9-4FD2-93E4-B1B51E5D82C5}.Debug|x64.ActiveCfg = Debug|Any CPU + {5FD0D810-03E9-4FD2-93E4-B1B51E5D82C5}.Release|Any CPU.ActiveCfg = Release|Any CPU + {5FD0D810-03E9-4FD2-93E4-B1B51E5D82C5}.Release|x64.ActiveCfg = Release|Any CPU {27A79ACA-7EA8-4406-8BB8-216578CC3AB7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {27A79ACA-7EA8-4406-8BB8-216578CC3AB7}.Debug|Any CPU.Build.0 = Debug|Any CPU {27A79ACA-7EA8-4406-8BB8-216578CC3AB7}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -208,4 +204,16 @@ Global GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {650BE642-C7CC-4FF5-9EE5-8C57BF553143} EndGlobalSection + GlobalSection(SharedMSBuildProjectFiles) = preSolution + ..\Objects\Converters\ConverterRevit\ConverterRevitShared\ConverterRevitShared.projitems*{236cff40-7dda-4cc5-84a9-b1df6f0985ef}*SharedItemsImports = 5 + ..\Objects\Converters\ConverterRevit\ConverterRevitShared\ConverterRevitShared.projitems*{240ead7e-ef10-482a-b299-3b85b64b032f}*SharedItemsImports = 5 + ConnectorRevit\ConnectorRevit.projitems*{27a79aca-7ea8-4406-8bb8-216578cc3ab7}*SharedItemsImports = 4 + ..\Objects\Converters\ConverterRevit\ConverterRevitShared\ConverterRevitShared.projitems*{2dcd648d-dca5-4d2a-8b14-ad2cb85d24b0}*SharedItemsImports = 13 + ConnectorRevit\ConnectorRevit.projitems*{586a5a37-93f6-427e-8df8-c10db4d6822a}*SharedItemsImports = 4 + ConnectorRevit\ConnectorRevit.projitems*{5fd0d810-03e9-4fd2-93e4-b1b51e5d82c5}*SharedItemsImports = 13 + ConnectorRevit\ConnectorRevit.projitems*{8a53b084-20d8-48f6-9591-9d53cfa74130}*SharedItemsImports = 4 + ..\Objects\Converters\ConverterRevit\ConverterRevitShared\ConverterRevitShared.projitems*{c74e4c61-ca68-47f9-825e-91b7a5c4546d}*SharedItemsImports = 5 + ..\Objects\Converters\ConverterRevit\ConverterRevitShared\ConverterRevitShared.projitems*{cfbd9a83-5aa2-4849-8735-28d4f73f4f56}*SharedItemsImports = 5 + ConnectorRevit\ConnectorRevit.projitems*{dfdfdbb8-018b-4dcb-a012-54227abf53a7}*SharedItemsImports = 4 + EndGlobalSection EndGlobal diff --git a/Objects/Converters/ConverterRevit/ConverterRevitShared/ConversionUtils.cs b/Objects/Converters/ConverterRevit/ConverterRevitShared/ConversionUtils.cs index 2cec6507fb..7745aa2cb9 100644 --- a/Objects/Converters/ConverterRevit/ConverterRevitShared/ConversionUtils.cs +++ b/Objects/Converters/ConverterRevit/ConverterRevitShared/ConversionUtils.cs @@ -1,21 +1,23 @@ using System; -using System.Collections; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text.RegularExpressions; + using Autodesk.Revit.DB; -using Objects.BuiltElements; -using Objects.BuiltElements.Revit; -using Objects.Geometry; -using Objects.Other; +using DB = Autodesk.Revit.DB; +using ElementType = Autodesk.Revit.DB.ElementType; + using Speckle.Core.Helpers; using Speckle.Core.Kits; using Speckle.Core.Models; using Speckle.Core.Models.GraphTraversal; -using DB = Autodesk.Revit.DB; + +using Objects.BuiltElements; +using Objects.BuiltElements.Revit; +using Objects.Geometry; +using Objects.Other; using Duct = Objects.BuiltElements.Duct; -using ElementType = Autodesk.Revit.DB.ElementType; using Floor = Objects.BuiltElements.Floor; using Level = Objects.BuiltElements.Level; using Line = Objects.Geometry.Line; @@ -297,8 +299,8 @@ private Dictionary GetElementParams(DB.Element element, bool //exclude parameters that don't have a value and those pointing to other elements as we don't support them var revitParameters = element.Parameters.Cast() - .Where(x => x.HasValue - && x.StorageType != StorageType.ElementId + .Where(x => x.HasValue + && x.StorageType != StorageType.ElementId && !exclusions.Contains(GetParamInternalName(x))).ToList(); //exclude parameters that failed to convert @@ -859,6 +861,19 @@ public bool IsIgnore(Element docObj, ApplicationObject appObj, out ApplicationOb const string ProjectBase = "Project Base"; const string Survey = "Survey"; + //cached during conversion + private List _revitLinkInstances = null; + private List RevitLinkInstances + { + get + { + if (_revitLinkInstances == null) + _revitLinkInstances = new FilteredElementCollector(Doc).OfClass(typeof(RevitLinkInstance)).ToElements().Cast().ToList(); + + return _revitLinkInstances; + } + } + private Dictionary _docTransforms = new Dictionary(); private DB.Transform GetDocReferencePointTransform(Document doc) { @@ -885,66 +900,38 @@ private DB.Transform GetDocReferencePointTransform(Document doc) //////////////////////////////////////////////// private DB.Transform GetReferencePointTransform(string type, Document doc) { - // get the correct base point from - // settings + // first get the main doc base points and reference setting transform var referencePointTransform = DB.Transform.Identity; - - var points = new FilteredElementCollector(doc).OfClass(typeof(BasePoint)).Cast().ToList(); + var points = new FilteredElementCollector(Doc).OfClass(typeof(BasePoint)).Cast().ToList(); var projectPoint = points.FirstOrDefault(o => o.IsShared == false); var surveyPoint = points.FirstOrDefault(o => o.IsShared == true); - var point = new XYZ(); - - //in the case of linked models, it seems they get aligned base off their surey point - //the translations below for linked models were retrieved a bit empirically - // TODO: This linked model code is hacky and incorrect for any linked models that have been moved! Use the `RevitLinkInstance` class transform to determine the full transform between an element in a linked model in the coordinate system of the main doc. - // See: https://thebuildingcoder.typepad.com/blog/2013/11/determining-host-document-location-of-a-linked-element.html switch (type) { - case ProjectBase: - if (projectPoint != null) - { - point = projectPoint.Position; - if (doc.IsLinked && surveyPoint != null) - { - var mainProjectPoint = new FilteredElementCollector(Doc).OfClass(typeof(BasePoint)).Cast().FirstOrDefault(o => o.IsShared == false); - point = point + mainProjectPoint.SharedPosition + surveyPoint.Position; - } - // rotation to base point is registered by survey point - referencePointTransform = DB.Transform.CreateTranslation(point); - } + case ProjectBase: // note that the project base (ui) rotation is registered on the survey pt, not on the base point + referencePointTransform = DB.Transform.CreateTranslation(projectPoint.Position); break; case Survey: - if (surveyPoint != null) - { - - point = surveyPoint.Position; - if (doc.IsLinked) - { - var mainSurveyPoint = new FilteredElementCollector(Doc).OfClass(typeof(BasePoint)).Cast().FirstOrDefault(o => o.IsShared == true); - point = point + mainSurveyPoint.SharedPosition; - } - - // !! retrieve survey point angle from project base point, null in some cases - var angle = projectPoint.get_Parameter(BuiltInParameter.BASEPOINT_ANGLETON_PARAM)?.AsDouble() ?? 0; - referencePointTransform = DB.Transform.CreateTranslation(point).Multiply(DB.Transform.CreateRotation(XYZ.BasisZ, angle)); - } + // note that the project base (ui) rotation is registered on the survey pt, not on the base point + // retrieve the survey point rotation from the project point + var angle = projectPoint.get_Parameter(BuiltInParameter.BASEPOINT_ANGLETON_PARAM)?.AsDouble() ?? 0; + referencePointTransform = DB.Transform.CreateTranslation(surveyPoint.Position).Multiply(DB.Transform.CreateRotation(XYZ.BasisZ, angle)); break; case InternalOrigin: - if (surveyPoint != null) - { - if (doc.IsLinked) - { - var mainSurveyPoint = new FilteredElementCollector(Doc).OfClass(typeof(BasePoint)).Cast().FirstOrDefault(o => o.IsShared == true); - point = surveyPoint.Position - mainSurveyPoint.Position + mainSurveyPoint.SharedPosition; - } - - referencePointTransform = DB.Transform.CreateTranslation(point); - } - break; - default: break; } + // Second, if this is a linked doc get the transform and adjust + if (doc.IsLinked) + { + // get the linked doc instance transform + var instance = RevitLinkInstances.FirstOrDefault(x => x.GetLinkDocument().PathName == doc.PathName); + if (instance != null) + { + var linkInstanceTransform = instance.GetTotalTransform(); + referencePointTransform = linkInstanceTransform.Inverse.Multiply(referencePointTransform); + } + } + return referencePointTransform; }