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.

  • 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?

  • 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.

Howdy, Stranger!

It looks like you're new here. Click one of the buttons on the top bar to get involved!