To find Reference face to make Dimension

To find Reference face to make Dimension

Joris.vd.Meulen
Collaborator Collaborator
8,664 Views
20 Replies
Message 1 of 21

To find Reference face to make Dimension

Joris.vd.Meulen
Collaborator
Collaborator

Hi guys,

 

Going for some auto-place dimensions for curtain walls in a section view.

 

Before I'm diving into this matter I try to understand the approach rather than doing random stuff until it works.

 

So:

- curtain walls are empty elements containing grids

- the grids have members (mullions) assigned.

 

Placing a dimension line(s)

NewLinearDimension Method (View, Line, ReferenceArray, DimensionType)

So I have to

- create a New ReferenceArray().

- feeding that New ReferenceArray: I have to get the References from a curtain wall.

 

How to get the References from a curtain wall. I can get to a bounding box but that seems a bit irrelavant. 

I tried look at @jeremytammik list of topics, but that seems to point to non-existing posts atm (http://thebuildingcoder.typepad.com/blog/about-the-author.html#5.45).

 

Any help if much appreciated.

love python coding
0 Likes
8,665 Views
20 Replies
Replies (20)
Message 2 of 21

jeremytammik
Autodesk
Autodesk

Dear Joris,

 

Good approach!

 

I wish you fruitful research.

 

The 500 'Internal Server Error' reported by The Building Coder list of topic groups is a TypePad issue.

 

It appeared last night. I hope they fix it soon.

 

Luckily, I have a backup version of The Building Coder blog on GitHub containing all the blog post sources:

 

https://github.com/jeremytammik/tbc

 

The topic groups are included in the blog post index:

 

https://jeremytammik.github.io/tbc/a 

 

Here is the topic group you are looking for on the GitHub pages:

 

http://jeremytammik.github.io/tbc/a/#5.45

 

All of the blog posts are also listed in the index.

 

For each blog post, you have two links:

 

  • Blog post title -- The official Typepad link
  • Circumflex sign ^ -- The local GitHub pages link

 

I hope this helps, and that the Typepad issue is resolved soon.

 

Cheers,

 

Jeremy

 



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

0 Likes
Message 3 of 21

Joris.vd.Meulen
Collaborator
Collaborator

@jeremytammik, thanks for that alternative url. 

 

I'm still puzzled. But that's probably due lack of in-depth-knowledge and transposing C# to python. 

Is it correct if I say that a curtain wall has no obtainable references as one has with regular walls (looking at your wall-examples?)

 

love python coding
0 Likes
Message 4 of 21

jeremy_tammik
Alumni
Alumni

Can you dimension a curtain wall in the user interface?

 

If you do so, do you see the required references in RevitLookup?

 

If you do not have RevitLookup installed, you need to do so first!

 

Cheers,

 

Jeremy

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

Joris.vd.Meulen
Collaborator
Collaborator

Okay I see where you heading at (I think)

 

Yes I have lookup (snoop objects FTW!).

 

So: you say 'reverse engineer' the whole idea. So:

1. place a regular dimension in Revit on the boundary of a curtain wall

2. snoop that dimension line and 

3. see what it refers to?

(4. I don't see the required references Smiley Frustrated  ... referring to "References")

 

(1 hour afk ... not behind pc atm)

 

Knipsel2.PNGKnipsel.PNG

 

 

love python coding
0 Likes
Message 6 of 21

jeremytammik
Autodesk
Autodesk

Yes, exactly.

 

If you can see the references, that is good and you need to try to replicate the same situation programmatically.

 

If you cannot, it might be tricky.

 

Here are some more hints at reverse engineering to solve a Revit API programming task:

 

http://thebuildingcoder.typepad.com/blog/2017/01/virtues-of-reproduction-research-mep-settings-ontol...

 

Cheers,

 

Jeremy



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

0 Likes
Message 7 of 21

Joris.vd.Meulen
Collaborator
Collaborator

Thanks Jeremy,

 

Yeah it will be tricky. But I'm up for a challenge. docs are in C#, dynamo uses python. I not that familiar with either of 'm, but now I have to translate c# to python ... but  doing a lot of research, googling, revitapidocs, python/dynamo to get to my solution. First understanding how it's actually done, then the c# approach / python comes next.

 

First a coffee, time for a fresh mindset-kick!

love python coding
0 Likes
Message 8 of 21

Joris.vd.Meulen
Collaborator
Collaborator

Okay, I need some help.

 

Dimensioning a curtain wall in revit is dimensioning the 'shape handle' line of a curtain wall. A continuous line.

That line doesn't seem to be reachable through api. 

 

Or I think, it's not reachable. 

 

So I'm trying:

- dimension has the reference of an elementReferenceType "Reference_type_surface".

- so if I can get to the ElementReferenceType of a curtainwall, I'm a bit further.

- .... and now the silence comes.

 

The curtain wall (Wall Type) gives me one plausable option and that seems to be curtaingrid.

 

 

for t in wallinputlist:    
     t1 = t.CurtainGrid.NumULines    
     t2 = t.get_Geometry
    #h = t.get_Geometry.Faces    
    #g = t.CurtainGrid.NumVLines
OUT = t1,t2

t2 gives me: IronPython.Runtime.Types.BuiltinFunction ... unknown stuff for now.

 

get_Geometry seems being used by many, but searching on revit api ... no results. ...

 

So I'm confused.

1. why get_Geometry is working

2. getting reference from a curtainwall.

 

 

 

 

 

love python coding
0 Likes
Message 9 of 21

jeremytammik
Autodesk
Autodesk

Look at this quite old discussion by The Building Coder on retrieving curtain wall geometry:

 

http://thebuildingcoder.typepad.com/blog/2010/05/curtain-wall-geometry.html

 

You need to set the option to true:

 

IncludeNonVisibleObjects

 

That adds additional subcomponents which are otherwise skipped.

 

Cheers,

 

Jeremy



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

0 Likes
Message 10 of 21

Joris.vd.Meulen
Collaborator
Collaborator

Yes, @jeremytammik, I did 'study' that post quite a few times now. And thanks for your suggestions, again: much appreciated!

 

And I slowly understand how things are build.

 

Some progress I made:

 

(sorry again: python coding)

 

IN[1] is a list with curtain walls. 

elements = UnwrapElement(IN[1])
opt = Options()
opt.ComputeReferences = True
opt.IncludeNonVisibleObjects = True
opt.View = doc.ActiveView

going through a loop of e in elements and asking for e.get_Geometry(opt) I'm getting a bunch of

Autodesk.Revit.DB.Line (Numerous)

Autodesk.Revit.DB.Solid (6x) (why 6? front back top bottom left right???)

 

To my logic, it seems that Solid is the way to go, so filtering that one to.... resulting in one list with 6 Autodesk.Revit.DB.Solid values.

 

Now I think I have to get the faces of them, then I'm guessing checking the planar of 'm, in order to get to the DB.Reference of them. 

 

Your thoughts? Am I on the right path?

 

(oh and btw.... asking for e.get_Geometry(opt).Faces returns an empty list)..... grrrr

love python coding
0 Likes
Message 11 of 21

Joris.vd.Meulen
Collaborator
Collaborator

In follow up of my last reply:

 

Im using the solids now ... using that I'm able to get the "Faces" of the Solid. This gives me a list of Autodesk.Revit.DB.PlanarFace.

 

fun fact (atleast to me): the 6 Solids are reduced to 5 Faces (4 PlanarFaces, 1 empty result). ... strange.

 

So now requesting the References of those PlanarFaces ... result: 5 Autodesk.Revit.DB.References ....

 

Next step: checking if those references are paralel? so they can be used for the ReferenceArray (dimension)?

love python coding
0 Likes
Message 12 of 21

Joris.vd.Meulen
Collaborator
Collaborator

@jeremytammik,

 

Finally, I'm getting places! Did some comparising with the Planes, DotProduct and can place some dimensions now.

 

However:

the line parameter in "NewDimension(doc.ActiveView, line, elementsRef)" : can I skip that and use a 'imaginairy line' instead?

So instead of using a line which has a geocurve: I want to do: "bottom plane, offset 1000" for horizontal dimension, "right plane, offset 1000" for vertical dimension. Two seperate loops ofcourse.

 

 

love python coding
0 Likes
Message 13 of 21

jeremytammik
Autodesk
Autodesk

The API should enable you to create the same dimensioning as you can achieve manually through the UI... can you achieve what you require through the user interface?



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

0 Likes
Message 14 of 21

Joris.vd.Meulen
Collaborator
Collaborator

@jeremytammik,

 

Well, this is how it goes now:

- manual select a revit-line (horizontal)

- run code

--- code gets geometrycurve from that line,

- dimension is placed at that revit-line location.

 

But I'd like to just place a dimension at an offset of 'x' ... no need to manually select a revit-line  ... does that make sense?

 

 

love python coding
0 Likes
Message 15 of 21

Clogboy82
Participant
Participant

Interesting topic. I know it's 'a bit old' but still up to date.

I'm also busy doing something similar. So far I have this (going by mullions but panels should work equally well):

 

 

        private void PeilMaten(Wall wall)
        {
            Richting richting = Richting.horizontaal;
            List<Face> faces = ValidFaces(wall, richting);

            BoundingBoxXYZ bb = wall.get_BoundingBox(doc.ActiveView);
            Reference r;

            if (faces != null)
            {
                foreach (Face fa in faces)
                {
                    foreach (EdgeArray ea in fa.EdgeLoops)
                    {
                        foreach (Edge e in ea)
                        {
                            XYZ pt = e.AsCurve().GetEndPoint(0);

                            if (pt.Z == bb.Min.Z || pt.Z == bb.Max.Z)
                            {
                                r = e.GetEndPointReference(0);

                                doc.Create.NewSpotElevation(doc.ActiveView, r, bb.Min, bb.Min, bb.Min, bb.Min, true);
                                //break;
                            }
                        }
                    }
                }
            }
        }

 

 

Since in this case I'm only interested in the top and bottom of the curtain wall, I'm going for the top- and bottom most mullion faces. I already have gathered the up- and down facing mullion faces using this method:

        List<Face> ValidFaces(Wall wall, Richting richting)
        {
            FilteredElementCollector mullions = new FilteredElementCollector(doc, wall.CurtainGrid.GetMullionIds())
                            .OfCategory(BuiltInCategory.OST_CurtainWallMullions);

            Options options = new Options();
            options.ComputeReferences = true;
            options.View = doc.ActiveView;
            options.IncludeNonVisibleObjects = true;

            List<Face> validFaces = new List<Face>();
            foreach (Mullion m in mullions)
            {
                if ((richting == Richting.horizontaal && m.LocationCurve.GetEndPoint(0).Z == m.LocationCurve.GetEndPoint(1).Z)
                    || (richting == Richting.verticaal && m.LocationCurve.GetEndPoint(0).Z != m.LocationCurve.GetEndPoint(1).Z))
                {
                    GeometryElement ge = m.get_Geometry(options);

                    foreach (GeometryInstance gi in ge)
                    {
                        GeometryElement ige = gi.GetInstanceGeometry();

                        foreach (GeometryObject igo in ige)
                        {
                            Solid s = igo as Solid;

                            if (s != null)
                            {
                                FaceArray faces = s.Faces;

                                foreach (Face fa in faces)
                                {
                                    if ((richting == Richting.horizontaal && fa.ComputeNormal(new UV(0, 0)).Z != 0)
                                        || (richting == Richting.verticaal && fa.ComputeNormal(new UV(0, 0)).Z == 0))
                                    {
                                        validFaces.Add(fa);
                                    }
                                }
                            }
                        }
                    }
                }
            }

            return validFaces;
        }
    }

I found this works best in InstanceGeometry, otherwise I get an invalid reference exception.

"Richting" (direction) is an enum object I made myself to distinct between horizontal and vertical direction.

 

The short result is I don't trigger an exception when I extract the reference from an edge in the face's EdgeArrayArray. Unfortunately, when I place this spotdimension it's not visible.

 

 

When I use the face's reference, I get an exception saying that the Spot Dimension doesn't lie on its reference, not even when I only place it for bb.Min.

0 Likes
Message 16 of 21

Clogboy82
Participant
Participant

Forgot to mention that the Globalpoint of the reference is null... however its type is also linear so I don't know if that's a big deal but it bothers me.

0 Likes
Message 17 of 21

Clogboy82
Participant
Participant

OK it is obvious to me now that the spot elevation is being generated, but it just won't show up.

 

Hope the code I posted is of use regarding other issues in this thread.

0 Likes
Message 18 of 21

jeremytammik
Autodesk
Autodesk
0 Likes
Message 19 of 21

Clogboy82
Participant
Participant

Thank you.

Yes I found that second link a while back, and it helped me debug a solution for auto dimensioning in plan views.

Not to hijack this topic, but do you know if there's something I need to pay special attention to in section views (or elevation views)? For instance, do dimensions need to lay on the viewplane itself or can it be any other position parallel to the plane? What's the difference between Line.CreateBound and Line.CreateUnbound, and which is more safe?

 

If it helps, I have the same problem with spot elevations.

I'm running out of guesses and am about to abandon this project, and I'll gladly send you my code if you have some ideas.

0 Likes
Message 20 of 21

jeremytammik
Autodesk
Autodesk

Well, in that case, don't just send the code.

 

Submit a complete self-contained minimal reproducible case instead for the development team to take a look at:

 

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

 

They might have a suggestion for you or spot a problem, either in the API usage or internals.

 

Thank you!

 

Cheers,

 

Jeremy

 



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

0 Likes