Using of Ji MLeader
Posted: Fri May 29, 2020 8:33 am
After looking for so many codes and suggestions, I decided tu debug my own code and build a Jig for MLeader with mirroring block object. Down below is my code running perfectly in VS19 x Intellicad 9.
Imports App = IntelliCAD.ApplicationServices.Application
Module JigLeader
Public Sub CreateLeader()
'' Get the current database
Dim acDoc As Document = App.DocumentManager.MdiActiveDocument
Dim acCurDb As Database = acDoc.Database
'' Start a transaction
Using acTrans As Transaction = acCurDb.TransactionManager.StartTransaction()
'' Open the Block table for read
Dim acBlkTbl As BlockTable
acBlkTbl = acTrans.GetObject(acCurDb.BlockTableId, Teigha.DatabaseServices.OpenMode.ForRead)
'' Open the Block table record Model space for write
Dim acBlkTblRec As BlockTableRecord
acBlkTblRec = acTrans.GetObject(acBlkTbl(BlockTableRecord.ModelSpace), Teigha.DatabaseServices.OpenMode.ForWrite)
'' Create the leader
Using acLdr As Leader = New Leader()
acLdr.AppendVertex(New Point3d(0, 0, 0))
acLdr.AppendVertex(New Point3d(4, 4, 0))
acLdr.AppendVertex(New Point3d(4, 5, 0))
acLdr.HasArrowHead = True
'' Add the new object to Model space and the transaction
acBlkTblRec.AppendEntity(acLdr)
acTrans.AddNewlyCreatedDBObject(acLdr, True)
End Using
'' Commit the changes and dispose of the transaction
acTrans.Commit()
End Using
End Sub
End Module
Namespace LeaderPlacement
Public Class MLeaderJig
Inherits EntityJig
Protected _start As Point3d, _end As Point3d
Private _index As Integer
Private _lineIndex As Integer
Protected _started As Boolean
Private _blkName As String
Private m_pts As Point3dCollection
'Private m_leaderIndex As Integer
'Private m_LeaderLineIndex As Integer
Private m_tempPoint As Point3d
Public Sub New(BlockContent As String, Start As Point3d)
MyBase.New(New MLeader())
m_pts = New Point3dCollection()
Dim ml As MLeader = GetEntity()
ml.SetDatabaseDefaults()
ml.ContentType = ContentType.BlockContent
ml.EnableDogleg = True
ml.EnableLanding = True
ml.LandingGap = 0
'_index = ml.AddLeader()
_lineIndex = -1
_started = False
_blkName = BlockContent
_start = Start
_end = Start
_index = ml.AddLeader()
AddVertex()
End Sub
' A fairly standard Sampler function
Protected Overrides Function Sampler(prompts As JigPrompts) As SamplerStatus
Dim opts As JigPromptPointOptions = New JigPromptPointOptions()
opts.UserInputControls = (UserInputControls.Accept3dCoordinates Or UserInputControls.NoNegativeResponseAccepted)
If m_pts.Count = 0 Then
opts.UserInputControls = (UserInputControls.Accept3dCoordinates Or UserInputControls.NoNegativeResponseAccepted)
opts.Message = vbLf & "Start point of multileader: "
opts.UseBasePoint = False
ElseIf m_pts.Count = 1 Then
opts.BasePoint = m_pts(m_pts.Count - 1)
opts.UseBasePoint = True
opts.Message = vbLf & "Specify multileader vertex: "
ElseIf m_pts.Count > 1 Then
'opts.UserInputControls = opts.UserInputControls Or UserInputControls.NullResponseAccepted 'UserInputControls.Accept3dCoordinates Or UserInputControls.GovernedByOrthoMode Or UserInputControls.GovernedByUCSDetect Or UserInputControls.UseBasePointElevation
opts.UserInputControls = (UserInputControls.AnyBlankTerminatesInput Or UserInputControls.NoNegativeResponseAccepted Or
UserInputControls.Accept3dCoordinates Or UserInputControls.AcceptMouseUpAsPoint Or UserInputControls.NullResponseAccepted Or UserInputControls.AcceptOtherInputString Or
UserInputControls.GovernedByUCSDetect Or UserInputControls.GovernedByOrthoMode Or UserInputControls.InitialBlankTerminatesInput Or UserInputControls.NoZeroResponseAccepted)
opts.BasePoint = m_pts(m_pts.Count - 1)
opts.UseBasePoint = True
opts.SetMessageAndKeywords(vbLf & "Specify multileader vertex or : [End]", "End")
'opts.Message = vbLf & "Specify multileader vertex: "
Else
Return SamplerStatus.Cancel
End If
Dim res As PromptPointResult = prompts.AcquirePoint(opts)
If _end = res.Value Then
Return SamplerStatus.NoChange
ElseIf res.Status = PromptStatus.OK Then
_end = res.Value
Return SamplerStatus.OK
End If
Return SamplerStatus.Cancel
End Function
Protected Overrides Function Update() As Boolean
Dim ml = DirectCast(Entity, MLeader)
If m_pts.Count > 0 Then
ml.SetLastVertex(_lineIndex, _end)
Dim _dl = New Vector3d(If(_end.X <= m_pts(m_pts.Count - 1).X, -1, 1), 0, 0)
Dim doglen As Double = ml.DoglegLength * IntelliCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Database.Cannoscale.DrawingUnits
Dim landgap As Double = ml.LandingGap
If _end.X <= m_pts(m_pts.Count - 1).X Then
ml.EnableDogleg = True
ml.SetDogleg(_lineIndex, _dl)
ml.BlockPosition = _end + ((doglen + landgap) * _dl)
Else
ml.EnableDogleg = False
ml.BlockPosition = _end
End If
End If
If Not _started Then
If _start.DistanceTo(_end) > Tolerance.[Global].EqualPoint Then
Dim doc As Document = App.DocumentManager.MdiActiveDocument
Dim db As Database = doc.Database
Dim ed As Editor = doc.Editor
ml.ContentType = ContentType.BlockContent
Dim ocm = db.ObjectContextManager
Dim occ = ocm.GetContextCollection("ACDB_ANNOTATIONSCALES")
ml.AddContext(occ.CurrentContext)
Using Tx As Transaction = db.TransactionManager.StartTransaction
Dim table As BlockTable = Tx.GetObject(db.BlockTableId, Teigha.DatabaseServices.OpenMode.ForRead)
Dim model As BlockTableRecord = Tx.GetObject(table(BlockTableRecord.ModelSpace), Teigha.DatabaseServices.OpenMode.ForWrite)
If Not table.Has(_blkName) Then
ed.WriteMessage(String.Format("\nPrecisa definir o bloco {0}", _blkName))
Return False
End If
ml.BlockContentId = table(_blkName)
'ml.BlockPosition = New Point3d(4, 2, 0)
Dim AttNumber As Integer = 0
Dim blkLeader As BlockTableRecord = TryCast(Tx.GetObject(ml.BlockContentId, Teigha.DatabaseServices.OpenMode.ForRead), BlockTableRecord)
Dim Transfo As Matrix3d = Matrix3d.Displacement(ml.BlockPosition.GetAsVector())
For Each blkEntId As ObjectId In blkLeader
Dim AttributeDef As AttributeDefinition = TryCast(Tx.GetObject(blkEntId, Teigha.DatabaseServices.OpenMode.ForRead), AttributeDefinition)
If AttributeDef IsNot Nothing Then
Dim AttributeRef As New AttributeReference()
AttributeRef.SetAttributeFromBlock(AttributeDef, Transfo)
AttributeRef.Position = AttributeDef.Position.TransformBy(Transfo)
Commit(AttributeRef)
ml.SetBlockAttribute(blkEntId, AttributeRef)
End If
Next
Tx.Commit()
End Using
'AddVertex()
_started = True
End If
Else
ml.Visible = True
'ml.SetLastVertex(_lineIndex, _end)
End If
Return True
End Function
Public Sub AddVertex()
Dim ml As MLeader = TryCast(Entity, MLeader)
If m_pts.Count = 0 Then
_lineIndex = ml.AddLeaderLine(_index)
ml.AddFirstVertex(_lineIndex, _start)
'ml.AddLastVertex(_lineIndex, _end)
Else
ml.AddLastVertex(_lineIndex, _end)
End If
m_pts.Add(_end)
End Sub
Public Sub RemoveLastVertex()
Dim ml As MLeader = TryCast(Entity, MLeader)
Dim dogvec As Vector3d = ml.GetDogleg(_index)
Dim doglen As Double = ml.DoglegLength * IntelliCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Database.Cannoscale.DrawingUnits
Dim landgap As Double = ml.LandingGap
'If m_pts.Count >= 1 Then
If ml.GetLastVertex(_lineIndex).X <= ml.GetVertex(_lineIndex, ml.VerticesCount(_lineIndex) - 2).X Then
dogvec = New Vector3d(-1, 0, 0)
ml.BlockPosition = ml.GetLastVertex(_lineIndex) + ((doglen + landgap) * dogvec)
Else
dogvec = New Vector3d(1, 0, 0)
End If
'End If
End Sub
Public Function GetEntity() As Teigha.DatabaseServices.MLeader
Return TryCast(MyBase.Entity, Teigha.DatabaseServices.MLeader)
End Function
Public Overridable Sub Commit(AttributeRef As AttributeReference)
' nada aqui
'Select Case AttributeRef.Tag
' Case "MARCA"
' AttributeRef.TextString = _contents.Marca
' Case "QTD"
' AttributeRef.TextString = _contents.Qtde
' Case "TRATAMENTO"
' AttributeRef.TextString = _contents.Tratamento
' Case "DESCRICAO"
' AttributeRef.TextString = _contents.descricao
' Case "LISTA"
' AttributeRef.TextString = _contents.lista
'End Select
End Sub
Public Sub MyMLeaderJig()
Dim doc As Document = IntelliCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument
Dim ed As Editor = doc.Editor
Dim db As Database = doc.Database
'Dim jig As MLeaderJig = New MLeaderJig("novo_ponto", CType(blockContent.Entity, DBPoint).Position)
Dim bSuccess As Boolean = True, bComplete As Boolean = False
While bSuccess AndAlso Not bComplete
Dim dragres As PromptResult = ed.Drag(Me)
bSuccess = (dragres.Status = PromptStatus.OK)
If bSuccess Then Me.AddVertex()
bComplete = (dragres.Status = PromptStatus.None)
If bComplete Then Me.RemoveLastVertex()
End While
If bComplete Then
Dim tr As Transaction = db.TransactionManager.StartTransaction()
Using tr
Dim bt As BlockTable = CType(tr.GetObject(db.BlockTableId, Teigha.DatabaseServices.OpenMode.ForRead, False), BlockTable)
Dim btr As BlockTableRecord = CType(tr.GetObject(bt(BlockTableRecord.ModelSpace), Teigha.DatabaseServices.OpenMode.ForWrite, False), BlockTableRecord)
btr.AppendEntity(Me.GetEntity())
tr.AddNewlyCreatedDBObject(Me.GetEntity(), True)
tr.Commit()
End Using
End If
End Sub
End Class
Public Class Leader
Inherits MLeaderJig
Protected blockContent As XPV
Public Sub New(PV As XPV)
MyBase.New("novo_ponto", CType(PV.Entity, DBPoint).Position)
blockContent = PV
' Store info that's passed in, but don't init the MLeader
End Sub
Public Overrides Sub Commit(AttributeRef As AttributeReference)
Select Case AttributeRef.Tag
Case Is = "PV"
AttributeRef.TextString = blockContent.PV
Case Is = "CT"
AttributeRef.TextString = blockContent.CT
Case Is = "CF"
AttributeRef.TextString = blockContent.CF
Case Is = "CTERRENO"
AttributeRef.TextString = blockContent.CTerreno
Case Is = "PON"
AttributeRef.TextString = blockContent.TAG
End Select
End Sub
End Class
End Namespace
Imports App = IntelliCAD.ApplicationServices.Application
Module JigLeader
Public Sub CreateLeader()
'' Get the current database
Dim acDoc As Document = App.DocumentManager.MdiActiveDocument
Dim acCurDb As Database = acDoc.Database
'' Start a transaction
Using acTrans As Transaction = acCurDb.TransactionManager.StartTransaction()
'' Open the Block table for read
Dim acBlkTbl As BlockTable
acBlkTbl = acTrans.GetObject(acCurDb.BlockTableId, Teigha.DatabaseServices.OpenMode.ForRead)
'' Open the Block table record Model space for write
Dim acBlkTblRec As BlockTableRecord
acBlkTblRec = acTrans.GetObject(acBlkTbl(BlockTableRecord.ModelSpace), Teigha.DatabaseServices.OpenMode.ForWrite)
'' Create the leader
Using acLdr As Leader = New Leader()
acLdr.AppendVertex(New Point3d(0, 0, 0))
acLdr.AppendVertex(New Point3d(4, 4, 0))
acLdr.AppendVertex(New Point3d(4, 5, 0))
acLdr.HasArrowHead = True
'' Add the new object to Model space and the transaction
acBlkTblRec.AppendEntity(acLdr)
acTrans.AddNewlyCreatedDBObject(acLdr, True)
End Using
'' Commit the changes and dispose of the transaction
acTrans.Commit()
End Using
End Sub
End Module
Namespace LeaderPlacement
Public Class MLeaderJig
Inherits EntityJig
Protected _start As Point3d, _end As Point3d
Private _index As Integer
Private _lineIndex As Integer
Protected _started As Boolean
Private _blkName As String
Private m_pts As Point3dCollection
'Private m_leaderIndex As Integer
'Private m_LeaderLineIndex As Integer
Private m_tempPoint As Point3d
Public Sub New(BlockContent As String, Start As Point3d)
MyBase.New(New MLeader())
m_pts = New Point3dCollection()
Dim ml As MLeader = GetEntity()
ml.SetDatabaseDefaults()
ml.ContentType = ContentType.BlockContent
ml.EnableDogleg = True
ml.EnableLanding = True
ml.LandingGap = 0
'_index = ml.AddLeader()
_lineIndex = -1
_started = False
_blkName = BlockContent
_start = Start
_end = Start
_index = ml.AddLeader()
AddVertex()
End Sub
' A fairly standard Sampler function
Protected Overrides Function Sampler(prompts As JigPrompts) As SamplerStatus
Dim opts As JigPromptPointOptions = New JigPromptPointOptions()
opts.UserInputControls = (UserInputControls.Accept3dCoordinates Or UserInputControls.NoNegativeResponseAccepted)
If m_pts.Count = 0 Then
opts.UserInputControls = (UserInputControls.Accept3dCoordinates Or UserInputControls.NoNegativeResponseAccepted)
opts.Message = vbLf & "Start point of multileader: "
opts.UseBasePoint = False
ElseIf m_pts.Count = 1 Then
opts.BasePoint = m_pts(m_pts.Count - 1)
opts.UseBasePoint = True
opts.Message = vbLf & "Specify multileader vertex: "
ElseIf m_pts.Count > 1 Then
'opts.UserInputControls = opts.UserInputControls Or UserInputControls.NullResponseAccepted 'UserInputControls.Accept3dCoordinates Or UserInputControls.GovernedByOrthoMode Or UserInputControls.GovernedByUCSDetect Or UserInputControls.UseBasePointElevation
opts.UserInputControls = (UserInputControls.AnyBlankTerminatesInput Or UserInputControls.NoNegativeResponseAccepted Or
UserInputControls.Accept3dCoordinates Or UserInputControls.AcceptMouseUpAsPoint Or UserInputControls.NullResponseAccepted Or UserInputControls.AcceptOtherInputString Or
UserInputControls.GovernedByUCSDetect Or UserInputControls.GovernedByOrthoMode Or UserInputControls.InitialBlankTerminatesInput Or UserInputControls.NoZeroResponseAccepted)
opts.BasePoint = m_pts(m_pts.Count - 1)
opts.UseBasePoint = True
opts.SetMessageAndKeywords(vbLf & "Specify multileader vertex or : [End]", "End")
'opts.Message = vbLf & "Specify multileader vertex: "
Else
Return SamplerStatus.Cancel
End If
Dim res As PromptPointResult = prompts.AcquirePoint(opts)
If _end = res.Value Then
Return SamplerStatus.NoChange
ElseIf res.Status = PromptStatus.OK Then
_end = res.Value
Return SamplerStatus.OK
End If
Return SamplerStatus.Cancel
End Function
Protected Overrides Function Update() As Boolean
Dim ml = DirectCast(Entity, MLeader)
If m_pts.Count > 0 Then
ml.SetLastVertex(_lineIndex, _end)
Dim _dl = New Vector3d(If(_end.X <= m_pts(m_pts.Count - 1).X, -1, 1), 0, 0)
Dim doglen As Double = ml.DoglegLength * IntelliCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Database.Cannoscale.DrawingUnits
Dim landgap As Double = ml.LandingGap
If _end.X <= m_pts(m_pts.Count - 1).X Then
ml.EnableDogleg = True
ml.SetDogleg(_lineIndex, _dl)
ml.BlockPosition = _end + ((doglen + landgap) * _dl)
Else
ml.EnableDogleg = False
ml.BlockPosition = _end
End If
End If
If Not _started Then
If _start.DistanceTo(_end) > Tolerance.[Global].EqualPoint Then
Dim doc As Document = App.DocumentManager.MdiActiveDocument
Dim db As Database = doc.Database
Dim ed As Editor = doc.Editor
ml.ContentType = ContentType.BlockContent
Dim ocm = db.ObjectContextManager
Dim occ = ocm.GetContextCollection("ACDB_ANNOTATIONSCALES")
ml.AddContext(occ.CurrentContext)
Using Tx As Transaction = db.TransactionManager.StartTransaction
Dim table As BlockTable = Tx.GetObject(db.BlockTableId, Teigha.DatabaseServices.OpenMode.ForRead)
Dim model As BlockTableRecord = Tx.GetObject(table(BlockTableRecord.ModelSpace), Teigha.DatabaseServices.OpenMode.ForWrite)
If Not table.Has(_blkName) Then
ed.WriteMessage(String.Format("\nPrecisa definir o bloco {0}", _blkName))
Return False
End If
ml.BlockContentId = table(_blkName)
'ml.BlockPosition = New Point3d(4, 2, 0)
Dim AttNumber As Integer = 0
Dim blkLeader As BlockTableRecord = TryCast(Tx.GetObject(ml.BlockContentId, Teigha.DatabaseServices.OpenMode.ForRead), BlockTableRecord)
Dim Transfo As Matrix3d = Matrix3d.Displacement(ml.BlockPosition.GetAsVector())
For Each blkEntId As ObjectId In blkLeader
Dim AttributeDef As AttributeDefinition = TryCast(Tx.GetObject(blkEntId, Teigha.DatabaseServices.OpenMode.ForRead), AttributeDefinition)
If AttributeDef IsNot Nothing Then
Dim AttributeRef As New AttributeReference()
AttributeRef.SetAttributeFromBlock(AttributeDef, Transfo)
AttributeRef.Position = AttributeDef.Position.TransformBy(Transfo)
Commit(AttributeRef)
ml.SetBlockAttribute(blkEntId, AttributeRef)
End If
Next
Tx.Commit()
End Using
'AddVertex()
_started = True
End If
Else
ml.Visible = True
'ml.SetLastVertex(_lineIndex, _end)
End If
Return True
End Function
Public Sub AddVertex()
Dim ml As MLeader = TryCast(Entity, MLeader)
If m_pts.Count = 0 Then
_lineIndex = ml.AddLeaderLine(_index)
ml.AddFirstVertex(_lineIndex, _start)
'ml.AddLastVertex(_lineIndex, _end)
Else
ml.AddLastVertex(_lineIndex, _end)
End If
m_pts.Add(_end)
End Sub
Public Sub RemoveLastVertex()
Dim ml As MLeader = TryCast(Entity, MLeader)
Dim dogvec As Vector3d = ml.GetDogleg(_index)
Dim doglen As Double = ml.DoglegLength * IntelliCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Database.Cannoscale.DrawingUnits
Dim landgap As Double = ml.LandingGap
'If m_pts.Count >= 1 Then
If ml.GetLastVertex(_lineIndex).X <= ml.GetVertex(_lineIndex, ml.VerticesCount(_lineIndex) - 2).X Then
dogvec = New Vector3d(-1, 0, 0)
ml.BlockPosition = ml.GetLastVertex(_lineIndex) + ((doglen + landgap) * dogvec)
Else
dogvec = New Vector3d(1, 0, 0)
End If
'End If
End Sub
Public Function GetEntity() As Teigha.DatabaseServices.MLeader
Return TryCast(MyBase.Entity, Teigha.DatabaseServices.MLeader)
End Function
Public Overridable Sub Commit(AttributeRef As AttributeReference)
' nada aqui
'Select Case AttributeRef.Tag
' Case "MARCA"
' AttributeRef.TextString = _contents.Marca
' Case "QTD"
' AttributeRef.TextString = _contents.Qtde
' Case "TRATAMENTO"
' AttributeRef.TextString = _contents.Tratamento
' Case "DESCRICAO"
' AttributeRef.TextString = _contents.descricao
' Case "LISTA"
' AttributeRef.TextString = _contents.lista
'End Select
End Sub
Public Sub MyMLeaderJig()
Dim doc As Document = IntelliCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument
Dim ed As Editor = doc.Editor
Dim db As Database = doc.Database
'Dim jig As MLeaderJig = New MLeaderJig("novo_ponto", CType(blockContent.Entity, DBPoint).Position)
Dim bSuccess As Boolean = True, bComplete As Boolean = False
While bSuccess AndAlso Not bComplete
Dim dragres As PromptResult = ed.Drag(Me)
bSuccess = (dragres.Status = PromptStatus.OK)
If bSuccess Then Me.AddVertex()
bComplete = (dragres.Status = PromptStatus.None)
If bComplete Then Me.RemoveLastVertex()
End While
If bComplete Then
Dim tr As Transaction = db.TransactionManager.StartTransaction()
Using tr
Dim bt As BlockTable = CType(tr.GetObject(db.BlockTableId, Teigha.DatabaseServices.OpenMode.ForRead, False), BlockTable)
Dim btr As BlockTableRecord = CType(tr.GetObject(bt(BlockTableRecord.ModelSpace), Teigha.DatabaseServices.OpenMode.ForWrite, False), BlockTableRecord)
btr.AppendEntity(Me.GetEntity())
tr.AddNewlyCreatedDBObject(Me.GetEntity(), True)
tr.Commit()
End Using
End If
End Sub
End Class
Public Class Leader
Inherits MLeaderJig
Protected blockContent As XPV
Public Sub New(PV As XPV)
MyBase.New("novo_ponto", CType(PV.Entity, DBPoint).Position)
blockContent = PV
' Store info that's passed in, but don't init the MLeader
End Sub
Public Overrides Sub Commit(AttributeRef As AttributeReference)
Select Case AttributeRef.Tag
Case Is = "PV"
AttributeRef.TextString = blockContent.PV
Case Is = "CT"
AttributeRef.TextString = blockContent.CT
Case Is = "CF"
AttributeRef.TextString = blockContent.CF
Case Is = "CTERRENO"
AttributeRef.TextString = blockContent.CTerreno
Case Is = "PON"
AttributeRef.TextString = blockContent.TAG
End Select
End Sub
End Class
End Namespace