Get CenterLinesCurves

Get CenterLinesCurves

Anonymous
Not applicable
2,002 Views
11 Replies
Message 1 of 12

Get CenterLinesCurves

Anonymous
Not applicable

HI, I am using vb.net for writing a new dll for Revit 2017.

 

I have found a C# sample "Get CenterLinesCurves from rebar" and I have converted it to VB:NET, but I have a problem with all RebarShape.GetCurvesForBrowser().

the function is red underlined and I receive this message: reference to a non-shared member requires an object reference.

What am I doing wrong?

 

Thanks

Stefano

 

Imports System.Collections.Generic
Imports System.Linq
Imports System.Text
Imports Autodesk.Revit.DB
Imports Autodesk.Revit.DB.Structure
Imports Autodesk.Revit.UI
Imports Autodesk.Revit.UI.Selection
Imports Autodesk.Revit.Attributes
Imports System
Imports Autodesk.Revit.ApplicationServices



Namespace CreateImageRebar
    <TransactionAttribute(TransactionMode.Manual)>
    <RegenerationAttribute(RegenerationOption.Manual)>
    Public Class ReinforcementDetail

        Implements IExternalCommand
        'Clase de filtro de selección
        Public Class RebarPickFilter
            Implements ISelectionFilter
            Public Function AllowElement(e As Element) As Boolean Implements ISelectionFilter.AllowElement
                Return (e.Category.Id.IntegerValue.Equals(CInt(BuiltInCategory.OST_Rebar)))
            End Function
            Public Function AllowReference(r As Reference, p As XYZ) As Boolean Implements ISelectionFilter.AllowReference
                Return False
            End Function
        End Class

        Public Function Execute(commandData As ExternalCommandData, ByRef message As String, elements As ElementSet) As Autodesk.Revit.UI.Result Implements IExternalCommand.Execute
            'Public Function Execute(commandData As ExternalCommandData, ByRef message As String, elements As ElementSet) As Result
            Dim uiApp As UIApplication = commandData.Application
            Dim doc As Document = uiApp.ActiveUIDocument.Document

            Dim pickedRef As Reference = Nothing


            Dim sel As Selection = uiApp.ActiveUIDocument.Selection
            Dim selFilter As New RebarPickFilter()
            pickedRef = sel.PickObject(ObjectType.Element, selFilter, "Seleccione una Armadura")
            'Obtener referencia
            Dim el As Element = doc.GetElement(pickedRef)
            Dim myRebar As Rebar = TryCast(el, Rebar)
            Dim lc As List(Of Curve) = myRebar.GetCenterlineCurves(True, True, False).ToList()




            Dim curvesForBrowser As IList(Of Curve) = RebarShape.GetCurvesForBrowser()
            Dim hookangle0 As Integer = RebarShape.GetDefaultHookAngle(0)
            Dim orient0 As RebarHookOrientation = RebarShape.GetDefaultHookOrientation(0)

            Dim hookangle1 As Integer = RebarShape.GetDefaultHookAngle(1)
            Dim orient1 As RebarHookOrientation = RebarShape.GetDefaultHookOrientation(1)

            Dim labelParamIdToDimId As IDictionary(Of ElementId, ElementId) = New Dictionary(Of ElementId, ElementId)()

            For Each [dim] As Dimension In familyDimensions
                Try
                    Dim famParam As FamilyParameter = [dim].FamilyLabel
                    If famParam Is Nothing Then
                        Continue For Try
		            End If
                    labelParamIdToDimId(famParam.Id) = [dim].Id
                Catch generatedExceptionName As Autodesk.Revit.Exceptions.InvalidOperationException
                    Continue For Try
	        End Try
            Next
            ' Get the shape definition : constraints should 
            ' be available for every definition.
            ' Get all the shape segments (indexes of segments) 
            ' and their corresponding constraint parameter ids
            ' The RebarShapeSegment should be in the same order 
            ' as the curvesForBrowser.
            ' The constraint param ids  should correspond to 
            ' the dimension label param ids.

            Dim defBySeg As RebarShapeDefinitionBySegments = TryCast(RebarShape.GetRebarShapeDefinition(), RebarShapeDefinitionBySegments)

            Dim segmentPosToLabel As IDictionary(Of Integer, String) = New Dictionary(Of Integer, String)()

            For ii As Integer = 0 To defBySeg.NumberOfSegments - 1
                Dim seg As RebarShapeSegment = defBySeg.GetSegment(ii)

                Dim constraints As IList(Of RebarShapeConstraint) = seg.GetConstraints()

                For Each constraint As RebarShapeConstraint In constraints
                    Dim paramID As ElementId = constraint.GetParamId()

                    If (paramID = ElementId.InvalidElementId) OrElse Not labelParamIdToDimId.ContainsKey(paramID) Then
                        Continue For
                    End If

                    Dim labelName As String = ""
                    For Each param As Parameter In RebarShape.Parameters
                        If param.Id = paramID Then
                            labelName = param.Definition.Name
                            Exit For
                        End If
                    Next
                    segmentPosToLabel.Add(ii, labelName)
                Next
            Next

            Dim curvesForPicture As IList(Of Curve) = New List(Of Curve)()
            For ii As Integer = 0 To defBySeg.NumberOfSegments - 1
                Dim curve As Curve = curvesForBrowser(ii)
                Dim label As String = ""
                If Not segmentPosToLabel.TryGetValue(ii, label) Then
                    Continue For
                End If
            Next




            Return Result.Succeeded
        End Function

    End Class
