ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

任意点地面投影点查找

2021-01-14 16:57:59  阅读:330  来源: 互联网

标签:List meshTriangle 投影 typography 查找 var new 任意


概述

    在一些设计场景中,用户需要贴着地面生成某些构件,或者将已有的构件移到地形表面。这时,就需要一个标高查找的功能,即用户输入一个点,就返回该点在地面的铅锤投影点。

原理

    Revit中的地形由一个个三角形组成的三角网构成。要获得输入点的铅锤投影点,先要查找与投影线相交的三角形,再通过线面相交获取交点。另外,当项目存在多个地面时,对每个地面去获取三角形再对每个三角形逐个判断是否相交效率很低,单个点可能几秒钟甚至几十秒才能找出交点。为了提高查找效率,可以对主体地形和它的子面域一起查找,同时只对与输入点平面距离最近的三个点相关的三角形查找交点。这样,每次查找消耗时间可以控制在0.5秒内。当找到交点时,返回交点坐标;未找到交点时,返回null。

代码实现

     完整的查找方法如下:

public static XYZ GetIntersectPointOnTopographySurface(TopographySurface typography, XYZ inputPoint)
{
    var document = typography.Document;
    var targetTypography = !typography.IsSiteSubRegion ? typography : document.GetElement(typography.AsSiteSubRegion().HostId) as TopographySurface;
    var typographyList = new List<TopographySurface>();
    var meshs = new List<Mesh>();
    var meshTriangles = new List<MeshTriangle>();
    var points = new List<XYZ>();
    typographyList.Add(targetTypography);
    var subRegionIds = targetTypography.GetHostedSubRegionIds();
    if (subRegionIds != null) typographyList.AddRange(subRegionIds.Select(x => document.GetElement(x) as TopographySurface));
    typographyList.ForEach(x => meshs.AddRange(GetMeshs(x.get_Geometry(new Options { DetailLevel = ViewDetailLevel.Fine }))));
    meshs.ForEach(x => { points.AddRange(x.Vertices); });
    points.Sort((x, y) => (x - XYZ.BasisZ * y.Z).DistanceTo(inputPoint) <= (y - XYZ.BasisZ * y.Z).DistanceTo(inputPoint) ? -1 : 1);
    var firstThreePoints = points.GetRange(0, 3);
    foreach (var mesh in meshs)
    {
        for (var i = 0; i < mesh.NumTriangles; i++)
        {
            var meshTriangle = mesh.get_Triangle(i);
            for (var j = 0; j < 3; j++)
            {
                if (firstThreePoints.Any(y => meshTriangle.get_Vertex(j).IsAlmostEqualTo(y)))
                {
                    meshTriangles.Add(meshTriangle);
                    break;
                }
            }
        }
    }

    foreach (var meshTriangle in meshTriangles)
    {
        try
        {
            var profile = new CurveLoop();
            for (var j = 0; j < 3; j++)
            {
                profile.Append(Line.CreateBound(meshTriangle.get_Vertex(j), meshTriangle.get_Vertex((j + 1) % 3)));
            }
            var intersectPoint = GetIntersectPointOnCurveloop(new List<CurveLoop> { profile }, inputPoint);
            if (intersectPoint == null) continue;
            return intersectPoint;
        }
        catch { }
    }
    return null;
}

标签:List,meshTriangle,投影,typography,查找,var,new,任意
来源: https://blog.csdn.net/m0_37820202/article/details/112619536

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有