Hi can anyone assist with the code in blue below
The code reports polyline id and alignment name for the alignment creation
but fails to create any alignment either empty with out geometry, the indented plops options
or any error reports
cheers
for any pointers
Trefor
Option Explicit On
Option Strict Off
Imports System
Imports Autodesk.AutoCAD.Runtime
Imports Autodesk.AutoCAD.ApplicationServices
Imports Autodesk.AutoCAD.DatabaseServices
Imports Autodesk.AutoCAD.EditorInput
Imports Autodesk.AutoCAD.Geometry
Imports Autodesk.Civil.DatabaseServices.Styles
Imports Autodesk.Civil.ApplicationServices
Imports Autodesk.Civil.DatabaseServices
<Assembly: CommandClass(GetType(Halign))>
<Assembly: ExtensionApplication(GetType(Halign))>
Public Class Halign
Implements Autodesk.AutoCAD.Runtime.IExtensionApplication
Private m_doc As CivilDocument = Nothing
Private m_trans As Transaction = Nothing
Private m_Database As Database = Nothing
Private m_Editor As Editor = Nothing
Private m_AlignmentLabelStyleSetId As ObjectId = ObjectId.Null
Private m_AligmentStyleId As ObjectId = ObjectId.Null
Private m_SiteId As ObjectId = ObjectId.Null
Private m_Alignment As Alignment = Nothing
''' <summary>
''' Implement Initialize of IExtensionApplication
''' </summary>
''' <remarks></remarks>
Sub Initialize() Implements Autodesk.AutoCAD.Runtime.IExtensionApplication.Initialize
End Sub
Sub Terminate() Implements Autodesk.AutoCAD.Runtime.IExtensionApplication.Terminate
End Sub
<CommandMethod("halign")>
Public Sub halign()
'' Get the current document and database
Dim acDoc As Document = Application.DocumentManager.MdiActiveDocument
Dim acCurDb As Database = acDoc.Database
Dim doc As Document = Application.DocumentManager.MdiActiveDocument
Dim db As Database = doc.Database
Dim ed As Editor = doc.Editor
Dim docCol As Autodesk.AutoCAD.ApplicationServices.DocumentCollection = Application.DocumentManager
m_Database = docCol.MdiActiveDocument.Database
m_Editor = docCol.MdiActiveDocument.Editor
m_doc = Autodesk.Civil.ApplicationServices.CivilApplication.ActiveDocument()
'' Start a transaction
Using acTrans As Transaction = acCurDb.TransactionManager.StartTransaction()
'' Open the Block table for read
Dim acBlkTbl As BlockTable
acBlkTbl = acTrans.GetObject(acCurDb.BlockTableId, OpenMode.ForRead)
'' Open the Block table record Model space for read
Dim acBlkTblRec As BlockTableRecord
acBlkTblRec = acTrans.GetObject(acBlkTbl(BlockTableRecord.ModelSpace),
OpenMode.ForRead)
'' Step through the Block table record
For Each acObjId As ObjectId In acBlkTblRec
If (acObjId.ObjectClass.DxfName = "LWPOLYLINE") Then
ed.WriteMessage(vbLf & acObjId.ToString)
Dim acount As Integer
acount += 1
Dim Alignmentlabel As String = "A"
Dim AlignmentName = Alignmentlabel & acount
ed.WriteMessage(vbLf & AlignmentName)
''Dim plops As Autodesk.Civil.DatabaseServices.PolylineOptions
''plops.AddCurvesBetweenTangents = False
''plops.EraseExistingEntities = True
''plops.PlineId = acObjId
Dim alignId As ObjectId = Nothing
alignId = Alignment.Create(m_doc, AlignmentName, "Site 1", "alignments", "Basic", "Basic")
End If
Next
'' Dispose of the transaction
End Using
End Sub
End Class
Solved! Go to Solution.
Solved by lu_an_jie. Go to Solution.
Solved by lu_an_jie. Go to Solution.
At first glance I would say that you are disposing the transaction...if you want the additions saved, you must Commit the transcation. Also, please use the code button (the one that looks like </> ) when inserting code to your posts.
End If Next '' Dispose of the transaction ***** NO! acTrans.Commit ''Do this in order for your additions/edits to be saved End Using End Sub
Hi Jeff
Thanks for that pointer.
The mist rose briefly.
Had to go back to work.
I'm now in the process of reviewing my code
Will get back to you and the other folks who contribute
cheers
Trefor
Hi Jeff,
I still having problems with "transaction"
My code successfully extracts the polylines ids from the AutoCAD database
and creates an alignment name. The code also seems to access the civil 3d database
and reports empty alignments being created (note showing in Prospector).
My intention is to create an alignment from each polyline
Many thanks to you or anyone who can help
cheers
Trefor
Imports System Imports Autodesk.AutoCAD.Runtime Imports Autodesk.AutoCAD.ApplicationServices Imports Autodesk.AutoCAD.DatabaseServices Imports Autodesk.AutoCAD.EditorInput Imports Autodesk.AutoCAD.Geometry Imports Autodesk.Civil.DatabaseServices.Styles Imports Autodesk.Civil.ApplicationServices Imports Autodesk.Civil.DatabaseServices Public Class Halignvalign Implements Autodesk.AutoCAD.Runtime.IExtensionApplication Sub Initialize() Implements Autodesk.AutoCAD.Runtime.IExtensionApplication.Initialize End Sub Sub Terminate() Implements Autodesk.AutoCAD.Runtime.IExtensionApplication.Terminate End Sub <CommandMethod("Halign")> Public Sub AlignmentsByLWPolylineCreation() Dim acDoc As Document = Application.DocumentManager.MdiActiveDocument Dim acCurDb As Database = acDoc.Database Dim doc As Document = Application.DocumentManager.MdiActiveDocument Dim db As Database = doc.Database Dim ed As Editor = doc.Editor '' Start a transaction '' Using acTrans As Transaction = acCurDb.TransactionManager.StartTransaction() '' Open the Block table for read Dim acBlkTbl As BlockTable acBlkTbl = acTrans.GetObject(acCurDb.BlockTableId, OpenMode.ForRead) '' Open the Block table record Model space for read Dim acBlkTblRec As BlockTableRecord acBlkTblRec = acTrans.GetObject(acBlkTbl(BlockTableRecord.ModelSpace), OpenMode.ForRead) '' Step through the Block table record For Each acObjId As ObjectId In acBlkTblRec If (acObjId.ObjectClass.DxfName = "LWPOLYLINE") Then ed.WriteMessage(vbLf & acObjId.ToString) Dim acount As Integer acount += 1 Dim Alignmentlabel As String = "A" Dim AlignmentName = Alignmentlabel & acount ed.WriteMessage(vbLf & AlignmentName) Dim docCol As Autodesk.AutoCAD.ApplicationServices.DocumentCollection = Application.DocumentManager Dim m_Database = docCol.MdiActiveDocument.Database Dim m_Editor = docCol.MdiActiveDocument.Editor Dim m_doc As Autodesk.Civil.ApplicationServices.CivilDocument m_doc = Autodesk.Civil.ApplicationServices.CivilApplication.ActiveDocument() Dim AlignIds As ObjectIdCollection = m_doc.GetAlignmentIds For Each alignId As ObjectId In AlignIds m_Editor.WriteMessage(vbLf & alignId.ToString) Next Using m_trans As Transaction = m_Database.TransactionManager.StartTransaction() Try Dim oAlignmentId As ObjectId = Alignment.Create(m_doc, AlignmentName, "", "alignments", "Basic", "Basic") Catch ex As System.Exception m_Editor.WriteMessage(vbLf & "Error when creating alignment") End Try m_trans.Commit() End Using End If Next End Using End Sub End Class
try this method
C#代码片段:
plineOptions = new PolylineOptions();
plineOptions.AddCurvesBetweenTangents = civilDoc.Settings.GetSettings<SettingsCmdCreateAlignmentEntities>().CreateFromEntities.AddCurveBetweenTangents.Value;
plineOptions.EraseExistingEntities = civilDoc.Settings.GetSettings<SettingsCmdCreateAlignmentEntities>().CreateFromEntities.EraseExistingEntities.Value;
foreach (ObjectId id in plIds) { alignmentName = Alignment.GetNextUniqueName(civilDoc.Settings.GetSettings<SettingsCmdCreateAlignmentEntities>().DefaultNameFormat.AlignmentNameTemplate.Value); plineOptions.PlineId = id; try { Alignment.Create(civilDoc, plineOptions, alignmentName, null, layerName, styleName, labelSetName); } catch (System.Exception ex) { ed.WriteMessage("\n"+ex.Message); } }
王磊
您认为此帖子是否有用?欢迎为此帖点赞。
您的问题是否已得到解答?请点击“接受解答”按钮。
Thanks for your reply 465340553
I have extracted your snippet for poptions.
In dwgs with out preloaded style sets m_Editor.WriteMessage(vbLf & acObjId.ToString) reports as expected
In dwgs with preloaded style sets m_Editor.WriteMessage(vbLf & acObjId.ToString) reports polyline id and
alignment name and finishes cleanly without creating any alignments.
many thanks for any pointers
Trefor
Dim poptions As Autodesk.Civil.DatabaseServices.PolylineOptions poptions.AddCurvesBetweenTangents = False poptions.EraseExistingEntities = True poptions.PlineId = acObjId Using m_trans As Transaction = m_Database.TransactionManager.StartTransaction() Try Dim AlignId As ObjectId = Nothing AlignId = Alignment.Create(m_doc, poptions, AlignmentName, "", "alignments", "Basic", "Basic") Catch ex As System.Exception m_Editor.WriteMessage(vbLf & acObjId.ToString) m_trans.Commit() m_trans.Dispose() End Try End Using
Dim poptions As Autodesk.Civil.DatabaseServices.PolylineOptions poptions.AddCurvesBetweenTangents = False poptions.EraseExistingEntities = True poptions.PlineId = acObjId Using m_trans As Transaction = m_Database.TransactionManager.StartTransaction() Try Dim AlignId As ObjectId = Nothing AlignId = Alignment.Create(m_doc, poptions, AlignmentName, "", "alignments", "Basic", "Basic") Catch ex As System.Exception m_Editor.WriteMessage(vbLf & acObjId.ToString) End Try m_trans.Commit() m_trans.Dispose() End Using
王磊
您认为此帖子是否有用?欢迎为此帖点赞。
您的问题是否已得到解答?请点击“接受解答”按钮。
1. Basic structure of transactions:
Dim trans As Transaction = dwg.TransactionManager.StartTransaction() Try
'your code here .... . trans.Commit() Catch ex As Exception ' ok so we have an exception ed.WriteMessage("problem due to " + ex.Message) Finally ' all done, whether an error on not - dispose the transaction. trans.Dispose() End Try
2. You need to pass null for the SiteName
3. You did not validated the existence of the StyleName, LayerName and LabelSetName. For testing I would rather use the first of them in the specific collections, than change to specific one and check if the present.
Here is a working code in C#
// (C) Copyright 2018 by // using System; using Autodesk.AutoCAD.Runtime; using Autodesk.AutoCAD.ApplicationServices; using Autodesk.AutoCAD.DatabaseServices; using Autodesk.AutoCAD.EditorInput; using Autodesk.Civil; using Autodesk.Civil.ApplicationServices; using Autodesk.Civil.DatabaseServices; using Autodesk.Civil.Settings; // This line is not mandatory, but improves loading performances [assembly: CommandClass(typeof(ALC_AlignmentFrpmPolyLine.MyCommands))] namespace ALC_AlignmentFrpmPolyLine { public class MyCommands { // Modal Command with pickfirst selection [CommandMethod("MyAlignmentFromPolyline", CommandFlags.Modal | CommandFlags.UsePickSet)] public void MyPickFirst() // This method can have any name { // Get the current document and database Document doc = Application.DocumentManager.MdiActiveDocument; Database db = doc.Database; Editor ed = doc.Editor; CivilDocument civdoc = CivilApplication.ActiveDocument; // Build a filter list so that only olyline are selected TypedValue[] listTV = new TypedValue[1] { new TypedValue((int)DxfCode.Start, "LWPOLYLINE") }; SelectionFilter filter = new SelectionFilter(listTV); PromptSelectionOptions pso = new PromptSelectionOptions(); pso.MessageForAdding = "Select polylines: "; // Get a selection PromptSelectionResult result = ed.GetSelection(pso, filter); if (result.Status == PromptStatus.OK) { using (Transaction tr = db.TransactionManager.StartTransaction()) { try { // get id of Layer ObjectId idLayer = db.Clayer; LayerTable lt = tr.GetObject(db.LayerTableId, OpenMode.ForRead) as LayerTable; if (lt.Has("alignments")) idLayer = (lt["alignments"]); // get objectid of the 1st Alignment style or Basic ObjectId idStyle = civdoc.Styles.AlignmentStyles[0]; if (civdoc.Styles.AlignmentStyles.Contains("Basic")) idStyle = civdoc.Styles.AlignmentStyles["Basic"]; // get objectid of the 1st AlignmentLabelSetStyle or Basic ObjectId idLabelSet = civdoc.Styles.LabelSetStyles.AlignmentLabelSetStyles[0]; if (civdoc.Styles.LabelSetStyles.AlignmentLabelSetStyles.Contains("Basic")) idLabelSet = civdoc.Styles.LabelSetStyles.AlignmentLabelSetStyles["Basic"]; // step through the objects in the selection set SelectionSet ss = result.Value; foreach (SelectedObject sob in ss) { // check list is not empty & object is from the expected type if (sob != null && sob.ObjectId.ObjectClass.DxfName == "LWPOLYLINE") { // set options PolylineOptions plos = new PolylineOptions(); plos.AddCurvesBetweenTangents = true; plos.EraseExistingEntities = true; plos.PlineId = sob.ObjectId; // create unique name String nAlign = Alignment.GetNextUniqueName(civdoc.Settings.GetSettings<SettingsCmdCreateAlignmentEntities>().DefaultNameFormat.AlignmentNameTemplate.Value); // create alignment ObjectId idAlign = Alignment.Create(civdoc, plos, nAlign, ObjectId.Null, idLayer, idStyle, idLabelSet); ed.WriteMessage("\nAlignment created with id: {0}", idAlign); } } // Save the new objects to the database tr.Commit(); } catch (Autodesk.AutoCAD.Runtime.Exception ex) { ed.WriteMessage("/n Exception message :" + ex.Message); } } } else { ed.WriteMessage("No Polylines selected"); } } } }
and VB
' (C) Copyright 2011 by ' Imports System Imports Autodesk.AutoCAD.Runtime Imports Autodesk.AutoCAD.ApplicationServices Imports Autodesk.AutoCAD.DatabaseServices Imports Autodesk.AutoCAD.Geometry Imports Autodesk.AutoCAD.EditorInput Imports Autodesk.Civil.ApplicationServices Imports Autodesk.Civil.DatabaseServices Imports Autodesk.Civil.Settings ' This line is not mandatory, but improves loading performances <Assembly: CommandClass(GetType(ALC_VB_AlignmentFromPolyline.MyCommands))> Namespace ALC_VB_AlignmentFromPolyline Public Class MyCommands ' Modal Command with pickfirst selection <CommandMethod("MyAlignmentFromPolyline", CommandFlags.Modal + CommandFlags.UsePickSet)> Public Sub MyPickFirst() 'Get the current document And database Dim doc As Document = Application.DocumentManager.MdiActiveDocument Dim db As Database = doc.Database Dim ed As Editor = doc.Editor Dim civdoc As CivilDocument = CivilApplication.ActiveDocument 'Build a filter list so that only olyline are selected Dim arTV(0) As TypedValue arTV.SetValue(New TypedValue(DxfCode.Start, "LWPOLYLINE"), 0) Dim filter As SelectionFilter = New SelectionFilter(arTV) Dim pso As PromptSelectionOptions = New PromptSelectionOptions() pso.MessageForAdding = "Select polylines" 'Get a selection Dim result As PromptSelectionResult = ed.GetSelection(pso, filter) If (result.Status = PromptStatus.OK And Not IsDBNull(result.Value)) Then ed.WriteMessage(vbCrLf + "Valid selection") Dim tr As Transaction = db.TransactionManager.StartTransaction() Try 'get id of Layer Dim idLayer As ObjectId = db.Clayer Dim lt As LayerTable = tr.GetObject(db.LayerTableId, OpenMode.ForRead) If (lt.Has("alignments")) Then idLayer = lt("alignments") 'get objectid of the 1st Alignment style Or Basic Dim idStyle As ObjectId = civdoc.Styles.AlignmentStyles(0) If (civdoc.Styles.AlignmentStyles.Contains("Basic")) Then idStyle = civdoc.Styles.AlignmentStyles("Basic") 'get objectid of the 1st AlignmentLabelSetStyle Or Basic Dim idLabelSet As ObjectId = civdoc.Styles.LabelSetStyles.AlignmentLabelSetStyles(0) If (civdoc.Styles.LabelSetStyles.AlignmentLabelSetStyles.Contains("Basic")) Then idLabelSet = civdoc.Styles.LabelSetStyles.AlignmentLabelSetStyles("Basic") 'step through the objects in the selection set Dim ss As SelectionSet = result.Value For Each sob As SelectedObject In ss 'check is object Is from the expected type If (sob.ObjectId.ObjectClass.DxfName = "LWPOLYLINE") Then ' set options Dim plos As PolylineOptions = New PolylineOptions() plos.AddCurvesBetweenTangents = True plos.EraseExistingEntities = True plos.PlineId = sob.ObjectId 'create unique name Dim sccae As SettingsCmdCreateAlignmentEntities = civdoc.Settings.GetSettings(Of SettingsCmdCreateAlignmentEntities)() Dim nAlign As String = Alignment.GetNextUniqueName(sccae.DefaultNameFormat.AlignmentNameTemplate.Value) ed.WriteMessage(vbCrLf + nAlign) 'create alignment Dim idAlign As ObjectId = Alignment.Create(civdoc, plos, nAlign, ObjectId.Null, idLayer, idStyle, idLabelSet) End If Next tr.Commit() Catch ex As Autodesk.AutoCAD.Runtime.Exception ' ok so we have an exception ed.WriteMessage("problem due to " + ex.Message) Finally ' all done, whether an error on not - dispose the transaction. tr.Dispose() End Try Else ed.WriteMessage("No Polylines selected") End If End Sub End Class End Namespace
.Net
Many thanks for all your help and an excellent template
Can't thank you enough
cheers
Trefor
Thanks a lot for providing that, works perfectly. I would like to try and get it to name the alignment as the original layer name of the selected objects if possible? just struggling to get the layer name as a String.
Thanks
Joe
I am new to coding in general but this is what i have got so far for having the Alignments named as per the Polyline Layer. I am getting an exception 'Specified cast is not valid'. Any help with this would be much appreciated.
Imports System Imports Autodesk.AutoCAD.Runtime Imports Autodesk.AutoCAD.ApplicationServices Imports Autodesk.AutoCAD.DatabaseServices Imports Autodesk.AutoCAD.Geometry Imports Autodesk.AutoCAD.EditorInput Imports Autodesk.Civil.ApplicationServices Imports Autodesk.Civil.DatabaseServices Imports Autodesk.Civil.Settings Imports Entity = Autodesk.AutoCAD.DatabaseServices.Entity ' This line is not mandatory, but improves loading performances <Assembly: CommandClass(GetType(ALC_VB_AlignmentFromPolyline.MyCommands))> Namespace ALC_VB_AlignmentFromPolyline Public Class MyCommands ' Modal Command with pickfirst selection <CommandMethod("MyAlignmentFromPolyline", CommandFlags.Modal + CommandFlags.UsePickSet)> Public Sub MyPickFirst() 'Get the current document And database Dim doc As Document = Application.DocumentManager.MdiActiveDocument Dim db As Database = doc.Database Dim ed As Editor = doc.Editor Dim civdoc As CivilDocument = CivilApplication.ActiveDocument 'Build a filter list so that only olyline are selected Dim arTV(0) As TypedValue arTV.SetValue(New TypedValue(DxfCode.Start, "LWPOLYLINE"), 0) Dim filter As SelectionFilter = New SelectionFilter(arTV) Dim pso As PromptSelectionOptions = New PromptSelectionOptions() pso.MessageForAdding = "Select polylines" 'Get a selection Dim result As PromptSelectionResult = ed.GetSelection(pso, filter) If (result.Status = PromptStatus.OK And Not IsDBNull(result.Value)) Then ed.WriteMessage(vbCrLf + "Valid selection") Dim tr As Transaction = db.TransactionManager.StartTransaction() Try 'get id of Layer Dim idLayer As ObjectId = db.Clayer Dim lt As LayerTable = tr.GetObject(db.LayerTableId, OpenMode.ForRead) If (lt.Has("alignments")) Then idLayer = lt("alignments") 'get objectid of the 1st Alignment style Or Basic Dim idStyle As ObjectId = civdoc.Styles.AlignmentStyles(0) If (civdoc.Styles.AlignmentStyles.Contains("Basic")) Then idStyle = civdoc.Styles.AlignmentStyles("Basic") 'get objectid of the 1st AlignmentLabelSetStyle Or Basic Dim idLabelSet As ObjectId = civdoc.Styles.LabelSetStyles.AlignmentLabelSetStyles(0) If (civdoc.Styles.LabelSetStyles.AlignmentLabelSetStyles.Contains("Basic")) Then idLabelSet = civdoc.Styles.LabelSetStyles.AlignmentLabelSetStyles("Basic") 'step through the objects in the selection set Dim ss As SelectionSet = result.Value For Each obj As ObjectId In ss Dim ent As Entity = CType(tr.GetObject(obj, OpenMode.ForRead), Entity) 'check object is from the expected type If TypeOf ent Is Polyline Then ' set options Dim plos As PolylineOptions = New PolylineOptions() plos.AddCurvesBetweenTangents = False plos.EraseExistingEntities = True plos.PlineId = obj 'Get layer Dim nLayer As String = ent.Layer().ToString 'create unique name Dim sccae As SettingsCmdCreateAlignmentEntities = civdoc.Settings.GetSettings(Of SettingsCmdCreateAlignmentEntities)() ed.WriteMessage(vbCrLf + nLayer) 'create alignment Dim idAlign As ObjectId = Alignment.Create(civdoc, plos, nLayer, ObjectId.Null, idLayer, idStyle, idLabelSet) End If Next tr.Commit() Catch ex As Autodesk.AutoCAD.Runtime.Exception ' ok so we have an exception ed.WriteMessage("problem due to " + ex.Message) Finally ' all done, whether an error on not - dispose the transaction. tr.Dispose() End Try Else ed.WriteMessage("No Polylines selected") End If End Sub End Class End Namespace
Cheers
Joe
Jeff pointed already you mistake:
the Layer Property of an entity is already a string, no need to convert.
What happens it that Layer() gives you an empty layer object, as this works as constructor in VB,
The call for a conversation would be: value.ToString().
Thanks for your help. I have tried that and still get the same error 'Specified Cast is Not Valid'. i think it may be to with these lines...
Dim ss As SelectionSet = result.Value For Each obj As ObjectId In ss Dim ent As Entity = CType(tr.GetObject(obj, OpenMode.ForRead), Entity)
Is it because i am trying to get the ObjectID's from a SelectionSet?
Cheers
Joe
Dim ss As SelectionSet = result.Value For Each obj As SelectedObject In ss Dim ent As Entity = CType(tr.GetObject(obj.objectId, OpenMode.ForRead), Entity)
The result.Value is a list of type: SelectedObject
Thanks for your help, like i said im pretty new to this.
I wonder then, if it needs to be a SelectedObject, how can i get the layer property from each of the SelectedObjects? can i retrieve entities of the selected objects?
Cheers
Joe
Can't find what you're looking for? Ask the community or share your knowledge.