Revit二次开发 自动生成剖面楼梯标注

引用

revit坐标与屏幕坐标的转换

前置

关于Revit中楼梯竖向标注的问题记录及生成方式的解决方案

样式

在这里插入图片描述
在这里插入图片描述

内容

上面链接文件中提供了一种屏幕坐标转换为项目坐标的办法,原理时通过屏幕中的点与边界的比例换算到项目中计算得出,但是博主的方法只适用于XY平面的情况下,如果应用到剖面中就无法满足了,剖面会出现正交剖面及平行XY轴切割或是斜向剖面,所以下面的使用了博主的思想修改了一下方法

  1. 首先分析剖面视图,可以看作横向与纵向,纵向仅代表Z值,横向代表(X,Y)值,但是横向面会出现旋转偏移,可以把这个看作小时候转的皮蜻蜓一样,其次我们再Revit中看到的剖面视图其实是斜剖面对于屏幕的投影
  2. 我们获取到点击的屏幕坐标时,会获得屏幕的(X,Y)点,然后获得Revit工作空间的屏幕Rectangle,从而求出XY再空间中的比例
    • 这里遇到两个情况,记录一下此处我最先想用UV换算,但是有个问题 无法获得View的BoudingBoxUV所以做吧
    • 后来直接用比例计算,但还是斜剖面的问题,此时斜剖面两个ZoomCorns代表一个立方体所以无法直接通过比例换算
    • 之后想通过Transform换算坐标,但是我们无法获取转换的三维点,因为屏幕的二位点只能给我们提供一个准确的Z值
  3. 此时因为对三维降维为XY平面操作,所以只需要考虑左边还是右边,因为Revit的特性所以Corns[0]代表左侧,1代表右侧,这是我们可以将两个相同Z值的点连接成为向量,将横向X比例带入Vector运算即可获得横向的XY值,结合起来便是准确的三维坐标
  4. 通过前三步加上一个透明的窗口点击界面即可实现用户选择竖向标注位置自动生成楼梯标注的功能,这个说起来也不是复杂只是自己一开始钻到矩阵运算的解决办法之中,绕了弯路。

码一篇现代的教程,对矩阵有着很清晰的讲解,看完这个会对矩阵运算有更深的理解
线性代数课程:线性代数的本质

代码

屏幕坐标到Revit坐标 , 仅适用于剖面,平面使用上面博主的即可

/// <summary>
        /// 屏幕坐标转换为项目坐标
        /// </summary>
        /// <param name="screenPoint"></param>
        /// <returns></returns>
        private XYZ Screen2ViewPlan(UIView uiView,System.Drawing.Point screenPoint)
        {
            /*
             * 由于剖面的方向具有不确定性,所以不能简单的返回XY坐标
             * 可以通过屏幕工作区域的坐标计算左上角的坐标位置,返回屏幕坐标与点击窗口屏幕坐标做对照
             * 通过屏幕数值的对比计算实际的对比
             * 参考链接:https://blog.csdn.net/w051108/article/details/107723510
             */

            //屏幕坐标
            var rect = _uiView.GetWindowRectangle();
            //屏幕比例
            double sWidth = rect.Right - rect.Left;
            double sHeight = rect.Bottom - rect.Top; // Y值从上到下依次递增

            double widthScale = (screenPoint.X - rect.Left) / sWidth;
            double heightScale = (rect.Bottom - screenPoint.Y) / sHeight;
            //此处如果是斜剖面视图,需要使用普通界面接收一下相应位置
            //此处只需要区分左右,并不是所有的视图都是左下和右上两个角
            var corners = _uiView.GetZoomCorners();
            XYZ wRight = corners[1];
            XYZ wLeft = corners[0];
            //var referVector = (corners[0] - corners[1]).Normalize();
            //var referAngle = referVector.AngleTo(XYZ.BasisX);
            //if ((referAngle >= 0 && referAngle < 0.5 * Math.PI) ||
            //    (referAngle >= 1.5 * Math.PI && referAngle <= 2 * Math.PI))
            //{
            //    wRight = corners[1];
            //    wLeft = corners[0];
            //}
            //else
            //{
            //    wRight = corners[0];
            //    wLeft = corners[1];
            //}

            //类似皮搋子样式的三维旋转算法
            var fakeTransform = Transform.Identity;
            /*
             * 先降维后分别计算之后组合即可成为三维坐标
             * 此算法适用所有剖面区域,通过将Z值统一从而将两个三维对焦点变为二维面
             * 两个点连成线之后通过工作平面与点击点的横向比例找出二维XY面上的点
             * 竖向比例可求出Z值,组合后即可求出XYZ三维坐标
             */
            //首先将Z降级,降到统一Z值
            var MoveReferPoint = new XYZ(wRight.X,wRight.Y,wLeft.Z);
            var referLine = Line.CreateBound(wLeft, MoveReferPoint);
            var referNormalVector = referLine.Direction;
            var sPoint = wLeft + (MoveReferPoint - wLeft) * widthScale;
            var baseHeight = wRight.Z - wLeft.Z > 0 ? wLeft.Z : wRight.Z;
            var referHeight = Math.Abs(wRight.Z - wLeft.Z);

            var rPoint = new XYZ(sPoint.X,sPoint.Y,baseHeight + referHeight*heightScale);


            //             double wWidth = wRightTop.X - wLeftBottom.X;
            //double wHeight = wRightTop.Y - wLeftBottom.Y;

            //double widthDis = wWidth * widthScale;
            //double heightDis = wHeight * heightScale;

            //var pointXY =  new XYZ(wLeftBottom.X + widthDis, wLeftBottom.Y + heightDis, 0);
            

            return rPoint;
        }
  • 0
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值