Revit API Forum
Welcome to Autodesk’s Revit API Forums. Share your knowledge, ask questions, and explore popular Revit API topics.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Create dimensions for familyinstance in linked file

7 REPLIES 7
SOLVED
Reply
Message 1 of 8
m.de.vriesTH5VM
2105 Views, 7 Replies

Create dimensions for familyinstance in linked file

I am trying to create dimension lines between certain parallel geometry faces of a FamilyInstance.

 

I can find the faces that need to be referenced and get their references for use in the Document.Create.NewDimension method.

If the family is instanced in the top level document then a dimension line is correctly created and displayed.

 

However, if the family is instanced in a linked file I get the error "Invalid number of references". Which makes sense I guess since the references are valid for the linked document, not for the project document itself and if they are filtered out the NewDimension method is called with an effectively empty array.

 

Then I tried to use the Reference.CreateLinkReference(RevitLinkInstance) method. According to the documentation this should create a reference in the project document based on the reference from the linked file that can be used for face based families. (the Reference is the geometry reference for a solid face from the familyinstance from a linked file and the RevitLinkInstance is set to the linked file from which that familyinstance was obtained)

Apparently that last part about 'used to create face based' must be taken quite literally because the NewDimension method throws and exception "The references are not geometric references". The ElementReferenceType of the references is set to REFERENCE_TYPE_SURFACE just like it is for FamilyInstances in the project file so whatever is different and prevents these references from being used is hidden in the proxy base class or Reference

 

It is evidently possible for dimension lines to be created for faces of families from linked files, since it can be done from the GUI. The question is if this is possible from the API and if so, how?

 

7 REPLIES 7
Message 2 of 8
FAIR59
in reply to: m.de.vriesTH5VM

For some reason, the NewDimension method expects a slightly different reference then the one you get from PickObject(). This method gets you a reference you can use.

 

		private Reference MakeLinkedReference4Dimension(Document doc, Reference r)
		{
			if (r.LinkedElementId==ElementId.InvalidElementId) return null;
			string[] ss = r.ConvertToStableRepresentation(doc).Split(':');
			string res = string.Empty;
			bool first = true;
			foreach(string s in ss)
			{
				string t = s;
				if (s.Contains("RVTLINK")) t = "RVTLINK";
				if(!first)
				{
					res = string.Concat(res,":",t);
				}
				else
				{
					res = t;
					first = false;
				}
			}
			return  Reference.ParseFromStableRepresentation(doc,res);
		}

 

Message 3 of 8
m.de.vriesTH5VM
in reply to: FAIR59

Unfortunately this solution does not seem to work for me.

 

I am not selecting the geometry faces with the GUI but through getting the GeometryInstance and filtering out the specific faces I need for the dimension lines.

 

The stable representation that is returned from from these references  have the form

21eebf7d-b67d-4e0e-a07d-c18e4b0ee2ca-0003f3d9:0:INSTANCE:21eebf7d-b67d-4e0e-a07d-c18e4b0ee2ca-0003f3e0:148:SURFACE

(and can only be converted and parsed in the linked document)

 

The sample code you provided will simply return the stable representation into what it already was (there is no string RVTLINK in the source to replace) and will the parsed reference will be ignored by the Create Dimension methods.

 

There does not seem to be any documentation about the format for stable representations so they can be used by the Create Dimension. Or any documentation about stable representations at all, really.

 

 

 

Message 4 of 8
FAIR59
in reply to: m.de.vriesTH5VM

So, you have a reference [refLink] in the LinkedDocument.

 

a966acef-f8b7-4364-94d0-fe27cf528490-001e2386:
0:
INSTANCE:
a966acef-f8b7-4364-94d0-fe27cf528490-001e23a9:
24:
SURFACE

[FamilySymbol-UniqueId:0:INSTANCE:FamilyInstance-UniqueId:'faceindex':SURFACE]

 

You need to transform that into a reference in the project document, using (as you have done)  :  linkInDoc = refLink.CreateLinkReference(linkedInstance).

 

6ffeaf1b-f233-4a23-98c1-6caa94ebffe1-001e23df:
RVTLINK/6ffeaf1b-f233-4a23-98c1-6caa94ebffe1-001e23de:
1975174:
0:
INSTANCE:
1975209:
24:
SURFACE: 

[RevitLinkedInstance-UniqueId:RVTLINK/RevitLinkedType-UniqueId:FamilySymbol-Id:0:INSTANCE:FamilyInstance-Id:'faceindex':SURFACE]

 

