.NET
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Using AcadSelectionSet to export selected 3dSolid to ACIS SAT file

7 REPLIES 7
Reply
Message 1 of 8
sszabo
1406 Views, 7 Replies

Using AcadSelectionSet to export selected 3dSolid to ACIS SAT file

I have a task that requires me to automate the export of a DWG to SAT without user interaction. I have to find a visible 3DSolid in the DWG database and select it programatically as users do when they have to export solids manually from the File menu to ACIS SAT format. 

 

I acheived the task but because I am new to AutoCAD it's very ugly and seems inefficient. I'd like to ask for some help to find a nicer .NET solution to this:

 

First of all, I can find the solid I want using .NET API with this function:

 

    Public Function GetVisible3dSolid(Optional ByVal Visible As Boolean = True) As Object
            Dim db As Database = Application.DocumentManager.MdiActiveDocument.Database
            Using tr As Transaction = db.TransactionManager.StartTransaction()
                For i As Long = db.BlockTableId.Handle.Value To db.Handseed.Value - 1
                    Dim id As ObjectId = ObjectId.Null
                    Dim h As New Handle(i)
                    If db.TryGetObjectId(h, id) Then
                        If id.ObjectClass.Name = "AcDb3dSolid" Then
                            Dim ent As Entity = CType(tr.GetObject(id, OpenMode.ForRead, True), Entity)
                            If ent.Visible = Visible Then
                                tr.Commit()
                                Return id
                            End If
                        End If
                    End If
                Next
                tr.Commit()
            End Using
        Return Nothing
    End Function

But I can't find a good .NET solution to how to select this ObjectID in a AcadSelectionSet.

 

I ended up coding it up in COM: I select AcSelect.acSelectionSetAll and when I loop through the selection I place everything in a removeObjects list EXCEPT the solid I just found above.  Then I call RemoveItems on my AcadSelectionSet to remove everything EXCEPT my solid.  What I would want ideally is to use AddItems to do the opposite: add my solid as the only selected object and then call Export.  Is there a way to do this (if possible using .NET)

 

Here is my current code:

 

    Public Function ExportDWG2SAT(ByVal lsFullName As String) As Object
        Dim ssetObj As AcadSelectionSet
        Dim removeObjects As New List(Of AcadEntity)
        Dim sImage_Type = "SAT"
        ssetObj = m_currentDoc.SelectionSets.Add("SSALL")   ' creates named selection set
        ssetObj.Select(AcSelect.acSelectionSetAll)          'select everything in the drawing
        Dim my3DSolidObj As Object = GetVisible3dSolid()
        If Not IsNothing(my3DSolidObj) Then
            Dim my3DSolid As ObjectId = CType(my3DSolidObj, ObjectId)
            For Each ent As AcadEntity In ssetObj
                Select Case ent.ObjectName
                    Case "AcDb3dSolid"
                            If ent.ObjectID <> CType(my3DSolid.OldIdPtr, Long) Then
                                removeObjects.Add(ent)
                            End If
                    Case Else
                        removeObjects.Add(ent)
                End Select
            Next
            Dim removeArr() As AcadEntity = removeObjects.ToArray
            ssetObj.RemoveItems(removeArr)
            m_currentDoc.Export(lsFullName, sImage_Type, ssetObj)
        End If
        Return Nothing
    End Function

7 REPLIES 7
Message 2 of 8
Hallex
in reply to: sszabo

I could not find API method to use Export ,

Try this code instead

 

       Imports Autodesk.AutoCAD.Interop
        --------------------------------
        <CommandMethod("exsat")> _
        Public Shared Sub testSolidsSelect()
            Dim doc As Document = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument
            Dim ed As Editor = doc.Editor
            Dim db As Database = HostApplicationServices.WorkingDatabase
            Dim tr As Transaction = db.TransactionManager.StartTransaction()
            Dim sImage_Type = "SAT"
            Dim satFullName As String = "C:\Test\mySolids.sat"
            Try

                ''Dim curlay As String = Autodesk.AutoCAD.ApplicationServices.Application.GetSystemVariable("clayer").ToString()
                Dim curtab As String = Autodesk.AutoCAD.ApplicationServices.Application.GetSystemVariable("ctab").ToString()
                Dim values(4) As TypedValue
                values(0) = New TypedValue(DxfCode.Operator, "<and")
                values(1) = New TypedValue(DxfCode.Start, "3dsolid")
                values(2) = New TypedValue(DxfCode.Visibility, 0)
                values(3) = New TypedValue(DxfCode.LayoutName, curtab)
                values(4) = New TypedValue(DxfCode.Operator, "and>")

                Dim selFilter As New SelectionFilter(values)
                Dim prompSelRes As PromptSelectionResult = ed.SelectAll(selFilter)
                If prompSelRes.Status <> PromptStatus.OK Then Return
                Dim oSset As SelectionSet = prompSelRes.Value
                ed.WriteMessage(vbLf + "{0}", oSset.Count)

                ed.SetImpliedSelection(oSset)

                Dim AcApp As Autodesk.AutoCAD.Interop.AcadApplication = DirectCast(Autodesk.AutoCAD.ApplicationServices.Application.AcadApplication, Autodesk.AutoCAD.Interop.AcadApplication)
                Dim ThisDrawing As Autodesk.AutoCAD.Interop.AcadDocument = AcApp.ActiveDocument
                Dim pickSset As AcadSelectionSet = ThisDrawing.PickfirstSelectionSet
                ThisDrawing.Export(satFullName, sImage_Type, pickSset)
                pickSset.Clear()
                pickSset = Nothing
                ThisDrawing = Nothing
                AcApp = Nothing
                ed.Regen()
            Catch ex As Autodesk.AutoCAD.Runtime.Exception
                Autodesk.AutoCAD.ApplicationServices.Application.ShowAlertDialog(ex.ToString & vbLf & ex.Message)
            Finally
                Autodesk.AutoCAD.ApplicationServices.Application.ShowAlertDialog("Find file " & satFullName & " to see result")
            End Try

        End Sub

 

 

