ImportSAT using Python

@jacob.small , I tried with IFailuresPreprocessor, but it didn’t resolved the warning as well the files are created twice in the output folder. Also I went through the Failure classes in RevitAPI.doc but couldn’t find this warning in any of the classes.
Hence went with “LostAcisObjectsOnImport” which is similar to the error

############################################################
########## configure the Dynam python environment ##########
############################################################
import clr, os # import the CLR (Common language Runtime) and OS modules
clr.AddReference('RevitAPI') #add the Revit API library to the CLR 
from Autodesk.Revit.DB import FilteredElementCollector, ImportPlacement, ImportUnit, SATImportOptions, SaveAsOptions, Transaction, View #import the reelevant sectiosn of the Revit API
clr.AddReference('RevitServices') #add the Revit services library to the CLR 
from RevitServices.Persistence import DocumentManager #import the document manager 
from RevitServices.Transactions import TransactionManager #import the transaciton manager
from Autodesk.Revit.DB import Transaction, IFailuresPreprocessor, BuiltInFailures, UV
from System.Collections.Generic import List

############################################################
################# get the active applicton #################
############################################################
app = DocumentManager.Instance.CurrentUIApplication.Application #gets the application 

############################################################
############ inputs from the Dynamo environment ############
############################################################
satDir = IN[0] #the directory with the SAT files
rfaDir = IN[1] #the directory for the RFA files
famTemplatePath = IN[2] #the template path to use

############################################################
################## get the sat file paths ##################
############################################################
satPaths = [ "{0}\{1}".format(satDir,f) for f in os.listdir(satDir) if ".sat" in f ]

############################################################
########## create and configure the SaveAsOptions ##########
############################################################
saveOptions = SaveAsOptions() #start a new save as options object
saveOptions.OverwriteExistingFile = True #overwrite any existing file
saveOptions.Compact = True #compact the file
saveOptions.MaximumBackups = 1 #set the number of backups to 1 - you're making a new file so really this could be zero, but that's not an allowed value

############################################################
######## create and configure  the SATImportOptions ########
############################################################
satOpt = SATImportOptions() #start a new sat import options object
satOpt.Placement = ImportPlacement.Origin #set the import placement to the origin
satOpt.Unit = ImportUnit.Foot #set the import unit to feet 
############################################################
	# NOTE: you might want to not always use feet, but 
	# instead pull the units from the SAT itself and find 
	# the assocaited value for the import unit. Look into 
	# the SAT file format  and ImportUnit class of the 
	# Revit API for information on how to do so.
############################################################

############################################################
############# setup the OUT variable as a list #############
############################################################
results = [] #an empty list for now 

class SATWarningSwallower(IFailuresPreprocessor):
    def PreprocessFailures(self, failuresAccessor):
        fail_list = List[FailureMessageAccessor]()
        fail_acc_list = failuresAccessor.GetFailureMessages()
        for failure in fail_acc_list:
            failure_id = failure.GetFailureDefinitionId()
            failure_type = BuiltInFailures.ImportFailures.LostAcisObjectsOnImport.Guid
            if failure_id == failure_type:
                failuresAccessor.DeleteWarning(failure)
        return FailureProcessingResult.Continue

############################################################
###### iterate the sat files to generate new families ######
############################################################
for satPath in satPaths: #for every SAT path in the list of sat paths
	# Get the rfa path, and start a new family document 
	rfaPath = satPath[:-4].replace(satDir,rfaDir)+".rfa" #take the SAT path and replace the directory with the RFA directory, and the .sat extention with the .rfa extension
	doc = app.NewFamilyDocument(famTemplatePath) #start a new document from the family template path
	#start a new transaction in the family document
	transaction = Transaction(doc,"import sat") #build a new transaction
	transaction.Start() #start the transaction 
	#get the first 3d view we can find as we'll need a view to run the import in
	view_fec = FilteredElementCollector(doc).OfClass(View) #get all views in the file
	view1 = [v for v in view_fec if str(v.ViewType) == 'ThreeD' and not v.IsTemplate] #for each view in the collector, filter out any which are not a ThreeD type or are a template
	#if a 3d view was found perform the following
	if len(view1) >0:
		view1 = view1[0] #set view1 to the first view found
		#import the SAT and commit the change
		satImport = doc.Import(satPath,satOpt, view1) # import the SAT geometry
		transaction.Commit() #commit the transaction
		failOpt = transaction.GetFailureHandlingOptions()
		failOpt.SetFailuresPreprocessor(SATWarningSwallower())
		transaction.SetFailureHandlingOptions(failOpt)
		#save the family and close it 
		doc.SaveAs(rfaPath, saveOptions) #save the familyw tih the previously defined options 
		doc.Close(False) #close the family document
		results.append(rfaPath) #append the rfa extension to the results list
	#otherwise
	else:
		results.append("No 3d view was found. Please pick a new family template.") #append a message to the results list

############################################################
####### return the results to the Dynamo environment #######
############################################################
OUT = results #set the OUT varaible to the results list 

Perhaps. Search around for taking action on warnings with Python; there are several examples here on the forum and on the web.

The only options will be to hit ok or cancel - this is Revit saying that the SAT isn’t functional. More likely you’ll want to check the file sizes as something with nothing it will be quite a bit smaller than one with imports. With that info you’ll know which SAT is problematic.

As far as duplicates go, are you sure those are the backup files which will be created on the second run?

Hi @jacob.small, yes I tried with our previous code too… for the first few runs the files are not duplicating but after that it get duplicated once.

Can you show a screenshot of the duplicate rfa file names adjacent to the sat names? I can’t reproduce and windows should prevent this in general.

Hi @jacob.small, please find the snapshot. On the third run I got this way of working.

The .0001 files are the backups, which cannot be prevented as the family options requires a value greater than 0 or a value of -1 (use Revit’s defaul which I think is 3 but do t quite me) for the maximum backup count.

There are a few tools around to delete backups, or you could do a clean up by using Dynamo to delete or archive any rfas in the folder prior to running the Python.