#coding=utf-8
import rhinoscriptsyntax as rs
import Rhino.Geometry as rgdef extend_lines_to_columns():print("开始运行脚本...")# 定义要处理的图层名称beam_layer = "Make2D::Visible::Curves::02 STR. SOLID MAMBER::1*.1.BEAM MAIN (UNIONED)"column_layers = ["03 STR. DRAFT MEMBER::COLUMN BELOW","03 STR. DRAFT MEMBER::COLUMN (BELOW AND ABOVE)"]# 检查范围(毫米)search_distance = 1000# 获取指定图层中的所有线条beam_objects = rs.ObjectsByLayer(beam_layer)print("在图层 {} 中找到 {} 个线条".format(beam_layer, len(beam_objects) if beam_objects else 0))if not beam_objects:print("未找到线条")return# 获取所有柱子对象column_objects = []for layer in column_layers:columns = rs.ObjectsByLayer(layer)if columns:for col in columns:if rs.IsCurveClosed(col):column_objects.append(col)print("在图层 {} 中找到 {} 个封闭曲线".format(layer, len(column_objects)))if not column_objects:print("未找到封闭曲线")returnmodified_count = 0# 处理每条线for beam in beam_objects:if not rs.IsLine(beam):continue# 获取线的端点start_point = rs.CurveStartPoint(beam)end_point = rs.CurveEndPoint(beam)if not start_point or not end_point:continue# 计算方向向量vector = rs.VectorCreate(end_point, start_point)vector = rs.VectorUnitize(vector)# 创建检查用的线段(在原始端点的位置延伸)start_search_point = rs.PointAdd(start_point, rs.VectorScale(vector, -search_distance))end_search_point = rs.PointAdd(end_point, rs.VectorScale(vector, search_distance))# 创建搜索线段start_search_line = rs.AddLine(start_point, start_search_point)end_search_line = rs.AddLine(end_point, end_search_point)need_update = Falsenew_start = start_pointnew_end = end_point# 检查每个柱子for column in column_objects:# 检查起点方向intersections = rs.CurveCurveIntersection(start_search_line, column)if intersections:new_start = intersections[0][1]need_update = True# 检查终点方向intersections = rs.CurveCurveIntersection(end_search_line, column)if intersections:new_end = intersections[0][1]need_update = True# 删除搜索线rs.DeleteObject(start_search_line)rs.DeleteObject(end_search_line)# 如果需要更新,创建新的线段if need_update:rs.DeleteObject(beam)new_beam = rs.AddLine(new_start, new_end)# 保持原始属性if new_beam:rs.ObjectLayer(new_beam, beam_layer)modified_count += 1print("处理完成,修改了 {} 个线条".format(modified_count))rs.Redraw()# 运行函数
if __name__ == "__main__":extend_lines_to_columns()
1. 整体流程图
2. 关键步骤解析
2.1 初始化和数据获取
2.2 直线处理流程
3. 代码关键部分解析
3.1 数据准备
# 获取beam直线
beam_objects = rs.ObjectsByLayer(beam_layer)
# 获取封闭的column曲线
column_objects = [col for col in rs.ObjectsByLayer(layer) if rs.IsCurveClosed(col)]
作用:从指定图层获取需要处理的几何对象
3.2 直线检查和处理
# 获取端点和方向
start_point = rs.CurveStartPoint(beam)
end_point = rs.CurveEndPoint(beam)
vector = rs.VectorCreate(end_point, start_point)
vector = rs.VectorUnitize(vector) # 单位化向量
作用:获取直线的基本信息用于后续计算
3.3 搜索范围创建
# 创建搜索点
start_search_point = rs.PointAdd(start_point, rs.VectorScale(vector, -search_distance))
end_search_point = rs.PointAdd(end_point, rs.VectorScale(vector, search_distance))# 创建搜索线段
start_search_line = rs.AddLine(start_point, start_search_point)
end_search_line = rs.AddLine(end_point, end_search_point)
作用:创建用于检测相交的临时线段
3.4 相交检测
# 检查相交
intersections = rs.CurveCurveIntersection(search_line, column)
if intersections:new_point = intersections[0][1] # 获取相交点
作用:检测搜索线段是否与柱子相交
4. 关键概念说明
-
搜索距离:
- 在直线端点延伸方向上下1000mm范围内搜索
- 只在这个范围内找到的相交点才会被考虑
-
方向向量:
- 使用直线的两个端点确定方向
- 向量单位化以保证搜索距离准确
-
相交检测:
- 使用临时搜索线段进行检测
- 分别检查起点和终点方向
- 找到相交点后更新端点位置
-
更新原则:
- 只有找到相交点时才更新端点
- 保持原始直线的图层属性
- 更新完成后删除原直线,创建新直线
5. 数据流向
这个代码的核心思想是:在不改变直线方向的情况下,仅当直线端点延伸方向上有柱子时,才将端点移动到相交位置,这样可以确保直线准确地连接到柱子上。