Author Topic: Problem with getting object from ObjecID in VB.NET  (Read 4407 times)

0 Members and 1 Guest are viewing this topic.

huiz

  • Swamp Rat
  • Posts: 917
  • Certified Prof C3D
Problem with getting object from ObjecID in VB.NET
« on: January 24, 2010, 07:47:05 AM »
As a novice in OOP I try to understand the concept of objects. So far I can understand this but while writing code things get blurry and confusing  :?

I tried to write a routine that convert text objects in AutoCAD into points where the Z value is the content of the text object. With this I can easily create a surface in Civil3D from measured heights.

Code: [Select]
  <CommandMethod("TxtPnt")> _
  Public Sub TextPoint()
    '' Get the current document and database, and start a transaction
    Dim acDoc As Document = Application.DocumentManager.MdiActiveDocument
    Dim acCurDb As Database = acDoc.Database

    Dim acTypedValue(0) As TypedValue
    acTypedValue(0) = New TypedValue(DxfCode.Start, "TEXT")

    Dim acFilter As New EditorInput.SelectionFilter(acTypedValue)

    Dim acPSR As EditorInput.PromptSelectionResult

    Dim acObjIDs As ObjectIdCollection
    Dim acObjID As ObjectId

    Dim acText As DBText

    Dim acPointObject As DBPoint

    Dim acBT As BlockTable
    Dim acBTR As BlockTableRecord

    acPSR = acDoc.Editor.GetSelection(acFilter)

    Using acTrans As Transaction = acCurDb.TransactionManager.StartTransaction()
      ' Check if there is a selection set
      If Not IsNothing(acPSR.Value) Then
        ' Fill Collection with selected objects IDs
        acObjIDs = New ObjectIdCollection(acPSR.Value.GetObjectIds)

        Try
          ' Open drawing for write
          acBT = acDoc.Database.BlockTableId.GetObject(OpenMode.ForRead)
          acBTR = acBT(BlockTableRecord.ModelSpace).GetObject(OpenMode.ForWrite)

          ' Loop through collection
          For Each acObjID In acObjIDs
            ' Get Text object
            acText = acObjID.GetObject(OpenMode.ForRead, False)
            ' Create Point object if text is numeric
            If IsNumeric(CDbl(acText.TextString)) Then
              Dim acPoint = New Geometry.Point3d(acText.Position.X, acText.Position.Y, Convert.ToDouble(acText.TextString))
              ' Place Point object in Modelspace
              acPointObject = New DBPoint(acPoint)
              acBTR.AppendEntity(acPointObject)
              ' Add to transaction
              acTrans.AddNewlyCreatedDBObject(acPointObject, True)
              ' Commit transaction
              acTrans.Commit()
            End If
          Next

        Catch ex As Exception

        End Try

      End If

      ' Close transaction
      acTrans.Dispose()
    End Using

  End Sub

The line
Code: [Select]
            acText = acObjID.GetObject(OpenMode.ForRead, False)
gives trouble, I get an error and the editor suggests me three options. Examine the objec acText shows me it exist but the TextString is empty.

Can someone give me a hint?  :-)
The conclusion is justified that the initialization of the development of critical subsystem optimizes the probability of success to the development of the technical behavior over a given period.

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8702
  • AKA Daniel
Re: Problem with getting object from ObjecID in VB.NET
« Reply #1 on: January 24, 2010, 07:55:17 AM »
You can try using the transaction, sorry I  don't do VB very well

