I've this problem
I'm triyng to change the Z value of lines in my draweing with this code
<Autodesk.AutoCAD.Runtime.CommandMethod("SETZETA")> _
Public Shared Sub AzzeraAsseZETA()
Dim doc As Document = Application.DocumentManager.MdiActiveDocument
Dim db As Database = doc.Database
Dim ed As Editor = doc.Editor
Dim dbObj As DBObject
Dim zeta As Single = 0
ed.CurrentUserCoordinateSystem = Matrix3d.Identity
ed.Regen()
Using docLock As DocumentLock = doc.LockDocument()
Using tr As Transaction = db.TransactionManager.StartTransaction
Dim filterforLine() As TypedValue = {New TypedValue(0, "LINE")}
Dim sf As SelectionFilter = New SelectionFilter(filterforLine)
Dim pSelRes As PromptSelectionResult = ed.SelectAll(sf)
Dim pSelRes As PromptSelectionResult = ed.SelectAll()
Try
If (pSelRes.Status <> PromptStatus.OK) Then
tr.Abort()
Exit Try
End If
Dim objIdArray() As ObjectId = pSelRes.Value.GetObjectIds()
For Each objId As ObjectId In objIdArray
dbObj = tr.GetObject(objId, OpenMode.ForWrite)
Dim l As Line = DirectCast(dbObj, Line)
l.EndPoint = New Point3d(l.EndPoint.X, l.EndPoint.Y, zeta)
l.StartPoint = New Point3d(l.StartPoint.X, l.StartPoint.Y, zeta)
Next
tr.Commit()
Catch ex As Exception
ed.WriteMessage(ex.ToString())
tr.Abort()
End Try
End Using
End Using
End Sub
First Time I call setzeta I've no problem, but the second time autocad crashes. I've an error in this line
Using tr As Transaction = db.TransactionManager.StartTransaction (NullReferenceException)
Really crash hapen also after the first time I execute SetZeta, if I try to save the drawing
Where is the mistake?
The mistake may be from misusage of transaction.Abort(). It may call transaction.Commit() after that. I cleaned up your code and it works flawlessly in AutoCAD 2014. I will test this code in AutoCAD 2010 at my home machine.
Here is your working code in AutoCAD 2014:
<CommandMethod("SETZETA")> _ Public Shared Sub AzzeraAsseZETA() Dim doc As Document = Application.DocumentManager.MdiActiveDocument Dim db As Database = doc.Database Dim ed As Editor = doc.Editor Dim dbObj As DBObject Dim zeta As Single = 0 ed.CurrentUserCoordinateSystem = Matrix3d.Identity ed.Regen() Using docLock As DocumentLock = doc.LockDocument() Using tr As Transaction = db.TransactionManager.StartTransaction() Dim filterForLine As TypedValue() = {New TypedValue(0, "LINE")} Dim sf As New SelectionFilter(filterForLine) Dim pSelRes As PromptSelectionResult = ed.SelectAll(sf) Try If pSelRes.Status = PromptStatus.OK Then Dim objIdArray As ObjectId() = pSelRes.Value.GetObjectIds() For Each objId As ObjectId In objIdArray dbObj = tr.GetObject(objId, OpenMode.ForWrite) Dim l As Line = DirectCast(dbObj, Line) l.EndPoint = New Point3d(l.EndPoint.X, l.EndPoint.Y, zeta) l.StartPoint = New Point3d(l.StartPoint.X, l.StartPoint.Y, zeta) Next tr.Commit() End If Catch ex As System.Exception 'tr.Abort(); ed.WriteMessage(ex.ToString()) End Try End Using End Using End Sub
Yes, your code seems to work fine
Now I'm triyng to use the same code for fifferent object, circle arc, spline, blockreference
No problem a part blockreference. For this object I obtain the same error. Why?
<CommandMethod("SETZETA")> _
Public Shared Sub AzzeraAsseZETA()
Dim doc As Document = Application.DocumentManager.MdiActiveDocument
Dim db As Database = doc.Database
Dim ed As Editor = doc.Editor
Dim dbObj As DBObject
Dim zeta As Single = 0
ed.CurrentUserCoordinateSystem = Matrix3d.Identity
ed.Regen()
Using docLock As DocumentLock = doc.LockDocument()
Using tr As Transaction = db.TransactionManager.StartTransaction()
Dim filterForLine As TypedValue() = {New TypedValue(0, "BLOCKREFERENCE")}
Dim sf As New SelectionFilter(filterForLine)
Dim pSelRes As PromptSelectionResult = ed.SelectAll(sf)
Try
If pSelRes.Status = PromptStatus.OK Then
Dim objIdArray As ObjectId() = pSelRes.Value.GetObjectIds()
For Each objId As ObjectId In objIdArray
dbObj = tr.GetObject(objId, OpenMode.ForWrite)
Dim l As blockreference = DirectCast(dbObj, blockreference)
l.Position = New Point3d(l.Position.X, l.Position.Y, zeta)
Next
tr.Commit()
End If
Catch ex As System.Exception
'tr.Abort();
ed.WriteMessage(ex.ToString())
End Try
End Using
End Using
End Sub
TypedValue uses DxfName of BlockReference which is INSERT.
Change your code as the following and it will work:
TypedValue[] filterForLine = { new TypedValue(0, "INSERT") };
Unfortunatly I've still that problem, even applying your suggestion.
Cause seems to be the line
l.Position = New Point3d(l.Position.X, l.Position.Y, zeta)
It's seems that I can't change Position, or at least I dont't change it in correct way
The code works at my end. I am not sure why it did not work on your code. BlockReference.Position is a read and write property so you can get and set it. I don't have AutoCAD 2010 at my work office so cannot test your code.
Hi,
If your block it's not in the WCS you will need to use a transformation matrix , see an example here: Move a Block Reference.
Gaston Nunez
Gaston is right to use BlockReference.TransformBy(Matrix3d.Displacement(new Vector(0,0,z)) to relocate the compound object such as BlockReference. Changing Position property does not make sense. Thank you.
Thank's to all for your answer and help. Unfortunatly I've always the same problem, BUT really I don't have Autocad 2010, but Autocad Mechanical 2010
I've tryied your code with Autocad and It works fine, My problem is just with mechanical. Can you explain me the difference? And there is a solution also for mechanical?
Basically when I execute my code second time I obtain an error NullReferenceException at the line
Using tr As Transaction = db.TransactionManager.StartTransaction()
(only with Autocad mechanical and only with blockreference)
If I execute my code just one time,when I try to save drawing Autocad crashes
I don't have AutoCAD Mechanical 2010 to try it out. Did you try to run your code on Mechanical 2010 for your very simple block (only basic lines), which does not have any Mechanical entities? What I am guessing is your block has some custom objects which work on AutoCAD vanilla but not work on AutoCAD Mechanical when you perform BlockReference.TransformBy
It would be good if you re-post your latest code and a sample drawing to test on other machines of readers in this forum.
Hi,
The last code you showed it's a mess:
1.- I'm not sure what kind of entity are you looking for as this line:
Dim filterForLine As TypedValue() = {New TypedValue(0, "BLOCKREFERENCE")}
misguide Khoa.ho to correctly point that "BLOCKREFERENCE" dosn't exists and you have to use "INSERT" instead, but the filteForLine show that you are looking for lines, so it's no clear your aim. If they are lines then you have to change "INSERT" for "LINE".
2.-Lines doesn't have a property called "position", they have StartPoint and Endpoint, but again, to properly move an entity you have to use matrix transform as this:
Dim fromPoint as point3d=...your base point for displacemente here
dim toPoint as point3d=... your destination point here
Dim m3d as Matrix3D=Matrix3d.Displacement(fromPoint.GetVectorTo(toPoint))
MyEntity.TransformBy(m3d)
MyEntity can be any entity object instance
3.- I don't know of any graphic entity that CAN'T be transformed using the matrix3D method, and given that Entity it's the base class for BlockReference it should work on them too (and lines too)
Please show your last code.
Gaston Nunez
Ok, there's a little bit of confusion
I have a lot of drawings imported from an old 2D cad (gbg). This cad doesn't have Z coordinates, just X,Y When I converted these drawings in dwg format, many objects assumed Z=0, but for many others Z was a different value (positive or negative). Of course this is a big problem, so I'm trying to built a dll with a command (SETZETA) to change Z coordinates to 0 for all objects
At the beginning I tried to change Z for Lines. then for other kind of object. No problem till Blockreference. Attached my full code
Probably this problem is caused from some mechanical custom object. Maybe I found the block that caused the problem (A0X2 attached). I don't know the english name. It's connect to the title drawing, It's the dimension of paper sheet
I hope I was more clear now 🙂