Files
speckle-sharp-connectors/Connectors/Revit/Speckle.Connectors.RevitShared/Operations/Receive/ToHostSettingsManager.cs
T
kekesidavid 4bb67318a8 feat(revit): Reference Point Setting on Receive (#948)
* Receive settings

* wip

* wip

* resolved warnings

* cleanup

* cleanup

* netlify url restored

* review comments fixed

---------

Co-authored-by: oguzhankoral <oguzhankoral@gmail.com>
Co-authored-by: Oğuzhan Koral <45078678+oguzhankoral@users.noreply.github.com>
2025-06-27 13:53:30 +02:00

98 lines
3.6 KiB
C#

using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using Speckle.Connectors.DUI.Models.Card;
using Speckle.Converters.RevitShared.Helpers;
using Speckle.Converters.RevitShared.Settings;
using Speckle.InterfaceGenerator;
namespace Speckle.Connectors.Revit.Operations.Receive.Settings;
[GenerateAutoInterface]
public class ToHostSettingsManager : IToHostSettingsManager
{
private readonly RevitContext _revitContext;
public ToHostSettingsManager(RevitContext revitContext)
{
_revitContext = revitContext;
}
public Transform? GetReferencePointSetting(ModelCard modelCard)
{
var referencePointString = modelCard.Settings?.First(s => s.Id == "referencePoint").Value as string;
if (
referencePointString is not null
&& ReferencePointSetting.ReferencePointMap.TryGetValue(
referencePointString,
out ReceiveReferencePointType referencePoint
)
)
{
// get the current transform from setting first
// we are doing this because we can't track if reference points were changed between send operations.
Transform? currentTransform = GetTransform(referencePoint);
return currentTransform;
}
throw new ArgumentException($"Invalid reference point value: {referencePointString}");
}
private Transform? GetTransform(ReceiveReferencePointType referencePointType)
{
Transform? referencePointTransform = null;
if (_revitContext.UIApplication is UIApplication uiApplication)
{
// first get the main doc base points and reference setting transform
using FilteredElementCollector filteredElementCollector = new(uiApplication.ActiveUIDocument.Document);
var points = filteredElementCollector.OfClass(typeof(BasePoint)).Cast<BasePoint>().ToList();
BasePoint? projectPoint = points.FirstOrDefault(o => !o.IsShared);
BasePoint? surveyPoint = points.FirstOrDefault(o => o.IsShared);
switch (referencePointType)
{
// note that the project base (ui) rotation is registered on the survey pt, not on the base point
case ReceiveReferencePointType.ProjectBase:
if (projectPoint is not null)
{
referencePointTransform = Transform.CreateTranslation(projectPoint.Position);
}
else
{
throw new InvalidOperationException("Couldn't retrieve Project Point from document");
}
break;
// note that the project base (ui) rotation is registered on the survey pt, not on the base point
case ReceiveReferencePointType.Survey:
if (surveyPoint is not null && projectPoint is not null)
{
// POC: should a null angle resolve to 0?
// retrieve the survey point rotation from the project point
var angle = projectPoint.get_Parameter(BuiltInParameter.BASEPOINT_ANGLETON_PARAM)?.AsDouble() ?? 0;
// POC: following disposed incorrectly or early or maybe a false negative?
using Transform translation = Transform.CreateTranslation(surveyPoint.Position);
referencePointTransform = translation.Multiply(Transform.CreateRotation(XYZ.BasisZ, angle));
}
else
{
throw new InvalidOperationException("Couldn't retrieve Survey and Project Point from document");
}
break;
case ReceiveReferencePointType.Source:
break;
case ReceiveReferencePointType.InternalOrigin:
break;
}
return referencePointTransform;
}
throw new InvalidOperationException(
"Revit Context UI Application was null when retrieving reference point transform."
);
}
}