Finally use my adepted method on the linkInDoc reference,  to get a reference that NewDimension will accept

 

6ffeaf1b-f233-4a23-98c1-6caa94ebffe1-001e23df:

0:
RVTLINK:
1975174:
0:
INSTANCE:
1975209:
24:
SURFACE: 

[RevitLinkedInstance-UniqueId:0:RVTLINK:FamilySymbol-Id:0:INSTANCE:FamilyInstance-Id:'faceindex':SURFACE]

 

  Adepted Method:

		private Reference MakeLinkedReference4Dimension(Document doc, Reference r)
		{
			if (r.LinkedElementId==ElementId.InvalidElementId) return null;
			string[] ss = r.ConvertToStableRepresentation(doc).Split(':');
			string res = string.Empty;
			bool first = true;
			foreach(string s in ss)
			{
				string t = s;
				if (s.Contains("RVTLINK"))
				{
					if (res.EndsWith(":0")) {t = "RVTLINK";}
					else { t = "0:RVTLINK";}
				}
				if(!first)
				{
					res = string.Concat(res,":",t);
				}
				else
				{
					res = t;
					first = false;
				}
			}
			return  Reference.ParseFromStableRepresentation(doc,res);
		}
Message 5 of 8
m.de.vriesTH5VM
in reply to: FAIR59

Thank you for taking the time to provide the solution.

There is no way I could have figured this out without help.

 

p.s. I had to make a small change to your example code.

You checked if a stable representation fragment ended on ":0" but since the stable representation was split on the character ":" there is no possible way that test can succeed.

Instead I changed the foreach loop into a for loop so I can look ahead to the next fragment and compare that with the string "0"

 

Snippet

if (idx + 1 < ss.Length && 0 == string.Compare(ss[idx + 1], "0"StringComparison.InvariantCultureIgnoreCase))
{
	t = "RVTLINK";
}
else
{
	t = "0:RVTLINK";
}
Message 6 of 8
RvdScheur
in reply to: FAIR59

@FAIR59@m.de.vriesTH5VM  I'm encoutering the same problem. When I use my code on elements within my current Revit document the (wall)dimension is placed. When i use my code on the exact same building, but linked to my main model the following exception is shown:

'Invalid number of references.'
 
I used your code, but the references I input have a LinkedElementId of -1. I changed the code to always run for any given reference (since they are all linked) and input both the reference and their linked file doc. This gave me the following exception:
'Attempted to read or write protected memory. This is often an indication that other memory is corrupt.'
 
Running in Revit 2023. 
 
Would you happen to know if I'm doing something wrong? If there is any more information I can give, just ask. 

EDIT: Somehow my StableRepresentation never has 'RVTLINK' in the string name. I'm inputting the linked document else I get the exception: 
Reference contained element ids not found in this document.

 

Message 7 of 8
RvdScheur
in reply to: RvdScheur

For anyone that has been googling/searching for a solution on linked file walls:

 

I found this solution is harder to achieve with walls in linked files. Walls don't give correct references that can be used to reformat. The problem we found was that walls won't give you a GeometryInstance (which belongs in the List of GeometryElement and is a GeometryObject). Walls only give solids (then faces, then references), therefor the method GetSymbolGeometry() can not be used.

To get the correct reference we used the following line:

 

Reference stRef = r.CreateLinkReference(GetLinkInstance(document, wallFromReference));

 


Where r is the face.reference and GetLinkInstance() the method below:

 

 public RevitLinkInstance GetLinkInstance(Document doc, Wall wall)
        {
            IList<Element> linkInstances = new FilteredElementCollector(doc).OfClass(typeof(RevitLinkInstance)).ToElements();
            Document walldoc = wall.Document;

            foreach (RevitLinkInstance linkinstance in linkInstances)
            {
                if (linkinstance.Name.Contains(walldoc.Title))
                {
                    return linkinstance;
                }
            }

            return null;
        }

 

 
From there on you can reformat the string as this blog and Jeremy pointed out.

 

https://thebuildingcoder.typepad.com/blog/2016/04/stable-reference-string-magic-voodoo.html

Message 8 of 8

For those encountering the same issue and coding in Python:

Dimensioning elements from linked files with Dynamo (maciejglowka.com)

It may help you save even more time!

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk DevCon in Munich May 28-29th


Rail Community