acTrans.GetObject(acObjID, OpenMode.ForRead,...

You will need to cast the result as this will return a dbobject.


huiz

  • Swamp Rat
  • Posts: 917
  • Certified Prof C3D
Re: Problem with getting object from ObjecID in VB.NET
« Reply #2 on: January 24, 2010, 08:00:07 AM »
I'll give it a try :)
The conclusion is justified that the initialization of the development of critical subsystem optimizes the probability of success to the development of the technical behavior over a given period.

sinc

  • Guest
Re: Problem with getting object from ObjecID in VB.NET
« Reply #3 on: January 24, 2010, 10:30:23 AM »
You might also be interested in knowing that this functionality is built-in to Civil 3D.

In the Surface -> Utilities, there's a "Move Text to Elevation" command.  It's a bit tricky to get to the command - you either have to select a Surface first, so you can see the Surface context tab, or turn on the menus, where it's in Surface -> Utilities.  Or type AeccMoveTextToElevation at the command line.

Once the text objects are moved to the elevation, you can simply add them to your C3D surface.

huiz

  • Swamp Rat
  • Posts: 917
  • Certified Prof C3D
Re: Problem with getting object from ObjecID in VB.NET
« Reply #4 on: January 24, 2010, 03:48:04 PM »
I didn't know the tool AeccMoveTextToElevation and it works quite well. I put it on my toolpalette :-)

But I would like to get my code work as well. acTrans.GetObject doesn't work.

It is weird that if I run the code and select one object, I do get a point object with the correct Z value. But if I select more objects, I get a fatal error.
The conclusion is justified that the initialization of the development of critical subsystem optimizes the probability of success to the development of the technical behavior over a given period.

fixo

  • Guest
Re: Problem with getting object from ObjecID in VB.NET
« Reply #5 on: January 24, 2010, 06:48:59 PM »
Try this one instead

Code: [Select]
Public Sub TextPoint()
            Dim doc As Document = acadApp.DocumentManager.MdiActiveDocument
            '' Get the current document editor
            Dim ed As Editor = doc.Editor
            '' Get the current database
            Using db As Database = HostApplicationServices.WorkingDatabase
                '' Get the current transaction
                Dim tr As Transaction = db.TransactionManager.StartTransaction
                '' using transaction
                Using (tr)
                    Try
                        '' Create a TypedValue array to define the filter criteria
                        Dim typefilter As TypedValue() = New TypedValue() {New TypedValue(DxfCode.Start, "TEXT")}
                        '' Assign the filter criteria to a SelectionFilter object
                        Dim filter As SelectionFilter = New SelectionFilter(typefilter)
                        Dim pso As PromptSelectionOptions = New PromptSelectionOptions()
                        pso.AllowDuplicates = False
                        pso.RejectObjectsFromNonCurrentSpace = True
                        '' Request for objects to be selected in the drawing area
                        Dim res As PromptSelectionResult = ed.GetSelection(pso, filter)
                        Dim oSset As SelectionSet = Nothing
                        '' If the prompt status is OK, objects were selected
                        If (res.Status = PromptStatus.OK) Then
                            '' get selection set
                            oSset = res.Value
                            '' show result
                            ed.WriteMessage(vbLf & "Number of objects selected: {0}", oSset.Count.ToString())
                        Else
                            ed.WriteMessage(vbLf & "Number of objects selected: 0")
                            '' exit if nothing selected
                            Return
                        End If

                        Dim btr As BlockTableRecord = CType(tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite), BlockTableRecord)

                        '' iterate through selected texts
                        For Each obj As SelectedObject In oSset

                            Dim id As ObjectId = obj.ObjectId
                            ''Cast obj as entity
                            Dim ent As Entity = TryCast(tr.GetObject(id, OpenMode.ForRead), Entity)
                            If (Not ent Is Nothing) Then
                                '' Cast entity as dbtext
                                Dim txt As DBText = TryCast(tr.GetObject(id, OpenMode.ForRead), DBText)
                                ' Create Point object if text is numeric
                                If IsNumeric(txt.TextString) Then
                                    Dim pt As Point3d = New Point3d(txt.Position.X, txt.Position.Y, CDbl(txt.TextString))
                                    ' Place Point object in current space
                                    Dim ptobj As DBPoint = New DBPoint(pt)
                                    btr.AppendEntity(ptobj)
                                    ' Add to transaction
                                    tr.AddNewlyCreatedDBObject(ptobj, True)
                                End If

                            End If
                        Next
                        ' Commit transaction
                        tr.Commit()
                    Catch ex As Autodesk.AutoCAD.Runtime.Exception
                        ed.WriteMessage("Error: {0}" & vbLf & "Stack trace: {1}", ex.Message, ex.StackTrace)
                    End Try
                End Using ''dispose transaction
            End Using ''dispose database
        End Sub

¬'J'¬

huiz

  • Swamp Rat
  • Posts: 917
  • Certified Prof C3D
Re: Problem with getting object from ObjecID in VB.NET
« Reply #6 on: January 25, 2010, 04:44:12 PM »
Tnx fixo! That code works!

I'll take some time to examin the code and try to understand every line till I get the trick :-)

Learing to code is to understand what you do, not being able to copy and paste from others  :-)
The conclusion is justified that the initialization of the development of critical subsystem optimizes the probability of success to the development of the technical behavior over a given period.

fixo

  • Guest
Re: Problem with getting object from ObjecID in VB.NET
« Reply #7 on: January 26, 2010, 03:08:26 AM »
That's right
Better yet to find a solution by yourself
But it's no harts to look at good programming manner
I.e. here:

http://through-the-interface.typepad.com/

Cheers :)

~'J'~

xsfhlzh

  • Guest
Re: Problem with getting object from ObjecID in VB.NET
« Reply #8 on: January 26, 2010, 09:05:22 AM »
Only select numeric,using this test:
Code: [Select]
            Database db = HostApplicationServices.WorkingDatabase;
            Document doc = Application.DocumentManager.GetDocument(db);
            Editor ed = doc.Editor;

            ed.SelectAll
                (
                    new SelectionFilter
                        (
                            new TypedValue[]
                            {
                                new TypedValue(0, "Text"),
                                new TypedValue(1, "~*[~.0-9]*"),
                                new TypedValue(1, "~*.*.*"),
                            }
                        )
                );