Create dimension to wall centerline, center of core, faces of core

Create dimension to wall centerline, center of core, faces of core

boostyourbim
Advocate Advocate
11,500 Views
53 Replies
Message 1 of 54

Create dimension to wall centerline, center of core, faces of core

boostyourbim
Advocate
Advocate

I'm trying to create dimensions to walls via the API. It is possible to get a reference to a wall's centerline, center of core, and faces of core? These options are avaiable when creating dimensions in the Revit UI.

0 Likes
11,501 Views
53 Replies
Replies (53)
Message 21 of 54

aricke59
Enthusiast
Enthusiast

Hi Jeremy,

 

I don't think that the Wall class (part of HostObject) intersects with FamilyInstance class, therefore I can't see how it is possible to do what you are suggesting. Am I missing something?

0 Likes
Message 22 of 54

jeremytammik
Autodesk
Autodesk

I guess you are right. Well, the wall centre line is always in the middle of the wall. Does that help?



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

0 Likes
Message 23 of 54

aricke59
Enthusiast
Enthusiast
I was really hoping to get references to the core layers. A client needs to
dimension to these.
0 Likes
Message 24 of 54

FAIR59
Advisor
Advisor

you can analyze the references of a dimension that measures the core using Reference.ConvertToStableRepresentation(document).

using that information you can then construct the references as follows:

 

			string unique = wall.UniqueId;
refString = string.Format("{0}:{1}:{2}",unique,-9999,1); Reference wall_centre = Reference.ParseFromStableRepresentation(doc,refString); refString = string.Format("{0}:{1}:{2}",unique,-9999,2); Reference core_outer = Reference.ParseFromStableRepresentation(doc,refString); refString = string.Format("{0}:{1}:{2}",unique,-9999,3); Reference core_inner = Reference.ParseFromStableRepresentation(doc,refString); refString = string.Format("{0}:{1}:{2}",unique,-9999,4); Reference core_centre = Reference.ParseFromStableRepresentation(doc,refString);
Message 25 of 54

aricke59
Enthusiast
Enthusiast

Thanks for that FAIR59. Your suggestion set me on the right path however I found that the 1,2,3,4 etc seemed to be different in 2018 using .Net. The results I got are as follows:

 

1 - Overall Centre

2 - No idea what this one gives. It is consistent but not anything of meaning to me 

3 - Core Exterior Face

4 - Core Interior Face

5 - Core Centre

6 - Exterior Wall Face

7 - Interior Wall Face

 

When I created multi layer walls (i.e., 5 layers and up) I started to get all manner of numbers e.g., 200, 32, etc when I probed the reference array using Reference.ConvertToStableRepresentation(document). Even dimensioning  the same wall types resulted in different numbers coming up for the same layers.  

 

Thanks again!


@FAIR59 wrote:

you can analyze the references of a dimension that measures the core using Reference.ConvertToStableRepresentation(document).

using that information you can then construct the references as follows:

 

			string unique = wall.UniqueId;
refString = string.Format("{0}:{1}:{2}",unique,-9999,1); Reference wall_centre = Reference.ParseFromStableRepresentation(doc,refString); refString = string.Format("{0}:{1}:{2}",unique,-9999,2); Reference core_outer = Reference.ParseFromStableRepresentation(doc,refString); refString = string.Format("{0}:{1}:{2}",unique,-9999,3); Reference core_inner = Reference.ParseFromStableRepresentation(doc,refString); refString = string.Format("{0}:{1}:{2}",unique,-9999,4); Reference core_centre = Reference.ParseFromStableRepresentation(doc,refString);

 

0 Likes
Message 26 of 54

jeremytammik
Autodesk
Autodesk

Dear Frank @FAIR59,

 

Very many thanks from me too for yet another powerful solution from the one and only stable representation man!

 

Dear Andreas @aricke59,

 

Thank you for confirming that this is useful and works for you.

 

Would you like to share a little code sample showing how you make use of this in context to create the dimensioning?

 

Thank you!

 

Cheers,

 

Jeremy



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

0 Likes
Message 27 of 54

aricke59
Enthusiast
Enthusiast

@aricke59 wrote:

Thanks for that FAIR59. Your suggestion set me on the right path however I found that the 1,2,3,4 etc seemed to be different in 2018 using .Net. The results I got are as follows:

 

1 - Overall Centre

2 - No idea what this one gives. It is consistent but not anything of meaning to me 

3 - Core Exterior Face

4 - Core Interior Face

5 - Core Centre

6 - Exterior Wall Face

7 - Interior Wall Face

 

