<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Re: Multipatch Union3D in Python Questions</title>
    <link>https://community.esri.com/t5/python-questions/multipatch-union3d/m-p/1652072#M74718</link>
    <description>&lt;P&gt;Dear,&lt;BR /&gt;&lt;BR /&gt;in attched file send Layer Merged_All_3D.lyrx.I would like to ask can solved my problem.I need to create Multipatch Union 3D with single output where geometry is on single row.Geometry must to be same as source.No Dissolve.&lt;BR /&gt;&lt;BR /&gt;Best Regard&lt;/P&gt;</description>
    <pubDate>Mon, 22 Sep 2025 10:49:19 GMT</pubDate>
    <dc:creator>KiroA74</dc:creator>
    <dc:date>2025-09-22T10:49:19Z</dc:date>
    <item>
      <title>Multipatch Union3D</title>
      <link>https://community.esri.com/t5/python-questions/multipatch-union3d/m-p/1639785#M74620</link>
      <description>&lt;LI-CODE lang="python"&gt;import arcpy
import os
from collections import defaultdict
from arcpy import AddFieldDelimiters, Describe
import time

start = time.time()
# === Setup ===
gdb_path = r"C:\Users\Administrator\Desktop\Downloaded\QC02002-ESA-MOD-BIM-ARC-06-V06-00001 (1).gdb"
arcpy.env.workspace = gdb_path
arcpy.env.overwriteOutput = True

columns = os.path.join(gdb_path, "Spaces_BIMFileToGeodatab")
footprint_fc = "Columns_Footprint"
footprint_path = os.path.join(gdb_path, footprint_fc)
count_over = os.path.join(gdb_path, "count_over")
count_over_tab = os.path.join(gdb_path, "columns_tab")
singlePart = os.path.join(gdb_path, "singlePart")
arcpy.management.MultipartToSinglepart(columns, singlePart)
# === Geometry repair and footprint ===
arcpy.management.RepairGeometry(singlePart)
arcpy.ddd.MultiPatchFootprint(singlePart, footprint_path)
arcpy.analysis.CountOverlappingFeatures(footprint_path, count_over, "", count_over_tab)

# === Prepare ===
union_all = []
union_one = []

if arcpy.Exists(count_over_tab):
fields = [f.name for f in arcpy.ListFields(count_over_tab) if f.type != "OID"]
if len(fields) &amp;lt; 2:
print("‌‌ Table does not have at least two fields.")
else:
key_field = fields[0]
value_field = fields[1]
print(f"Using: key = {key_field}, value = {value_field}")

result_dict = defaultdict(list)
with arcpy.da.SearchCursor(count_over_tab, [key_field, value_field]) as cursor:
for key, value in cursor:
result_dict[key].append(value)

# === Get OID field and prepare layer ===
oid_field = Describe(singlePart).OIDFieldName
field_name = AddFieldDelimiters(singlePart, oid_field)
arcpy.MakeFeatureLayer_management(singlePart, "columns_layer")

# === Export all single-feature groups at once ===
single_oids = [str(oid_list[0]) for oid_list in result_dict.values() if len(oid_list) == 1]
if single_oids:
where_clause = f"{field_name} IN ({','.join(single_oids)})"
single_fc = os.path.join(gdb_path, "single_all")
arcpy.conversion.FeatureClassToFeatureClass(
in_features=singlePart,
out_path=gdb_path,
out_name="single_all",
where_clause=where_clause
)
print(f"‌‌ Exported {len(single_oids)} single-feature groups.")
union_one.append(single_fc)

# === Process multi-feature groups using selections ===
for group_id, oid_list in result_dict.items():
if len(oid_list) &amp;gt; 1:
oid_values = ", ".join(str(oid) for oid in oid_list)
where_clause = f"{field_name} IN ({oid_values})"
arcpy.SelectLayerByAttribute_management("columns_layer", "NEW_SELECTION", where_clause)

group_fc = os.path.join(gdb_path, f"group_{group_id}")
arcpy.CopyFeatures_management("columns_layer", group_fc)
count_group = int(arcpy.management.GetCount(group_fc)[0])
print(f"‌‌ Exported group {group_id} with {count_group} features.")

