Chuyển đến nội dung
Diễn đàn CADViet
Đăng nhập để thực hiện theo  
quyenpv

Hỗ trợ sửa code để Block có thể căn chỉnh theo đường curve

Các bài được khuyến nghị

Hiện tại em đang dùng Jig để căn chỉnh Block bằng cách sử dụng VB.NET. Lớp này cho phép người dùng tạo và tương tác di chuyển, xoay và chia tỷ lệ tham chiếu đến đường curve. Tuy nhiên khi di chuyển nó lại không được như mong muốn bằng lisp Align Text to Curve

 

Imports System.Collections.Generic
Imports Autodesk.AutoCAD.DatabaseServices
Imports Autodesk.AutoCAD.Runtime
Imports Autodesk.AutoCAD.EditorInput
Imports Autodesk.AutoCAD.Geometry
Imports MgdAcApplication = Autodesk.AutoCAD.ApplicationServices.Application

Namespace AcadNetAddinWizard_Namespace
    Public Class DynamicBlockAlignmentJig
        Inherits EntityJig

        Private mCurJigFactorNumber As Integer = 1
        Private mIsDynamicAlignment As Boolean = False
        Private mAlignmentAngle As Double = 0.0
        Private mObjectIdToAlignWith As ObjectId = ObjectId.Null
        Private mAngleOffset As Double = 0.0
        Private mPosition As Point3d = New Point3d(0, 0, 0)
        Private mRotation As Double = 0.0
        Private mScaleFactor As Double = 1.0

        Public Sub New(ByVal ent As BlockReference)
            MyBase.New(ent)
            mAngleOffset = ent.Rotation
            If ent.IsDynamicBlock Then mIsDynamicAlignment = True
        End Sub

        Protected Shared ReadOnly Property CurEditor As Editor
            Get
                Return MgdAcApplication.DocumentManager.MdiActiveDocument.Editor
            End Get
        End Property

        Protected Shared ReadOnly Property UCS As Matrix3d
            Get
                Return CurEditor.CurrentUserCoordinateSystem
            End Get
        End Property

        Protected Overloads ReadOnly Property Entity As BlockReference
            Get
                Return CType(MyBase.Entity, BlockReference)
            End Get
        End Property

        Protected Overrides Function Update() As Boolean
            Select Case mCurJigFactorNumber
                Case 1
                    Entity.Position = mPosition.TransformBy(UCS)

                    If mIsDynamicAlignment AndAlso Not mObjectIdToAlignWith.IsNull Then

                        If mObjectIdToAlignWith.ObjectClass.IsDerivedFrom(RXClass.GetClass(GetType(Curve))) Then
                            Dim curve As Curve = CType(Entity.Database.TransactionManager.TopTransaction.GetObject(mObjectIdToAlignWith, OpenMode.ForRead), Curve)
                            Dim dir As Vector3d = curve.GetFirstDerivative(curve.GetClosestPointTo(Entity.Position, False)).TransformBy(UCS.Inverse())
                            mAlignmentAngle = Vector3d.XAxis.GetAngleTo(dir, Vector3d.ZAxis)
                            Entity.Rotation = mAlignmentAngle + mAngleOffset
                        Else
                            mObjectIdToAlignWith = ObjectId.Null
                        End If
                    End If

                Case 2
                    Entity.Rotation = mRotation + mAngleOffset
                Case 3
                    Entity.ScaleFactors = New Scale3d(mScaleFactor)
                Case Else
            End Select

            Return True
        End Function

        Protected Overrides Function Sampler(ByVal prompts As JigPrompts) As SamplerStatus
            Select Case mCurJigFactorNumber
                Case 1
                    Dim prOptions1 As JigPromptPointOptions = New JigPromptPointOptions(vbLf & "Block insertion point:")
                    Dim prResult1 As PromptPointResult = prompts.AcquirePoint(prOptions1)
                    If prResult1.Status = PromptStatus.Cancel Then Return SamplerStatus.Cancel
                    Dim tempPt As Point3d = prResult1.Value.TransformBy(UCS.Inverse())

                    If tempPt.IsEqualTo(mPosition) Then
                        Return SamplerStatus.NoChange
                    Else
                        mPosition = tempPt
                        mObjectIdToAlignWith = pickObjId
                        Return SamplerStatus.OK
                    End If

                Case 2
                    Dim prOptions2 As JigPromptAngleOptions = New JigPromptAngleOptions(vbLf & "Block rotation angle:")
                    prOptions2.BasePoint = mPosition.TransformBy(UCS)
                    prOptions2.UseBasePoint = True
                    Dim prResult2 As PromptDoubleResult = prompts.AcquireAngle(prOptions2)
                    If prResult2.Status = PromptStatus.Cancel Then Return SamplerStatus.Cancel

                    If prResult2.Value.Equals(mRotation) Then
                        Return SamplerStatus.NoChange
                    Else
                        mRotation = prResult2.Value
                        Return SamplerStatus.OK
                    End If

                Case 3
                    Dim prOptions3 As JigPromptDistanceOptions = New JigPromptDistanceOptions(vbLf & "Block scale factor:")
                    prOptions3.BasePoint = mPosition.TransformBy(UCS)
                    prOptions3.UseBasePoint = True
                    Dim prResult3 As PromptDoubleResult = prompts.AcquireDistance(prOptions3)
                    If prResult3.Status = PromptStatus.Cancel Then Return SamplerStatus.Cancel

                    If prResult3.Value.Equals(mScaleFactor) Then
                        Return SamplerStatus.NoChange
                    Else
                        mScaleFactor = prResult3.Value
                        Return SamplerStatus.OK
                    End If

                Case Else
            End Select

            Return SamplerStatus.OK
        End Function

        Private Shared pickObjId As ObjectId = ObjectId.Null

        Private Shared Sub Editor_PointMonitor(ByVal sender As Object, ByVal e As PointMonitorEventArgs)
            Dim computedPt As Point3d = e.Context.ComputedPoint
            Dim pickedEnts As FullSubentityPath() = e.Context.GetPickedEntities()

            If pickedEnts IsNot Nothing AndAlso pickedEnts.Length > 0 Then
                pickObjId = pickedEnts(0).GetObjectIds()(0)
            Else
                pickObjId = ObjectId.Null
            End If
        End Sub

        Public Shared Function Jig(ByVal ent As BlockReference) As Boolean
            Try
                Dim jigger As DynamicBlockAlignmentJig = New DynamicBlockAlignmentJig(ent)
                Dim pr As PromptResult

                Do
                    pr = CurEditor.Drag(jigger)
                    If jigger.mCurJigFactorNumber = 1 AndAlso jigger.mIsDynamicAlignment AndAlso Not jigger.mObjectIdToAlignWith.IsNull Then jigger.mCurJigFactorNumber += 1
                Loop While pr.Status <> PromptStatus.Cancel AndAlso pr.Status <> PromptStatus.[Error] AndAlso Math.Min(System.Threading.Interlocked.Increment(jigger.mCurJigFactorNumber), jigger.mCurJigFactorNumber - 1) <= 3

                Return pr.Status = PromptStatus.OK
            Catch
                Return False
            End Try
        End Function

        <CommandMethod("DynamicBlockAlignmentJig")>
        Public Shared Sub BlockAttributeJig_Method()
            Dim db As Database = HostApplicationServices.WorkingDatabase

            Try
                Dim pr As PromptResult = CurEditor.GetString(vbLf & "Name of the block to jig:")

                If pr.Status = PromptStatus.OK Then

                    Using tr As Transaction = db.TransactionManager.StartTransaction()
                        Dim bt As BlockTable = CType(tr.GetObject(db.BlockTableId, OpenMode.ForRead), BlockTable)

                        If Not bt.Has(pr.StringResult) Then
                            CurEditor.WriteMessage(vbLf & "The block <{0}> does not exist.", pr.StringResult)
                            Return
                        End If

                        Dim btr As BlockTableRecord = TryCast(tr.GetObject(bt(pr.StringResult), OpenMode.ForRead), BlockTableRecord)

                        Using ent As BlockReference = New BlockReference(New Point3d(0, 0, 0), btr.ObjectId)
                            ent.TransformBy(UCS)
                            Dim modelspace As BlockTableRecord = CType(tr.GetObject(bt(BlockTableRecord.ModelSpace), OpenMode.ForWrite), BlockTableRecord)
                            modelspace.AppendEntity(ent)
                            tr.AddNewlyCreatedDBObject(ent, True)
                            CurEditor.TurnForcedPickOn()
                            AddHandler CurEditor.PointMonitor, AddressOf Editor_PointMonitor

                            If DynamicBlockAlignmentJig.Jig(ent) Then tr.Commit()
                            RemoveHandler CurEditor.PointMonitor, AddressOf Editor_PointMonitor

                            CurEditor.TurnForcedPickOff()
                        End Using
                    End Using
                End If

            Catch ex As Exception
                CurEditor.WriteMessage(ex.Message)
            End Try
        End Sub
    End Class
End Namespace

Nhờ các anh xem điều chỉnh giúp em với nhé. Em cám ơn

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

Nếu có thể, em hãy thử với một block có sẵn, scale=1 xem nó có hoạt động không? Và sử dụng c# thay vb. Vì đã có lớp arraypath nên thứ em viết cũng không quá cần.

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

Tạo một tài khoản hoặc đăng nhập để nhận xét

Bạn cần phải là một thành viên để lại một bình luận

Tạo tài khoản

Đăng ký một tài khoản mới trong cộng đồng của chúng tôi. Điều đó dễ mà.

Đăng ký tài khoản mới

Đăng nhập

Bạn có sẵn sàng để tạo một tài khoản ? Đăng nhập tại đây.

Đăng nhập ngay
Đăng nhập để thực hiện theo  

×