When I created multi layer walls (i.e., 5 layers and up) I started to get all manner of numbers e.g., 200, 32, etc when I probed the reference array using Reference.ConvertToStableRepresentation(document). Even dimensioning  the same wall types resulted in different numbers coming up for the same layers.  

 

Thanks again!


@FAIR59 wrote:

you can analyze the references of a dimension that measures the core using Reference.ConvertToStableRepresentation(document).

using that information you can then construct the references as follows:

 

			string unique = wall.UniqueId;
refString = string.Format("{0}:{1}:{2}",unique,-9999,1); Reference wall_centre = Reference.ParseFromStableRepresentation(doc,refString); refString = string.Format("{0}:{1}:{2}",unique,-9999,2); Reference core_outer = Reference.ParseFromStableRepresentation(doc,refString); refString = string.Format("{0}:{1}:{2}",unique,-9999,3); Reference core_inner = Reference.ParseFromStableRepresentation(doc,refString); refString = string.Format("{0}:{1}:{2}",unique,-9999,4); Reference core_centre = Reference.ParseFromStableRepresentation(doc,refString);

 


A quick update on the numbers to use for Core Faces. Having spent more time and trying out the routine in several project files I find that 1 stays fairly constant in referencing the overall centre however the core faces can almost be just about anything, although they do always seem to be sequential, e.g. 2-3, 3-4, 9-10 or 15-16, etc.

 

I have now resorted to a brute force approach of first ascertaining the core width by using the compoundstructure of the wall and then incrementing through the number pairs, starting with 2,3 and going up from there, eventually stopping once I have a matching value. I get the value by creating a dimension using the two references. Not exactly fine programming but it seems to get the job done.

 

 

0 Likes
Message 28 of 54

jeremytammik
Autodesk
Autodesk

Dear Andreas,

 

Your brute force approach does indeed sound hacky in the extreme.

 

Congratulations on solving it and overcoming such hard obstacles and challenges!

 

Cheers,

 

Jeremy



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

0 Likes
Message 29 of 54

desdinova
Advocate
Advocate

Hello Fair99,

 

Is it possible to get references from floor layers,

I tested your code for floor and i only get top and bottom layers.

 

Thanks in advance....

 

0 Likes
Message 30 of 54

aricke59
Enthusiast
Enthusiast

@desdinova wrote:

Hello Fair99,

 

Is it possible to get references from floor layers,

I tested your code for floor and i only get top and bottom layers.

 

Thanks in advance....

 


Hi Desdinova, I did a quick check on a floor slab with multiple layers, Using 0 and 1 I got the top and bottom faces. The layer faces ranged from 19 to 22

 

i.e., UniqID:-9999:19, UniqID:-9999:20, etc. Seems like it would be fairly arbitrary last numbers.

 

An approach would be to just keep looping higher and higher and comparing the value of a dimension using the references to the layer thicknesses in the floor. Brute force but it should work. 

Message 31 of 54

FAIR59
Advisor
Advisor

if find (again) a difference af 1. In my testing the layers start from index 18

Message 32 of 54

Clogboy82
Participant
Participant

I've found the stable reference methodology in the Api to be a bit cumbersome, but overall hassle free.

 

What I've done is the following and it works (although I don't know what exactly is in the SideFaces array):

 

 

  IList<Reference> sideFaces = HostObjectUtils.GetSideFaces(wall, ShellLayerType.Exterior);
  if (!references.Contains(sideFaces[0]))
      references.Add(sideFaces[0]);

Note that I made a list of references rather than a ReferenceArray. The purpose is that I can address a list better than a reference array.

 

I then added the references to the array ra as follows:

  foreach (Reference f in references)
  {
      ra.Append(Reference.ParseFromStableRepresentation(doc, f.ConvertToStableRepresentation(doc)));
  }

This will get me the faces of the wall / outside layers of the wall in a reference array. This solved my problem that I couldn't alter the references of the dimensions placed by my API.

 

To broaden the context of my solution: I'm creation ModelCurves at points in my project that I want to dimension, then use an Intersect filter to see what walls are hitting with it perpendicularly, get the faces references, and use them in a ReferenceArray in the way that I described.

 

My only problem is that I have to start and commit a Transaction to place the Curve, before I can use the Curve for my interference filter. If there is a more elegant way to obtain the same result in a single transaction then I'd be very happy.

0 Likes
Message 33 of 54

Anonymous
Not applicable

Dear all,

 

I was reading through this with greate intereset and It actually solved my buissnes logic, but I ended up in a runtime problem.

 

I am doing some magic rebuilding elements, however that kills any dimensions associated with those elements, so the idea was to simply look through all References and than rebuild the dimensions with thoses References that are closest to the old one. Sound good, but as discussed here has one downside not all possible References for an object are accessible. 

