Preventing duplicate tags

Hi,
I’m working on a script to place conditional tag types at specific elements, for this I use a modified version of the Archi_labs tool (I changed it so that it can handle a list of tags as input, rather than only a single tag).

However when I run the script more than once, it will place duplicate instances of the tag. I am looking for a way to prevent this.
It would be preferable to remove tags that already exist at a given location, or all tags that are similar to the input tags (however any working solution would be very welcome). I have noticed that with the element.location node, you can’t get the XYZ of a tag. I think this is because you can only get the position of the tag head, and this can only be done via the API (Python).
Is there a good way to do any of this quickly?

Hi @Bram_Weinreder1

Show us your complete graph with modified version of archi-lab tool.

IN[6] is a list of all current duct- and pipe-tags in the view. Rest should be fairly self explanatory I hope :slight_smile:

import clr
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *

# Import Element wrapper extension methods
clr.AddReference("RevitNodes")
import Revit
clr.ImportExtensions(Revit.Elements)

# Import geometry conversion extension methods
clr.ImportExtensions(Revit.GeometryConversion)

# Import DocumentManager and TransactionManager
clr.AddReference("RevitServices")
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager

doc = DocumentManager.Instance.CurrentDBDocument
uiapp = DocumentManager.Instance.CurrentUIApplication
app = uiapp.Application

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

import sys
pyt_path = r'C:\Program Files (x86)\IronPython 2.7\Lib'
sys.path.append(pyt_path)

#The inputs to this node will be stored as a list in the IN variable.
dataEnteringNode = IN

locationPts = UnwrapElement(IN[0])
tagType = UnwrapElement(IN[1])
elements = UnwrapElement(IN[2])

if IN[4] != None:
	link = UnwrapElement(IN[4])
else:
	link = None
	
RunIt = IN[5]

existingTags = UnwrapElement(IN[6])

tagPositions = []





if isinstance(IN[3], list):
	views = [UnwrapElement(i) for i in IN[3]]
else:
	views = UnwrapElement(IN[3])

def toRvtPoint(point):
	return point.ToXyz()

def toRvtId(_id):
	if isinstance(_id, int) or isinstance(_id, str):
		id = ElementId(int(_id))
		return id
	elif isinstance(_id, ElementId):
		return _id

def GetUVPoint(pt):
	if type(pt) == Autodesk.DesignScript.Geometry.Point:
		return Autodesk.Revit.DB.UV(pt.X, pt.Y)
	elif type(pt) == Autodesk.DesignScript.Geometry.UV:
		return Autodesk.Revit.DB.UV(pt.U, pt.V)

def CreateSpaceTag(space, uv, view):
	doc = DocumentManager.Instance.CurrentDBDocument
	return doc.Create.NewSpaceTag(space, uv, view)

tagTypeId = [];
for tag in tagType:
	tagTypeId.append(toRvtId(tag.Id))

try:
	errorReport = None
	TransactionManager.Instance.EnsureInTransaction(doc)
	tags = []
	if isinstance(views, list):
		for i,j,k,t in zip(elements, views, locationPts, tagTypeId):
			location = toRvtPoint(k)
			tag = doc.Create.NewTag(j, i, False, TagMode.TM_ADDBY_CATEGORY, TagOrientation.Horizontal, location)
			tag.ChangeTypeId(t)
			tags.append(tag)
	else:
		for i, j, t in zip(elements, locationPts, tagTypeId):
			location = toRvtPoint(j)
			tag = doc.Create.NewTag(views, i, False, TagMode.TM_ADDBY_CATEGORY, TagOrientation.Horizontal, location)
			tag.ChangeTypeId(t)
			tags.append(tag)
	TransactionManager.Instance.TransactionTaskDone()
	result = tags
except:
	# if error accurs anywhere in the process catch it
	import traceback
	errorReport = traceback.format_exc()

#Assign your output to the OUT variable
if errorReport == None:
	OUT = result
else:
	OUT = errorReport

@Bram_Weinreder1 Correct me if i am wrong. Your trying to get location of existing tags and move them by x distance and place new tags?

No… with ‘skip over’ I mean in code. If at a certain position the required tag already exists (placed in a previous run), then there’s no need to place it again. Hence, that portion of the code can be skipped in that iteration.
Or given the short execution time of the script, it would also be OK to remove all tags from the view that are similar to the ones I’m trying to place.

Found a working solution.
For the ‘skipping over’ part I’d need to invest time that I don’t have, but right now I have it working for all tags of a specific family type in the current view.
For all tags in the project I got the OwnerView (Clockwork package), then crossreferenced with the active view. For those elements I crossreference with the different tag types that need to be placed. Tags of the same type get deleted.

This interfered with the tags that need to be placed, so I implemented a short delay in that function. Now only one instance of the tag will be associated with the element on a given view, every time.

Hi Bram,

Looks as though you should be able to get the Tagged Element that’s related to each existing Tag: http://dynamobim.org/forums/topic/get-tag-host-element/.

Then you could filter those elements out, so you only place new tags on un-tagged elements.

I explored that avenue earlier but wasn’t aware of the Delete node back then. But I like the idea, thanks.
I can also use this to ignore elements that already have the right tag type (or else delete the associated tag if it is of a different type). Definitely putting it on the to-do list.

Hi There

I came across your post because of a problem that i have.

We have dedicated equipment tagging views in a project. Some how, someone created duplicate tags for all these elements in the rooms. ie. 1 x component and 3 x tags for that component.

Is there a way to get rid of duplicated tags? (not elements).

If someone has made a graph that does this please share, it will be greatly appreciated and kind of critical.

regards!

Hi Dirk,

I think there is a way. For a small part it will look like the implementation I posted earlier. I have done some tests with a Python script or custom node I found to detect the family that a tag was attached to, but I can’t find it anymore.

So here’s the workflow I recommend:

  • find tags of all categories that you’re interested in and join them in a list (as implemented on the left side of my screenshot).
  • find a way to retrieve the owner element of that tag. It can be done but it is going to take some effort.
  • Get all unique elements in a flattened list of owner families.
  • Next, use the list of unique owner families to find out which of them appears more than once (‘all indices of’, lacing cross product). This should give you sublists of indices, that corresponds to duplicate tags.
  • Remove the first item of each of the sublists (list.removefirstitem, lacing: longest). The sublists should only contain all the duplicate tags after this.
  • Using the document.delete node, you can remove all these duplicate tage.

Give it a spin, see how far you get, if you’re stuck then post a screenshot of what you have.