【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()
相关推荐
芒果快进我嘴里17 分钟前
C++打印乘法口诀表
开发语言·c++
22 分钟前
Lua基础复习之Lua元表
开发语言·lua
可能是猫猫人32 分钟前
【Python打卡Day39】图像数据与显存 @浙大疏锦行
开发语言·python
爬虫程序猿32 分钟前
利用 Python 爬虫获取 Amazon 商品详情:实战指南
开发语言·爬虫·python
_w_z_j_36 分钟前
C++----剖析stack、queue
开发语言·c++
aiweker42 分钟前
python web开发-Flask 重定向与URL生成完全指南
前端·python·flask
电院工程师43 分钟前
2.4 Python基础概念:通过一个文字冒险游戏学习编程
开发语言·python·学习·算法·游戏·游戏程序
设计师小聂!1 小时前
vue3 - 自定义hook
开发语言·javascript·ecmascript
风起云涌~1 小时前
【Java】BlockQueue
java·开发语言
daomingwu0171 小时前
【day51】复习日
python