Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Open profiles are not supported in multi profile sweeping

Hi all,

In my command I programmed to get a spline, existing solid and polylines form their layers automatically.
Then the solid is being erased and the spline and polylines are used to make a new solid.
With two polylines it works well. But when I have three polylines this message appears in the command box:
Open profiles are not supported in multi profile sweeping
And I also get an error message for the Solid3d.CreateLoftedSolid method.

Anybody knows how to handle the message and solve the problem?
(PS: When I select the entities by prompt it works with three profiles)

Thank you.

Comments

  • Hi Andreas,
    As you say, you use the method Solid3d.CreateLoftedSolid method to create a lofted 3D Solid.
    For a lofted 3DSolid you have to provide closed profiles as profile curves !
    Check your profile curves, are they ALL closed ????

  • Hi Konstantin,

    yes they are. Like I said, I create the solid by selecting the spline and the profiles by mous klick in my first command and this works.
    And the Update command that deletes the solid and makes a new solid by getting the spline and profiles automatically does work when I have just two profiles. But when I have three profiles this message appears.

    Maybe the 'closed profiles' has a different meaning..?

  • from what you are describing, you are trying to loft a 3DSolid along 3 or more profiles using a spline as a Guide , right ?
    The functionality or option to using a Guide for a loft operation has not yet been implemented !
    This applies to the command LOFT and the .NET API method Solid3d.CreateLoftedSolid , in other words you can't use the method as follows
    sol.CreateLoftedSolid(cSections.ToArray(), new Entity[0], lPath , lOptsB.ToLoftOptions());
    Just use the LOFT command to reproduce it . Maybe that is the cause of the error ?

    : LOFT
    Select cross sections in lofting order [MOde/selection options (?)]:
    Select cross sections in lofting order [MOde/selection options (?)]:
    Select cross sections in lofting order [MOde/selection options (?)]:
    Select cross sections in lofting order [MOde/selection options (?)]:
    3 cross sections selected
    Enter an option [Guides/Path/Cross sections only/Settings] <Cross sections only>:p
    Select path curve [selection options (?)]:
    Modeling operation error:
    this functionality has not yet been implemented
    Could not loft using the selected entities.
    

    On the other hand i see in your error "....multi profile sweeping "
    Are you using the method CreateLoftedSolid or the sweep method CreateSweptSolid(ent, pathEnt, sOptsB.ToSweepOptions()); ?

  • Sorry Andreas i mean the functionality of lofting using a ** Path** is not yet implemented !
    Correction !!!

    from what you are describing, you are trying to loft a 3DSolid along 3 or more profiles using a spline as a Path , right ?
    The functionality or option to using a Path for a loft operation has not yet been implemented !

  • But in my code when I take these entities in the model space it works...
    See attached pictures of the Code and the model space before and after my command.

    Forum_Spline_Querschnitte.PNG
    1503 x 573 - 19K
    Forum_Solid3d.PNG
    1506 x 570 - 40K
    Forum_Code.PNG
    949 x 50 - 7K
  • Well looking at your screenshots, i assume that you are using the spline curve in the command line as a Guide curve ( NOT as Path curve)
    LOFT
    Select cross sections in lofting order [MOde/selection options (?)]:
    Select cross sections in lofting order [MOde/selection options (?)]:
    Select cross sections in lofting order [MOde/selection options (?)]:
    Select cross sections in lofting order [MOde/selection options (?)]:
    3 cross sections selected
    Enter an option [ Guides /Path/Cross sections only/Settings] : g
    The C# method has following arguments :
    Solid3D.CreateLoftedSolid(Entity[] crossSectionsCurves, Entity[] guideCurves, Entity pathCurve, LoftOptions loftOptions);

    In your code you are using the spline curve as a path in the 3rd argument (not supported yet) and not as a Guide in the 2nd argument !
    sol.CreateLoftedSolid ( cSections.ToArray(), new Entity[0], Spline02 , lOptsB.ToLoftOptions());

    Therefore, first select the spline (Spline02) as a Guide curve in an array and pass it as 2nd argument to the CreateLoftedSolid method...
    Use following code....

                    // Select Guide Curves
                    PromptSelectionOptions gCurvesOpts = new PromptSelectionOptions();
    
                    gCurvesOpts.MessageForAdding = "\nSelect any number of guide curves";
                    gCurvesOpts.AllowDuplicates = false;
    
                    PromptSelectionResult gSelres = ed.GetSelection(gCurvesOpts);
    
                    if (gSelres.Status == PromptStatus.Error) return;
                    if (gSelres.Status == PromptStatus.Cancel) return;
    
                    SelectionSet gss = gSelres.Value;
                    ObjectId[] gidarray = gss.GetObjectIds();
    
                    foreach (ObjectId oid in gidarray)
                    {
                        Entity guidecurveEnt = tr.GetObject(oid, OpenMode.ForRead) as Entity;
                        guides.Add(guidecurveEnt);
                    }
    

    Now the spline curve is selected in the gidarray and the lofted solid can be created !

    sol.CreateLoftedSolid(cSections.ToArray(), guides.ToArray() , null, lOptsB.ToLoftOptions());

    I hope this helps

  • No, this solid in the screenshots in made with this code.
    Here my whole code:

    <CommandMethod("TakeSplineQuerschnittMakeSolid")>
        Public Sub TakeSplineQuerschnittMakeSolid()
            ' auf Editor des aktiven Dokuments zugreifen:
            Dim editor As Editor = _AcAp.Application.DocumentManager.MdiActiveDocument.Editor
            ' *********************************** Spline auswählen, Querschnitte auswählen und Solid erzeugen *****************************************
            Using action As Transaction = HostApplicationServices.WorkingDatabase.TransactionManager.StartTransaction
                Dim Liste As New List(Of Entity)
                Dim EntList As Entity() = Nothing
                Dim Profile01 As _AcDb.Polyline = Nothing
                ' Eingabeaufforderung: Spline wählen
                Dim peoSpline As New PromptEntityOptions(vbLf & "Select a Spline")
                peoSpline.SetRejectMessage("Not a Spline!")
                peoSpline.AddAllowedClass(GetType(Spline), True)
                Dim perSpline As PromptEntityResult = editor.GetEntity(peoSpline)
                Dim Spline02 As Spline = Nothing
                ' Falls Objektwahl erfolgreich:
                If (perSpline.Status = PromptStatus.OK) Then
                    Spline02 = TryCast(action.GetObject(perSpline.ObjectId, OpenMode.ForWrite), Spline)
                    '°°°°°°°°°°°°°°°°° neuer Schleifen-Test: Anzahl der Querschnitte vorher eingeben [ besser: Exit wenn ENTER gedrückt wird ]
                    Dim i As Integer = 0
                    Dim z As Integer = Nothing
                    ' Eingabeaufforderung für Anzahl an Querschnitten (= z):
                    Dim AnzahlQuerschnitteOptions As New PromptIntegerOptions(vbLf & "Anzahl Querschnitte")
                    Dim AnzahlQuerschnitteResult As PromptIntegerResult = Nothing
                    AnzahlQuerschnitteResult = editor.GetInteger(AnzahlQuerschnitteOptions)
                    z = AnzahlQuerschnitteResult.Value
                    Dim perProf As PromptEntityResult = Nothing
                    Do
                        Dim peoProf As PromptEntityOptions = Nothing
                        peoProf = New PromptEntityOptions(vbLf & "Select a Profile")
                        peoProf.SetRejectMessage("Not a Profile!")
                        peoProf.AddAllowedClass(GetType(Teigha.DatabaseServices.Polyline), True)
                        perProf = editor.GetEntity(peoProf)
                        Profile01 = TryCast(action.GetObject(perProf.ObjectId, OpenMode.ForWrite), _AcDb.Polyline)
                        Liste.Add(Profile01)
                        i = i + 1
                        If i = z Then Exit Do
                    Loop
                End If
                EntList = Liste.ToArray()
                ' *********************************************************** Extrusionskörper *******************************************
                Dim LoftOption As New LoftOptions
                Dim Brückenüberbau As New Solid3d
                Brückenüberbau.CreateLoftedSolid(EntList, New Entity() {}, Spline02, LoftOption)
                Brückenüberbau.Layer = "Solid3d"
                ' *********************************************** Füge Objekte dem Modellbereich hinzu ***********************************
                AddToModelSpace(New Entity() {Brückenüberbau})
                ' Save the new object to the database
                action.Commit()
                ' Dispose of the transaction
            End Using
        End Sub

    --> with this code it works well. I have three profiles and spline as path.
  • But in this code when I want to get the entities automatically from the database I get the error described in my issue.

    <CommandMethod("GetSplineQuerschnittMakeSolid")>
        Public Sub GetSplineQuerschnittMakeSolid()
            Dim editor As Editor = _AcAp.Application.DocumentManager.MdiActiveDocument.Editor
            '' Get the current document and database
            Dim acDoc As Document = _AcAp.Application.DocumentManager.MdiActiveDocument
            Dim acCurDb As Database = acDoc.Database      
            Dim acBlkTbl As BlockTable
            acBlkTbl = acCurDb.BlockTableId.GetObject(OpenMode.ForWrite)   
            Dim acBlkTblRec As BlockTableRecord
            acBlkTblRec = acBlkTbl(BlockTableRecord.ModelSpace).GetObject(OpenMode.ForWrite)
            Dim BrückeAlt As Solid3d = Nothing
            Dim Spline02 As Spline = Nothing
            Dim Profile01 As _AcDb.Polyline = Nothing
            Dim Profile02 As _AcDb.Polyline = Nothing
            Dim Profile03 As _AcDb.Polyline = Nothing
            Dim Liste As New List(Of Entity)
            Dim EntList As Entity() = Nothing
            Dim acEnt As Entity = Nothing
            '' Start a transaction
            Using acTrans As Transaction = acCurDb.TransactionManager.StartTransaction()
                ' ############## Querschnittlayer als Schleife #############
                ' Objekte nach ObjektID durchsuchen:
                For Each acObjId As ObjectId In acBlkTblRec
                    '' Open the selected object for write
                    acEnt = acTrans.GetObject(acObjId, OpenMode.ForWrite)
                    acDoc.Editor.WriteMessage(vbLf & acEnt.Layer)
                    'acEnt.XData()
                    If acEnt.Layer = "Solid3d" Then
                        BrückeAlt = CType(acEnt, Solid3d)
                        BrückeAlt.Erase()
                    ElseIf acEnt.Layer = "Spline" Then
                        Spline02 = CType(acEnt, Spline)
                    End If
                    Dim Zahl As Integer
                    Dim Text As String
                    Dim QuerschnittLayer As String
                    For Zahl = 10 To 30 Step 10
                        Text = CType(Zahl, String)
                        QuerschnittLayer = "Querschnitt" & Text
                        If acEnt.Layer = QuerschnittLayer Then
                            Profile01 = CType(acEnt, _AcDb.Polyline)
                            Liste.Add(Profile01)
                        End If
                        Zahl = CType(Text, Integer)
                    Next
                Next
                EntList = Liste.ToArray()
                ' *********************************************************** Extrusionskörper *******************************************
                Dim LoftOption As New LoftOptions
                Dim Brückenüberbau As New Solid3d
                'Brückenüberbau.CreateLoftedSolid(New Entity() {Profile01, Profile02, Profile03}, New Entity() {}, Spline02, LoftOption)
                Brückenüberbau.CreateLoftedSolid(EntList, New Entity() {}, Spline02, LoftOption)
                Brückenüberbau.Layer = "Solid3d" 'BrückeAlt.Layer 
                ' *********************************************** Füge Objekte dem Modellbereich hinzu ***********************************
                AddToModelSpace(New Entity() {Brückenüberbau})
                ' Save the new object to the database
                acTrans.Commit()
                ' Dispose of the transaction
            End Using
        End Sub
  • I compiled both routines but they are not producing any results !
    I used VS 2019 on WIN 10 x64 using Bricscad V20 x64

  • Do you have this function?

    ' ********************************** AddToModelSpace Function ****************************
        Public Shared Function AddToModelSpace(ByVal ParamArray list As Entity()) As ObjectIdCollection
            Dim ids As New ObjectIdCollection
            Dim database As Database = HostApplicationServices.WorkingDatabase
            Using action As Transaction = database.TransactionManager.StartTransaction
                Dim blockTable As BlockTable = TryCast(action.GetObject(database.BlockTableId, OpenMode.ForRead), BlockTable)
                If (blockTable Is Nothing) Then
                    Throw New NullReferenceException("blockTable == null")
                End If
                Dim blockTableRecord As BlockTableRecord = TryCast(action.GetObject(blockTable.Item(BlockTableRecord.ModelSpace), OpenMode.ForWrite), BlockTableRecord)
                If (blockTableRecord Is Nothing) Then
                    Throw New NullReferenceException("blockTableRecord == null")
                End If
                Dim ent As Entity
                For Each ent In list
                    ids.Add(blockTableRecord.AppendEntity(ent))
                    action.AddNewlyCreatedDBObject(ent, True)
                Next
                action.Commit()
            End Using
            Return ids
        End Function
        ' ******************************************** End Function *********************************

    And are your profiles rectangular to your spline?

  • Maybe you use this template

    dwg
    dwg
    Vorlage_SplineMitQuerschnitten.dwg
    15K
  • You have to explicitly sort the profile curves in your code, because you don't select them interactively but by looping through the database !
    The order of the lofting profiles is important !
    I have replaced the code and add the necessary sorting steps.

    Step 1, get three profiles looping through the database

    ~~    Select Case acEnt.Layer
                               Case "Querschnitt10"
                                    Profile01 = TryCast(acTrans.GetObject(acObjId, OpenMode.ForWrite), _AcDb.Polyline)
                                    'Liste.Insert(0, Profile01)
                                    Liste.Add(Profile01)
                                    acDoc.Editor.WriteMessage(vbLf & acEnt.Layer)
                                Case "Querschnitt20"
                                    Profile02 = TryCast(acTrans.GetObject(acObjId, OpenMode.ForWrite), _AcDb.Polyline)
                                    'Liste.Insert(1, Profile02)
                                    Liste.Add(Profile02)
                                    acDoc.Editor.WriteMessage(vbLf & acEnt.Layer)
                                Case "Querschnitt30"
                                    Profile03 = TryCast(acTrans.GetObject(acObjId, OpenMode.ForWrite), _AcDb.Polyline)
                                    'Liste.Insert(2, Profile03)
                                    Liste.Add(Profile03)
                                    acDoc.Editor.WriteMessage(vbLf & acEnt.Layer)
                            End Select~~
    

    Step2 sorting the array argument

                        EntList(0) = Profile01
                        EntList(1) = Profile02
                        EntList(2) = Profile03
    

    Enjoy !!!

            <CommandMethod("LoftSol")>
            Public Sub LoftSol()
                Dim editor As Editor = _AcAp.Application.DocumentManager.MdiActiveDocument.Editor
                '' Get the current document and database
                Dim acDoc As Document = _AcAp.Application.DocumentManager.MdiActiveDocument
                Dim acCurDb As Database = acDoc.Database
                Dim acBlkTbl As BlockTable
                acBlkTbl = acCurDb.BlockTableId.GetObject(OpenMode.ForWrite)
                Dim acBlkTblRec As BlockTableRecord
                acBlkTblRec = acBlkTbl(BlockTableRecord.ModelSpace).GetObject(OpenMode.ForWrite)
                Dim BrückeAlt As Solid3d = Nothing
                Dim Spline02 As Spline = Nothing
                Dim Profile01 As _AcDb.Polyline = Nothing
                Dim Profile02 As _AcDb.Polyline = Nothing
                Dim Profile03 As _AcDb.Polyline = Nothing
                Dim Liste As New List(Of Entity)
                Dim EntList As Entity() = Nothing
                Dim acEnt As Entity = Nothing
                '' Start a transaction
                Using acTrans As Transaction = acCurDb.TransactionManager.StartTransaction()
                    ' ############## Querschnittlayer als Schleife #############
                    ' Objekte nach ObjektID durchsuchen:
                    For Each acObjId As ObjectId In acBlkTblRec
                        '' Open the selected object for write
                        acEnt = acTrans.GetObject(acObjId, OpenMode.ForWrite)
                        acDoc.Editor.WriteMessage(vbLf & acEnt.Layer)
                        'acEnt.XData()
                        If acEnt.Layer = "Solid3d" Then
                            BrückeAlt = CType(acEnt, Solid3d)
                            BrückeAlt.Erase()
                        ElseIf acEnt.Layer = "Spline" Then
                            Spline02 = CType(acEnt, Spline)
                        End If
    
                        Select Case acEnt.Layer
    
                            Case "Querschnitt10"
                                Profile01 = TryCast(acTrans.GetObject(acObjId, OpenMode.ForWrite), _AcDb.Polyline)
                                'Liste.Insert(0, Profile01)
                                Liste.Add(Profile01)
                                acDoc.Editor.WriteMessage(vbLf & acEnt.Layer)
                            Case "Querschnitt20"
                                Profile02 = TryCast(acTrans.GetObject(acObjId, OpenMode.ForWrite), _AcDb.Polyline)
                                'Liste.Insert(1, Profile02)
                                Liste.Add(Profile02)
                                acDoc.Editor.WriteMessage(vbLf & acEnt.Layer)
                            Case "Querschnitt30"
                                Profile03 = TryCast(acTrans.GetObject(acObjId, OpenMode.ForWrite), _AcDb.Polyline)
                                'Liste.Insert(2, Profile03)
                                Liste.Add(Profile03)
                                acDoc.Editor.WriteMessage(vbLf & acEnt.Layer)
                        End Select
                    Next
    
    
                    EntList = Liste.ToArray()
    
                    EntList(0) = Profile01
                    EntList(1) = Profile02
                    EntList(2) = Profile03
    
                    ' *********************************************************** Extrusionskörper *******************************************
                    Dim LoftOption As New LoftOptions
                    Dim Brückenüberbau As New Solid3d
                    'Brückenüberbau.CreateLoftedSolid(New Entity() {Profile01, Profile02, Profile03}, New Entity() {}, Spline02, LoftOption)
                    Brückenüberbau.CreateLoftedSolid(EntList, New Entity() {}, Spline02, LoftOption)
                    Brückenüberbau.Layer = "Solid3d" 'BrückeAlt.Layer 
                    ' *********************************************** Füge Objekte dem Modellbereich hinzu ***********************************
                    AddToModelSpace(New Entity() {Brückenüberbau})
                    ' Save the new object to the database
                    acTrans.Commit()
                    ' Dispose of the transaction
                End Using
            End Sub
    
  • Thank you so much @Konstantin Sakellaris

    Is it possible to write the Select Case command in a loop?
    (I tried it with a For loop. But I failed because the scanning of the entities of the programm does not match with the counting of the For loop.)

  • you are welcome Andreas
    You can use the Select case construct within any loop and select entities according to specific features (in this case the Layer property),
    but the point is that the sequence of entities in the database is not the same with the sequence that these selected entities must
    be passed to the CreateLoftedSolid method,
    as in your case !
    The selection sequence of the entities has to be reordered for the lofting operation to be succesfull, as needed!
    And the three lines of code EntList(0) = Profile01 EntList(1) = Profile02 EntList(2) = Profile03 do exactly this reordering !

  • Already done, thanks!
    Somehow I managed it now with a Do Loop :)

Sign In or Register to comment.
Origami
Origami is the Japanese word for paper folding. ORI means to fold and KAMI means paper and involves the creation of paper forms usually entirely by folding.

Powered by VanillaForums, Designed by Steam