End Namespace

 

0 Likes
Accepted solutions (1)
2,003 Views
11 Replies
Replies (11)
Message 2 of 12

matthew_taylor
Advisor
Advisor

Hi @Anonymous,

It looks like the GetCenterlineCurves function has been obsoleted in Revit 2017.

Reading the warning, it says:

Warning 1 'Public Function GetCenterlineCurves(adjustForSelfIntersection As Boolean, suppressHooks As Boolean, suppressBendRadius As Boolean) As System.Collections.Generic.IList(Of Autodesk.Revit.DB.Curve)' is obsolete: 'The GetCenterlineCurves(bool, bool, bool) function became obsolete for Revit 2017. Please use the overloaded GetCenterlineCurves(bool, bool, bool, MultiplanarOption.Enum, int) function instead. The last input argument (int barPositionIndex) should typically be 0 to match the previous behavior of this function.'. ...

 

So, in summary, you need to use a different overload of that function:

Dim lc As IList(Of DB.Curve) = _
myRebar.GetCenterlineCurves(True, True, False, _
DB.Structure.MultiplanarOption.IncludeAllMultiplanarCurves, 0).ToList()

You may need to substitute the MultiPlanar option for another option, depending on your use.

 

Note that I also changed the object type of lc from List to IList. A quick google should tell you the difference if you're curious.

 

