【Rhino】【Python】根据contour创建地形mesh

将surface生成open curve封闭

#coding=utf-8
import rhinoscriptsyntax as rs
import math

def adjust_endpoints():
    # 获取指定图层中的所有曲线
    all_objects = rs.ObjectsByLayer("Level 19")
    if not all_objects:
        print("在'Level 19'图层中未找到对象")
        return
    
    # 筛选有效的开放曲线
    open_curves = []
    invalid_objects = 0
    
    for obj in all_objects:
        try:
            # 检查对象是否为曲线且是否有效
            if rs.IsCurve(obj) and not rs.IsCurveClosed(obj):
                # 尝试获取端点
                try:
                    start = rs.CurveStartPoint(obj)
                    end = rs.CurveEndPoint(obj)
                    if start and end:
                        open_curves.append({
                            'curve': obj,
                            'start': start,
                            'end': end
                        })
                except:
                    invalid_objects += 1
                    print("无法获取曲线端点: " + str(obj))
            else:
                invalid_objects += 1
        except:
            invalid_objects += 1
            print("无效对象: " + str(obj))
    
    if not open_curves:
        print("未找到有效的开放曲线")
        return
    
    print("找到 {0} 条有效开放曲线".format(len(open_curves)))
    if invalid_objects > 0:
        print("跳过 {0} 个无效对象".format(invalid_objects))
    
    # 关闭重绘以提高性能
    rs.EnableRedraw(False)
    
    try:
        adjustments_made = 0
        
        # 遍历所有曲线的端点
        for i in range(len(open_curves)):
            curve1 = open_curves[i]
            
            # 检查终点
            end1 = curve1['end']
            closest_point = None
            min_distance = 5000
            
            # 查找最近的端点
            for j in range(len(open_curves)):
                if i == j:
                    continue
                    
                curve2 = open_curves[j]
                
                # 检查与其他曲线起点的距离
                dist_es = rs.Distance(end1, curve2['start'])
                if 0 < dist_es < min_distance:
                    min_distance = dist_es
                    closest_point = curve2['start']
                
                # 检查与其他曲线终点的距离
                dist_ee = rs.Distance(end1, curve2['end'])
                if 0 < dist_ee < min_distance:
                    min_distance = dist_ee
                    closest_point = curve2['end']
            
            # 如果找到最近点,调整当前曲线的终点
            if closest_point and min_distance < 5000:
                try:
                    # 获取原始控制点
                    points = rs.CurvePoints(curve1['curve'])
                    if points:
                        # 修改最后一个控制点的坐标
                        points[-1] = closest_point
                        # 创建新曲线
                        new_curve = rs.AddCurve(points)
                        if new_curve:
                            # 复制原始曲线的属性
                            rs.MatchObjectAttributes(new_curve, curve1['curve'])
                            # 删除原始曲线
                            rs.DeleteObject(curve1['curve'])
                            # 更新曲线信息
                            curve1['curve'] = new_curve
                            curve1['end'] = closest_point
                            adjustments_made += 1
                            print("调整了曲线端点 - 距离: {:.2f}".format(min_distance))
                except Exception as e:
                    print("调整曲线时出错: " + str(e))
                    continue
        
        print("\n完成端点调整")
        print("- 成功调整: {0} 条曲线".format(adjustments_made))
        
    except Exception as e:
        print("发生错误: " + str(e))
    finally:
        rs.EnableRedraw(True)

# 运行函数
adjust_endpoints()

绘制方向线,调整相交的contour的z坐标值

#coding=utf-8
import rhinoscriptsyntax as rs
import Rhino.Geometry as rg

def sort_intersection_points(points):
    # 按X坐标排序交点
    return sorted(points, key=lambda pt: pt.X)

