Revit 二次开发 项目基点坐标,链接模型坐标系,族坐标系,模型坐标系

1.项目基点获取:

// 获取项目原点位置
            ProjectPosition projectPosition = doc.ActiveProjectLocation.GetProjectPosition(XYZ.Zero);

            XYZ translationVector = new XYZ(projectPosition.EastWest, projectPosition.NorthSouth, 0);

            Transform translationTransform = Transform.CreateTranslation(translationVector);

            Transform rotationTransform = Transform.CreateRotation(XYZ.BasisZ, projectPosition.Angle);

            Transform finalTransform = translationTransform.Multiply(rotationTransform);

2.链接文件坐标转换为模型坐标

 /// <summary>
        /// 获取当前文档中的连接文件
        /// </summary>
        /// <param name="doc"></param>
        /// <returns></returns>
        public static List<ElementInfo> GetLinkDoc(Document doc)
        {
            FilteredElementCollector linkInstances = new FilteredElementCollector(doc);
            linkInstances = linkInstances.WherePasses(new ElementClassFilter(typeof(RevitLinkInstance)));

            if (linkInstances != null && linkInstances.Any())
            {
                List<ElementInfo> listElementInfo = new List<ElementInfo>();

                foreach (RevitLinkInstance linkIns in linkInstances)
                {
                    var listLinkInsts = LinkInstanceAnalyse(doc, linkIns);

                    if (listLinkInsts != null)
                    {
                        listElementInfo.AddRange(listLinkInsts);
                    }
                }

                return listElementInfo;
            }

            return null;
        }

        /// <summary>
        /// 链接文件实例解析
        /// </summary>
        /// <param name="doc"></param>
        /// <param name="projectLocationTransform"></param>
        /// <param name="linkIns"></param>
        public static List<ElementInfo> LinkInstanceAnalyse(Document doc, RevitLinkInstance linkIns)
        {
            var linkdDocTrans = linkIns.GetTransform();

            Autodesk.Revit.DB.Document linkDoc = linkIns.GetLinkDocument();
            if (linkDoc != null)
            {
                //选取你想要的构件
                var instances = RevitUtil.GetFamilyInstances(linkDoc);

                CategorySet categorySet = RevitUtil.DocBindingParamCategory(linkDoc);

                //其他专业有很多元素不是族实例,为线和片段,所以这里根据元数据编码的大类来批量获取
                //即可获取族实例,也可以获取其他片段和线段数据
                if (categorySet != null)
                {
                    instances = RevitUtil.GetElements(linkDoc, categorySet);
                }

                List<ElementInfo> listElementInfo = new List<ElementInfo>();

                foreach (var element in instances)
                {
                    //调用链接文件的解析方式
                    ElementInfo elementInfo = RevitUtil.ElInstanceToInfo(element, doc.ActiveView);

                    if (elementInfo.CenterXyz != null)
                    {
                        //通过链接模型实例转换器,将链接文件中的坐标转为当前文件打开视图的全局坐标
                        elementInfo.CenterXyz = linkdDocTrans.OfPoint(elementInfo.CenterXyz);

                        if (elementInfo.MaxLocation != null)
                        {
                            //通过链接模型实例转换器,将链接文件中的坐标转为当前文件打开视图的全局坐标
                            elementInfo.MaxLocation = linkdDocTrans.OfPoint(elementInfo.MaxLocation);
                        }

                        if (elementInfo.MinLocation != null)
                        {
                            //通过链接模型实例转换器,将链接文件中的坐标转为当前文件打开视图的全局坐标
                            elementInfo.MinLocation = linkdDocTrans.OfPoint(elementInfo.MinLocation);
                        }

                        listElementInfo.Add(elementInfo);
                    }
                }

                return listElementInfo;
            }
            return null;
        }

