Тема: Системы координат блоков и WCS

Ситуация. Есть блок. В нем точки. Блок вставлен в WCS не в нулевой точке. Хочу вычленить любую точку из блока и вставить ее в модели, НО! чтобы она появилась там, где она выглядит в модели, находясь в блоке. Иными словами. Если точка, находясь в блоке имеет координаты 3,3,0, а блок вставлен с координатами 2,2,0, то при извлечении из блока точка должна иметь координаты 5,5,0, а не 3,3,0 как получается у меня сейчас. Чувствую что работать надо с Matrix3d. Подбросьте информацию

Re: Системы координат блоков и WCS

Понадобится использовать BlockReference.BlockTransform
Подробнее у меня в подписи.

(изменено: Сергей, 1 марта 2014г. 23:17:17)

Re: Системы координат блоков и WCS

Спасибо. Принцип понял. АКАД выдает фатал ерор...  Как вылечить?
кусок кода
  Dim pner = acEd.GetNestedEntity(pneo)

        Using acTrans As Transaction = acDb.TransactionManager.StartTransaction()
            Dim acBlkTbl As BlockTable
            acBlkTbl = CType(acTrans.GetObject(acDb.BlockTableId, OpenMode.ForRead), BlockTable)
            Dim acBlkTblRec As BlockTableRecord
            acBlkTblRec = CType(acTrans.GetObject(acBlkTbl(BlockTableRecord.ModelSpace), OpenMode.ForWrite), BlockTableRecord)
           
Dim blkpoly As Autodesk.AutoCAD.DatabaseServices.Polyline = DirectCast(acTrans.GetObject(pner.ObjectId, OpenMode.ForRead), Autodesk.AutoCAD.DatabaseServices.Polyline)
           
Dim blk As BlockReference = TryCast(acTrans.GetObject(blkpoly.OwnerId, OpenMode.ForRead), BlockReference)

            Dim SelectedPoly As Autodesk.AutoCAD.DatabaseServices.Polyline = DirectCast(blkpoly.Clone(), Autodesk.AutoCAD.DatabaseServices.Polyline)

            SelectedPoly.SetDatabaseDefaults()
            acBlkTblRec.AppendEntity(SelectedPoly)
            acTrans.AddNewlyCreatedDBObject(SelectedPoly, True)
            Dim scaleX As Double = blk.ScaleFactors(0)
            Dim scaleY As Double = blk.ScaleFactors(1)

            Dim coeffs As Double() = New Double() {scaleX, 0, 0, 0, 0, scaleY, _
                0, 0, 0, 0, 1, 0, _
                0, 0, 0, 1}

            Dim scaleMatrix As New Matrix3d(coeffs)
            SelectedPoly.TransformBy(scaleMatrix)
            acTrans.Commit()

        End Using

Re: Системы координат блоков и WCS

Сергей пишет:

Как вылечить?

Говорят некоторые могут лечить по фотографии. У меня иногда получается. А вот совсем без фотографии (без исходника) у меня не получается...

(изменено: Сергей, 1 марта 2014г. 23:21:54)

Re: Системы координат блоков и WCS

да я уже так и подумал) исправился) даже без PreMultypleBy... все равно фаталит. решил без BlockTransform пока.

Re: Системы координат блоков и WCS

Может под отладчиком пошагово пройдешься и найдешь где фаталит?!

(изменено: Сергей, 1 марта 2014г. 23:26:59)

Re: Системы координат блоков и WCS

а вот это вообще проблема. я так и не понял, как привязать дебагер. Методы, что описывают - запускают акад но он не привязывает dll-ку

Re: Системы координат блоков и WCS

разницы с этим нет
<CommandMethod("ol")> _
    Public Sub ol()
        Dim acDoc As Document = Application.DocumentManager.MdiActiveDocument
        Dim acEd As Editor = acDoc.Editor
        Dim acDb As Database = acDoc.Database
        Dim pneo = New PromptNestedEntityOptions(vbLf & "Select poly inside block")
        Dim pner = acEd.GetNestedEntity(pneo)
        Using acTrans As Transaction = acDb.TransactionManager.StartTransaction()
            Dim acBlkTbl As BlockTable
            acBlkTbl = CType(acTrans.GetObject(acDb.BlockTableId, OpenMode.ForRead), BlockTable)
            Dim acBlkTblRec As BlockTableRecord
            acBlkTblRec = CType(acTrans.GetObject(acBlkTbl(BlockTableRecord.ModelSpace), OpenMode.ForWrite), BlockTableRecord)
            Dim blkpoly As Autodesk.AutoCAD.DatabaseServices.Polyline = DirectCast(acTrans.GetObject(pner.ObjectId, OpenMode.ForRead), Autodesk.AutoCAD.DatabaseServices.Polyline)
            Dim blk As BlockReference = TryCast(acTrans.GetObject(blkpoly.OwnerId, OpenMode.ForRead), BlockReference)
            Dim SelectedPoly As Autodesk.AutoCAD.DatabaseServices.Polyline = DirectCast(blkpoly.Clone(), Autodesk.AutoCAD.DatabaseServices.Polyline)
            SelectedPoly.SetDatabaseDefaults()
            acBlkTblRec.AppendEntity(SelectedPoly)
            acTrans.AddNewlyCreatedDBObject(SelectedPoly, True)
            SelectedPoly.TransformBy(blk.BlockTransform)
            acTrans.Commit()

        End Using
    End Sub

