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: 

Analytical opening creation throws ArgumentException

12 REPLIES 12
Reply
Message 1 of 13
RPTHOMAS108
461 Views, 12 Replies

Analytical opening creation throws ArgumentException

Hello All

 

I'm getting ArgumentException when trying to create an analytical opening in a newly created panel. Document regeneration and separating out transactions doesn't appear to help.

 

I believe I have satisfied all of the requirements for the input CurveLoop as described in RevitAPI.chm under AnalyticalOpening.Create. Therefore I've included a sample macro to highlight the following:

CurveLoop for opening is planar

CurveLoop for opening is not self intersecting

CurveLoop for opening is located within the CurveLoop for the AnalyticalPanel the opening is to be associated with

CurveLoop is on same plane as that of CurveLoop for the AnalyticalPanel the opening is to be associated with

 

I've also reversed the direction of the opening CurveLoop using CurveLoop.Flip and by manually re-ordering the curves and curve direction to see if that helped but it didn't. Interestingly even when reversed the CurveLoop is always anticlockwise with the normal for the plane being reversed to maintain that. Seems impossible to create a clockwise CurveLoop or a discontinuous one via CurveLoop.Create or CurveLoop.Append.

 

I can't really understand why this exception above is being thrown. Seems the API can be a bit pedantic about these things compared to sketching similar in the UI.

 

Therefore please find code attached below and project document containing macro.

 

 

 

Imports System
Imports Autodesk.Revit.UI
Imports Autodesk.Revit.DB
Imports Autodesk.Revit.UI.Selection
Imports System.Collections.Generic
Imports System.Linq
Imports Autodesk.Revit.DB.[Structure]
Imports System.Diagnostics

<Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)> _
<Autodesk.Revit.DB.Macros.AddInId("47F465AE-B00B-4795-97E2-62B148427DDF")> _
Partial Public Class ThisDocument

    Private Sub Module_Startup(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Startup
	End Sub
	
    Private Sub Module_Shutdown(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Shutdown
	End Sub
    
    Private Shared Function LN(ep0x As Double, ep0y As Double, ep0z As Double, ep1x As Double, ep1y As Double, ep1z As Double) As Line
        Return Line.CreateBound(New XYZ(ep0x, ep0y, ep0z), New XYZ(ep1x, ep1y, ep1z))
    End Function
    Public Sub CreatePanel
    	Dim IntUIApp As UIApplication = Me.Application
        Dim IntUIDoc As UIDocument = IntUIApp.ActiveUIDocument
        Dim IntDoc As Document = IntUIDoc.Document

        'Common X value to show curveloops are planar on YZ plane and share same plane.
        Dim Xa As Double = -165.201660016252

        'All loops are planar and anticlockwise
        'Main outer loop
        Dim LNSa As Curve() = New Curve(7) {}
        LNSa(0) = LN(Xa, -124.167471493235, 11.4857251912482,
                     Xa, -91.3590725431041, 11.4857251912482)
        LNSa(1) = LN(Xa, -91.3590725431041, 11.4857251912482,
                     Xa, -91.3590725431041, 0)
        LNSa(2) = LN(Xa, -91.3590725431041, 0,
                     Xa, -109.860817750644, 0)
        LNSa(3) = LN(Xa, -109.860817750644, 0,
                     Xa, -109.860817750644, 5.28189701052064)
        LNSa(4) = LN(Xa, -109.860817750644, 5.28189701052064,
                     Xa, -114.453993603662, 5.28189701052064)
        LNSa(5) = LN(Xa, -114.453993603662, 5.28189701052064,
                     Xa, -114.453993603662, 0)
        LNSa(6) = LN(Xa, -114.453993603662, 0,
                     Xa, -124.167471493235, 0)
        LNSa(7) = LN(Xa, -124.167471493235, 0,
                     Xa, -124.167471493235, 11.4857251912482)

        'Inner loop with normal opposite to normal of outer loop
        Dim LNSb As Curve() = New Curve(3) {}
        LNSb(0) = LN(Xa, -96.2126418630068, 3.95242011869356,
                     Xa, -96.2126418630068, 8.54559597171193)
        LNSb(1) = LN(Xa, -96.2126418630068, 8.54559597171193,
                     Xa, -100.805817716025, 8.54559597171193)
        LNSb(2) = LN(Xa, -100.805817716025, 8.54559597171193,
                     Xa, -100.805817716025, 3.95242011869356)
        LNSb(3) = LN(Xa, -100.805817716025, 3.95242011869356,
                     Xa, -96.2126418630068, 3.95242011869356)

        'Inner loop with normal same as normal of outer loop
        Dim LNSc As Curve() = New Curve(3) {}
        LNSc(0) = LN(Xa, -96.2126418630068, 3.95242011869356,
                     Xa, -100.805817716025, 3.95242011869356)
        LNSc(1) = LN(Xa, -100.805817716025, 3.95242011869356,
                     Xa, -100.805817716025, 8.54559597171193)
        LNSc(2) = LN(Xa, -100.805817716025, 8.54559597171193,
                     Xa, -96.2126418630068, 8.54559597171193)
        LNSc(3) = LN(Xa, -96.2126418630068, 8.54559597171193,
                     Xa, -96.2126418630068, 3.95242011869356)


        Dim Cla As CurveLoop = CurveLoop.Create(LNSa.ToList)
        Dim Clb As CurveLoop = CurveLoop.Create(LNSb.ToList)
        Dim Clc As CurveLoop = CurveLoop.Create(LNSc.ToList)
        
        Dim SB As New Text.StringBuilder
        
        Try
            Using Tx As New Transaction(IntDoc, "Panel with opening (opposite normal)")
                If Tx.Start = TransactionStatus.Started Then
                    'This is ok
                    Dim AP As AnalyticalPanel = AnalyticalPanel.Create(IntDoc, Cla)
                    'This throws exception
                    AnalyticalOpening.Create(IntDoc, Clb, AP.Id)
                    Tx.Commit()
                End If
            End Using
        Catch ex As Exception
        	SB.AppendLine(ex.Message)
            'Debug.WriteLine(ex.Message)
        End Try

        Try
            Using Tx As New Transaction(IntDoc, "Panel with opening (same normal)")
                If Tx.Start = TransactionStatus.Started Then
                    'This is ok
                    Dim AP As AnalyticalPanel = AnalyticalPanel.Create(IntDoc, Cla)
                    'This throws exception
                    AnalyticalOpening.Create(IntDoc, Clc, AP.Id)
                    Tx.Commit()
                End If
            End Using
        Catch ex As Exception
        	SB.AppendLine(ex.Message)
            'Debug.WriteLine(ex.Message)
        End Try

        'Draw curves to show openings are within outer loop and share same plane.
        Using Tx As New Transaction(IntDoc, "Draw")
            If Tx.Start = TransactionStatus.Started Then

                Dim PL As Plane = Cla.GetPlane
                Dim SKP As SketchPlane = SketchPlane.Create(IntDoc, PL)

                For Each item As Curve In Cla
                    IntDoc.Create.NewModelCurve(item, SKP)
                Next
                For Each item As Curve In Clb
                    IntDoc.Create.NewModelCurve(item, SKP)
                Next
                For Each item As Curve In Clc
                    IntDoc.Create.NewModelCurve(item, SKP)
                Next

                Tx.Commit()
            End If
        End Using
    	    	
    	    	
    	If SB.Length > 0 Then
    	    TaskDialog.Show("Error",SB.ToString)
    	End If
    	    	
    End Sub
End Class

 

 

 

Model line result of running macroModel line result of running macro

On plan view with opening selected and top line of outer loop removed to show alignmentOn plan view with opening selected and top line of outer loop removed to show alignment

 

 

12 REPLIES 12
Message 2 of 13
RPTHOMAS108
in reply to: RPTHOMAS108

An additional aspect I've discovered:

 

When you remove the door outline from the outer loop then the opening can be added without raising the exception e.g.

Below works ok:

220604a.PNG

 

However below fails:

220602a.PNG

There is no difference in the outer loop apart from the removal of the door aspect.

Note that the exception is thrown when creating the opening not the panel so the panel with or without door is created fine. It is only when you add the opening to the panel with the door outline you get the exception.

 

Here is the information for the CurveLoop with door:

#Planar Loop
#Plane Origin: -165.201660016252,-109.960338847661,4.19190555044222
#Plane Normal: 1,0,0
#Loop is anticlockwise according to plane normal.
Line|-165.201660016252,-124.167471493235,11.4857251912482|-165.201660016252,-124.167471493235,-3.5527136788005E-15
Line|-165.201660016252,-124.167471493235,-1.77635683940025E-15|-165.201660016252,-114.453993603662,-1.77635683940025E-15
Line|-165.201660016252,-114.453993603662,-1.77635683940025E-15|-165.201660016252,-114.453993603662,5.28189701052064
Line|-165.201660016252,-114.453993603662,5.28189701052064|-165.201660016252,-109.860817750644,5.28189701052064
Line|-165.201660016252,-109.860817750644,5.28189701052064|-165.201660016252,-109.860817750644,-1.77635683940025E-15
Line|-165.201660016252,-109.860817750644,-1.77635683940025E-15|-165.201660016252,-91.3590725431041,-1.77635683940025E-15
Line|-165.201660016252,-91.3590725431041,-3.5527136788005E-15|-165.201660016252,-91.3590725431041,11.4857251912482
Line|-165.201660016252,-91.3590725431041,11.4857251912482|-165.201660016252,-124.167471493235,11.4857251912482
#Loop is closed.

 

Without door

#Planar Loop
#Plane Origin: -165.201660016252,-107.xxx-xxxxxxxx,5.74286259562412
#Plane Normal: 1,0,0
#Loop is anticlockwise according to plane normal.
Line|-165.201660016252,-124.167471493235,11.4857251912482|-165.201660016252,-124.167471493235,-3.5527136788005E-15
Line|-165.201660016252,-124.167471493235,-1.77635683940025E-15|-165.201660016252,-91.3590725431041,-1.77635683940025E-15
Line|-165.201660016252,-91.3590725431041,-3.5527136788005E-15|-165.201660016252,-91.3590725431041,11.4857251912482
Line|-165.201660016252,-91.3590725431041,11.4857251912482|-165.201660016252,-124.167471493235,11.4857251912482
#Loop is closed.

 

 ...and the forum (or something in-between) doesn't like the number:

RPTHOMAS108_1-1654357745664.png

 

 

 

 

 

 

Message 3 of 13
jeremy_tammik
in reply to: RPTHOMAS108

The forum? You cannot enter that number in your post? Wow, craziness galore. 

 

Thank you very much for the report, I'll pass it on asap.

 

Wishing you a peaceful and relaxing weekend, 

  

Jeremy

  

Jeremy Tammik, Developer Advocacy and Support, The Building Coder, Autodesk Developer Network, ADN Open
Message 4 of 13
RPTHOMAS108
in reply to: jeremy_tammik

Thanks Jeremy

 

I think part of the number is perhaps being filtered out because it looked like a phone number.

 

Regarding the issue I think I'm getting to the bottom of the cause, looks like an error in the checking process to determine if an opening can be placed within the boundary. I noticed that when I varied the door height on the last example there was the possibility to place the opening without an issue (if door height reduced). So it got me thinking about the Origin of the Plane from CurveLoop.GetPlane. It seems to be the case that if the Origin of the CurveLoop that forms the AnalyticalPanel is outside the panel profile itself then you will not be able to add any opening to it via the API regardless of opening position. So in effect the geometry of the AnalyticalPanel in isolation is ruling out placing openings with the API that could be placed with the UI (which can't be right). The origin of the plane can't be manipulated it is an inherent value so a fix is required.

 

I've demonstrated this error in checking logic below with three variations of a simple shape on the XY plane.

 

220605a.PNG

In the above if the apex of the bottom triangle is 0.5 or greater then placement of the opening will fail.

 

Code used in above study:

Private Shared Function LN(ep0x As Double, ep0y As Double, ep0z As Double, ep1x As Double, ep1y As Double, ep1z As Double) As Line
        Return Line.CreateBound(New XYZ(ep0x, ep0y, ep0z), New XYZ(ep1x, ep1y, ep1z))
    End Function
    Public Function Obj_220604a(commandData As ExternalCommandData, ByRef message As String, elements As ElementSet) As Result
        Dim IntUIApp As UIApplication = commandData.Application
        Dim IntUIDoc As UIDocument = commandData.Application.ActiveUIDocument
        Dim IntDoc As Document = IntUIDoc.Document

        Dim Env = Function(H As Double) As CurveLoop
                      Dim LNSb As Curve() = New Curve(4) {}
                      LNSb(0) = LN(0, 0, 0,
                                   0, 1, 0)
                      LNSb(1) = LN(0, 1, 0,
                                   1, 1, 0)
                      LNSb(2) = LN(1, 1, 0,
                                   1, 0, 0)
                      LNSb(3) = LN(1, 0, 0,
                                   0.5, H, 0)
                      LNSb(4) = LN(0.5, H, 0,
                                   0, 0, 0)

                      Return CurveLoop.Create(LNSb.ToList)
                  End Function

        Dim LNSa As Curve() = New Curve(3) {}
        LNSa(0) = LN(0.01, 0.99, 0, 0.99, 0.99, 0)
        LNSa(1) = LN(0.99, 0.99, 0, 0.99, 0.8, 0)
        LNSa(2) = LN(0.99, 0.8, 0, 0.01, 0.8, 0)
        LNSa(3) = LN(0.01, 0.8, 0, 0.01, 0.99, 0)
        Dim CL_Opening As CurveLoop = CurveLoop.Create(LNSa.ToList)

        'The below 3 variations demonstrate that position of Plane.Origin of CurveLoop.GetPlane
        'for the AnalyticalPanel the opening is being placed in
        'governs if an opening can be placed in the AnalyticalPanel
        'i.e. if the Plane.Origin is on the boundary of the AnalyticalPanel or outside of it
        'then no opening will be able to be positioned on that AnalyticalPanel regardless of opening position
        'A simple shape on the XY plane containing 5 points is assumed in this test
        'The Plane.Origin value is found to be based upon the average of all line end points within the CurveLoop
        'Therefore the penultimate point in the loop can be given a Y value to demonstrate the three situations below:

        Dim Height1 As Double = 0.6 'Height of point (1+1+0+0+0.6)/5 = 0.52 (Lower than boundary point of 0.6 = NOT OK)
        Dim Height2 As Double = 0.5 'Height of point (1+1+0+0+0.5)/5 = 0.5 (At same height as boundary point = NOT OK)
        Dim Height3 As Double = 0.2 'Height of point (1+1+0+0+0.2)/5 = 0.44 (Higher than boundary point of 0.2 = OK)

        Dim Variations As Double() = New Double() {Height1, Height2, Height3}

        Using tx As New Transaction(IntDoc, "AP")
            If tx.Start = TransactionStatus.Started Then

                For I = 0 To 2
                    'Transform used only to shift each case beside the last on screen
                    Dim Shift As Double = 1.5 * I
                    Dim T As Transform = Transform.CreateTranslation(New XYZ(Shift, 0, 0))

                    Try
                        Dim CL As CurveLoop = Env(Variations(I))
                        CL.Transform(T)
                        CL.DebugOutputList

                        Dim AP As AnalyticalPanel = AnalyticalPanel.Create(IntDoc, CL)

                        Dim CL_O = CurveLoop.CreateViaCopy(CL_Opening)
                        CL_O.Transform(T)

                        AnalyticalOpening.Create(IntDoc, CL_O, AP.Id)

                    Catch ex As Exception
                        Debug.WriteLine("Fail at " & I)
                    End Try
                Next

                tx.Commit()
            End If
        End Using

        Return Result.Succeeded
    End Function

Regards

 

Richard

 

 

Message 5 of 13
jeremy_tammik
in reply to: RPTHOMAS108

Dear Richard,

 

Thank you for your report, reproducible case, clear description and careful in-depth analysis!

 

Sorry to hear about this.

 

I logged the issue REVIT-193494 [Analytical opening creation throws ArgumentException] with our development team for this on your behalf as it requires further exploration and possibly a modification to our software. Please make a note of this number for future reference.

 

You are welcome to request an update on the status of this issue or to provide additional information on it at any time quoting this change request number.

 

This issue is important to me. What can I do to help?

 

This issue needs to be assessed by our engineering team and prioritised against all other outstanding change requests. Any information that you can provide to influence this assessment will help. Please provide the following where possible:

 

  • Impact on your application and/or your development.
  • The number of users affected.
  • The potential revenue impact to you.
  • The potential revenue impact to Autodesk.
  • Realistic timescale over which a fix would help you.
  • In the case of a request for a new feature or a feature enhancement, please also provide detailed Use cases for the workflows that this change would address.

 

This information is extremely important. Our engineering team have limited resources, and so must focus their efforts on the highest impact items. We do understand that this will cause you delays and affect your development planning, and we appreciate your cooperation and patience.

 

Best regards,

 

Jeremy

 

Jeremy Tammik, Developer Advocacy and Support, The Building Coder, Autodesk Developer Network, ADN Open
Message 6 of 13
RPTHOMAS108
in reply to: jeremy_tammik

Thanks Jeremy

 

Below are my answers:

 

Impact on your application and/or your development.

I'm mitigating by plotting model lines for such openings that the end user would then have to trace.

The number of users affected.

This issue will also affect the Autodesk Dynamo script that generates analytical elements. I've attached a file with two wall arrangements to demonstrate this (OneWillFail). So number of users affected = number of global Revit Structure users.

The potential revenue impact to you.

0

The potential revenue impact to Autodesk.

For Autodesk to estimate based on global users affected

Realistic timescale over which a fix would help you.

Within year (based on my current publishing schedule)

 

Same result with 'Analytical Automation' via Autodesk toolSame result with 'Analytical Automation' via Autodesk tool

 

 

Regards

 

Richard

Message 7 of 13
jeremy_tammik
in reply to: RPTHOMAS108

Thank you for your appreciation, business case and further test and sample. I added them to the development ticket.

  

Jeremy Tammik, Developer Advocacy and Support, The Building Coder, Autodesk Developer Network, ADN Open
Message 8 of 13
jeremy_tammik
in reply to: RPTHOMAS108

Dear Richard,

 

Thank you again for your report and your patience with this.

 

The development team confirm the behaviour you report, closed the exploration ticket REVIT-193494 [Analytical opening creation throws ArgumentException] as 'code fix needed' and created a new development ticket REVIT-193553 [Analytical opening creation throws ArgumentException] to address this issue in a future major release of Revit. Please make a note of this number for future reference.

 

Best regards,

 

Jeremy

 

Jeremy Tammik, Developer Advocacy and Support, The Building Coder, Autodesk Developer Network, ADN Open
Message 9 of 13

Hello,

Is that problem fixed by API DEV team?

I have the same problem during creation an openining in AnalyticalPanel.

Below is an example of slab with opening creation problem:

andrzejmalesa_0-1699622411266.png

I think the problem is in algorithm of detecting outside/inside.

In my programs I am using ray crosing algo INPOLY.C as linked below, and it is excelent(I've made checking by iterating each CurveLoop ->Curve.Tessellate points)

https://www.visibone.com/inpoly/

 

 

 

Message 10 of 13

The accompanying text that you point to is excellent too. Thank you for pointing that out and wishing you a nice weekend.

  

Jeremy Tammik, Developer Advocacy and Support, The Building Coder, Autodesk Developer Network, ADN Open
Message 11 of 13

I checked the status of the development ticket REVIT-193553 Analytical opening creation throws ArgumentException for you. It has been closed and fixed, and the enhancement was release in Revit 2023.1 and Revit 2024.

  

Jeremy Tammik, Developer Advocacy and Support, The Building Coder, Autodesk Developer Network, ADN Open
Message 12 of 13

I've updated to 2023.1, and yes, it's working  now like a charm.

 

Message 13 of 13

Added your inpoly.c pointer to the blog as well:

  

  

Jeremy Tammik, Developer Advocacy and Support, The Building Coder, Autodesk Developer Network, ADN Open

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