Tag Width/Height or Accurate BoundingBox of IndependentTag

FlorisvdG
Advocate
Advocate

Tag Width/Height or Accurate BoundingBox of IndependentTag

FlorisvdG
Advocate
Advocate

Hello RevitCoders,

 

I'm trying to get the width and height of IndependentTags on a sheet.

Turns out the boundingbox goes all the way to the element to which the tag is assigned. So the boundingbox is almost always a lot bigger than the tag itself.

 

Tag doesn't have .Width or .Height property like a TextNote does.

 

Is there any workaround to get the actual width and height of a Tag?

0 Likes
Reply
3,271 Views
16 Replies
Replies (16)

jeremytammik
Autodesk
Autodesk

Dear Floris,

 

Thank you for your query.

 

I find it surprising to hear that the bounding box of the tag is affected by the element which is being tagged.

 

Can you provide an example of that?

 

Here are some notes by The Building Coder on setting the size if a text note and text note width calculation:

 

 

I assume that similar principles would apply to tags as well.

 

I hope this helps.

 

Best regards,

 

Jeremy

 



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder

0 Likes

FlorisvdG
Advocate
Advocate

 

Capture.PNG

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Here's an example. As you can see the boundingbox expands when distance from tag to element is increased.

@jeremytammik, since you are surprised, I reccon this is irregular behaviour for a tag? Could it be a family thing?

0 Likes

jeremytammik
Autodesk
Autodesk

Dear Floris,

 

Thank you for your update and sample image.

 

I am surprised by many things, every day, so that is nothing remarkable.

 

In your image, it looks as if the tag's bounding box includes some point or something on the element being tagged.

 

You could try to create a temporary transaction, move the tag directly over the tagged element, regenerate the model, query it for its bounding box, and then roll back the transaction without committing it, so nothing changes in the model, cf. the 'temporary transaction trick':

 

https://thebuildingcoder.typepad.com/blog/about-the-author.html#5.53

 

I hope this helps.

 

Best regards,

 

Jeremy

 



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder

0 Likes

david_rock
Enthusiast
Enthusiast

I'm getting the same result, the bounding box is including an imaginary leader even if the leader is off. This issue only seems to occur on horizontally modeled system families.

If you hover over the tag without selecting it, Revit highlights an imaginary line to the tagged element. This imaginary line is included in the bounding box.

I wish I knew how to prevent this.

Kind Regards

David

 

 

 

0 Likes

david_rock
Enthusiast
Enthusiast

Following is my code to get the IndependentTag width by creating a new tag in the center of the reference. Needs some work but seems to work OK.

I was using this to left justify a selection of tags, however I cannot work out how to move the original tag from the TagHeadPosition to the selected point, less half the width using this function.

 

Public Shared Function GetIndependentTagWidth(ByVal objIndependentTag As IndependentTag) As Double
        Dim dblWidth As Double = 0
        Try
            Dim objDocument As Document = objIndependentTag.Document
            Dim objActiveView As View = objDocument.ActiveView
            Using transGroup As New TransactionGroup(objDocument)
                transGroup.Start("Transaction Group")
                Using firstTrans As New Transaction(objDocument)
                    Dim objReference As Reference = objIndependentTag.GetTaggedReference
                    Dim objBoundingBoxXYZ As BoundingBoxXYZ = objDocument.GetElement(objReference.ElementId).BoundingBox(objActiveView)
                    Dim boundingBoxMaxX As Double = objBoundingBoxXYZ.Max.X
                    Dim boundingBoxMaxY As Double = objBoundingBoxXYZ.Max.Y
                    Dim boundingBoxMinX As Double = objBoundingBoxXYZ.Min.X
                    Dim boundingBoxMinY As Double = objBoundingBoxXYZ.Min.Y
                    Dim elementXYZ As New XYZ(boundingBoxMaxX - ((boundingBoxMaxX - boundingBoxMinX) / 2), boundingBoxMaxY - ((boundingBoxMaxY - boundingBoxMinY) / 2), 0)
                    firstTrans.Start("First Transaction")
                    Dim objNewIndependentTag As IndependentTag = IndependentTag.Create(
                        objDocument, objActiveView.Id, objIndependentTag.GetTaggedReference,
                        False, TagMode.TM_ADDBY_CATEGORY, objIndependentTag.TagOrientation, elementXYZ)
                    objBoundingBoxXYZ = objNewIndependentTag.BoundingBox(objActiveView)
                    boundingBoxMaxX = objBoundingBoxXYZ.Max.X
                    boundingBoxMinX = objBoundingBoxXYZ.Min.X
                    dblWidth = boundingBoxMaxX - boundingBoxMinX
                    objIndependentTag.HasLeader = False
                    firstTrans.Commit()
                    objBoundingBoxXYZ = objIndependentTag.BoundingBox(objActiveView)
                End Using
                transGroup.RollBack()
            End Using
        Catch ex As Exception
            Msgbox(ex.message)
        End Try
        Return dblWidth
    End Function