(изменено: Сергей, 2 марта 2014г. 01:02:20)

Re: Системы координат блоков и WCS

Нашел ошибку. Дело пошло. Неверно определял ObjectID для блока, в котором лежит полилиния.
Однако теперь приходится определять ObjectID блока через выбор объектов. Не есть гут. Наверняка можно как то через OwnerID... Но как, что-то не соображу

<CommandMethod("ol")> _
    Public Sub ol()
        Dim acDoc As Document = Application.DocumentManager.MdiActiveDocument
        Dim acEd As Editor = acDoc.Editor
        Dim acDb As Database = acDoc.Database


        Dim pneo1 = New PromptEntityOptions(vbLf & "Select Blockref ")
        Dim pner1 = acEd.GetEntity(pneo1)
        Dim pneo = New PromptNestedEntityOptions(vbLf & "Select Polyline inside block")
        Dim pner = acEd.GetNestedEntity(pneo)

        Using acTrans As Transaction = acDb.TransactionManager.StartTransaction()
            Dim acBlkTbl As BlockTable
            acBlkTbl = CType(acTrans.GetObject(acDb.BlockTableId, OpenMode.ForRead), BlockTable)
            Dim acBlkTblRec As BlockTableRecord
            acBlkTblRec = CType(acTrans.GetObject(acBlkTbl(BlockTableRecord.ModelSpace), OpenMode.ForWrite), BlockTableRecord)
            Dim selent As Entity = DirectCast(acTrans.GetObject(pner.ObjectId, OpenMode.ForWrite), Entity)
            Dim btrec As BlockTableRecord = TryCast(acTrans.GetObject(selent.OwnerId, OpenMode.ForWrite), BlockTableRecord)
            Dim blk As BlockReference = TryCast(acTrans.GetObject(pner1.ObjectId, OpenMode.ForWrite), BlockReference)
            Dim blkpoly As Autodesk.AutoCAD.DatabaseServices.Polyline = DirectCast(acTrans.GetObject(pner.ObjectId, OpenMode.ForRead), Autodesk.AutoCAD.DatabaseServices.Polyline)
            Dim SelectedPoly As Autodesk.AutoCAD.DatabaseServices.Polyline = DirectCast(blkpoly.Clone(), Autodesk.AutoCAD.DatabaseServices.Polyline)
            acBlkTblRec.AppendEntity(SelectedPoly)
            SelectedPoly.SetDatabaseDefaults()
            acTrans.AddNewlyCreatedDBObject(SelectedPoly, True)
            SelectedPoly.TransformBy(blk.BlockTransform)
            SelectedPoly.Draw()
            acTrans.Commit()
        End Using
    End Sub

Re: Системы координат блоков и WCS

РЕШЕНО. Можно закрывать.

<CommandMethod("ol")> _
    Public Sub ol()
        Dim acDoc As Document = Application.DocumentManager.MdiActiveDocument
        Dim acEd As Editor = acDoc.Editor
        Dim acDb As Database = acDoc.Database
        Dim pneo = New PromptNestedEntityOptions(vbLf & "Select Polyline inside block")
        Dim pner = acEd.GetNestedEntity(pneo)
        Using acTrans As Transaction = acDb.TransactionManager.StartTransaction()
            Dim acBlkTbl As BlockTable
            acBlkTbl = CType(acTrans.GetObject(acDb.BlockTableId, OpenMode.ForRead), BlockTable)
            Dim acBlkTblRec As BlockTableRecord
            acBlkTblRec = CType(acTrans.GetObject(acBlkTbl(BlockTableRecord.ModelSpace), OpenMode.ForWrite), BlockTableRecord)
            Dim blk As BlockReference = TryCast(acTrans.GetObject(pner.GetContainers(0), OpenMode.ForWrite), BlockReference)
            Dim blkpoly As Autodesk.AutoCAD.DatabaseServices.Polyline = DirectCast(acTrans.GetObject(pner.ObjectId, OpenMode.ForRead), Autodesk.AutoCAD.DatabaseServices.Polyline)
            Dim SelectedPoly As Autodesk.AutoCAD.DatabaseServices.Polyline = DirectCast(blkpoly.Clone(), Autodesk.AutoCAD.DatabaseServices.Polyline)
            acBlkTblRec.AppendEntity(SelectedPoly)
            SelectedPoly.SetDatabaseDefaults()
            acTrans.AddNewlyCreatedDBObject(SelectedPoly, True)
            SelectedPoly.TransformBy(blk.BlockTransform)
            SelectedPoly.Draw()
            acTrans.Commit()
        End Using
    End Sub