if count_group &amp;lt; 2:
print(f"‌‌ Skipping group {group_id} — not enough features.")
continue

enclosed_fc = os.path.join(gdb_path, f"enclosed_{group_id}")
try:
arcpy.ddd.EncloseMultiPatch(group_fc, enclosed_fc)
print(f"‌‌ Enclosed: {enclosed_fc}")
except Exception as e:
print(f"‌‌ Enclose failed for group {group_id}: {e}")
continue

union_fc = os.path.join(gdb_path, f"union_{group_id}")
try:
arcpy.ddd.Union3D(enclosed_fc, union_fc, '', 'DISABLE', 'ENABLE')
print(f"‌‌ Union3D completed: {union_fc}")
count = int(arcpy.management.GetCount(union_fc)[0])
print(f"‌‌ Union result contains {count} feature(s)")
if count &amp;gt; 0:
union_all.append(union_fc)
except Exception as e:
print(f"‌‌ Union3D failed for group {group_id}: {e}")

try:
# === Final Union: union_all + union_one ===
union_full = []

# Union All
if union_all:
merge_all = os.path.join(gdb_path, "merge_all")
enclosed_all = os.path.join(gdb_path, "enclosed_all")
union_all_fc = os.path.join(gdb_path, "union_all")
arcpy.management.Merge(union_all, merge_all)
arcpy.ddd.EncloseMultiPatch(merge_all, enclosed_all)
arcpy.ddd.Union3D(enclosed_all, union_all_fc, '', 'DISABLE', 'ENABLE')
union_full.append(union_all_fc)
count_all = int(arcpy.management.GetCount(union_all_fc)[0])
print(f"‌‌ Union ALL result contains {count_all} feature(s)")

# Union One
if union_one:
merge_one = os.path.join(gdb_path, "merge_one")
enclosed_one = os.path.join(gdb_path, "enclosed_one")
union_one_fc = os.path.join(gdb_path, "union_one")
arcpy.management.Merge(union_one, merge_one)
arcpy.ddd.EncloseMultiPatch(merge_one, enclosed_one)
arcpy.ddd.Union3D(enclosed_one, union_one_fc, '', 'DISABLE', 'ENABLE')
union_full.append(union_one_fc)
count_one = int(arcpy.management.GetCount(union_one_fc)[0])
print(f"‌‌ Union ONE result contains {count_one} feature(s)")

# Final Full Union
if union_full:
merge_full = os.path.join(gdb_path, "merge_full")
enclosed_full = os.path.join(gdb_path, "enclosed_full")
union_full_fc = os.path.join(gdb_path, "union_full")
arcpy.management.Merge(union_full, merge_full)
arcpy.ddd.EncloseMultiPatch(merge_full, enclosed_full)
arcpy.ddd.Union3D(enclosed_full, union_full_fc, '', 'DISABLE', 'ENABLE')
count_full = int(arcpy.management.GetCount(union_full_fc)[0])
print(f"‌‌ FINAL Union FULL result contains {count_full} feature(s)")

