frostrap Posted December 1, 2008 Posted December 1, 2008 Well I'm ever so slowly making progress with vb.net. Here's the latest issue I'm having: I have a program that prompts for two endpoints, then inserts a line based on those endpoints. Once the line is inserted the program then also inserts a block at the centerpoint of the line. The program works just fine when the UCS is in it's normal position (aligned with the WCS?). However, if I move the UCS in any way (rotate 15 degrees for instance), the lines and blocks end up inserted in odd places on the drawing. Their sizes and relative orientations are correct, but their overal insertion points are not. I'd post some code, but it's not very straight forward looking. However, I'm using standard methods for getting user input fromt the editor and inserting the line and block into the active drawing database. My best guess is that when the user enters the two points, AutoCAD is converting those points to some WCS coordinate that isn't getting translated back to the current UCS when the line and block is inserted. Unfortunately I don't know how to fix this (assuming that is the problem). Any ideas about what might be causing this? Quote
SEANT Posted December 2, 2008 Posted December 2, 2008 Yes, that is a translation issue and requires steps similar to those needed with VBA. Below is a vb.net demo. Like most demo code, error checking should be modified to whatever level required. Imports Autodesk.AutoCAD.Runtime Imports Autodesk.AutoCAD.ApplicationServices Imports Autodesk.AutoCAD.DatabaseServices Imports Autodesk.AutoCAD.EditorInput Imports Autodesk.AutoCAD.Geometry Public Class STSCCommands <CommandMethod("BTM")> _ Public Sub Tester() Dim strBlkName As String = "Arrow_E" 'change to suit Dim strBlkPath As String = "C:\STCustomCommon\Arrow_E.dwg" 'change to suit If Block2Mid(strBlkName, strBlkPath) Then Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage(vbCr & "Block insertion successful.") End If End Sub Public Function Block2Mid(ByVal strBlkName As String, ByVal strBlkPath As String) As Boolean Dim db As Database = HostApplicationServices.WorkingDatabase Dim ed As Editor = Application.DocumentManager.MdiActiveDocument.Editor Dim ucsMat As Matrix3d = ed.CurrentUserCoordinateSystem Dim bt As BlockTable Dim btr As BlockTableRecord Dim btrSpace As BlockTableRecord Dim entBref As BlockReference Dim ppo As PromptPointOptions = New PromptPointOptions("Select first point: ") ppo.AllowNone = False ppo.AllowArbitraryInput = False Dim ppr As PromptPointResult = ed.GetPoint(ppo) If ppr.Status = PromptStatus.Cancel Or ppr.Status = PromptStatus.Error Then Exit Function Dim p3d1 As Point3d = ppr.Value ppo.UseBasePoint = True ppo.BasePoint = p3d1 ppo.Message = vbCr & "Select second point: " ppr = ed.GetPoint(ppo) If ppr.Status = PromptStatus.Cancel Or ppr.Status = PromptStatus.Error Then Exit Function Dim p3d2 As Point3d = ppr.Value Dim v3d1 As Vector3d = p3d1.GetAsVector() Dim v3d2 As Vector3d = p3d2.GetAsVector() v3d2 = v3d2 - v3d1 v3d2 = v3d1 + (v3d2 / 2.0) Dim midPt As Point3d = New Point3d(v3d2.ToArray()) p3d1 = p3d1.TransformBy(ucsMat) p3d2 = p3d2.TransformBy(ucsMat) midPt = midPt.TransformBy(ucsMat) Dim entLine As Line = New Line(p3d1, p3d2) Using tr As Transaction = db.TransactionManager.StartTransaction() bt = tr.GetObject(db.BlockTableId, OpenMode.ForRead) If bt.Has(strBlkName) Then btr = tr.GetObject(bt.Item(strBlkName), OpenMode.ForRead) Else btr = RtrvBlk(strBlkName, strBlkPath, ed, db) If btr = Nothing Then Block2Mid = False Exit Function End If End If Try btrSpace = tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite) btrSpace.AppendEntity(entLine) entBref = New BlockReference(midPt, btr.ObjectId) entBref.Normal = ucsMat.CoordinateSystem3d.Zaxis entBref.Position = midPt 'requires re-positioning after Normal mod btrSpace.AppendEntity(entBref) tr.AddNewlyCreatedDBObject(entLine, True) tr.AddNewlyCreatedDBObject(entBref, True) tr.Commit() Catch ex As System.Exception ed.WriteMessage(ex.Message) Block2Mid = False End Try Block2Mid = True End Using End Function Public Function RtrvBlk(ByVal strBlkName As String, ByVal strBlkPath As String, ByRef ed As Editor, ByRef db As Database) As BlockTableRecord Dim bt As BlockTable Dim btr As BlockTableRecord = Nothing Dim id As ObjectId Dim actDoc As Document = Application.DocumentManager.MdiActiveDocument Using tr As Transaction = db.TransactionManager.StartTransaction() Try bt = tr.GetObject(db.BlockTableId, OpenMode.ForWrite) Using importDb As Database = New Database(False, False) Try importDb.ReadDwgFile(strBlkPath, IO.FileShare.Read, True, "") id = db.Insert(strBlkPath, importDb, True) btr = tr.GetObject(id, OpenMode.ForWrite) btr.Name = strBlkName btr.DowngradeOpen() Catch ex As System.Exception ed.WriteMessage(ex.Message) Return Nothing Exit Function Finally importDb.Dispose() End Try End Using tr.Commit() Catch ex As System.Exception ed.WriteMessage(ex.Message) End Try End Using Return btr End Function End Class Quote
frostrap Posted December 2, 2008 Author Posted December 2, 2008 Ok, so it sounds like all point input is done in terms of the WCS and is then translated to the current UCS using a transofmation matrix. Thanks for the sample code. Did you write it or did you get it from ome other resource? - Joe Quote
SEANT Posted December 2, 2008 Posted December 2, 2008 Generally, everything I post is self written. I wouldn’t necessarily take credit for a fairly generic routine such as this (when I say generic, I mean one that has probably been written numerous times before, not necessarily one that was easy to write). This generic quality (because the need for this task is quite common) means that useful snippets are quite plentiful and I was able to borrow – heh hem – portions here and there. Most of the UCS stuff was similar enough to VBA that previous experience was very helpful. Now that I’ve admitted ownership to a good portion of this ‘compilation’, I expect the real pros to stop by and tell what I really should have done to make it better. Quote
frostrap Posted December 2, 2008 Author Posted December 2, 2008 Hah, good enough for me. As you can tell, I'm still in the thick of trying to figure out the ins and outs of dealing with AutoCAD behind the scenes. It can be a bit daunting at times trying to remember how things are structured. I'm just now starting to learn about transformations, it's great stuff to know. Thanks for your help. Quote
SEANT Posted December 2, 2008 Posted December 2, 2008 Despite the enormity of the .NET api, transformations are an area where the process has been simplified; at least compared to VBA. Once located, a lot of .NET tools are readily available. Thanks for your help. You're welcome. Quote
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.