3.将链接文件中构件的模型坐标,转为项目的基点坐标参考,projectLocationTransform为第一步获取的基点转换器


            //读取链接文件的解析和当前文档中的解析数据
            var linkInstElInfos = RevitUtil.GetLinkDoc(document);
            //链接文件不为空时,解析
            if (linkInstElInfos != null)
            {
                //将链接文件中的坐标点转为当前项目模型文件中的 基点坐标点和实际地理位置坐标对应
                foreach (ElementInfo elementInfo in linkInstElInfos)
                {
                    if (elementInfo.CenterXyz != null)
                    {
                        //将构件的中心点坐标转换为基点项目所在的坐标
                        var CenterXyz = projectLocationTransform.OfPoint(elementInfo.CenterXyz);
                        elementInfo.CenterXyz = RevitUtil.ConvertXyzToProjectUnit(document, CenterXyz);

                        if (elementInfo.MaxLocation != null)
                        {
                            //将构件的最大点坐标转换为基点项目所在的坐标
                            var MaxLocation = projectLocationTransform.OfPoint(elementInfo.MaxLocation);
                            elementInfo.MaxLocation = RevitUtil.ConvertXyzToProjectUnit(document, MaxLocation);
                        }

                        if (elementInfo.MinLocation != null)
                        {
                            //将构件的最小点坐标转换为基点项目所在的坐标
                            var MinLocation = projectLocationTransform.OfPoint(elementInfo.MinLocation);
                            elementInfo.MinLocation = RevitUtil.ConvertXyzToProjectUnit(document, MinLocation);
                        }

                        //链接文件放入集合中
                        listElementInfo.Add(elementInfo);
                    }
                }
            }

 

4.获取构件Element/族实例的坐标系,下面代码只是参考,因为只读取了最大最小两点,使用到了构件元素的参考点,试图裁剪,族坐标实例转换等方式。

 public static void Getinfo_ElementLocation(Element elem, ref ElementInfo elInfo, View view)
        {
            try
            {
                if (elInfo != null)
                {
                    //获取到Element的裁剪框。//三维矩形,立方体
                    BoundingBoxXYZ cropBox = elem.get_BoundingBox(view);

                    if (cropBox != null)
                    {
                        //获取到裁剪框的 最大和最小2个顶点。
                        elInfo.MaxLocation = cropBox.Transform.OfPoint(cropBox.Max);
                        elInfo.MinLocation = cropBox.Transform.OfPoint(cropBox.Min);

                        //计算构建的中心点位置坐标
                        elInfo.CenterXyz = new XYZ((elInfo.MaxLocation.X + elInfo.MinLocation.X) / 2, (elInfo.MaxLocation.Y + elInfo.MinLocation.Y) / 2, (elInfo.MaxLocation.Z + elInfo.MinLocation.Z) / 2);
                    }

                    //保存Element参考点坐标位置,不一定是中心点
                    var transform = Transform.Identity;

                    if (elem is FamilyInstance)
                    {
                        var fmInst = elem as FamilyInstance;

                        //获取实例的坐标点,覆盖计算的中心坐标点
                        LocationPoint location = fmInst.Location as LocationPoint;
                        if (location != null)
                        {
                            //判断当前坐标点不为零点,正常情况下,应该不为0,0,0
                            if (!location.Point.X.Equals(0) && !location.Point.Y.Equals(0))
                            {
                                elInfo.CenterXyz = location.Point;
                            }
                        }

                        //根据族中的包围盒大小,转换到模型中,计算最大最小
                        try
                        {
                            FamilySymbol familySymbol = fmInst.Symbol;
                            BoundingBoxXYZ bBoxSymbol = familySymbol.get_BoundingBox(view);
                            XYZ bBoxMax = bBoxSymbol.Max;
                            XYZ bBoxMin = bBoxSymbol.Min;
                            transform = fmInst.GetTransform();
                            if (bBoxMax != null && bBoxMin != null)
                            {
                                XYZ trbBoxMax = transform.OfPoint(bBoxMax);
                                XYZ trbBoxMin = transform.OfPoint(bBoxMin);

                                //获取到最大和最小2个顶点。
                                elInfo.MaxLocation = trbBoxMax;
                                elInfo.MinLocation = trbBoxMin;

                                //计算构建的中心点位置坐标
                                elInfo.CenterXyz = new XYZ((elInfo.MaxLocation.X + elInfo.MinLocation.X) / 2, (elInfo.MaxLocation.Y + elInfo.MinLocation.Y) / 2, (elInfo.MaxLocation.Z + elInfo.MinLocation.Z) / 2);
                            }
                        }
                        catch (Exception)
                        { }

                        //计算是否有自由点参考引用,如果有,则采用参考点作为范围
                        IList<FamilyPointPlacementReference> listref = fmInst.GetFamilyPointPlacementReferences();

                        if (listref != null)
                        {
                            if (listref.Count > 1)
                            {
                                //参考值最大和最小2个顶点。
                                elInfo.MaxLocation = listref[0].Location.Origin;
                                elInfo.MinLocation = listref[1].Location.Origin;

                                //计算构建的中心点位置坐标
                                elInfo.CenterXyz = new XYZ((elInfo.MaxLocation.X + elInfo.MinLocation.X) / 2, (elInfo.MaxLocation.Y + elInfo.MinLocation.Y) / 2, (elInfo.MaxLocation.Z + elInfo.MinLocation.Z) / 2);
                            }
                        }
                    }
                }
            }
            catch (Exception)
            { }
        }