def adjust_curves_by_intersection():
    # 获取指定图层的直线
    direction_lines = rs.ObjectsByLayer("Contour::Direction")
    if not direction_lines:
        print("未找到方向线")
        return
    
    # 获取Level 19图层的曲线
    level_curves = rs.ObjectsByLayer("Level 19")
    if not level_curves:
        print("未找到Level 19的曲线")
        return
    
    # 筛选开放曲线
    open_curves = [crv for crv in level_curves if rs.IsCurve(crv) and not rs.IsCurveClosed(crv)]
    
    # 存储所有交点信息
    intersection_data = []
    
    # 关闭重绘以提高性能
    rs.EnableRedraw(False)
    
    try:
        # 获取所有交点
        for line in direction_lines:
            for curve in open_curves:
                intersection_points = rs.CurveCurveIntersection(line, curve)
                if intersection_points:
                    for intersection in intersection_points:
                        # 交点信息格式:[交点坐标, 相关曲线]
                        intersection_data.append({
                            'point': intersection[1],  # 交点坐标
                            'curve': curve            # 相交的曲线
                        })
        
        if not intersection_data:
            print("未找到交点")
            return
        
        # 按X坐标排序交点
        intersection_data.sort(key=lambda x: x['point'].X)
        
        # 设置初始Z坐标
        base_z = -110000
        z_increment = 5000
        
        # 记录已处理的曲线,避免重复处理
        processed_curves = set()
        
        # 依次处理每个交点对应的曲线
        for idx, data in enumerate(intersection_data):
            curve = data['curve']
            
            # 如果曲线已经处理过,跳过
            if curve in processed_curves:
                continue
                
            # 计算新的Z坐标
            new_z = base_z + (idx * z_increment)
            
            # 获取曲线的控制点
            points = rs.CurvePoints(curve)
            if points:
                # 调整所有控制点的Z坐标
                new_points = []
                for pt in points:
                    new_pt = rs.CreatePoint(pt.X, pt.Y, new_z)
                    new_points.append(new_pt)
                
                # 创建新曲线
                new_curve = rs.AddCurve(new_points)
                if new_curve:
                    # 复制原始曲线的属性
                    rs.MatchObjectAttributes(new_curve, curve)
                    # 删除原始曲线
                    rs.DeleteObject(curve)
                    # 标记曲线为已处理
                    processed_curves.add(curve)
                    print("调整曲线Z坐标至: {0}".format(new_z))
        
        print("\n完成调整")
        print("- 处理曲线数量: {0}".format(len(processed_curves)))
        
    except Exception as e:
        print("发生错误: " + str(e))
    finally:
        rs.EnableRedraw(True)

# 运行函数
adjust_curves_by_intersection()

在这里插入图片描述

project pile onto Contour for obtaining Bottom level

#coding=utf-8
import rhinoscriptsyntax as rs
import Rhino.Geometry as rg
import scriptcontext as sc

def get_bottom_levels():
    # 获取PILE图层中的所有对象
    pile_curves = rs.ObjectsByLayer("PILE")
    if not pile_curves:
        print("在PILE图层中未找到对象")
        return
    
    # 获取Contour::Mesh图层中的mesh对象
    mesh_objects = rs.ObjectsByLayer("Contour::Mesh")
    if not mesh_objects:
        print("在Contour::Mesh图层中未找到mesh对象")
        return
    
    print("找到 {0} 个mesh对象".format(len(mesh_objects)))
    
    # 筛选出封闭曲线
    closed_curves = []
    for curve in pile_curves:
        if rs.IsCurve(curve) and rs.IsCurveClosed(curve):
            degree = rs.CurveDegree(curve)
            if degree == 2:
                closed_curves.append(curve)
    
    if not closed_curves:
        print("未找到符合条件的封闭曲线")
        return
    
    print("找到 {0} 个封闭曲线".format(len(closed_curves)))
    
    # 关闭重绘以提高性能
    rs.EnableRedraw(False)
    
    try:
        # 使用单个mesh对象(假设只有一个地形mesh)
        mesh_obj = mesh_objects[0]
        # 直接从文档中获取mesh
        mesh = sc.doc.Objects.Find(mesh_obj).Geometry
        
        if not mesh:
            print("无法获取有效的mesh几何体")
            return
            
        print("成功获取mesh几何体")
        
        # 为每个封闭曲线处理投影点
        processed_count = 0
        
        for curve in closed_curves:
            try:
                # 获取曲线的中心点
                bbox = rs.BoundingBox(curve)
                if not bbox:
                    print("无法获取曲线边界框,曲线ID: " + str(curve))
                    continue
                    
                # 获取中心点坐标
                center_x = (bbox[0].X + bbox[6].X) / 2
                center_y = (bbox[0].Y + bbox[6].Y) / 2
                
                # 创建一条从高处向下的射线
                ray_start = rg.Point3d(center_x, center_y, 10000)
                ray_dir = rg.Vector3d(0, 0, -1)  # 向下的方向
                ray = rg.Ray3d(ray_start, ray_dir)
                
                # 计算射线与mesh的交点
                intersection_result = rg.Intersect.Intersection.MeshRay(mesh, ray)
                
                if intersection_result >= 0:  # 如果找到交点
                    # 计算交点的实际位置
                    intersection_point = ray_start + ray_dir * intersection_result
                    bottom_level = intersection_point.Z
                    
                    # 添加或更新属性
                    rs.SetUserText(curve, "bottom level", str(bottom_level))
                    
                    processed_count += 1
                    if processed_count % 50 == 0:  # 每处理50个打印一次进度
                        print("已处理 {0} 个曲线对象".format(processed_count))
                else:
                    print("未找到投影点,曲线ID: " + str(curve))
                
            except Exception as e:
                print("处理曲线对象时出错: " + str(e))
                print("问题曲线ID: " + str(curve))
                continue
        
        print("\n完成处理")
        print("- 成功处理: {0} 个曲线对象".format(processed_count))
        
    except Exception as e:
        print("发生错误: " + str(e))
    finally:
        rs.EnableRedraw(True)

# 运行函数
get_bottom_levels()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hmywillstronger

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值