It may be that this is possibly solved, and this may be the solutionSo, the only unsolved problem of zooming to known object id was this:
4) set viewport to layout's defaultIt has been bugging me for days and it seems that solution is this one liner:
If lay.LayoutName <> "Model" Then ed.SwitchToPaperSpace()
What it does - once you have your layout on (by iterating layouts and comparing its btr-s), your problem is multiple viewports that exists and possibly, one of them is left active, meaning - you cannot zoom because you are not zooming paperspace but inside that viewport.
I have trying different approaches to find all viewports that exist, comparing that to...
With this one liner, problem is solved.
Now, i have not tested code in modelspace (don't know what happens it you zoom and have tiled space), but this is a good start if someone is having the same problem. Also, if someone has better solution or advice, please contribute.
And, to user who asked me if
Dim doc As Document = Application.DocumentManager.MdiActiveDocument
is needed... there are other ways to get doc, admitingly i didn't know them all, and thank you for that, but in this scenario - what is the point of zooming if your doc is not active.
so, steps are:
1) - know your handle or objectid of object you need zoom to.
2) - open file, switch layout, switch viewport
3) - zoom to extents with any of googleable ways
this is what it is all about
Private Sub openLayoutAndViewport(ByRef oid As ObjectId)
Dim doc As Document = Application.DocumentManager.MdiActiveDocument
Dim ed As Editor = doc.Editor
Dim db As Database = doc.Database
Using trans As Transaction = db.TransactionManager.StartTransaction()
Dim ent As Entity = trans.GetObject(oid, OpenMode.ForRead)
Dim btr As BlockTableRecord = trans.GetObject(ent.BlockId, OpenMode.ForRead)
Dim layoutdic As DBDictionary = trans.GetObject(db.LayoutDictionaryId, OpenMode.ForRead)
For Each laye As DBDictionaryEntry In layoutdic
Dim lay As Layout = trans.GetObject(laye.Value, OpenMode.ForRead)
If lay.BlockTableRecordId = ent.BlockId Then
If lay.TabSelected = False Then
Using lock As DocumentLock = doc.LockDocument()
LayoutManager.Current.CurrentLayout = lay.LayoutName
End Using
End If
If lay.LayoutName <> "Model" Then ed.SwitchToPaperSpace()
Exit For
End If
Next
trans.Commit()
End Using
End Sub
one of ways to zoom to extents
credit for this one is possibly Gile although not sure
Private Sub ZoomObjects(idCol As List(Of ObjectId))
Dim doc As Document = Application.DocumentManager.MdiActiveDocument
Dim db As Database = doc.Database
Dim ed As Editor = doc.Editor
Using trans As Transaction = db.TransactionManager.StartTransaction()
Using view As ViewTableRecord = ed.GetCurrentView()
Dim WCS2DCS As Matrix3d = Matrix3d.PlaneToWorld(view.ViewDirection)
WCS2DCS = Matrix3d.Displacement(view.Target - Point3d.Origin) * WCS2DCS
WCS2DCS = Matrix3d.Rotation(-view.ViewTwist, view.ViewDirection, view.Target) * WCS2DCS
WCS2DCS = WCS2DCS.Inverse()
Dim ent As Entity = DirectCast(trans.GetObject(idCol(0), OpenMode.ForRead), Entity)
Dim ext As Extents3d = ent.GeometricExtents
For Each oid As ObjectId In idCol
ent = DirectCast(trans.GetObject(oid, OpenMode.ForRead), Entity)
Dim tmp As Extents3d = ent.GeometricExtents
ext.AddExtents(tmp)
Next
ext.TransformBy(WCS2DCS)
view.Width = ext.MaxPoint.X - ext.MinPoint.X
view.Height = ext.MaxPoint.Y - ext.MinPoint.Y
view.CenterPoint = New Point2d((ext.MaxPoint.X + ext.MinPoint.X) / 2.0, (ext.MaxPoint.Y + ext.MinPoint.Y) / 2.0)
ed.SetCurrentView(view)
trans.Commit()
End Using
End Using
End Sub
now, this code below is not needed for this problem, but i use it as a part of this in a sense that i will open file and zoom to object
-do have in mind all the implications of using handle to access object instead of using objectid!
Public Sub zoomtotextandload(ByVal text As String, hndl As Int64)
'what if *.dwg is corrupt -try catch
'Try
If System.IO.File.Exists(text) Then
If Application.DocumentManager.CurrentDocument IsNot Nothing Then
Dim edbefore As Editor = Application.DocumentManager.MdiActiveDocument.Editor
If edbefore.Document.CommandInProgress.Length > 0 Then
edbefore.WriteMessage("Another command active")
Exit Sub
End If
If edbefore.IsDragging Then
edbefore.WriteMessage("Another command active")
Exit Sub
End If
End If
Dim doc As Document = Nothing
For Each d As Document In Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager
If d.Name = text Then
doc = d
Exit For
End If
Next
If doc = Nothing Then doc = DocumentCollectionExtension.Open(Application.DocumentManager, text, False)
Application.DocumentManager.MdiActiveDocument = doc
'now we have open dwg and will try to find object
Dim ed As Editor = doc.Editor
Dim db As Database = doc.Database
Dim hn As Handle = New Handle(hndl)
Dim oid2 As ObjectId
If db.TryGetObjectId(hn, oid2) Then
If oid2.IsResident = True And Not oid2.IsErased Then
Dim tmp1 As New List(Of ObjectId)
tmp1.Add(oid2)
openLayoutAndViewport(oid2)
ZoomObjects(tmp1)
End If
End If
End If
'Catch ex As Exception
'End Try
End Sub