using Autodesk.Revit.DB; namespace ShrlAlgo.RvKits.RvCommon; internal class AlignModelElement { private readonly View ownerView; public AlignModelElement(Element e) { Parent = e; var doc = e.Document; ownerView = doc.GetElement(e.OwnerViewId) != null ? doc.GetElement(e.OwnerViewId) as View : doc.ActiveView; //var viewPlane = Plane.CreateByNormalAndOrigin(ownerView is View3D ? XYZ.BasisZ : ownerView!.ViewDirection, ownerView.Origin); var bounding = e.get_BoundingBox(ownerView); var max = bounding.Max; var min = bounding.Min; //var globalMax = bounding.Max; //var globalMin = bounding.Min; //var distanceProjected = ProjectedDistance(viewPlane, globalMax, globalMin); //XYZ alternateMax = new(globalMax.X, globalMin.Y, globalMax.Z); //XYZ alternateMin = new(globalMin.X, globalMax.Y, globalMin.Z); //var alternateDistanceProjected = ProjectedDistance(viewPlane, alternateMax, alternateMin); //if (alternateDistanceProjected > distanceProjected) //{ // globalMax = alternateMax; // globalMin = alternateMin; //} //var ownerViewTransform = ownerView.CropBox.Transform; //var max = ownerViewTransform.Inverse.OfPoint(globalMax); //Max in the coordinate space of the view //var min = ownerViewTransform.Inverse.OfPoint(globalMin); //Min in the coordinate space of the view UpLeft = new XYZ(Math.Min(min.X, max.X), Math.Max(max.Y, min.Y), 0); UpRight = new XYZ(Math.Max(min.X, max.X), Math.Max(max.Y, min.Y), 0); DownLeft = new XYZ(Math.Min(min.X, max.X), Math.Min(max.Y, min.Y), 0); DownRight = new XYZ(Math.Max(min.X, max.X), Math.Min(max.Y, min.Y), 0); Center = (UpRight + DownLeft) / 2; Bottom = min.Z; Top = max.Z; Middle = (max.Z + min.Z) / 2; //if (ownerView is View3D) //{ // Bottom = min.Z; //} //else //{ // Bottom = Math.Min(max.Z, min.Z); //} } //private static double ProjectedDistance(Plane plane, XYZ pointA, XYZ pointB) //{ // //To be tested // var uva = plane.ProjectOf(pointA); // var uvb = plane.ProjectOf(pointB); // return uva.DistanceTo(uvb); //} public void MoveTo(XYZ point, AlignType alignType) { if (!Parent.Pinned) { var displacementVector = alignType switch { AlignType.Left => point - UpLeft, AlignType.Right => point - UpRight, AlignType.Up => point - UpRight, AlignType.Down => point - DownRight, AlignType.HorizontallyCenter => point - Center, AlignType.VerticallyCenter => point - Center, AlignType.Bottom => XYZ.BasisZ * (point.Z - Bottom), AlignType.Top => XYZ.BasisZ * (point.Z - Top), AlignType.Middle => XYZ.BasisZ * (point.Z - Middle), _ => throw new ArgumentOutOfRangeException(nameof(alignType), alignType, null) }; //位置不一样,移动 if (!displacementVector.IsZeroLength()) { //var translate = ownerView.CropBox.Transform.OfVector(displacementVector); //Parent.Location.Move(translate); ElementTransformUtils.MoveElement(Parent.Document, Parent.Id, displacementVector); } } } public double Bottom { get; } /// /// 水平面的中心 /// public XYZ Center { get; } public XYZ DownLeft { get; } public XYZ DownRight { get; } /// /// 垂向的中心 /// public double Middle { get; } public Element Parent { get; } public double Top { get; } public XYZ UpLeft { get; } public XYZ UpRight { get; } }