except Exception as e:
print(f"‌‌ Final Union3D process failed: {e}")
# Elapsed time in minutes
elapsed_minutes = (end - start) / 60
print("Elapsed time:", round(elapsed_minutes, 2), "minutes")&lt;/LI-CODE&gt;&lt;P&gt;Hello,&lt;/P&gt;&lt;P&gt;i would like to create union from feature class which have more of 2000 features.My iterations is:&lt;/P&gt;&lt;OL&gt;&lt;LI&gt;create feature class from gdb&lt;/LI&gt;&lt;LI&gt;create MultipartToSinglepart&lt;/LI&gt;&lt;LI&gt;RepairGeometry of&amp;nbsp; single part&lt;/LI&gt;&lt;LI&gt;create MultiPatchFootprint&lt;/LI&gt;&lt;LI&gt;CountOverlappingFeatures&lt;/LI&gt;&lt;LI&gt;create Enclosed&lt;/LI&gt;&lt;LI&gt;create union of two, tree... pair multipatch which is overloading(first encode)&lt;/LI&gt;&lt;LI&gt;merge single feature class&lt;/LI&gt;&lt;LI&gt;create encode of merget sigle feature class&lt;/LI&gt;&lt;LI&gt;create union of encode&lt;/LI&gt;&lt;/OL&gt;&lt;P&gt;Apear error:&lt;/P&gt;&lt;P&gt;&lt;SPAN&gt;warning stating that the resulting feature is not simple&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;How to solved problem?&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;BR /&gt;&lt;BR /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Sun, 10 Aug 2025 12:53:38 GMT</pubDate>
      <guid>https://community.esri.com/t5/python-questions/multipatch-union3d/m-p/1639785#M74620</guid>
      <dc:creator>KiroAndreevGDI</dc:creator>
      <dc:date>2025-08-10T12:53:38Z</dc:date>
    </item>
    <item>
      <title>Re: Multipatch Union3D</title>
      <link>https://community.esri.com/t5/python-questions/multipatch-union3d/m-p/1639795#M74621</link>
      <description>&lt;P&gt;to make the code readable&lt;/P&gt;&lt;P&gt;&lt;A href="https://community.esri.com/t5/python-blog/code-formatting-the-community-version/ba-p/1007633" target="_blank"&gt;Code formatting ... the Community Version - Esri Community&lt;/A&gt;&lt;/P&gt;</description>
      <pubDate>Wed, 06 Aug 2025 19:34:28 GMT</pubDate>
      <guid>https://community.esri.com/t5/python-questions/multipatch-union3d/m-p/1639795#M74621</guid>
      <dc:creator>DanPatterson</dc:creator>
      <dc:date>2025-08-06T19:34:28Z</dc:date>
    </item>
    <item>
      <title>Re: Multipatch Union3D</title>
      <link>https://community.esri.com/t5/python-questions/multipatch-union3d/m-p/1640704#M74622</link>
      <description>&lt;P&gt;&lt;A href="https://pro.arcgis.com/en/pro-app/latest/tool-reference/3d-analyst/union-3d.htm" target="_blank" rel="noopener"&gt;Union 3D (3D Analyst)—ArcGIS Pro | Documentation&lt;/A&gt;&lt;/P&gt;&lt;P&gt;&lt;EM&gt;A warning stating that the resulting feature is not simple and could not be created is raised if two or more multipatch features share only an edge or a vertex. This message indicates that the features were not merged because they did not share a volume of space.&lt;/EM&gt;&lt;/P&gt;&lt;P&gt;DISABLE&amp;nbsp; output all may be needed if features aren't overlapping.&lt;/P&gt;&lt;P&gt;Before you try scripting, have you tried the process manually to see at which step it is failing?&lt;/P&gt;&lt;P&gt;( PS&amp;nbsp; code formatting is still missing indentation, so sometimes, it is best to apply the code formatting to a new copy of the code)&lt;/P&gt;</description>
      <pubDate>Sun, 10 Aug 2025 16:59:46 GMT</pubDate>
      <guid>https://community.esri.com/t5/python-questions/multipatch-union3d/m-p/1640704#M74622</guid>
      <dc:creator>DanPatterson</dc:creator>
      <dc:date>2025-08-10T16:59:46Z</dc:date>
    </item>
    <item>
      <title>Re: Multipatch Union3D</title>
      <link>https://community.esri.com/t5/python-questions/multipatch-union3d/m-p/1645588#M74658</link>
      <description>&lt;P&gt;Dear Dan,&lt;BR /&gt;&lt;BR /&gt;i will send new version of code.I try:&lt;BR /&gt;&lt;BR /&gt;&lt;/P&gt;&lt;OL&gt;&lt;LI&gt;To create Union 3d to find which multipatch is overlopping&lt;/LI&gt;&lt;LI&gt;Create Union whith single output&lt;/LI&gt;&lt;LI&gt;Create Feature Class where is not overlopping features&lt;/LI&gt;&lt;/OL&gt;&lt;P&gt;Problem is with not overlopping features.It can not to Union as single output.This multipatch features is or not Closed or not Simple.&lt;/P&gt;&lt;P&gt;How to repair Not Ovrlopping features to be for creating Union with single output?&lt;BR /&gt;&lt;BR /&gt;Best Regard&lt;BR /&gt;&lt;BR /&gt;&lt;/P&gt;&lt;LI-CODE lang="python"&gt;for i, fc in enumerate(merge_enclose):
    union_over_fc = os.path.join(gdb_path, f"unionOver_{i}")
    union_over_final_fc = os.path.join(gdb_path, f"unionOver_final_{i}")
    enclose_over_final = os.path.join(gdb_path, f"encloseOver_final_{i}")
    table_union_over = os.path.join(gdb_path, f"table_union_Over_{i}")
    
    try:
        # --- Step 1: Make union directly on input
        arcpy.ddd.Union3D(fc, union_over_fc, '', 'ENABLE', 'DISABLE', table_union_over)
        
        # --- Step 2: Enclose and union again
        grid_size = calculate_grid_size(fc)
        print(grid_size)
        arcpy.ddd.EncloseMultiPatch(union_over_fc, enclose_over_final)
        arcpy.ddd.Union3D(enclose_over_final, union_over_final_fc, '', 'DISABLE', 'ENABLE')
        
        # --- Step 3: Collect IDs from table_union_over
        ids = [row[0] for row in arcpy.da.SearchCursor(table_union_over, ["Input_ID"])]
        print(f"Found {len(ids)} overlapping IDs")
        
        # --- Step 4: Find the OID field of fc
        oid_field = arcpy.Describe(fc).OIDFieldName
        print(f"OID field in {fc}: {oid_field}")
        
        # --- Step 5: Apply filter + export
        if not ids:
            print("No overlaps found, copying all features.")
            out_fc = os.path.join(gdb_path, f"_NotOver_{i}")
            arcpy.management.CopyFeatures(fc, out_fc)
        else:
            values_sql = ",".join(map(str, ids))
            expression = f"NOT {oid_field} IN ({values_sql})"
            print(f"Using SQL: {expression}")
            
            out_fc = os.path.join(gdb_path, f"_NotOver_{i}")
            arcpy.conversion.FeatureClassToFeatureClass(fc, gdb_path, f"space_NotOver_{i}", expression)
            print(f"Created {out_fc}")
    
    except Exception as e:
        print(f"❌ Union3D failed for {fc}: {e}")&lt;/LI-CODE&gt;</description>
      <pubDate>Tue, 26 Aug 2025 14:00:27 GMT</pubDate>
      <guid>https://community.esri.com/t5/python-questions/multipatch-union3d/m-p/1645588#M74658</guid>
      <dc:creator>KiroA74</dc:creator>
      <dc:date>2025-08-26T14:00:27Z</dc:date>
    </item>
    <item>
      <title>Re: Multipatch Union3D</title>
      <link>https://community.esri.com/t5/python-questions/multipatch-union3d/m-p/1645676#M74659</link>
      <description>&lt;P&gt;Skip the script for now.&lt;/P&gt;&lt;P&gt;Can you run the whole process manually using the standard tools in Arctoolbox?&lt;/P&gt;&lt;P&gt;If you get the same error message, then there is no solution to the problem.&amp;nbsp; It may be something in one of the iterations of the input data that causes the failure.&lt;/P&gt;</description>
      <pubDate>Tue, 26 Aug 2025 16:00:44 GMT</pubDate>
      <guid>https://community.esri.com/t5/python-questions/multipatch-union3d/m-p/1645676#M74659</guid>
      <dc:creator>DanPatterson</dc:creator>
      <dc:date>2025-08-26T16:00:44Z</dc:date>
    </item>
    <item>
      <title>Re: Multipatch Union3D</title>
      <link>https://community.esri.com/t5/python-questions/multipatch-union3d/m-p/1650224#M74690</link>
      <description>&lt;LI-CODE lang="python"&gt;import arcpy