The Rebar parts of Revit (both in the UI and the API) are advancing fairly quickly, hence the 'obsoleted' (no longer valid), and 'deprecated' (still works, but won't in the next version of Revit) functions.

 

Cheers,

 

-Matt


Cheers,

-Matt
_______________________________________________________________________________
Marking a post as a 'solution' helps the community. Giving a post 'Kudos' is as good as saying thanks. Why not do both?
0 Likes
Message 3 of 12

Anonymous
Not applicable

hI @MATT

 

thanks for your quick response, I will try your solution.

 

I have another question for you.

When I debug my dll I receive an error on RevitApiUI symbol. I have to set any option? 

 

thanks

Stefano

0 Likes
Message 4 of 12

Anonymous
Not applicable

Hi

I have try to insert your solution, but rebarshape is red underined

imm.jpg

 

0 Likes
Message 5 of 12

matthew_taylor
Advisor
Advisor

Hi @Anonymous,

Well, it looks like you have found your next issue, after solving the initial one.

 

You are calling a static method when you should be calling a property of a RebarShape element.

I'd suggest that that has happened because you have renamed RebarShape to myRebar or something similar?

Change each error instance of RebarShape with myRebar, and see how you get on.

If you look at the Error List in visual studio, it will probably tell you something about the errors and how to fix them.

 

If you still can't get the code working, you would do well to show the c# code. Fixing your code is problematic.

 

You should also look at the second post in this forum, which will guide you through successively harder examples to build your knowledge.

Also, take a look at The Building Coder. Search for 'Porting' and you will find examples such as this:

http://thebuildingcoder.typepad.com/blog/2009/07/porting-from-c-to-vbnet.html

 

Also this:

http://thebuildingcoder.typepad.com/blog/2014/11/migrating-deprecated-api-and-2d-boolean-operations.html#3

 

Cheers,

 

-Matt


Cheers,

-Matt
_______________________________________________________________________________
Marking a post as a 'solution' helps the community. Giving a post 'Kudos' is as good as saying thanks. Why not do both?
0 Likes
Message 6 of 12

Anonymous
Not applicable

this is the code:

But can you tell me why when I use F11 on debug I receive an error on revitapiui symbol?

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Structure;
using Autodesk.Revit.UI;
using Autodesk.Revit.UI.Selection;
using Autodesk.Revit.Attributes;

namespace CreateImageRebar
{
    [TransactionAttribute(TransactionMode.Manual)]
    [RegenerationAttribute(RegenerationOption.Manual)]
    public class ReinforcementDetail : IExternalCommand
    {
        //Clase de filtro de selección
        public class RebarPickFilter : ISelectionFilter
        {
            public bool AllowElement(Element e)
            {
                return (e.Category.Id.IntegerValue.Equals((int)BuiltInCategory.OST_Rebar));
            }
            public bool AllowReference(Reference r, XYZ p)
            {
                return false;
            }
        }
        public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
        {
            UIApplication uiApp = commandData.Application;
            Document doc = uiApp.ActiveUIDocument.Document;

            Reference pickedRef = null;
            

            Selection sel = uiApp.ActiveUIDocument.Selection;
            RebarPickFilter selFilter = new RebarPickFilter();
            pickedRef = sel.PickObject(ObjectType.Element, selFilter, "Seleccione una Armadura");
            //Obtener referencia
            Element el = doc.GetElement(pickedRef);
            Rebar myRebar = el as Rebar;
            List<Curve> lc = myRebar.GetCenterlineCurves(true, true, false).ToList();
            return Result.Succeeded;
         }
     }
}
0 Likes
Message 7 of 12

matthew_taylor
Advisor
Advisor
Accepted solution

Hi @Anonymous,

Take a look at http://thebuildingcoder.typepad.com/blog/about-the-author.html#5.49 for debugging tips and workflows.

You should probably use a wizard for creating an addin. That will do a lot of work for you. : http://thebuildingcoder.typepad.com/blog/2016/06/revitpythonshell-dynamic-model-updater-tutorial-and-wizard-update.html#2

 

Here's the converted code. This is the process I used to translate it:

  1. Convert code using http://converter.telerik.com/
  2. Add the 3 'Implements...' parts to the 3 functions.
  3. Fixed the GetCenterlineCurves line as I showed you earlier.
  4. Added the message box to report that something was done.

It worked fine here.

 

Imports System.Collections.Generic
Imports System.Linq
Imports System.Text
Imports Autodesk.Revit.DB
Imports Autodesk.Revit.DB.Structure
Imports Autodesk.Revit.UI
Imports Autodesk.Revit.UI.Selection
Imports Autodesk.Revit.Attributes

Namespace CreateImageRebar
    <TransactionAttribute(TransactionMode.Manual)> _
    <RegenerationAttribute(RegenerationOption.Manual)> _
    Public Class ReinforcementDetail
        Implements IExternalCommand
        'Clase de filtro de selección
        Public Class RebarPickFilter
            Implements ISelectionFilter
            Public Function AllowElement(e As Element) As Boolean Implements ISelectionFilter.AllowElement
                Return (e.Category.Id.IntegerValue.Equals(CInt(BuiltInCategory.OST_Rebar)))
            End Function
            Public Function AllowReference(r As Reference, p As XYZ) As Boolean Implements ISelectionFilter.AllowReference
                Return False
            End Function
        End Class
        Public Function Execute(commandData As ExternalCommandData, ByRef message As String, elements As ElementSet) As Result Implements IExternalCommand.Execute
            Dim uiApp As UIApplication = commandData.Application
            Dim doc As Document = uiApp.ActiveUIDocument.Document

            Dim pickedRef As Reference = Nothing
            Dim sel As Selection = uiApp.ActiveUIDocument.Selection
            Dim selFilter As New RebarPickFilter()
            pickedRef = sel.PickObject(ObjectType.Element, selFilter, "Seleccione una Armadura")
            'Obtener referencia
            Dim el As Element = doc.GetElement(pickedRef)
            Dim myRebar As Rebar = TryCast(el, Rebar)
            Dim lc As List(Of Curve) = myRebar.GetCenterlineCurves(True, True, False, MultiplanarOption.IncludeAllMultiplanarCurves, 0).ToList()
            MsgBox(String.Format("{0} curves", lc.Count.ToString))
            Return Result.Succeeded
        End Function
    End Class
End Namespace

Cheers,

 

 

-Matt


Cheers,

-Matt
_______________________________________________________________________________
Marking a post as a 'solution' helps the community. Giving a post 'Kudos' is as good as saying thanks. Why not do both?
0 Likes
Message 8 of 12

Anonymous
Not applicable

Thanks a lot Matt!!!

0 Likes
Message 9 of 12

matthew_taylor
Advisor
Advisor

You're welcome! Good luck with your app.


Cheers,

-Matt
_______________________________________________________________________________
Marking a post as a 'solution' helps the community. Giving a post 'Kudos' is as good as saying thanks. Why not do both?
0 Likes
Message 10 of 12

Anonymous
Not applicable

Hi Matt

 

have you a sample for draw the curve (ilist) as detail element?

0 Likes
Message 11 of 12

matthew_taylor
Advisor
Advisor

Hi @Anonymous,

 

Creating a detail line is easy. The main issue you will have is that a rebar is in 3D, in a 3D space, and you want to recreate that in 2D on another view (I guess). It is probably not a simple task.

 

Please go the 2nd post in this forum and do some guided learning. Search the SDK. Manually (using the UI) do the task you are trying to automate. Investigate existing rebar elements using RevitLookup - check their object types and use those types as search criteria.

 

Once you have done all of that, and still have questions, you are best starting a new forum question. That way others will help also - this topic has a solution already.

 

Cheers,

 

-Matt


Cheers,

-Matt
_______________________________________________________________________________
Marking a post as a 'solution' helps the community. Giving a post 'Kudos' is as good as saying thanks. Why not do both?
0 Likes
Message 12 of 12

Revitalizer
Advisor
Advisor

Hi Matt,

 

there is a Document.ConvertModelToDetailCurves  method which will do the projection calculation automatically.

RevitAPI.chm says: "If the model curves do not lie in a plane parallel to the view, their geometry will be projected to the view.".

 

 

Revitalizer




Rudolf Honke
Software Developer
Mensch und Maschine