But there is "ParseFromStableRepresentation" Methode, so the idea was to simply construct the first 999 Reference Strings and than check if they exist. e.g.:
UniqueID:0:ReferenceType

UniqueID:1:ReferenceType

UniqueID:2:ReferenceType

UniqueID:3:ReferenceType

...

It basicly works but is realy slow, because the only way I figured out to find out if the Reference is actually valid is to use it and construct a SketchPlane, but this would require a transaction, and this is painfuly slow.

So my question ist: Is there an other way to validate the constructed Reference that is faster? 

0 Likes
Message 34 of 54

miguel.bardaji
Participant
Participant
I am in the same boat, did anyone figured out a different way to get these references?
0 Likes
Message 35 of 54

TripleM-Dev.net
Advisor
Advisor

Hi @Anonymous ,

 

If you are rebuilding elements, if the replaced elements of the same kind (Wall => Wall etc) then maybe create a translate dictionary "Old UniqueId" -> "New Unique ID" and use this to rebuild the Dimensions, by replacing the UniqueID in the stable reference string to the new value.

 

Depends how the new elements are rebuild of course, this then also could be used to replace tags etc..

 

- Michel

0 Likes
Message 36 of 54

TripleM-Dev.net
Advisor
Advisor

Hi @miguel.bardaji 

 

See this article: Reference Stable Representation Magic Voodoo 

Dimensioning to the center of the wall uses the 1 code in the stable reference string 'magic' (=> 1 = Center Left/Right)

 

- Michel

0 Likes
Message 37 of 54

matthew_conwayN7C2G
Enthusiast
Enthusiast

@aricke59 

 

I have now resorted to a brute force approach of first ascertaining the core width by using the compoundstructure of the wall and then incrementing through the number pairs, starting with 2,3 and going up from there, eventually stopping once I have a matching value. I get the value by creating a dimension using the two references. Not exactly fine programming but it seems to get the job done.


How are you creating the dimensions to get the value? Are you using the CreateDimension() method, committing it, getting the dimension and then uncommitting? Also when you are incrementing through the number pairs, how do you know if that reference is a valid reference?

 

@jeremytammik Was there ever any progress on the GetCoreFaces() that was mentioned?








Message 38 of 54

jeremy_tammik
Alumni
Alumni

I checked the status of the development ticket REVIT-86488 [Make core centerline a reference] for you and see no current activity on that. I asked the development team for a status update for you. Meanwhile, I wonder whether the other updates to retrieve more detailed references in the past few releases of Revit might not have enabled other solutions to this issue since this wish was originally raised?

  

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

bhprest
Advocate
Advocate

@FAIR59   @jeremy_tammik 

 

Hi all-

I apologize in advance for this not-specifically-revit-api question. I'm by no means a beginner programmer, but like many on here, I come from the AEC side of things, so I don't have formal education in programming.

 

My question focuses in on this:

 

string.Format("{0}:{1}:{2}",unique,-9999,1);

 

 

The question is: how are things like the "-9999" and "1" even discovered? Specifically, when references from system families are converted to the stable string representation, they take the form of

 

d360e456-c09d-41be-997b-2baee3785c44-00629c93:1:SURFACE

 

 

whereas the string above (which does, of course, work) takes the form of:

 

d360e456-c09d-41be-997b-2baee3785c44-00629c93:-9999:1

 

 

Is this the work of brute-force trial-and-error, or is there some documentation in the api/debugger/etc that tips off that this alternate format would work?

 

I appreciate any tips you can give me- thank you.

0 Likes
Message 40 of 54

jeremy_tammik
Alumni
Alumni

Dear Ben,

 

Thank you for the interesting question and sorry for the late reply. I had to read it a couple of times before I got the point. I am sorry to say that I am not aware of any such documentation and I very much doubt any exists. I would hazard that this is a mixture of trial and error, guesswork, intuition, and deep understanding of the underlying mechanisms.

 

I would guess that the number 9999 just means a biggish number that is not too big. In this case, it seems to be an index into some geometric aspect of something and generally ranges in the low single or possibly double digits. Therefore 10000 may be too big by far and hence rejected, whereas 9999 is just big enough to be too big for any realistic index yet small enough not to be rejected by some ad-hoc filtering logic that checks index validity.

 

Similarly, SURFACE etc. may be some kind of enumeration of geometric flavours, like point, edge, face, etc., and the number 1 corresponds to one of those and  is interpreted as such.

 

Reverse engineering, hacking, you name it.

 

However, I did not discover this approach, so I am just guessing.

    

Cheers,

  

Jeremy

  

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