Author Topic: Creating multiple layouts  (Read 2158 times)

0 Members and 1 Guest are viewing this topic.

Proctor

  • Guest
Creating multiple layouts
« on: February 05, 2009, 11:55:10 AM »
Hello: I have created command BOM that asks the user to select all objects in model
space they want to have in the new layout.

After they select these objects, it opens a custom template, creates the layout
and places these objects into the new layout.

If the user then clicks bom again, and selects a different set of objects this time,
another new layout with a unique name is created with these object inside it.

This code is all working great.

HERE'S THE PROBLEM:
After entering BOM and therefore creating the first layout, I click on it and I see it's perfect.
After I entering BOM and therefore creating the second layout, I click on it and I see it's perfect.

If however, I now click back to the tab to view the first layout,
I see that this first layout not only contains all the stuff it's suppose to, it also contains all the objects from the second layout...and I don't understand why.

Below is my code...I was hoping someone could please take a look at it
and see and help explain to me what I'm doing wrong.

Thanks  for your time,
Proctor



Code: [Select]
    <CommandMethod("BOM")> _
     Sub BOM()
 
        Dim myDWG As Autodesk.AutoCAD.ApplicationServices.Document
        Dim idLayout As ObjectId = ObjectId.Null
        Dim myBT As BlockTable
        Dim myBTE As SymbolTableEnumerator
        Dim layout As New DatabaseServices.Layout
        Dim myLayout As New Layout
        Dim myPSR As PromptSelectionResult
        Dim myPSO As New PromptSelectionOptions
        Dim ext As Extents3d
        Dim minPt(2), maxPt(2) As Double
        Dim fstEnt As Boolean = True
        Dim ent As Entity
        Dim iIncrement As Integer = 0
        Dim iIncrementText As Integer = 0

        Dim doc As Document = Application.DocumentManager.MdiActiveDocument
        Dim db As Database = doc.Database
        Dim lm As LayoutManager = LayoutManager.Current()


        Dim btr As BlockTableRecord


        Dim ed As Editor = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor()
        Dim layoutId As ObjectId
        Dim dLayoutNameParsedHightestIncrement As Double = 0
        Dim bIncrementedName As Boolean = False 'CO_ESTIMATE was found and needed to increment it
        Dim sIncrement As String = ""
        Dim sHightestLastValue As Integer = 0


        Using tr As Transaction = db.TransactionManager.StartTransaction()
            ' (1) create the new layout
            myBT = db.BlockTableId.GetObject(DatabaseServices.OpenMode.ForRead)
            myBTE = myBT.GetEnumerator
            'ASSIGN UNIQUE LAYOUT NAME
            While myBTE.MoveNext
                btr = myBTE.Current.GetObject(DatabaseServices.OpenMode.ForRead)
                If btr.IsLayout Then
                    myLayout = btr.LayoutId.GetObject(DatabaseServices.OpenMode.ForRead)
                    Debug.Print("lAYOUTNAME: " & vbCr & myLayout.LayoutName)
                    If InStr(myLayout.LayoutName, "CO_ESTIMATE") = 1 Then
                        layoutNameInDwg = myLayout.LayoutName & "1"
                        bIncrementedName = True
                        'if there's already a layout that has at least part of this name
                        If myLayout.LayoutName.Length >= 14 Then
                            'Do a check of the new assignment
                            'if we had already assigned a new layout name, need to make sure there's not another like it
                            'check the number for the layout
                            If myLayout.LayoutName.Length = 14 Then
                                sLayoutNameParsedRight = 0
                            Else
                                sLayoutNameParsedRight = myLayout.LayoutName.Substring(14, myLayout.LayoutName.Length - 14)
                            End If
                            If sIncrement = "" Then
                                sIncrement = sLayoutNameParsedRight
                            Else
                                sIncrement = sIncrement & "," & sLayoutNameParsedRight
                            End If

                            Dim MyIncrementArray() As String = Split(sIncrement, ",")
                            If MyIncrementArray.Length = 1 Then
                                sHightestLastValue = sLayoutNameParsedRight
                            Else
                                For g As Integer = 0 To MyIncrementArray.Length - 1
                                    Dim sValue As Integer = CInt(MyIncrementArray(g))
                                    If sLayoutNameParsedRight > sValue Then
                                        If sHightestLastValue = 0 Then
                                            sHightestLastValue = sLayoutNameParsedRight
                                        Else
                                            If sLayoutNameParsedRight > sHightestLastValue Then
                                                sHightestLastValue = sLayoutNameParsedRight
                                            End If
                                        End If
                                    End If
                                Next
                            End If
                            layoutNameInDwg = "CO_ESTIMATE" & (sHightestLastValue + 1)
                            bIncrementedName = True
                        End If
                    End If
                End If
            End While
            If bIncrementedName = False Then
                layoutNameInDwg = "CO_ESTIMATE"
            End If

            layoutId = lm.CreateLayout(layoutNameInDwg)
            layout = tr.GetObject(layoutId, Autodesk.AutoCAD.DatabaseServices.OpenMode.ForWrite)
            myDWG = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument
            Dim myEd As Editor

            myPSO.MessageForAdding = "Please select all objects you wish to place in BOM."

            myEd = myDWG.Editor
            myPSO.SingleOnly = False

            myPSR = myEd.GetSelection(myPSO)
            If Not IsNothing(myPSR.Value) Then

                Dim pBOMIds As ObjectIdCollection = New ObjectIdCollection(myPSR.Value.GetObjectIds)
                Dim pBOMId As ObjectId

                btr = tr.GetObject(db.CurrentSpaceId, Autodesk.AutoCAD.DatabaseServices.OpenMode.ForWrite, False, False) 'GOPINATH


                For Each pBOMId In pBOMIds
                    ent = DirectCast(tr.GetObject(pBOMId, Autodesk.AutoCAD.DatabaseServices.OpenMode.ForRead), Entity)
                    If (fstEnt) Then
                        ext = New Extents3d(ent.GeometricExtents.MinPoint, ent.GeometricExtents.MaxPoint)
                        minPt(0) = ent.GeometricExtents.MinPoint.X
                        minPt(1) = ent.GeometricExtents.MinPoint.Y
                        minPt(2) = ent.GeometricExtents.MinPoint.Z
                        maxPt(0) = ent.GeometricExtents.MaxPoint.X
                        maxPt(1) = ent.GeometricExtents.MaxPoint.Y
                        maxPt(2) = ent.GeometricExtents.MaxPoint.Z
                        fstEnt = False
                    Else

                        If (minPt(0) > ent.GeometricExtents.MinPoint.X) Then
                            minPt(0) = ent.GeometricExtents.MinPoint.X
                        End If
                        If (minPt(1) > ent.GeometricExtents.MinPoint.Y) Then
                            minPt(1) = ent.GeometricExtents.MinPoint.Y
                        End If
                        If (minPt(2) > ent.GeometricExtents.MinPoint.Z) Then
                            minPt(2) = ent.GeometricExtents.MinPoint.Z
                        End If
                        If (maxPt(0) < ent.GeometricExtents.MaxPoint.X) Then
                            maxPt(0) = ent.GeometricExtents.MaxPoint.X
                        End If
                        If (maxPt(1) < ent.GeometricExtents.MaxPoint.Y) Then
                            maxPt(1) = ent.GeometricExtents.MaxPoint.Y
                        End If
                        If (maxPt(2) < ent.GeometricExtents.MaxPoint.Z) Then
                            maxPt(2) = ent.GeometricExtents.MaxPoint.Z
                        End If
                    End If
                Next

                ext = New Extents3d(New Point3d(minPt), New Point3d(maxPt))
                Using docLock As DocumentLock = ed.Document.LockDocument()
                    Using db2 As New Database(False, True)
                        Using tr2 As Transaction = db2.TransactionManager.StartTransaction()

                            db2.ReadDwgFile("C:\BOM_TEMPLATE.dwt", System.IO.FileShare.Read, True, Nothing)

                            Dim ld2 As DBDictionary = tr2.GetObject(db2.LayoutDictionaryId, Autodesk.AutoCAD.DatabaseServices.OpenMode.ForWrite)
                            Dim bt2 As BlockTable = tr2.GetObject(db2.BlockTableId, Autodesk.AutoCAD.DatabaseServices.OpenMode.ForWrite)
                            Dim layout2 As Layout
                            Dim btr2 As BlockTableRecord

                            If ld2.Contains(layoutNameInDwt) Then
                                layout2 = tr2.GetObject(ld2(layoutNameInDwt), Autodesk.AutoCAD.DatabaseServices.OpenMode.ForWrite)
                                btr2 = tr2.GetObject(layout2.BlockTableRecordId, Autodesk.AutoCAD.DatabaseServices.OpenMode.ForWrite)
                                '(2) copy layout properties from the other drawing
                                layout.CopyFrom(layout2)
                            Else
                                tr2.Abort()
                                tr.Abort()
                                Return
                            End If

                            ' (3) copy the contents of the layout

                            Dim plotSet As PlotSettings = New PlotSettings(False)
                            plotSet = CType(tr.GetObject(layoutId, Autodesk.AutoCAD.DatabaseServices.OpenMode.ForWrite, False, False), PlotSettings)

                            Dim oPSVal As PlotSettingsValidator = PlotSettingsValidator.Current
                            oPSVal.SetZoomToPaperOnUpdate(plotSet, True)


                            Dim idc As New ObjectIdCollection()
                            For Each id As ObjectId In btr2
                                idc.Add(id)

                                ent = tr2.GetObject(id, Autodesk.AutoCAD.DatabaseServices.OpenMode.ForWrite, True)

                                If TypeOf ent Is Viewport Then
                                    SetViewportToExtents(id, ext)
                                End If
                            Next
                            Dim im As IdMapping = New IdMapping()
                            db.WblockCloneObjects(idc, layout.BlockTableRecordId, im, DuplicateRecordCloning.MangleName, False)
                        End Using
                        tr.Commit()
                        lm.CurrentLayout = layoutNameInDwg
                        doc.Database.Psltscale = False

                        doc.SendStringToExecute("REGENALL ", True, False, True)

                    End Using
                End Using
            End If
        End Using
    End Sub



bikelink

  • Guest
Re: Creating multiple layouts
« Reply #1 on: February 13, 2009, 01:55:04 AM »
WHy you donět copy the layout  ?  IMHO its more simple to keep your layout empty in a drawing and copy it when you need.
I think that you have some problem with bocktable of layout. Me too i've tried to build  layouts.. and then i leaves this solution.