Get Default Tag Location

floretti
Advocate
Advocate

Get Default Tag Location

floretti
Advocate
Advocate

Hi all and thanks for reading.

 

When tagging an element in the UI, Revit automatically picks up a certain point for the tag which, as far as I know, seems to be related to the visible solids. Is there a way to get this point without having to resort to some convoluted maths?

 

I'm creating tags via the API and I've tried the LocationPoint and the center of the BoundingBox but neither are ideal.

 

Manually via the UI (the desired result)

FabioLorettiOliveira_1-1678940638213.png

 

Via LocationPoint (it looks like it's the origin point in the family)

FabioLorettiOliveira_2-1678940696194.png

 

Via center of BoundingBox (these families have different family types at different sizes, which is probably causing the bounding box to be bigger than the visible element)

FabioLorettiOliveira_3-1678940775322.png

 

 

These are the articles I've gone through so far.

https://forums.autodesk.com/t5/revit-api-forum/placing-a-door-tag/m-p/8850786

https://github.com/jeremytammik/SetoutPoints

https://forums.autodesk.com/t5/revit-api-forum/bounding-box-bounds/m-p/9922479

https://forums.autodesk.com/t5/revit-api-forum/independent-tag/m-p/8243286

https://forums.autodesk.com/t5/revit-api-forum/independent-tag-position/m-p/8922777

 

Thank you.

0 Likes
Reply
Accepted solutions (1)
646 Views
3 Replies
Replies (3)

caroline.gitonga
Autodesk
Autodesk

Hi,

A bit of 'convoluted maths' will be required to getting the 'desired optimal' location of the tags. For a door you may be required to get arcs associated with the plan view of a door using ExporterIFCUtils.GetDoor2DArcsFromFamily With the arc info you may be able to determine arcs midpoint and centre point. Kindly, refer to this thread for more information: https://forums.autodesk.com/t5/revit-api-forum/get-an-arcs-midpoint-and-centre-point-error/td-p/7320.... With this location you now move your tag to the calculated optimal location.

This forum thread has broken down the whole solution on how to achieving the actual location of the tag, you may have a look: https://forums.autodesk.com/t5/revit-api-forum/place-a-door-tag-at-the-center-of-the-hosting-door-sw...

Carol Gitonga, Developer Advocacy and Support, ADN Open

floretti
Advocate
Advocate

Hi Caroline,

 

Thanks for the reply. I went through these links and I can see how they are useful if you are tagging doors. Fortunately, doors is not something I'm trying to tag at this point in time and those articles are very specific to deal with arcs from doors and not helpful to me. In fact, if you check the list of links I put in the post, the first one is about doors.

 

I'm trying to tag supermarket refrigeration cases, which are mostly rectangles and should be simpler than doors. The only tricky part about them is that they have several family types at different sizes, which is affecting the position of the tag if I try to use their BoundingBox.

 

Thanks again.

floretti
Advocate
Advocate
Accepted solution

I just realised I worked out a solution but never posted it in case someone needs it but here it is.

 

/// <summary>
/// Returns the centre point of a family (in 2D) within a project taking into consideration only
/// the visible geometry. Useful for tagging families. Note this method should be under a Try/Catch
/// depending on which families instances are passed as arguments as some families have no geometry
/// and will raise an exception.
/// </summary>
/// <param name="famInst"></param>
/// <returns></returns>
public static XYZ GetFamilyGeometryCentre2D(FamilyInstance famInst)
{
	// Lists of boundary box corners
	var bbCornersX = new List<double>();
	var bbCornersY = new List<double>();

	var allGeom = famInst.get_Geometry(new Options()
	{
		ComputeReferences = false,
		IncludeNonVisibleObjects = false
	});

	var famInstTransf = famInst.GetTransform();

	foreach (object obj in allGeom)
	{
		GeometryInstance geomInst = obj as GeometryInstance;

		if (geomInst != null)
		{
			foreach (object solidObj in geomInst.GetSymbolGeometry())
			{
				if (solidObj.GetType() == typeof(Solid))
				{
					Solid solid = solidObj as Solid;
					if (solid.Volume == 0) continue;

					var symbBB = solid.GetBoundingBox();
					var symbBBtransf = symbBB.Transform;  // This "decentralises" the solids from around the origin.

					// Get real position of solid bounding box within family
					var symbBbmin = symbBBtransf.OfPoint(symbBB.Min);
					var symbBbmax = symbBBtransf.OfPoint(symbBB.Max);

					// List out real corners of family solids within family
					bbCornersX.Add(symbBbmin.X);
					bbCornersX.Add(symbBbmax.X);
					bbCornersY.Add(symbBbmin.Y);
					bbCornersY.Add(symbBbmax.Y);
				}
			}
		}
	}

	var minX = bbCornersX.Min();
	var minY = bbCornersY.Min();
	var maxX = bbCornersX.Max();
	var maxY = bbCornersY.Max();

	// Find centre point within family
	var ctrPtX = (maxX - minX) / 2 + minX;
	var ctrPtY = (maxY - minY) / 2 + minY;
	var famCtrPt = new XYZ(ctrPtX, ctrPtY, 0);

	// Centre point within project
	var famProjCtrPt = famInstTransf.OfPoint(famCtrPt);

	return famProjCtrPt;
}
0 Likes