Hi,
I've used the following function to convert a lightweight polyline into a polyline2d for years successfully but in AutoCAD 2019 the ConvertTo method throws an eInvalidContext exception.. which makes no sense to me. Does anyone have an idea why this exception is thrown or how I could convert the polyline while retaining the ObjectId?
void ConvertFromLightweightPolyline(Database acDb, ObjectId polylineId) { using (var tr = acDb.TransactionManager.StartOpenCloseTransaction()) { var polyLine = tr.GetObject(polylineId, OpenMode.ForWrite) as Polyline; if (polyLine != null) {
tr.AddNewlyCreatedDBObject(polyLine, false); var polyLine2d = polyLine.ConvertTo(true); tr.AddNewlyCreatedDBObject(polyLine2d, true); } tr.Commit(); } }
Thanks in advance,
Christian
Solved! Go to Solution.
Hi,
if you already have an ObjectID for your polyline, this means you have it already in the database.
Isn't that statement then incorrect (to add it once more)?
tr.AddNewlyCreatedDBObject(polyLine, false);
- alfred -
Well, I got that code snippet from the ADN Devblog so even though it looks a bit weird to me as well, I must assume that the guys on the Devblog know what they're doing. Link: https://adndevblog.typepad.com/autocad/2012/06/converting-polyline-to-polyline2d.html
I made some quick tests and this code worked as expected with AutoCAD 2017, 2018, 2019 and 2020.
What i was asking is: in which context do you call this method? from a CommandMethod? a modal dialog? a modeless palette? ...
IOW, you should show the code which call this method.
Thank you for your hints and help. My method is directly called from a CommandMethod (Modal, UsePickSet). I'll try to determine what causes the exception because if it works for you, then it should work for me as well 🙂
All right, I figured it out. The problem was that I queried the lightweight polyline for XRecord data before I tried to convert it. And in the method that reads the XRecord stuff, a StartTransaction call was used.. when I change that to StartOpenCloseTransaction, everything works fine. Here's a relatively short snippet that reproduces the Exception:
[AdRun.CommandMethod("MYPLUGIN", "MYCMD_CONVERT_POLY", "MYCMD_CONVERT_POLY", AdRun.CommandFlags.Modal | AdRun.CommandFlags.UsePickSet)] public void ConvertPolyline() { var acDoc = Application.DocumentManager.MdiActiveDocument; var pso = new PromptSelectionOptions(); pso.SingleOnly = true; var selectionResult = acDoc.Editor.GetSelection(pso); if (selectionResult.Status != PromptStatus.OK) return; var selectedEntities = selectionResult.Value; if (selectedEntities.Count > 1) return; var objId = selectedEntities[0].ObjectId; if (this.HasXRecordData(acDoc.Database, objId, "my_xrecord_name")) return; this.ConvertFromLightweightPolyline(acDoc.Database, objId); //Work with the Polyline2d... } private bool HasXRecordData(Database acDb, ObjectId dbObjectId, string xRecordName) { if (dbObjectId.IsNull || dbObjectId.IsErased) return false; using (var tr = acDb.TransactionManager.StartTransaction()) { //THIS is the problem! var dbObject = tr.GetObject(dbObjectId, OpenMode.ForRead); bool hasXrecord = dbObject.ExtensionDictionary != ObjectId.Null; tr.Commit(); return hasXrecord; } } private void ConvertFromLightweightPolyline(Database acDb, ObjectId polylineId) { using (var tr = acDb.TransactionManager.StartOpenCloseTransaction()) { var polyLine = tr.GetObject(polylineId, OpenMode.ForWrite) as Polyline; if (polyLine != null) { tr.AddNewlyCreatedDBObject(polyLine, false); var polyLine2d = polyLine.ConvertTo(true); tr.AddNewlyCreatedDBObject(polyLine2d, true); } tr.Commit(); } }
Now, for performance reasons it should've been StartOpenCloseTransaction in HasXRecordData anyway but I think that the regular StartTransaction call should work as well, no? And after all, this code worked since AutoCAD 2013 up to AutoCAD 2018 without a problem.. so have I been using the API wrong and I just got lucky so far or is this some problem in the API?
Thanks again so far
Christian
Hi,
sorry to not understand this part of the code:
var polyLine = tr.GetObject(polylineId, OpenMode.ForWrite) as Polyline; if (polyLine != null) { tr.AddNewlyCreatedDBObject(polyLine, false);
Why do you add a polyline to the transaction again as like a new object when you have it opened using the same transaction as an existing object? That does not make sense for me or I have to learn something new...
- alfred -
You have to remove an object from a transaction before a in place conversion, that's why.
See Post #5 here: https://www.theswamp.org/index.php?topic=42055.0
Hi,
thank you, I always used the HandOverTo in a different way.
Opening an object for write and then exclude it from a transaction sounds strange at least.
- alfred -
Can't find what you're looking for? Ask the community or share your knowledge.