I am trying to run a batch process for a set of Drawing files in a folder, trying to turn CAD Layers ON/OFF in Civil 3D. Somehow the script is failing. I am using a couple of references similar to this one below:
https://forum.dynamobim.com/t/changing-the-visibility-of-layers-in-a-viewport-vp-freeze/74979
The Python Code below, I used a couple of sourced references as below, but its failing in the function
i = t.GetObject(lt[layer], OpenMode.ForWrite)
where I try to get the Layer Object. The layers are fed as layerNames Strings, as seen in the Dynamo Graph
"""
"""
Copyright 2020 Autodesk, Inc. All rights reserved.
This file is part of the Civil 3D Python Module.
"""
# __author__ = 'Paolo Emilio Serra - paolo.serra@autodesk.com'
# __copyright__ = '2020'
# __version__ = '1.0.0'
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')
clr.AddReference('AutoCADNodes')
clr.AddReference('Civil3DNodes')
# Add standard Python references
import sys
sys.path.append('C:\Program Files (x86)\IronPython 2.7\Lib')
import os
import math
import logging
import tempfile
from logging import error
FORMAT = '[%(asctime)-15s] %(levelname)s: %(module)s.%(funcName)s %(message)s'
logging.basicConfig(filename=os.path.join(tempfile.gettempdir(), 'D4C3D.log'), level=logging.DEBUG, format=FORMAT, datefmt='%Y/%m/%d %I:%M:%S')
# 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 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 *
# Import references for Civil 3D
from Autodesk.Civil.ApplicationServices import *
from Autodesk.Civil.DatabaseServices import *
# Import AutoCAD and Civil 3D Dynamo Nodes
import Autodesk.AutoCAD.DynamoNodes as DA
import Autodesk.Civil.DynamoNodes as DC
from Autodesk.AutoCAD.ApplicationServices import Application as acapp
from Autodesk.AutoCAD.ApplicationServices import DocumentCollectionExtension
from Autodesk.AutoCAD.ApplicationServices import DocumentExtension
# Useful link
# http://www.theswamp.org/index.php?topic=37686.0
def set_layer_on_off_for_dwgs(path, layers, bool):
# """
# Loads the document in the application.
# Searches the new block, in case it is missing it will load it.
# Searches the BlockReferences of the old block and deletes them.
# Creates a new BlockReference at location with the new Block.
# Rotates the new block Reference.
# Saves the Document and closes it.
# @path: The path to the document
# @returns: True if successful, otherwise False
# """
if path is None or layers is None or bool is None:
return False
adoc = DocumentCollectionExtension.Open(acapp.DocumentManager, path, False) # Open for Write
acapp.DocumentManager.CurrentDocument = adoc
editor = adoc.Editor
if adoc is None:
return False
ret = True
errorReport = None
name = []
global lt
global lt_test
with adoc.LockDocument():
with adoc.Database as db:
with db.TransactionManager.StartTransaction() as t:
for layer in layers:
lt = t.GetObject(db.LayerTableId, OpenMode.ForWrite) # Get Layers
try:
if lt.Has(layer):
i = t.GetObject(lt[layer], OpenMode.ForWrite)
i.IsOff=True
name.append(i.Name)
# Error Handling
except:
import traceback
# t.AddNewlyCreatedDBObject(bref, True) # Add to Database
t.Commit() # Commit the changes
# if errorReport == None:
# return name
# # return get_layer
# else:
# return errorReport
if adoc:
DocumentExtension.CloseAndSave(adoc, path)
return ret
def main(folder, layers, bool):
# """
# Gets all the DWGs in at the folder path recursively.
# Opens each file, removes the old block references, creates a new block reference, saves the file.
# Writes a log file of the files that are processed in %temp%\D4C3D.log
# @folder: The path to folder containing DWGs
# @returns: A Dictionary of successes and failures
# """
# If critical inputs are missing returns the insturctions
if folder is None or layers is None or bool is None:
return main.__doc__
# Initialize dictionary
ret = {}
ret['Success'] = []
ret['Failure'] = []
dwgs = []
res = []
adoc = acapp.DocumentManager.MdiActiveDocument
# Get DWGs
for dirpath, dnames, fnames in os.walk(folder):
for f in fnames:
if f.endswith('.dwg'):
dwgs.append(os.path.join(dirpath, f)) # create the references to the DWG files in the folder and subfolders
# Process DWGs
for dwg in dwgs:
try:
res = set_layer_on_off_for_dwgs(dwg, layers, bool)
if res:
ret.setdefault('Success', []).append(dwg) # populate the dictionary
logging.info('File processed correctly {}'.format(dwg))
else:
ret.setdefault('Failure', []).append(dwg)
logging.error('File not processed {}'.format(dwg))
# except Exception() as ex:
# logging.exception('{}\n{}'.format(dwg, ex.message)) # add exception to log file
except:
pass
acapp.DocumentManager.CurrentDocument = adoc
# for dwg in dwgs:
# res = set_layer_on_off_for_dwgs(dwg,layers, bool)
# # if res:
# # ret.setdefault('Success', []).append(dwg)
# acapp.DocumentManager.CurrentDocument = adoc
return ret
OUT = main(IN[0], IN[1], IN[2]), lt # Using most of the default values for brevity
Please suggest the way forward and the issue.