Kind Regards

David

0 Likes

jeremytammik
Autodesk
Autodesk

Dear David,

 

Thank you for the cool idea and efficient solution. Yet another example of the temporary transaction trick.

 

Two questions:

 

I suppose you could also omit the transaction group, and just use the naked, unwrapped, transaction directly for this purpose?

 

Could you possibly also omit the creation of a new tag, and just set HasLeader to false on the original tag within the temporary transaction instead?

 

You ask, how to move the original tag from the TagHeadPosition to the selected point, less half the width.

 

It might be very simple. Does this discussion answer your question?

 

https://thebuildingcoder.typepad.com/blog/2013/10/move-tag-to-host-location.html

 



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder

0 Likes

chau.npt
Participant
Participant

Because it includes tag's leader regardless the leader is turned on or off.

0 Likes

sonicer
Collaborator
Collaborator

Move tag to center point of leader and get boudingbox and then move the tag to previous position 

AmitMetz
Explorer
Explorer

Following the helpful comments above. here is a method that return tag dimensions.

few comments:

  1. first we need to make sure the LeaderEndCondition is free in order to find the LeaderEndPoint.
  2. move the tag and it's elbow to LeaderEndPoint.
  3. we get the correct BoundingBox only after moving the tag and it's elbow, and  commit the Transaction.
  4. I tried to use an unwrapped  transaction.rollback() without transactionGroup, but it didn't work. so if we want to keep the tag in it's original location first we commit the transaction and than rollback the transactionGroup.
public static Tuple<double, double> GetTagDimension(Document doc, IndependentTag newTag)
{
	//Dimension to return
	double tagWidth;
	double tagHeight;

	//Tag's View and Element
	View sec = doc.GetElement(newTag.OwnerViewId) as View;
	XYZ rightDirection = sec.RightDirection;
	XYZ upDirection = sec.UpDirection;
	Reference pipeReference = newTag.GetTaggedReferences().First();
	//Reference pipeReference = newTag.GetTaggedReference(); //Older Revit Version

	using (TransactionGroup transG = new TransactionGroup(doc, "Tag Dimension"))
	{
		transG.Start();

		using (Transaction trans = new Transaction(doc, "Tag D"))
		{
			trans.Start();

			newTag.LeaderEndCondition = LeaderEndCondition.Free;
			XYZ leaderEndPoint = newTag.GetLeaderEnd(pipeReference);
			newTag.TagHeadPosition = leaderEndPoint;
			newTag.SetLeaderElbow(pipeReference, leaderEndPoint);

			trans.Commit();
		}

		//Tag Dimension
		BoundingBoxXYZ tagBox = newTag.get_BoundingBox(sec);
		tagWidth = (tagBox.Max - tagBox.Min).DotProduct(rightDirection);
		tagHeight = (tagBox.Max - tagBox.Min).DotProduct(upDirection);

		transG.RollBack();
	}

	return Tuple.Create(tagWidth, tagHeight);
}