import os
from collections import defaultdict
from collections import Counter
import re

def calculate_grid_size(fc, fraction=1000.0, min_size=0.01):
    desc = arcpy.Describe(fc)
    extent = desc.extent

    XMax, XMin = extent.XMax, extent.XMin
    YMax, YMin = extent.YMax, extent.YMin
    ZMax, ZMin = extent.ZMax, extent.ZMin

    x_size = XMax - XMin if XMax is not None and XMin is not None else 0
    y_size = YMax - YMin if YMax is not None and YMin is not None else 0

    if ZMax is not None and ZMin is not None:
        z_size = ZMax - ZMin
        min_dim = min(x_size, y_size, z_size)
    else:
        # Fallback: 2D only
        min_dim = min(x_size, y_size)

    grid_size = max(min_dim / fraction, min_size)
    return grid_size

gdb_path = r"F:\INS\Downloaded\MultipatchALL\QC02002-ESA-MOD-BIM-ARC-06-V06-00001 (1).gdb"
arcpy.env.workspace = gdb_path
arcpy.env.overwriteOutput = True

fc = os.path.join(gdb_path, "Walls_BIMFileToGeodatab")
merge_inputs=[]

def process_recursive(fc, gdb_path, iteration=0, merge_inputs=None):
    if merge_inputs is None:
        merge_inputs = []

    suffix = "" if iteration == 0 else f"_{iteration}"
    over = os.path.join(gdb_path, f"over{suffix}")
    over_enclose = os.path.join(gdb_path, f"over_enclose{suffix}")
    over_union = os.path.join(gdb_path, f"over_union{suffix}")
    over_tab = os.path.join(gdb_path, f"over_tab{suffix}")
    not_over = os.path.join(gdb_path, f"not_over{suffix}")
    not_over_enclose = os.path.join(gdb_path, f"not_over_enclose{suffix}")
    not_over_union = os.path.join(gdb_path, f"not_over_union{suffix}")
    not_over_tab = os.path.join(gdb_path, f"not_over_tab{suffix}")
    not_simple = os.path.join(gdb_path, f"not_simple{suffix}")
    single = os.path.join(gdb_path, f"single{suffix}")
    single_enclose= os.path.join(gdb_path, f"single_enclose{suffix}")
    single_union= os.path.join(gdb_path, f"single_union{suffix}")
    not_simple_fp = os.path.join(gdb_path, f"not_simple_fp{suffix}")
    not_simple_fp_3D = os.path.join(gdb_path, f"not_simple_fp_3D{suffix}")
    not_simple_multipatch = os.path.join(gdb_path, f"not_simple_multipatch{suffix}")
    not_simple_enclose = os.path.join(gdb_path, f"not_simple_enclose{suffix}")
    not_simple_union = os.path.join(gdb_path, f"not_simple_union{suffix}")
    merge = os.path.join(gdb_path, "merge")
    merge_enclose = os.path.join(gdb_path, "merge_enclose")
    merge_union = os.path.join(gdb_path, "merge_union")

    print(f"\n🔄 Iteration {iteration} → Processing {os.path.basename(fc)}")

        # --- Step 1: Enclose + Union3D on input ---
    grid_size = calculate_grid_size(fc)
    arcpy.ddd.EncloseMultiPatch(fc, over_enclose, grid_size)
    arcpy.ddd.Union3D(over_enclose, over, '', 'ENABLE', 'DISABLE', over_tab)
    
    # --- Step 2: Remove overlapping features ---
    oid_field = arcpy.Describe(fc).OIDFieldName
    
    if arcpy.Exists(over_tab):
        over_ids = {row[0] for row in arcpy.da.SearchCursor(over_tab, ["Input_ID"])}
    else:
        over_ids = set()
    
    if over_ids:
        id_list = ",".join(map(str, over_ids))
        where_clause = f'"{oid_field}" NOT IN ({id_list})'
    else:
        where_clause = "1=1"
    
    arcpy.FeatureClassToFeatureClass_conversion(fc, gdb_path, os.path.basename(not_over), where_clause)
    
    # --- Step 3: Enclose + Union3D on not_over ---
    grid_size = calculate_grid_size(not_over)
    arcpy.ddd.EncloseMultiPatch(not_over, not_over_enclose, grid_size)
    arcpy.ddd.Union3D(not_over_enclose, not_over_union, '', 'ENABLE', 'DISABLE', not_over_tab)
    
    # --- Step 4: Capture warnings ---
    warnings = arcpy.GetMessages(1)
    problematic_oids = []
    for line in warnings.split("\n"):
        if "NOT simple" in line and "OID" in line:
            nums = re.findall(r"\d+", line.split("OID")[-1])
            problematic_oids.extend(map(int, nums))
    
    print(f"⚠️ Found NOT simple OIDs: {problematic_oids}")
    
    # --- Step 5: Choose correct dataset for export ---
    if arcpy.Exists(not_over_union):
        export_source = not_over_union
    else:
        export_source = not_over
        print("⚠️ Using not_over instead of not_over_union (Union3D output missing)")
    
    oid_field = arcpy.Describe(export_source).OIDFieldName
    
    if problematic_oids:
        id_list = ",".join(map(str, problematic_oids))
        where_clause = f'"{oid_field}" IN ({id_list})'
        arcpy.FeatureClassToFeatureClass_conversion(export_source, gdb_path, os.path.basename(not_simple), where_clause)
        print(f"✅ Created 'not_simple' feature class")
    
        where_clause = f'"{oid_field}" NOT IN ({id_list})'
        arcpy.FeatureClassToFeatureClass_conversion(export_source, gdb_path, os.path.basename(single), where_clause)
        print(f"✅ Created 'single' feature class")
    else:
        arcpy.FeatureClassToFeatureClass_conversion(export_source, gdb_path, os.path.basename(single))
        print(f"✅ All features are simple → only 'single' created")
               # Collect merge candidates
    
    
    if arcpy.Exists(single):
        grid_size = calculate_grid_size(single)
        arcpy.ddd.EncloseMultiPatch(single, single_enclose, grid_size)
        arcpy.ddd.Union3D(single_enclose, single_union, '', 'DISABLE', 'ENABLE')
        problematic_single_oids = []
        # Collect all messages
        warnings_single = arcpy.GetMessages()
    
        for line in warnings_single.split("\n"):
            # Check for "NOT simple" or "not closed"
            if ("NOT simple" in line or "Non closed" in line) and "OID" in line:
                nums = re.findall(r"\d+", line.split("OID")[-1])
                problematic_single_oids.extend(map(int, nums))
    
        if problematic_single_oids:
            print(
                f"⚠️ Found problematic multipatch OIDs: {problematic_single_oids}. "
                f"Some geometries are not simple or not closed."
            )
        else:
            print("✅ All multipatches are valid (simple and closed).")
         # ✅ Check feature count in single_union
        count = int(arcpy.management.GetCount(single_union)[0])
        if count == 1:
            print("✅ Union result OK (single feature).")
            merge_inputs.append(single_union)
        else:
            print(f"❌ Union result NOK — expected 1 feature, got {count}.")

        
    if arcpy.Exists(over):
        grid_size = calculate_grid_size(over)
        arcpy.ddd.EncloseMultiPatch(over, over_enclose, grid_size)
        arcpy.ddd.Union3D(over_enclose, over_union, '', 'DISABLE', 'ENABLE')
        problematic_over_oids = []
        # Collect all messages
        warnings_over = arcpy.GetMessages()
    
        for line in warnings_over.split("\n"):
            # Check for "NOT simple" or "not closed"
            if ("NOT simple" in line or "Non closed" in line) and "OID" in line:
                nums = re.findall(r"\d+", line.split("OID")[-1])
                problematic_over_oids.extend(map(int, nums))
    
        if problematic_over_oids:
            print(
                f"⚠️ Found problematic multipatch OIDs: {problematic_over_oids}. "
                f"Some geometries are not simple or not closed."
            )
        else:
            print("✅ All multipatches are valid (simple and closed).")
         # ✅ Check feature count in over_union
        count = int(arcpy.management.GetCount(over_union)[0])
        if count == 1:
            print("✅ Union result OK (over feature).")
            merge_inputs.append(over_union)
        else:
            print(f"❌ Union result NOK — expected 1 feature, got {count}.")
    
    if arcpy.Exists(not_simple):
        arcpy.ddd.MultiPatchFootprint(not_simple, not_simple_fp)
        arcpy.cartography.SmoothSharedEdges(not_simple_fp, "", 0.001)
        if "Height" not in [f.name for f in arcpy.ListFields(not_simple_fp)]:
            arcpy.management.AddField(not_simple_fp, "Height", "DOUBLE")
        
        arcpy.management.CalculateField(not_simple_fp, "Height", "!Z_MAX! - !Z_MIN!", "PYTHON3")
     
        arcpy.ddd.FeatureTo3DByAttribute(not_simple_fp, not_simple_fp_3D, "Z_MIN", "Height")   
    
        layer_name="not_simple_fp_3D_layer"
    
        arcpy.management.MakeFeatureLayer(not_simple_fp_3D, layer_name)
    
        arcpy.management.ApplySymbologyFromLayer(layer_name, r"F:\INS\Walls_3D_layer.lyrx")
        
        arcpy.ddd.Layer3DToFeatureClass(
            layer_name,
            not_simple_multipatch
        )


    else:
        print("⚠️ Skipping not_simple processing → dataset not created")
    if arcpy.Exists(not_simple_multipatch):
        if int(arcpy.management.GetCount(not_simple_multipatch)[0]) &amp;gt; 0:
            # Recursive call
            return process_recursive(not_simple_multipatch, gdb_path, iteration + 1, merge_inputs)
    
    
    # Final merge
    if merge_inputs:
        arcpy.management.Merge(merge_inputs, merge)
        grid_size = calculate_grid_size(merge)
        arcpy.ddd.EncloseMultiPatch(merge, merge_enclose, grid_size)
        arcpy.ddd.Union3D(merge_enclose, merge_union, '', 'DISABLE', 'ENABLE')
        print(f"✅ Final union created: {merge_union}")
    elif iteration == 0:
        print("⚠️ No valid datasets found for merge → skipping")

    return merge_inputs