_____________________________________
C6309D9E0751D165D0934D0621DFF27919
Message 3 of 8
sszabo
in reply to: Hallex

Thanks Hallex,

This solution works great if you get the selection from the user and you can use the Editor's SelectionFilter. 

 

My problem is that

 

A) I can't figure out how to create such a selection filter that can be passed to the COM Select call without getting the user/editor involved:

 

AcadSelectionSet.Select(AcSelect.acSelectionSetAll, [Point1 as Object], [Point2 as Object], [FilterType as Object], [FilterData as Object])

 

I imagine I need something like this:

1
2
3
4
5
6
            Dim my3DSolid As ObjectId = CType(my3DSolidObj, ObjectId)
            Dim FilterType(0) As Int16
            Dim FilterData(0) As Object
            FilterType(0) = 0
            FilterData(0) = "3dSolid"
            ssetObj.Select(AcSelect.acSelectionSetAll, , FilterType, FilterData)

 

 Unfortunately this will not work: how do I tell it to select my3DSolid?  I tried different combinations for lines 4 and 5 including passing the ObjectID, my problem is I can't find a good documentation of how to use this API, a link to that would probably help too.

 

B) How to do this in .NET, meaning what's the corresponding Select API in .NET and how to use it, again without the Editor.

 

Message 4 of 8
Jeff_M
in reply to: sszabo


@sszabo wrote:

Thanks Hallex,

This solution works great if you get the selection from the user and you can use the Editor's SelectionFilter. 

...

B) How to do this in .NET, meaning what's the corresponding Select API in .NET and how to use it, again without the Editor.

 


?? Selectionsets with .NET are avaialble only through the Editor namespace. You want to use .net but don't want to use the Editor namespace? Just because it says "Editor" does not men it will require user interaction. Did you try Hallex's code? It should do exactly what you are asking for.

Jeff_M, also a frequent Swamper
EESignature
Message 5 of 8
sszabo
in reply to: Jeff_M

My apologies I wasn't precise in my previous response.  I did try the code and it fails on the line (17) that checks PromptStatus:

 

 

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
    Public Function ExportDWG2SAT(ByVal lsFullName As String) As Object
        Dim doc As Document = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument
        Dim ed As Editor = doc.Editor
        Dim db As Database = HostApplicationServices.WorkingDatabase
        Dim tr As Transaction = db.TransactionManager.StartTransaction()
        Dim oSset As SelectionSet = Nothing
        Dim sImage_Type = "SAT"
        Try
            Dim curtab As String = Autodesk.AutoCAD.ApplicationServices.Application.GetSystemVariable("ctab").ToString()
            Dim values(4) As TypedValue
            values(0) = New TypedValue(DxfCode.Operator, "<and")
            values(1) = New TypedValue(DxfCode.Start, "3dsolid")
            values(2) = New TypedValue(DxfCode.Visibility, 0)
            values(3) = New TypedValue(DxfCode.LayoutName, curtab)
            values(4) = New TypedValue(DxfCode.Operator, "and>")
            Dim selFilter As New SelectionFilter(values)
            Dim prompSelRes As PromptSelectionResult = ed.SelectAll(selFilter)
            If prompSelRes.Status <> PromptStatus.OK Then
                log.Error("prompSelRes.Status: {0}", prompSelRes.Status)
                Return Nothing
            End If
            oSset = prompSelRes.Value
            ed.WriteMessage(vbLf + "{0}", oSset.Count)
            ed.SetImpliedSelection(oSset)
            Dim AcApp As Autodesk.AutoCAD.Interop.AcadApplication = DirectCast(Autodesk.AutoCAD.ApplicationServices.Application.AcadApplication, Autodesk.AutoCAD.Interop.AcadApplication)
            Dim ThisDrawing As Autodesk.AutoCAD.Interop.AcadDocument = AcApp.ActiveDocument
            Dim pickSset As AcadSelectionSet = ThisDrawing.PickfirstSelectionSet
            ThisDrawing.Export(lsFullName, sImage_Type, pickSset)
            pickSset.Clear()
            pickSset = Nothing
            ThisDrawing = Nothing
            AcApp = Nothing
            ed.Regen()
        Catch
            Return SetApiException(Err.GetException,
                                   String.Format("ERROR:134 Can't export '{0}'", lsFullName),
                                   DisplayExceptions)
        End Try
        Return Nothing
    End Function

 

 

The problem seems to be line 17. prompSelRes.Status comes back with "Error" and the prompSelRes.Value will be empty and when it hits line 22 it errors out with 'Object reference not set to an instance of an object.'. (obviously this only hits if I take out "Return Nothing", I tried many other iterations with no avail)

 

Again, your help is very much appreciated and I thank you for your patience I am very new to this.

 

Message 6 of 8
sszabo
in reply to: Hallex

Hallex,

 

I finally got it. I ended up replacing PickfirstSelectionSet with ActiveSelectionSet and your code works exactly as advertised. 

Again, thanks for your help.

Message 7 of 8
bairuize
in reply to: Hallex

Dear Hallex,

 I use the code in my project,but dont work, but i cant find the result .sat in the specified position

Message 8 of 8
bairuize
in reply to: sszabo

i take out the try -cath,then i meet the error“System.AccessViolationException”;why.could somebody help me

best wishes to you

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


Autodesk Design & Make Report

”Boost