Regards,
Amit

jeremy_tammik
Autodesk
Autodesk

Dear Amit,

 

Thank you very much for the useful code snippet and nice implementation!

 

I think I'll add that to The Building Coder samples asap to ensure it is preserved and easily found.

 

Cheers,

 

Jeremy

  

Jeremy Tammik Developer Advocacy and Support + The Building Coder + Autodesk Developer Network + ADN Open

jeremy_tammik
Autodesk
Autodesk

Dear Amit,

 

Looking more closely at your code, I wonder why you pass in the Document argument.

 

Is it not always the same as the tag's document, accessible via newTag.Document?

 

Is that intentional? Can they differ?

 

Thank you!

 

Cheers,

 

Jeremy

  

Jeremy Tammik Developer Advocacy and Support + The Building Coder + Autodesk Developer Network + ADN Open
0 Likes

AmitMetz
Explorer
Explorer

Hi Jeremy,

Thank you for your feedback.
It's not intentional, I guess it will be cleaner and better to retrieve the document via 
newTag.Document as suggested.


Happy to make it in the The Building Coder samples 🙂

Regards,
Amit

 

0 Likes

jeremy_tammik
Autodesk
Autodesk

Thank you for clarifying and confirming so quickly! I shared this thread on The Building Coder here:

 

https://thebuildingcoder.typepad.com/blog/2022/07/tag-extents-and-lazy-detail-components.html#2

 

The method is added to The Building Coder samples here:

 

https://github.com/jeremytammik/the_building_coder_samples/blob/master/BuildingCoder/CmdSetTagType.c...

  

Thank you for sharing it!

  

Jeremy Tammik Developer Advocacy and Support + The Building Coder + Autodesk Developer Network + ADN Open
0 Likes

jeremy_tammik
Autodesk
Autodesk

Steven Micaletti, VDC Software & Technology Developer adds a comment to this method on LinkedIn:

  

https://www.linkedin.com/feed/update/urn:li:activity:6952994276876169216?commentUrn=urn%3Ali%3Acomme...

 

Good stuff; however, the GetTagExtents() implementation is missing a critical step - rotating the Pipe. The Pipe in the thread is at an angle, while the tag is not, and this is not generally how MEP elements are tagged. MEP tag families usually have the "rotate with component" option enabled, and in that scenario the bounding box returned is unusable. We must first disconnect and rotate the pipe to be model axis aligned before we set the TagHeadPosition, get the BoundingBox, and RollBack() the Transaction.

 

Thank you, Steven, for pointing this out!

  

Jeremy Tammik Developer Advocacy and Support + The Building Coder + Autodesk Developer Network + ADN Open
0 Likes

gediminas67YAA
Explorer
Explorer

Hi,
I have some problems with IndependentTag Width and Height.

I use these code lines from the example:

tagWidth = (tagBox.Max - tagBox.Min).DotProduct(rightDirection);
tagHeight = (tagBox.Max - tagBox.Min).DotProduct(upDirection);

 

Script works fine only when tag is aligned with xyz axis. Here I found that tag width is 0.2966535433071 and height 0.22299868766404.

 

Bounding box min and max points marked with green lines.

gediminas67YAA_0-1658143596460.png

 

 

In another case tag is rotated only on z axis

gediminas67YAA_1-1658143726091.png

Tag bounding box min and max looks like this:

gediminas67YAA_2-1658143791888.png

With such values tagWidth and tagHeight are wrong..

gediminas67YAA_3-1658145485085.png

 

I cant find any way to get tag size.

Any help would be appreciated.

 

 

jeremy_tammik
Autodesk
Autodesk

Yes. As Steven Micaletti suggests in his comment above, you need to ensure that all possible tag rotations are temporarily removed before you try to determine its extents.

  

Jeremy Tammik Developer Advocacy and Support + The Building Coder + Autodesk Developer Network + ADN Open