Tag Leader Geometry

Tag Leader Geometry

sahin.ikbal
Advocate Advocate
1,246 Views
8 Replies
Message 1 of 9

Tag Leader Geometry

sahin.ikbal
Advocate
Advocate

Tag.png

 

I want to modify the Tag Leaders in certain way, But I see there is no way to directly control the Tags leader instead it is controlled by other parameters such as Head Position and leader elbow, How is the leader logically created? And what parameters effect it directly?

0 Likes
1,247 Views
8 Replies
Replies (8)
Message 2 of 9

jeremy_tammik
Alumni
Alumni

Please look at the Revit SDK samples, especially the TagBeam sample, and let us know whether that helps. Among many other thins, it allows you to 'select the tag orientation and choose whether tags have leaders', so it should cover what you need.

  

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

sahin.ikbal
Advocate
Advocate

In the example I found it's controlling Leader-end point but I am not able to understand start point control.
After a bit of tinkering I found Leaders are starting from the edge middle positions of the Bounding box of tag only when it's without leader,
But now for some test files I found its not coming from bounding box middle position Image attached(In the lower tag its elbow position is given in parallel direction from boundingbox middle but still its not straight), So I wanted to know from where does it actually come, I mean what are the things that controls this?

Tag.png

Tag.png

0 Likes
Message 4 of 9

jeremy_tammik
Alumni
Alumni

Maybe the answer requires some content creation knowledge on how to create the tag family definition?

   

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

sahin.ikbal
Advocate
Advocate

Seems like that.

For now I'm going with Boundingbox middle position, it seems to work fine most of the time.

0 Likes
Message 6 of 9

RPTHOMAS108
Mentor
Mentor

You can think of the tag as starting from the centre of the geometry bounding box but being hidden behind the tag graphics. From previous experience it doesn't seem to follow the position of reference plane intersection (I believe that is where tag head is found to be).

 

The usual approach is therefore to analyses the bounding box without a leader and centre on that. This could mean either:

A) Turning the leader off in a temporary transaction

B) Looking at the label position bounding box in relation to the family origin and then applying this same vector translation from TagHeadPosition in the project.

 

For (B) if your label is top left centred then you need to consider that aspect: how the bounding box will change due to due to text length. Additionally you can have multiple labels all with differing alignments and also other graphics so option (A) is usually the best worst option.

 

Message 7 of 9

sahin.ikbal
Advocate
Advocate
var tag = CreatedFrom.Tag;
            var taggedElement = tag.Document.GetElement(tag.GetTaggedReference());
            var taggedElementBbx = taggedElement.get_BoundingBox(tag.Document.ActiveView);
            hostMaxbbx = taggedElementBbx.Max;
            hostMinbbx = taggedElementBbx.Min;
            hostTopMid = new XYZ((hostMaxbbx.X + hostMinbbx.X) / 2, hostMaxbbx.Y, tag.TagHeadPosition.Z);
            hostLowerMid = new XYZ((hostMaxbbx.X + hostMinbbx.X) / 2, hostMinbbx.Y, tag.TagHeadPosition.Z);
            hostLeftMid = new XYZ(hostMinbbx.X, (hostMaxbbx.Y + hostMinbbx.Y) / 2, tag.TagHeadPosition.Z);
            hostRightMid = new XYZ(hostMaxbbx.X, (hostMaxbbx.Y + hostMinbbx.Y) / 2, tag.TagHeadPosition.Z);

            var tagBbx = tagBounding.BoundingBox;

            tagMaxbbx = tagBbx.Max;
            tagMinbbx = tagBbx.Min;
            tagTopMid = new XYZ((tagMaxbbx.X + tagMinbbx.X) / 2, tagMaxbbx.Y, tag.TagHeadPosition.Z);
            tagLowerMid = new XYZ((tagMaxbbx.X + tagMinbbx.X) / 2, tagMinbbx.Y, tag.TagHeadPosition.Z);
            tagLeftMid = new XYZ(tagMinbbx.X, (tagMaxbbx.Y + tagMinbbx.Y) / 2, tag.TagHeadPosition.Z);
            tagRightMid = new XYZ(tagMaxbbx.X, (tagMaxbbx.Y + tagMinbbx.Y) / 2, tag.TagHeadPosition.Z);

 

 

 tagBbxPoints = new List<PositionXYZ>()
            {new PositionXYZ(){xyz= tagLeftMid,position=Position.LeftMid },
             new PositionXYZ(){xyz=  tagTopMid, position=Position.TopMid},
             new PositionXYZ(){xyz=  tagRightMid, position=Position.RightMid},
             new PositionXYZ(){  xyz= tagLowerMid ,position=Position.LowerMid}};
            hostBbxPoints = new List<PositionXYZ>()
            {new PositionXYZ(){xyz= hostLeftMid,position=Position.LeftMid },
             new PositionXYZ(){xyz= hostTopMid, position=Position.TopMid},
             new PositionXYZ(){xyz= hostRightMid, position=Position.RightMid},
             new PositionXYZ(){  xyz= hostLowerMid ,position=Position.LowerMid}};

 

 public PositionXYZ ClosestPoint(ElemType elemType)
        {

            var combinedDistData = hostBbxPoints.SelectMany(h =>
            {
                return tagBbxPoints.Select(t =>
                {
                    return new { host = h, tag = t, dist = t.xyz.DistanceTo(h.xyz) };
                });
            });

            var closest = combinedDistData.OrderBy(x => x.dist).FirstOrDefault();

            if (elemType is ElemType.Host)
                return closest.host;
            else
                return closest.tag;

        }
        public PositionXYZ ClosestPoint(ElemType elemType, XYZ otherPoint)
        {


            var hostPoint = hostBbxPoints.OrderBy(x => x.xyz.DistanceTo(otherPoint)).FirstOrDefault();
            var tagPoint = tagBbxPoints.OrderBy(x => x.xyz.DistanceTo(otherPoint)).FirstOrDefault();


            if (elemType is ElemType.Host)
                return hostPoint;
            else
                return tagPoint;

        }

 

This are the methods I'm using to calculate the starting and end position.
Where taggedElementBbx is the Host Elements Bounding Box
and TagBbx is taken by temporary transaction and turning off the leader then taking the bounding box.

Other Point I'm giving when leader elbow is available, It's working for attached end geometry as well.


Just don't know why some cases are giving anomalies.

Message 8 of 9

sahin.ikbal
Advocate
Advocate

@RPTHOMAS108   //Looking at the label position bounding box in relation to the family origin//

what u meant by family origin here for IndependentTag?

0 Likes
Message 9 of 9

RPTHOMAS108
Mentor
Mentor

If you edit the family you can find bounding box of label in family. Then from that find the difference between the centre of the label bounding box and intersection of ref planes (which defines family origin and I believe the TagHeadPosition in project). 

 

The quirk is that in the family the label bounding box hasn't grown to show the same value in the project and as previously noted multiple labels can grow and shrink in different directions affecting the overall bounding box relationship to family origin. There may be other non-visible graphics skewing the result.

 

In the cases where you find it not quite working is there non-visible graphics in the family or other labels without parameter values etc? If all the labels are centred on origin and justified that way then it doesn't matter because overall bounding box centre doesn't change.