Python adds MText - raises error

Hi @ondrej.janota

Here are 2 solutions

CPython3 code

import sys
import clr
import System
# Add Assemblies for AutoCAD and Civil3D
clr.AddReference('AcMgd')
clr.AddReference('AcCoreMgd')
clr.AddReference('AcDbMgd')
clr.AddReference('AecBaseMgd')
clr.AddReference('AecPropDataMgd')
clr.AddReference('AeccDbMgd')

# 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 from Civil3D
from Autodesk.Civil.ApplicationServices import *
from Autodesk.Civil.DatabaseServices import *

adoc = Application.DocumentManager.MdiActiveDocument
editor = adoc.Editor

import traceback

def toList(x):
    if isinstance(x, (list, dict)) or \
            (hasattr(x, "GetType") and x.GetType().GetInterface("ICollection") is not None):
        return x
    else : return [x]

lst_pts = toList(IN[0])
lst_texts = toList(IN[1])
out = []

acLckDoc  = adoc.LockDocument()
db = adoc.Database
t = db.TransactionManager.StartTransaction()
# Place your code below
try:
    bt = t.GetObject(db.BlockTableId, OpenMode.ForRead)
    btr = t.GetObject(bt.get_Item(BlockTableRecord.ModelSpace), OpenMode.ForWrite)
    for pt, text in zip(lst_pts, lst_texts):
        mtext = MText()
        mtext.Location = Point3d(pt.X, pt.Y, pt.Z)
        mtext.Contents = text
        btr.AppendEntity(mtext)
        t.AddNewlyCreatedDBObject(mtext, True)
        out.append(mtext)
#
except Exception as ex:
    OUT = traceback.format_exc()
else:
    OUT = out
    t.Commit()
finally:
    t.Dispose()
    db.Dispose()
    acLckDoc.Dispose()

PythonNet3 code (new python engine)

import sys
import clr
import System
# Add Assemblies for AutoCAD and Civil3D
clr.AddReference('AcMgd')
clr.AddReference('AcCoreMgd')
clr.AddReference('AcDbMgd')
clr.AddReference('AecBaseMgd')
clr.AddReference('AecPropDataMgd')
clr.AddReference('AeccDbMgd')

# 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 from Civil3D
from Autodesk.Civil.ApplicationServices import *
from Autodesk.Civil.DatabaseServices import *

adoc = Application.DocumentManager.MdiActiveDocument
editor = adoc.Editor

import traceback

def toList(x):
    if isinstance(x, (list, dict)) or \
            (hasattr(x, "GetType") and x.GetType().GetInterface("ICollection") is not None):
        return x
    else : return [x]

lst_pts = toList(IN[0])
lst_texts = toList(IN[1])
out = []

class CManager:
    """
    a custom context manager for Disposable Object
    """
    def __init__(self, obj):
        self.obj = obj
        
    def __enter__(self):
        return self.obj
        
    def __exit__(self, exc_type, exc_value, exc_tb):
        self.obj.Dispose()
        if exc_type:
            error = f"{exc_value} at line {exc_tb.tb_lineno}"
            raise ValueError(error)
        return self
        
with adoc.LockDocument():
    with CManager(adoc.Database) as db:
        print(db)
        with CManager(db.TransactionManager.StartTransaction()) as t:
            bt = t.GetObject(db.BlockTableId, OpenMode.ForRead)
            btr = t.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite)
            for pt, text in zip(lst_pts, lst_texts):
                mtext = MText()
                mtext.Location = Point3d(pt.X, pt.Y, pt.Z)
                mtext.Contents = text
                btr.AppendEntity(mtext)
                t.AddNewlyCreatedDBObject(mtext, True)
                out.append(mtext)
            t.Commit()

OUT = out
3 Likes