Alright I have an issue and not sure how to even show this... Or even if its possible without the block files (can't post them, company rules).
I got a ribbon bar that has many blocks, now when inserting them into the drawing, yeah I can do that. Select a point, rotate, thats all good. Though not all my blocks that I place will allow the snap functions to work on them? Some have no snap functions to existing blocks I placed, some will only select the base point that I inserted said block, and some will allow all the snap functions to work with placing them on mid points, corners, etc.
Is this a code function or an autocad setting I would need to change, really comes down to the question. Tool Pallet and a custom CUI that I does the same function in autocad works flawlessly, and I just didn't notice it til recently.
Here is the code segments related to the jigging of the blocks.
Imports Autodesk.AutoCAD.DatabaseServices Imports Autodesk.AutoCAD.Geometry Imports Autodesk.AutoCAD.EditorInput Imports Autodesk.AutoCAD.ApplicationServices Namespace Insert Public Class InsertBlockJig Public Class InsertJig Inherits EntityJig Private vJigPromptCounter As Integer Private vRotationAngleUse As Boolean = False Private vRotationAngleValue As Double = 0.0 ' private double objPrevAngle; ' private double objCurAngle; Private vScaleValue As Double = 1.0 Public Sub New(ByVal BlockId As ObjectId, ByVal Position__1 As Point3d, ByVal Normal As Vector3d) MyBase.New(New BlockReference(Position__1, BlockId)) BlockReference.Normal = Normal position = Position__1 End Sub Private mCenterPt As Point3d, mActualPoint As Point3d Public Sub New(ByVal br As BlockReference) MyBase.New(br) mCenterPt = br.Position End Sub Protected Overrides Function Sampler(ByVal prompts As JigPrompts) As SamplerStatus If vJigPromptCounter = 0 Then ' Maybe let the scale (and/or rotation) be changed with a option on the command-line Me.BlockReference.ScaleFactors = New Scale3d(vScaleValue, vScaleValue, vScaleValue) ' And eval rotation here... If vRotationAngleUse Then Me.BlockReference.Rotation = vRotationAngleValue End If ' Maybe still check the counter no (1) if the rotation was set... Dim jigOpts As New JigPromptPointOptions() jigOpts.UserInputControls = UserInputControls.NoZeroResponseAccepted & UserInputControls.NullResponseAccepted & UserInputControls.Accept3dCoordinates jigOpts.Message = vbLf & "Insertion point: " Dim res As PromptPointResult = prompts.AcquirePoint(jigOpts) 'Point3d BlkRefPoint = BlockReference.Position; Dim curPoint As Point3d = res.Value If position.DistanceTo(curPoint) > 0.0001 Then ' 1.0e-4 make it 10 units (depending on drawing...) 'if (this.BlockReference.Position != curPoint) // 1.0e-4 make it 10 units (depending on drawing...) position = curPoint Else Return SamplerStatus.NoChange End If If res.Status = PromptStatus.Cancel Then Return SamplerStatus.Cancel jigOpts.Message = vbLf & "Block Insertion Canceled" Else Return SamplerStatus.OK End If Else If vJigPromptCounter = 1 Then ' Activate Rotate Jig...Just check if there already was a rotation...?? ' JigPromptAngleOptions Dim jigOpts As New JigPromptAngleOptions() jigOpts.BasePoint = Me.BlockReference.Position jigOpts.DefaultValue = 0 jigOpts.Message = "Get angle: " jigOpts.UseBasePoint = True jigOpts.UserInputControls = UserInputControls.Accept3dCoordinates 'jigOpts.UserInputControls = UserInputControls.NoZeroResponseAccepted & ' UserInputControls.NullResponseAccepted & ' UserInputControls.Accept3dCoordinates Dim res As PromptDoubleResult = prompts.AcquireAngle(jigOpts) Dim curAngle As Double = res.Value If Me.BlockReference.Rotation <> curAngle Then blockRotation = curAngle Else Return SamplerStatus.NoChange End If If res.Status = PromptStatus.Cancel Then Return SamplerStatus.Cancel Else Return SamplerStatus.OK End If Else ' Just in case... Return SamplerStatus.NoChange End If End If End Function Protected Overrides Function Update() As Boolean Try Dim returnvalue As Boolean = False Select Case vJigPromptCounter Case 0 ' Insert point Update... ' this.BlockReference.Position = position; ' return true; If Me.BlockReference.Position.DistanceTo(position) > 0.0001 Then ' Idem aan boven depending on drawing scale.. ' Maybe the distance can be less..if solved? Me.BlockReference.Position = position returnvalue = True End If Exit Select Case 1 ' Rotate Update... If Me.BlockReference.Rotation <> blockRotation Then Me.BlockReference.Rotation = blockRotation returnvalue = True End If Exit Select End Select Return returnvalue Catch generatedExceptionName As System.Exception End Try Return False ' Why Why Why.. End Function Public Property RotationAngleUse() As Boolean Get Return vRotationAngleUse End Get Set(ByVal value As Boolean) vRotationAngleUse = value End Set End Property Public Property RotationAngleValue() As Double Get Return vRotationAngleValue End Get Set(ByVal value As Double) vRotationAngleValue = value End Set End Property Public Property ScaleValue() As Double Get Return vScaleValue End Get Set(ByVal value As Double) If value <> 0 Then vScaleValue = value End If End Set End Property Public Property JigPromptCounter() As Integer Get Return vJigPromptCounter End Get Set(ByVal value As Integer) vJigPromptCounter = value End Set End Property Public ReadOnly Property BlockReference() As BlockReference Get Return TryCast(MyBase.Entity, BlockReference) End Get End Property Private position As Point3d Private blockRotation As Double End Class ' Test InsertJig from command line Private vRotationVal As Double = 0.0 Private vRotationUse As Boolean = True Private vScaleVal As Double = 1.0 Public Property RotationAngleUse() As Boolean Get Return vRotationUse End Get Set(ByVal value As Boolean) vRotationUse = value End Set End Property Public Property RotationAngleValue() As Double Get Return vRotationVal End Get Set(ByVal value As Double) vRotationVal = value End Set End Property Public Property ScaleValue() As Double Get Return vScaleVal End Get Set(ByVal value As Double) If value <> 0 Then vScaleVal = value End If End Set End Property ' AcadApp.DocumentManager.MdiActiveDocument.Editor ' [CommandMethod("DragInsertDemo")] static Public Sub StartInsert(ByVal JigBlockName As [String]) Dim ed As Editor = Application.DocumentManager.MdiActiveDocument.Editor Dim db As Database = HostApplicationServices.WorkingDatabase ' Application.DocumentManager.MdiActiveDocument.Database; Dim Normal As Vector3d = db.Ucsxdir.CrossProduct(db.Ucsydir) ' Editor ed = Application.DocumentManager.MdiActiveDocument.Editor; ' PromptStringOptions opts = new PromptStringOptions("\nBlock name: "); ' opts.AllowSpaces = true; ' using( DocumentLock docLock = ed.Document.LockDocument() ) // Maybe Move this at first..?? ' { Dim res As PromptResult ' = ed.GetString(opts); If JigBlockName <> String.Empty Then Dim block As ObjectId = GetBlockId(db, JigBlockName) If block.IsNull Then ed.WriteMessage(vbLf & "Block {0} not found.", JigBlockName) Return End If Dim jig As New InsertJig(block, Point3d.Origin, Normal.GetNormal()) If vRotationUse = True Then jig.RotationAngleUse = True jig.RotationAngleValue = vRotationVal Else jig.RotationAngleUse = False End If jig.ScaleValue = vScaleVal jig.JigPromptCounter = 0 ' Start with insertpoint Using docLock As DocumentLock = Application.DocumentManager.MdiActiveDocument.LockDocument() res = ed.Drag(jig) ' First Jig option..[Insertpoint] ' Should it accept a rightclick as the 0-point of the drawing? ' or does that cancel the operation...? If res.Status = PromptStatus.OK Then ' Here also the Rotation-Jig should Start... ' if Rotation was fixed this should have been set at first... ' Should Accept rightclick as 0-rotation ' Ready...end the Jig If vRotationUse = True Then Else ' Start a new Jig for the rotation.. jig.JigPromptCounter = 1 res = ed.Drag(jig) End If ' if jig.RotationAngleUse = false then do it... ' jig.RotationAngleValue = 1; // Or skip this al together if it's a given rotation... ' No checking to be done by Jig(ger)..?? Dim tm As Autodesk.AutoCAD.DatabaseServices.TransactionManager = db.TransactionManager If res.Status = PromptStatus.OK Then ' Second check needed if there was a rotation Jig.. Using tr As Transaction = tm.StartTransaction() Dim bt As BlockTable = DirectCast(tr.GetObject(db.BlockTableId, OpenMode.ForRead, False), BlockTable) ' Do Check in what space You are!!! ' It could be a Layout... Dim btr As BlockTableRecord = DirectCast(tr.GetObject(bt(BlockTableRecord.ModelSpace), OpenMode.ForWrite, False), BlockTableRecord) btr.AppendEntity(jig.BlockReference) tr.AddNewlyCreatedDBObject(jig.BlockReference, True) tr.Commit() End Using End If End If End Using End If ' } End Sub Private Shared Function GetBlockId(ByVal db As Database, ByVal Name As String) As ObjectId Dim id As ObjectId = ObjectId.Null Using tr As Transaction = db.TransactionManager.StartTransaction() Dim blocks As BlockTable = DirectCast(tr.GetObject(db.BlockTableId, OpenMode.ForRead), BlockTable) If blocks.Has(Name) Then id = blocks(Name) If id.IsErased Then For Each btrId As ObjectId In blocks If Not id.IsErased Then Dim rec As BlockTableRecord = DirectCast(tr.GetObject(btrId, OpenMode.ForRead), BlockTableRecord) If String.Compare(rec.Name, Name, True) = 0 Then id = btrId Exit For End If End If Next End If End If tr.Commit() End Using Return id End Function End Class End Namespace
Imports Autodesk.AutoCAD.DatabaseServices Imports Autodesk.AutoCAD.EditorInput Imports Autodesk.AutoCAD.ApplicationServices Namespace Insert Public Class InsertDrawing Public DrawingPath As [String] = "" Public BlockName As [String] = "" Public Sub InsertIntoAutoCAD() ' Insert the block into the AutoCAD model Try Dim doc As Document = Application.DocumentManager.MdiActiveDocument Dim fname As [String] = DrawingPath Using docLock As DocumentLock = Application.DocumentManager.MdiActiveDocument.LockDocument() Using db As New Database(False, False) 'read block drawing do we need Lockdocument..?? Not Always..? db.ReadDwgFile(fname, System.IO.FileShare.Read, True, Nothing) Using t As Transaction = doc.TransactionManager.StartTransaction() Dim idBTR As ObjectId = doc.Database.Insert(BlockName, db, False) t.Commit() End Using End Using End Using Catch e As System.Exception Dim ed As Editor = Application.DocumentManager.MdiActiveDocument.Editor ' Console.WriteLine("{0} Exception caught.", e); ed.WriteMessage(vbLf & "Error {0} DrawingInsert", e) End Try End Sub End Class End Namespace
Commands
Imports Autodesk.AutoCAD.Runtime Imports Autodesk.AutoCAD.Geometry Imports Autodesk.AutoCAD.EditorInput Imports Autodesk.AutoCAD.ApplicationServices <Assembly: CommandClass(GetType(Insert.Commands))> Namespace Insert Public Class Commands <CommandMethod("InsertBottleConveyor")> _ Public Sub InsertConveyor() Dim InsClass As New InsertDrawing() InsClass.BlockName = ConveyorRibbonBar.BlockName InsClass.DrawingPath = "C:\Temp\" & ConveyorRibbonBar.BlockName & ".dwg" InsClass.InsertIntoAutoCAD() InsClass = Nothing Dim BlkClass As New InsertBlockJig() BlkClass.RotationAngleUse = False BlkClass.StartInsert(ConveyorRibbonBar.BlockName) BlkClass = Nothing End Sub End Class End Namespace
Again selecting the proper snap points I have sometimes it works flawlessly, others its only on node points and sometimes nothing of an existing block in the drawing. Oh another note, even sometimes snap points will work with a block just put down but not with any other blocks of the same name.