5.构件几何数据获取,下面代码只是参考,由于项目需要,暂时只获取的构件的轮廓坐标,需要所有坐标的话,把Mesh中的点都记录下来即可,获取的构件坐标,可以通过2步骤,转换为项目基点坐标系。

/// <summary>
        /// 获取元素构件的8个边的坐标值
        /// </summary>
        /// <returns></returns>
        public static List<XYZ> GetElementPoints(Element element)
        {
            List<XYZ> points = new List<XYZ>();

            try
            {
                解析实例的几何数据
                //FamilyInstance familyInstance = element as FamilyInstance;
                //var familyTrans = familyInstance.GetTransform();

                Options opt = new Options();
                opt.ComputeReferences = false;
                opt.DetailLevel = ViewDetailLevel.Undefined;
                GeometryElement e = element.get_Geometry(opt);

                //解析几何数据
                foreach (GeometryObject obj in e)
                {
                    if (obj is GeometryInstance)
                    {
                        GeometryInstance geoInstance = obj as GeometryInstance;

                        GeometryElement geoElement = geoInstance.GetInstanceGeometry();

                        foreach (GeometryObject obj2 in geoElement)
                        {
                            Solid solid = obj2 as Solid;

                            if (null == solid || 0 == solid.Faces.Size || 0 == solid.Edges.Size)
                            {
                                continue;
                            }
                            Transform instTransform = geoInstance.Transform;

                            // 从实体Solid获取面和边,提取轮廓不需要所有面的数据,只需要边即可
                            foreach (Edge edge in solid.Edges)
                            {
                                Curve curve = edge.AsCurve();

                                //按道理来说这里是需要进行族转换器进行坐标转换的

                                //取起点和终点即可
                                points.Add(curve.GetEndPoint(0));
                                points.Add(curve.GetEndPoint(1));
                            }
                        }
                    }
                    else if (obj is Solid)
                    {
                        Solid solid = obj as Solid;

                        if (null == solid || 0 == solid.Faces.Size || 0 == solid.Edges.Size)
                        {
                            continue;
                        }
                        // 从实体Solid获取面和边,提取轮廓不需要所有面的数据,只需要边即可
                        foreach (Edge edge in solid.Edges)
                        {
                            Curve curve = edge.AsCurve();

                            //按道理来说这里是需要进行族转换器进行坐标转换的

                            //取起点和终点即可
                            points.Add(curve.GetEndPoint(0));
                            points.Add(curve.GetEndPoint(1));
                        }
                    }
                    else if (obj is Mesh)
                    {
                        //Mesh mesh = obj as Mesh;

                        //mesh.get

                        //foreach (XYZ ii in mesh.Vertices)
                        //{
                        //    //按道理来说这里是需要进行族转换器进行坐标转换的

                        //    points.Add(ii);
                        //}
                    }
                }
            }
            catch (Exception)
            { }

            return points;
        }

参考:

https://blog.csdn.net/Dai_Aixy/article/details/103150898

  • 6
    点赞
  • 43
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值