final_multipatch=process_recursive(fc, gdb_path)&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I have new python script:&lt;/P&gt;&lt;OL&gt;&lt;LI&gt;Create Union 3D with single output from Overloping Multipatch&lt;/LI&gt;&lt;LI&gt;Find and create Union 3D with single output from Single Multipatch.&lt;/LI&gt;&lt;LI&gt;Not Simple geometry convert to multipatch and with function&amp;nbsp;SmoothSharedEdges corect shared Multipatches.&lt;/LI&gt;&lt;LI&gt;All process is on recursion.&lt;/LI&gt;&lt;LI&gt;I must to use&amp;nbsp; arcpy.management.ApplySymbologyFromLayer(layer_name, r"F:\INS\Walls_3D_layer.lyrx") where&amp;nbsp;Walls_3D_layer.lyrx is created manual.&amp;nbsp;&lt;/LI&gt;&lt;LI&gt;How to create&amp;nbsp;rcpy.management.ApplySymbologyFromLayer(layer_name, r"F:\INS\Walls_3D_layer.lyrx")&amp;nbsp; generic with programming?&lt;/LI&gt;&lt;/OL&gt;</description>
      <pubDate>Fri, 12 Sep 2025 23:39:09 GMT</pubDate>
      <guid>https://community.esri.com/t5/python-questions/multipatch-union3d/m-p/1650224#M74690</guid>
      <dc:creator>KiroA74</dc:creator>
      <dc:date>2025-09-12T23:39:09Z</dc:date>
    </item>
    <item>
      <title>Re: Multipatch Union3D</title>
      <link>https://community.esri.com/t5/python-questions/multipatch-union3d/m-p/1652072#M74718</link>
      <description>&lt;P&gt;Dear,&lt;BR /&gt;&lt;BR /&gt;in attched file send Layer Merged_All_3D.lyrx.I would like to ask can solved my problem.I need to create Multipatch Union 3D with single output where geometry is on single row.Geometry must to be same as source.No Dissolve.&lt;BR /&gt;&lt;BR /&gt;Best Regard&lt;/P&gt;</description>
      <pubDate>Mon, 22 Sep 2025 10:49:19 GMT</pubDate>
      <guid>https://community.esri.com/t5/python-questions/multipatch-union3d/m-p/1652072#M74718</guid>
      <dc:creator>KiroA74</dc:creator>
      <dc:date>2025-09-22T10:49:19Z</dc:date>
    </item>
  </channel>
</rss>

