.NET

.NET

Reply
Valued Contributor
sszabo
Posts: 86
Registered: ‎09-05-2012
Message 1 of 6 (599 Views)

Using AcadSelectionSet to export selected 3dSolid to ACIS SAT file

599 Views, 5 Replies
11-22-2012 07:44 AM

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

*Expert Elite*
Hallex
Posts: 1,569
Registered: ‎10-08-2008
Message 2 of 6 (575 Views)

Re: Using AcadSelectionSet to export selected 3dSolid to ACIS SAT file

11-22-2012 12:30 PM 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
Valued Contributor
sszabo
Posts: 86
Registered: ‎09-05-2012
Message 3 of 6 (554 Views)

Re: Using AcadSelectionSet to export selected 3dSolid to ACIS SAT file

11-23-2012 10:50 AM 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.

 

*Expert Elite*
Jeff_M
Posts: 4,310
Registered: ‎07-22-2003
Message 4 of 6 (547 Views)

Re: Using AcadSelectionSet to export selected 3dSolid to ACIS SAT file

11-23-2012 12:44 PM 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
Valued Contributor
sszabo
Posts: 86
Registered: ‎09-05-2012
Message 5 of 6 (530 Views)

Re: Using AcadSelectionSet to export selected 3dSolid to ACIS SAT file

11-24-2012 07:48 AM 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.

 

Valued Contributor
sszabo
Posts: 86
Registered: ‎09-05-2012
Message 6 of 6 (488 Views)

Re: Using AcadSelectionSet to export selected 3dSolid to ACIS SAT file

11-27-2012 12:12 PM 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.

Announcements
Are you familiar with the Autodesk Expert Elites? The Expert Elite program is made up of customers that help other customers by sharing knowledge and exemplifying an engaging style of collaboration. To learn more, please visit our Expert Elite website.
Need installation help?

Start with some of our most frequented solutions or visit the Installation and Licensing Forum to get help installing your software.