【Python】【Rhino】assign column mark into bearing area‘s user text attributing

catalog

  • [Assigning Text to Surfaces](#Assigning Text to Surfaces)
    • [Required Layers and Objects](#Required Layers and Objects)
      • [1. Text Layer](#1. Text Layer)
      • [2. Surface Layer](#2. Surface Layer)
  • V20250616

Assigning Text to Surfaces

Required Layers and Objects

1. Text Layer

  • Layer Name : 03 STR. DRAFT MEMBER::COLUMN MARK
  • Contains: Text objects representing structural element IDs or column marks
  • Purpose: These text objects will be associated with surfaces

2. Surface Layer

  • Layer Name : Edwin::Loading bay
  • Contains: Surface objects (like floor areas, loading bays, etc.)
  • Purpose: These surfaces will receive attributes from the nearest text

V20250616

c 复制代码
import rhinoscriptsyntax as rs
import scriptcontext as sc
import Rhino

def diagnostic_check():
    """Check what's available on both layers"""
    text_layer = "03 STR. DRAFT MEMBER::COLUMN MARK"
    surface_layer = "Edwin::Loading bay"
    
    print("=== DIAGNOSTIC CHECK ===")
    
    # Check text objects
    text_objects = rs.ObjectsByLayer(text_layer)
    print("Text layer '{}':".format(text_layer))
    if text_objects:
        print("  Found {} text objects".format(len(text_objects)))
        for i, text_id in enumerate(text_objects[:5]):  # Show first 5
            text_content = rs.TextObjectText(text_id)
            text_point = rs.TextObjectPoint(text_id)
            print("  Text {}: '{}' at {}".format(i+1, text_content, text_point))
        if len(text_objects) > 5:
            print("  ... and {} more".format(len(text_objects) - 5))
    else:
        print("  No text objects found!")
    
    # Check surface objects
    surface_objects = rs.ObjectsByLayer(surface_layer)
    print("\nSurface layer '{}':".format(surface_layer))
    if surface_objects:
        print("  Found {} surface objects".format(len(surface_objects)))
        for i, surf_id in enumerate(surface_objects[:3]):  # Show first 3
            bbox = rs.BoundingBox(surf_id)
            if bbox:
                print("  Surface {}: BBox from {} to {}".format(i+1, bbox[0], bbox[6]))
    else:
        print("  No surface objects found!")
    
    print("=== END DIAGNOSTIC ===\n")

def assign_text_to_surfaces_debug():
    """Enhanced version with debug output"""
    text_layer = "03 STR. DRAFT MEMBER::COLUMN MARK"
    surface_layer = "Edwin::Loading bay"
    
    # Get all text objects from the text layer
    text_objects = rs.ObjectsByLayer(text_layer)
    if not text_objects:
        print("No text objects found on layer: " + text_layer)
        return
    
    # Get all surface objects from the surface layer
    surface_objects = rs.ObjectsByLayer(surface_layer)
    if not surface_objects:
        print("No surface objects found on layer: " + surface_layer)
        return
    
    print("Processing {} surfaces and {} text objects".format(len(surface_objects), len(text_objects)))
    
    matches_found = 0
    surfaces_processed = 0
    tolerance = 1000  # Increased tolerance for testing
    
    # Loop through each surface
    for surf_idx, surf_id in enumerate(surface_objects):
        print("Processing surface {} of {}".format(surf_idx + 1, len(surface_objects)))
        
        # Calculate and assign surface area
        surface_area = rs.SurfaceArea(surf_id)
        if surface_area:
            area_value = surface_area[0]
            rs.SetUserText(surf_id, "area", str(area_value))
            surfaces_processed += 1
        
        # Get the surface bounding box
        bbox = rs.BoundingBox(surf_id)
        if not bbox: 
            print("  No bounding box for surface")
            continue
        
        print("  Surface bbox: {} to {}".format(bbox[0], bbox[6]))
        
        # Track closest text for this surface
        closest_text = None
        closest_distance = float('inf')
        closest_text_content = None
        
        # Loop through each text object
        for text_idx, text_id in enumerate(text_objects):
            text_point = rs.TextObjectPoint(text_id)
            if not text_point: 
                continue
            
            text_content = rs.TextObjectText(text_id)
            
            # Check if text is within bounding box (with some tolerance)
            margin = 500  # Add margin to bounding box
            if (bbox[0].X - margin <= text_point.X <= bbox[6].X + margin and
                bbox[0].Y - margin <= text_point.Y <= bbox[6].Y + margin):
                
                print("    Text '{}' at {} is within bbox (with margin)".format(text_content, text_point))
                
                # Calculate distance to surface
                try:
                    # Get surface center point for distance calculation
                    surface_center = rs.SurfaceAreaCentroid(surf_id)
                    if surface_center:
                        center_point = surface_center[0]
                        distance = rs.Distance(text_point, center_point)
                        print("      Distance to surface center: {:.2f}".format(distance))
                        
                        if distance < closest_distance:
                            closest_distance = distance
                            closest_text = text_id
                            closest_text_content = text_content
                            print("      New closest text for this surface")
                        
                except Exception as e:
                    print("      Error calculating distance: {}".format(e))
                    continue
        
        # Assign the closest text to this surface (if within tolerance)
        if closest_text and closest_distance < tolerance:
            rs.SetUserText(surf_id, "Structure", closest_text_content)
            print("  ASSIGNED: '{}' to surface (distance: {:.2f})".format(closest_text_content, closest_distance))
            matches_found += 1
        else:
            if closest_text:
                print("  Closest text '{}' too far (distance: {:.2f} > {})".format(closest_text_content, closest_distance, tolerance))
            else:
                print("  No text found within bounding box")
    
    print("\nProcess completed.")
    print("{} surfaces processed with area attributes.".format(surfaces_processed))
    print("{} text matches found and structure attributes assigned.".format(matches_found))

def assign_text_to_surfaces_improved():
    """Improved version with multiple strategies"""
    text_layer = "03 STR. DRAFT MEMBER::COLUMN MARK"
    surface_layer = "Edwin::Loading bay"
    
    # Get objects
    text_objects = rs.ObjectsByLayer(text_layer)
    surface_objects = rs.ObjectsByLayer(surface_layer)
    
    if not text_objects or not surface_objects:
        print("Missing objects on one or both layers")
        return
    
    matches_found = 0
    surfaces_processed = 0
    
    # Strategy: For each text, find the closest surface
    for text_id in text_objects:
        text_point = rs.TextObjectPoint(text_id)
        text_content = rs.TextObjectText(text_id)
        
        if not text_point or not text_content:
            continue
        
        closest_surface = None
        closest_distance = float('inf')
        
        # Check all surfaces
        for surf_id in surface_objects:
            try:
                # Get surface center
                surface_center = rs.SurfaceAreaCentroid(surf_id)
                if surface_center:
                    center_point = surface_center[0]
                    distance = rs.Distance(text_point, center_point)
                    
                    if distance < closest_distance:
                        closest_distance = distance
                        closest_surface = surf_id
            except:
                continue
        
        # Assign text to closest surface (if reasonable distance)
        if closest_surface and closest_distance < 2000:  # Adjust tolerance as needed
            rs.SetUserText(closest_surface, "Structure", text_content)
            print("Assigned '{}' to closest surface (distance: {:.2f})".format(text_content, closest_distance))
            matches_found += 1
    
    # Process areas for all surfaces
    for surf_id in surface_objects:
        surface_area = rs.SurfaceArea(surf_id)
        if surface_area:
            area_value = surface_area[0]
            rs.SetUserText(surf_id, "area", str(area_value))
            surfaces_processed += 1
    
    print("Process completed.")
    print("{} surfaces processed with area attributes.".format(surfaces_processed))
    print("{} text-to-surface assignments made.".format(matches_found))

# Run diagnostic first
diagnostic_check()

# Try the improved method
print("Running improved assignment method...")
assign_text_to_surfaces_improved()

# If you want detailed debugging, uncomment this:
# print("\nRunning debug version...")
# assign_text_to_surfaces_debug()
相关推荐
Lynnxiaowen9 分钟前
今天我们学习python编程常用模块与面向对象
运维·python·学习·云计算
小火柴12310 分钟前
利用R绘制条形图
开发语言·r语言
一头生产的驴21 分钟前
java整合itext pdf实现固定模版pdf导出
java·python·pdf
魔都吴所谓22 分钟前
【python】快速实现pdf批量去除指定位置水印
java·python·pdf
沐知全栈开发31 分钟前
PHP MySQL 插入数据详解
开发语言
YFCodeDream1 小时前
MLLM技术报告 核心创新一览
python·gpt·aigc
自由会客室1 小时前
在 Ubuntu24.04 上安装 JDK 21(Java 21)
java·开发语言
喜欢读源码的小白1 小时前
SpringBoot的启动流程原理——小白的魔法引擎探秘
java·开发语言·spring boot·springboot启动原理
夜幽青玄2 小时前
mybatis-plus调用报 org.springframework.dao.DataIntegrityViolationException 错误处理
开发语言·python·mybatis
洲覆2 小时前
Redis 内存淘汰策略
开发语言·数据库·redis·缓存