TheSwamp
Code Red => .NET => Topic started by: Proctor on May 16, 2008, 04:12:10 PM
-
Hello: I create a polyline but don't want to write it to modelspace. if I leave out this line however:
trans.AddNewlyCreatedDBObject(newPl, True)
it gives me an unhandled Access violation Read error when I try to click on any paperspace tab. What am I doing wrong?
trans = ed.Document.TransactionManager.StartTransaction()
Dim bt As BlockTable = doc.Database.BlockTableId.GetObject(Autodesk.AutoCAD.DatabaseServices.OpenMode.ForRead)
Dim btr As BlockTableRecord = bt(BlockTableRecord.ModelSpace).GetObject(Autodesk.AutoCAD.DatabaseServices.OpenMode.ForWrite)
Dim blkdef As BlockTableRecord = bt(sBlockName).GetObject(Autodesk.AutoCAD.DatabaseServices.OpenMode.ForRead)
Dim docLock As DocumentLock = doc.LockDocument()
Dim newPl As Polyline2d = DirectCast(curves.Item(i), Polyline2d)
btr.AppendEntity(newPl)
[color=red]'this is the line that breaks it:[/color]
[color=red] 'trans.AddNewlyCreatedDBObject(newPl, True)[/color]
Call AddLayer()
''GET LENGTH OF NEW POLY
Dim length As Double
length = newPl.Length
'use the length of the poly chosen to tell us how many leds(blocks) to insert()
Dim noOfLeds As Integer = CInt((length / 12) * num)
If dCount = 0 Then
dCount = noOfLeds
Else
dCount = dCount + noOfLeds
End If
Call WriteLEDCount(dCount, newPl, curves.Count, i)
For z As Integer = 0 To noOfLeds - 1
Dim pt As Point3d = newPl.GetPointAtDist((12 / num) * z)
Dim endPoint As Point3d = newPl.GetPointAtDist(((12 / num) * z) + 0.1)
Dim v As Vector3d = endPoint - pt
Dim plane As New Plane(New Point3d(0, 0, 0), New Vector3d(0, 0, 1))
Dim ang As Double = v.AngleOnPlane(plane)
Dim blkref As New BlockReference(pt, bt(sBlockName))
blkref.Layer = myLayerName 'Derrived from sub AddLayer()
btr.AppendEntity(blkref)
blkref.Rotation = ang
trans.AddNewlyCreatedDBObject(blkref, True)
Next
ed.Regen()
trans.Commit()
trans.Dispose()
Application.DocumentManager.MdiActiveDocument.LockDocument.Dispose()
Any helps appreciated,
Proctor
-
Have you tried to run it in debug mode ?
-
Hi - thanks for your reply. Yes, I tried; however, it doesn't give me the error until after all my code executes and I click on the paperspace tab ...so was unable to tell anything. I just noticed that if I rem out that one line that adds newly created...it's happy...so assumed it has some connection w/ that.
Can you tell me if I'm starting, commiting and disposing my transaction correctly?
thanks again,
Proctor
-
If you don't want it to be added to the db, why are you adding it as a block table record ?
btr.AppendEntity(newPl)
just a tip ( and for others) ,
when posting code with issues, it MAY help if the code is complete. ( or at least compilable)
added:
... though I don't do VB, so probably ignore me.
-
wow, why the heck am i adding it to the block table record? that's a very good question....
ok...also, sorry that I didn't include all the code...i'll be sure to from now on.
I remmed out the code that appends the poly to the table record, however, now it errors out on the line below:
Dim pt As Point3d = newPl.GetPointAtDist((12 / num) * z)
I'm confused as to when I need to add the poly to the block table record.
here's the full code:
Public Shared Sub OffsetMyPoly(ByVal pEstimatePolyId, ByVal dDouble)
Dim ed As Editor = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor()
Dim num As Double = iModulesPerUnit 'this number represents the distance between the leds given the product chosen
Dim doc As Document = Application.DocumentManager.MdiActiveDocument
Dim db As Database = doc.Database
Dim trans As Transaction
trans = ed.Document.TransactionManager.StartTransaction()
Dim ent As Entity = DirectCast(trans.GetObject(pEstimatePolyId, Autodesk.AutoCAD.DatabaseServices.OpenMode.ForRead), Entity)
Dim curves As DBObjectCollection
Dim pl As Polyline2d = DirectCast(ent, Polyline2d)
Try
curves = pl.GetOffsetCurves(dDouble)
trans.Dispose()
For i As Integer = 0 To curves.Count - 1
trans = ed.Document.TransactionManager.StartTransaction()
Dim bt As BlockTable = doc.Database.BlockTableId.GetObject(Autodesk.AutoCAD.DatabaseServices.OpenMode.ForRead)
Dim btr As BlockTableRecord = bt(BlockTableRecord.ModelSpace).GetObject(Autodesk.AutoCAD.DatabaseServices.OpenMode.ForWrite)
Dim blkdef As BlockTableRecord = bt(sBlockName).GetObject(Autodesk.AutoCAD.DatabaseServices.OpenMode.ForRead)
Dim docLock As DocumentLock = doc.LockDocument()
Dim newPl As Polyline2d = DirectCast(curves.Item(i), Polyline2d)
[color=red][font=Verdana]
'remming this out now
'btr.AppendEntity(newPl)[/font][/color]
'when this line is added, it creates the offset polyline.
'trans.AddNewlyCreatedDBObject(newPl, True)
Call AddLayer()
''GET LENGTH OF NEW POLY
Dim length As Double
length = newPl.Length
'use the length of the poly chosen to tell us how many leds(blocks) to insert()
Dim noOfLeds As Integer = CInt((length / 12) * num)
If dCount = 0 Then
dCount = noOfLeds
Else
dCount = dCount + noOfLeds
End If
Call WriteLEDCount(dCount, newPl, curves.Count, i)
For z As Integer = 0 To noOfLeds - 1
[color=red]
'erroring out on this line now
Dim pt As Point3d = newPl.GetPointAtDist((12 / num) * z)[/color]
Dim endPoint As Point3d = newPl.GetPointAtDist(((12 / num) * z) + 0.1)
Dim v As Vector3d = endPoint - pt
Dim plane As New Plane(New Point3d(0, 0, 0), New Vector3d(0, 0, 1))
Dim ang As Double = v.AngleOnPlane(plane)
Dim blkref As New BlockReference(pt, bt(sBlockName))
blkref.Layer = myLayerName 'Derrived from sub AddLayer()
btr.AppendEntity(blkref)
blkref.Rotation = ang
trans.AddNewlyCreatedDBObject(blkref, True)
Next
ed.Regen()
trans.Commit()
trans.Dispose()
Application.DocumentManager.MdiActiveDocument.LockDocument.Dispose()
Next
curves.Dispose()
Catch ex As Autodesk.AutoCAD.Runtime.Exception
MsgBox(ex.Message)
Finally
End Try
End Sub
-
however, now it errors out on the line below:
<snip>
.. and the error is ??
-
and as I posted elsewhere,
Have you considered structuring your code something like this :-
using (AcAp.DocumentLock doclock = ed.Document.LockDocument())
{
using (AcDb.Transaction tr = db.TransactionManager.StartTransaction())
{
/// do mojo here
tr.Commit();
}
}
-
I get this error:
eInvalidInput
-
I just saw your post ....
let me try that....
Thank you
-
Have you stepped through the code in debug mode .. with the LocalVariables pane open ?
-
LocalVariables pane?
-
If you are just creating a polyline for calculations and don't want to add it to the dwg, then ditch the transaction altogether and wrap the creation of the polyline in a 'using' statement so it's destroyed when it's done.
Posting the same question on multiple forums is considered by some as 'bad form' by the way.
-
LocalVariables pane?
a piccy ...
-
I didn't realize the effects of posting the same topic to multiple sites till I Kerry answering for me in both ...and felt bad. I'm really sorry.
Kerry...thanks for the pic on using local variable. I added the Using statement for the transaction and it's still erroring on the same line. as I step through using looking at the local variable, i see that the acadobject says HRESULT E_Fail has been returned from a call to a com component. The poly showing other properties...e.g. length.
Public Shared Sub OffsetMyPoly_2Row(ByVal pEstimatePolyId, ByVal dDouble)
Dim ed As Editor = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor()
Dim num As Double = iModulesPerUnit 'this number represents the distance between the leds given the product chosen
Dim doc As Document = Application.DocumentManager.MdiActiveDocument
Dim db As Database = doc.Database
Using docLock As DocumentLock = ed.Document.LockDocument()
Using trans As Transaction = ed.Document.TransactionManager.StartTransaction()
Try
' Dim trans As Transaction
' trans = ed.Document.TransactionManager.StartTransaction()
'using AcAp.DocumentLock doclock = ed.Document.LockDocument()
Dim ent As Entity = DirectCast(trans.GetObject(pEstimatePolyId, Autodesk.AutoCAD.DatabaseServices.OpenMode.ForRead), Entity)
Dim curves As DBObjectCollection
Dim pl As Polyline2d = DirectCast(ent, Polyline2d)
curves = pl.GetOffsetCurves(dDouble)
For i As Integer = 0 To curves.Count - 1
'trans = ed.Document.TransactionManager.StartTransaction()
Dim bt As BlockTable = doc.Database.BlockTableId.GetObject(Autodesk.AutoCAD.DatabaseServices.OpenMode.ForRead)
Dim btr As BlockTableRecord = bt(BlockTableRecord.ModelSpace).GetObject(Autodesk.AutoCAD.DatabaseServices.OpenMode.ForWrite)
Dim blkdef As BlockTableRecord = bt(sBlockName).GetObject(Autodesk.AutoCAD.DatabaseServices.OpenMode.ForWrite)
'Dim docLock As DocumentLock = doc.LockDocument()
Dim newPl As Polyline2d = DirectCast(curves.Item(i), Polyline2d)
'btr.AppendEntity(newPl)
'trans.AddNewlyCreatedDBObject(newPl, True)
Call AddLayer()
''GET LENGTH OF NEW POLY
Dim length As Double
length = newPl.Length
'use the length of the poly chosen to tell us how many leds(blocks) to insert()
Dim noOfLeds As Integer = CInt((length / 12) * num)
If dCount = 0 Then
dCount = noOfLeds
Else
dCount = dCount + noOfLeds
End If
Call WriteLEDCount(dCount, newPl, curves.Count, i)
'MEASURE
For z As Integer = 0 To noOfLeds - 1
Dim pt As Point3d = newPl.GetPointAtDist((12 / num) * z)
Dim endPoint As Point3d = newPl.GetPointAtDist(((12 / num) * z) + 0.1)
Dim v As Vector3d = endPoint - pt
Dim plane As New Plane(New Point3d(0, 0, 0), New Vector3d(0, 0, 1))
Dim ang As Double = v.AngleOnPlane(plane)
Dim blkref As New BlockReference(pt, bt(sBlockName))
blkref.Layer = myLayerName 'Derrived from sub AddLayer()
btr.AppendEntity(blkref)
blkref.Rotation = ang
trans.AddNewlyCreatedDBObject(blkref, True)
Next
ed.Regen()
trans.Commit()
'trans.Dispose()
'Application.DocumentManager.MdiActiveDocument.LockDocument.Dispose()
''End If
Next
curves.Dispose()
Catch ex As Autodesk.AutoCAD.Runtime.Exception
MsgBox(ex.Message)
Finally
End Try
End Using
End Using
End Sub
-
Does VB require that parameters be typed ?
Public Shared Sub OffsetMyPoly_2Row(ByVal pEstimatePolyId, ByVal dDouble)
as you have it
or
Public Shared Sub OffsetMyPoly_2Row(ByVal pEstimatePolyId As whatever , ByVal dDouble As whatever )
What are your includes ?
vb brings be out in boils , and I'm a little busy,
if the message is 'eInvalidInput'
where do you think it is occuring ?
-
Hi Kerry: I've been struggling w/ this same issue all morning and still getting nowhere.
I don't belive that VB requires parameters be typed; however, I tried placing in the type as well and it didn't make any difference:
from this:
Public Shared Sub OffsetMyPoly_2Row(ByVal pEstimatePolyId, ByVal dDouble)
to this:
Public Shared Sub OffsetMyPoly_2Row(ByVal pEstimatePolyId As DatabaseServices.ObjectId, ByVal dDouble As Double)
Here's the import statements I'm using for this page:
Imports System
Imports System.Data
Imports System.Data.OleDb
Imports Autodesk.AutoCAD.Runtime
Imports Autodesk.AutoCAD
Imports Microsoft.VisualBasic
Imports Autodesk.AutoCAD.ApplicationServices
Imports Autodesk.AutoCAD.DatabaseServices
Imports Autodesk.AutoCAD.Geometry
Imports Autodesk.AutoCAD.EditorInput
Imports Autodesk.AutoCAD.Runtime.Interop
Imports System.Drawing
Imports Autodesk.AutoCAD.Colors
Imports System.Math
Imports System.Object
Imports System.Runtime.InteropServices.Marshal
Imports System.Drawing.Imaging
Imports System.Runtime.InteropServices
When I rem out the line below:
' btr.AppendEntity(newPl)
It won't let me run this line - and it's the line I get the einvalid input. :
Dim pt As Point3d = newPl.GetPointAtDist((12 / num) * z)
When i look at it using the local variables window you showed me I see the the new poly has no objectid.
Why is it that I can get the length of the new poly...but i can get point at distance?
It seems that I have to append it to the database in order to use this method....
However, if i do that...but not this line:
'trans.AddNewlyCreatedDBObject(newPl1, True)
it won't let me open the layout tab.
I sure appreciate all the help you've been giving me. I'm really stuck...I appreciate any ideas you can spare.
Thanks again,
Proctor
-
I'm running out the door to catch a train ... I'll have a look tonight If I can make the time.
-
ok...thank you very much!!!
-
What Acad API version are you using. ?
I recall that there was a bug in either the GetPointAtDist or GetParameterAtDistance methods .. I'll need to check to make sure .. I think it was GetParameterAtDistance in one of the API releases.
-
Hi Kerry: I'm working w/ autoCad 2008.
-
Hi Kerry: I just wanted to write to tell you that I ended up writing someone at autodesk to see if this was in fact an AutoCad bug and here's what they told me:
Some operations require an entity to be database resident to work. It looks like this is one. You could use the AcGe classes instead if you’re just calculating geometry, or you could add the entity to the database and transaction, make your calculation, then abort the transaction to remove the entity from the database. (You can use nested transactions if you need to).
I don't know what the AcGe classes are that he's refferring to....I tried to find them in the object browser w/ no success.
I tried aborting the transaction but it didn't seem to like that...
I finally ended up making the polyline invisible and I can now open my layouts and don't see the polyline.
Thanks again for all your help.
Proctor
-
AcGe is the prefix for the ARX geometry classes...look up geometry in the acad .net reference (which wraps the AcGe* ARX classes).
-
yep, you have the reference ..
Imports Autodesk.AutoCAD.Geometry
-
oh...ok... thank you for clarifying for me.
Proctor