Copying pressure pipes

I’m trying to copy pressure pipes and translate the copied ones up in the z axis. From a high level the object are getting copied but end up having duplicate pipe names, which isn’t the same behaviour as copying them manually in the host application. The copied pressure pipes also don’t show up in the Pressure Network pipes list in toolspace.

From past experience I have only been able to manipulate pressure pipes in Python by interacting with the AcadObject (system comm object). I am also aware the .net API only exposes ready only attributes for this object class.

In my example I have 2 pressure pipes that are being copied up vertically a few times.

Open to suggestions here, thanks.

CreateDuctBank_v1.0.0.dyn (20.0 KB)

I have also tried making copies of the pressure pipes using Python and still get the same results.

Method 1

# Load Python standard libraries
import clr

# Add Assemblies for AutoCAD and Civil 3D APIs
clr.AddReference('acmgd')
clr.AddReference('acdbmgd')
clr.AddReference('accoremgd')
clr.AddReference('AecBaseMgd')
clr.AddReference('AecPropDataMgd')
clr.AddReference('AeccDbMgd')
clr.AddReference('AeccPressurePipesMgd')
clr.AddReference('acdbmgdbrep')
clr.AddReference('System.Windows.Forms')

# Add standard Python references
import sys
sys.path.append('C:\Program Files (x86)\IronPython 2.7\Lib')
import os
import math

# Add references to manage arrays, collections and interact with the user
from System import *
from System.IO import *
from System.Collections.Specialized import *
from System.Windows.Forms import MessageBox

# Create an alias to the Autodesk.AutoCAD.ApplicationServices.Application class
import Autodesk.AutoCAD.ApplicationServices.Application as acApp

# Import references for Civil 3D
from Autodesk.Civil.ApplicationServices import *
from Autodesk.Civil.DatabaseServices import *

# Import references from AutoCAD
from Autodesk.AutoCAD.Runtime import *
from Autodesk.AutoCAD.ApplicationServices import *
from Autodesk.AutoCAD.EditorInput import *
from Autodesk.AutoCAD.DatabaseServices import *
from Autodesk.AutoCAD.Geometry import *

# Import references for PropertySets
from Autodesk.Aec.PropertyData import *
from Autodesk.Aec.PropertyData.DatabaseServices import *

# Declare global variables
a_doc = acApp.DocumentManager.MdiActiveDocument
ed = a_doc.Editor

   
    global a_doc
    error_report = None
    result = []
    try:
        # Get the active document in the AutoCAD session:
        with a_doc.LockDocument():
            with a_doc.Database as db:
                # Start a transaction
                with db.TransactionManager.StartTransaction() as t:
                    # Open the Block table for read
                    bt = t.GetObject(db.BlockTableId, OpenMode.ForRead)
                    # Open the Block table record Model space for write
                    btr = t.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite)
                    # Iterate through the list of handles
                    for h in handles:
                        # Convert the handle hexadecimal string to 64-bit integer
                        # Get the object id using handle
                        oid = db.GetObjectId(False, Handle(int(h, 16)), 0) 
                        # Get the object from the database
                        obj = t.GetObject(oid, OpenMode.ForRead)
                        # Clone the object
                        obj_clone = obj.Clone()
                        # Add the cloned object
                        btr.AppendEntity(obj_clone)
                        t.AddNewlyCreatedDBObject(obj_clone, True)
                    # Commit changes to the database before ending transaction
                    t.Commit()
    except:
        import traceback
        error_report = traceback.format_exc()
    if error_report is None:
        return btr
    else:
        return error_report
    
OUT = multiple_copy(IN[0])

Method 2

# Load Python standard libraries
import clr

# Add Assemblies for AutoCAD and Civil 3D APIs
clr.AddReference('acmgd')
clr.AddReference('acdbmgd')
clr.AddReference('accoremgd')
clr.AddReference('AecBaseMgd')
clr.AddReference('AecPropDataMgd')
clr.AddReference('AeccDbMgd')
clr.AddReference('AeccPressurePipesMgd')
clr.AddReference('acdbmgdbrep')
clr.AddReference('System.Windows.Forms')

# Add standard Python references
import sys
sys.path.append('C:\Program Files (x86)\IronPython 2.7\Lib')
import os
import math

# Add references to manage arrays, collections and interact with the user
from System import *
from System.IO import *
from System.Collections.Specialized import *
from System.Windows.Forms import MessageBox

# Create an alias to the Autodesk.AutoCAD.ApplicationServices.Application class
import Autodesk.AutoCAD.ApplicationServices.Application as acApp

# Import references for Civil 3D
from Autodesk.Civil.ApplicationServices import *
from Autodesk.Civil.DatabaseServices import *

# Import references from AutoCAD
from Autodesk.AutoCAD.Runtime import *
from Autodesk.AutoCAD.ApplicationServices import *
from Autodesk.AutoCAD.EditorInput import *
from Autodesk.AutoCAD.DatabaseServices import *
from Autodesk.AutoCAD.Geometry import *

# Import references for PropertySets
from Autodesk.Aec.PropertyData import *
from Autodesk.Aec.PropertyData.DatabaseServices import *

# Declare global variables
a_doc = acApp.DocumentManager.MdiActiveDocument
ed = a_doc.Editor

def multiple_copy(handles):
    """
   
    """
    
    global a_doc
    error_report = None
    result = []
    try:
        # Get the active document in the AutoCAD session:
        with a_doc.LockDocument():
            with a_doc.Database as db:
                # Start a transaction
                with db.TransactionManager.StartTransaction() as t:
                    # Iterate through the list of handles
                    for h in handles:
                        # Convert the handle hexadecimal string to 64-bit integer
                        # Get the object id using handle
                        oid = db.GetObjectId(False, Handle(int(h, 16)), 0) 
                        # Get the object from the database
                        obj = t.GetObject(oid, OpenMode.ForRead)
                        # Create an ObjectIdCollection
                        oid_collection = ObjectIdCollection()
                        oid_collection.Add(oid)
                        # Clone the object
                        obj_clone = db.DeepCloneObjects(oid_collection, SymbolUtilityServices.GetBlockModelSpaceId(db), IdMapping(), False)
                    t.Commit()
    except:
        import traceback
        error_report = traceback.format_exc()
    if error_report is None:
        return btr
    else:
        return error_report
    
OUT = multiple_copy(IN[0])


I figured it out with the help of some colleagues at work. My first approach in Python was producing a shallow copy of the pressure pipe. To finish things off I just add a few more lines to add the shallow copied object to a PressureNetwork using the AddPipe method.

C3D didn’t automatically rename the PressurePipes copied so I did that in Python as well through the COM api (ie AcadObject.Name)

2 Likes