DELETE / ERASE Floor Layer

Hi,

Another structure software, that I’m importing in my template… is creating a floor with a lot layers, that is wrong.

image

Should have only one layer.

OK.

So, i need remove 3 of 4 layers, to leave only one.

image

Hi @daniel.petrin,

Yes this is possible, here is some Python code to help you out…

LayerFunctions (Py)

import clr
import System

clr.AddReference("RevitAPI")
from Autodesk.Revit.DB import *

OUT = System.Enum.GetValues(MaterialFunctionAssignment)

The above corresponds to the Function Field as shown below…

image

FloorType.DeleteLayers (Py)

import clr

import System
from System.Collections.Generic import *

clr.AddReference("RevitServices")
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
doc =  DocumentManager.Instance.CurrentDBDocument
app = DocumentManager.Instance.CurrentUIApplication.Application

clr.AddReference("RevitNodes")
import Revit
clr.ImportExtensions(Revit.Elements)
clr.ImportExtensions(Revit.GeometryConversion)

clr.AddReference("RevitAPI")
from Autodesk.Revit.DB import *

def tolist(obj1):
	if hasattr(obj1,"__iter__"): return obj1
	else: return [obj1]

# Inputs...
ft = tolist(UnwrapElement(IN[0]))[0]
layFuncs = tolist(UnwrapElement(IN[1]))
inCore = tolist(IN[2])[0]

# Output...
outList = []
xErrInfo = []

# Temp Variables...
layersToKeep = List[CompoundStructureLayer]()

# Out error Dictionaries for CompoundStructure.IsValid() method...
isValidError = clr.StrongBox[IDictionary[int, CompoundStructureError]]()
isValidError2Layer = clr.StrongBox[IDictionary[int, int]]()

# Get Compound Structure...
compStr = ft.GetCompoundStructure()
# Get and sort layers by Id in reverse order (Highest id first)...
layers = list(compStr.GetLayers())
layers.sort(key=lambda x: x.LayerId, reverse=True)

# Test if there is only one Layer within Core Boundaries. If so, then we will not include this for deleting...
if compStr.GetFirstCoreLayerIndex()-compStr.GetLastCoreLayerIndex() == 0:
	inCore = False

# Test if there is at least one layer with the function passed in. Otherwise, keep all layers within core boundaries...
if inCore:
	i = compStr.GetFirstCoreLayerIndex()
	while i <= compStr.GetLastCoreLayerIndex():
		if compStr.GetLayerFunction(i) in layFuncs:
			inCore = True
			break
		else:
			inCore = False
		i = i+1

# Keep only the layers in which match the Function given and if they are in core boundary if inCore = True...
for l in layers:
	if inCore:
		if l.Function in layFuncs and compStr.IsCoreLayer(l.LayerId):
			layersToKeep.Add(l)
	else:
		if compStr.IsCoreLayer(l.LayerId):
			layersToKeep.Add(l)			

# Reset Composite Structure and pass in the Layers marked to keep...
TransactionManager.Instance.EnsureInTransaction(doc)
try:
	compStr.SetLayers(layersToKeep)
	if compStr.IsValid(doc, isValidError, isValidError2Layer):
		ft.SetCompoundStructure(compStr)
		outList.append("Updated")
	else:
		outList.append("Failed:-\nNot Valid")
except Exception, e:
	outList.append("Failed:-\n" + e.message)
TransactionManager.Instance.TransactionTaskDone()

xErrInfo = list(isValidError.Value)

OUT = outList, xErrInfo

Note: If you have multiple Layers of the same function within the core boundaries, these will not be deleted as there is no way for me to really tell how you want to treat these to leave just one. So I have opted to just keep them.

Hope this helps…

Cheers,
Dan

8 Likes