Community
Civil 3D Customization
Welcome to Autodesk’s AutoCAD Civil 3D Forums. Share your knowledge, ask questions, and explore popular AutoCAD Civil 3D Customization topics.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

System.AccessViolationException_

3 REPLIES 3
SOLVED
Reply
Message 1 of 4
flowerpapa
562 Views, 3 Replies

System.AccessViolationException_

Hello, 
While debugging it's throwing the below, but it working fine with less no. of objects, 
could anyone advise me on the same

 

--systemaccessviolationsystemaccessviolation

Gr

Raja

 

Tags (1)
3 REPLIES 3
Message 2 of 4

Look at the Output panel in Visual Studio. I suspect its providing messages about objects not being disposed of. If one of those improperly disposed of objects hit AutoCAD at the wrong time it will cause that type of error. Then look in your code for that object type and put a using or dispose of it when you are done with it.

Civil Reminders
http://blog.civil3dreminders.com/
http://www.CivilReminders.com/
Alumni
Message 3 of 4

could you please tell me a bit more, I'm a beginner level in this. my code is below

using System;
using System.Windows.Forms;
using Microsoft.VisualBasic;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.Runtime;
using AcAp = Autodesk.AutoCAD.ApplicationServices.Application;
using Autodesk.AutoCAD.Colors;
using Autodesk.Gis.Map.ObjectData;
using Autodesk.Gis.Map.Project;
using Autodesk.Gis.Map.Utilities;
using Autodesk.Aec.PropertyData.DatabaseServices;


namespace OD2DataSet_EditedVersie
{
    public class Commands
    {
        [CommandMethod("ARCOD2DataSet")]

        public static  void ShowForm()
        {

            var oODTable = new Form1();
            AcAp.ShowModalDialog(oODTable);

        }

        //Getting ObjectTable available in the current drawing       
        public static StringCollection ODTableList()
        {
            var doc = AcAp.DocumentManager.MdiActiveDocument;
            var db = doc.Database;
            var ed = doc.Editor;
            Database oDb = HostApplicationServices.WorkingDatabase;
            Tables oTables = Autodesk.Gis.Map.HostMapApplicationServices.Application.ActiveProject.ODTables;
            StringCollection oTablesName = oTables.GetTableNames();

            return oTablesName;
        }

        //fetching fields of the selected ODTableName by go>> button
        public static StringCollection ODTableField()
        {
            
            string TableName = Form1.ODTableName;

            var doc = AcAp.DocumentManager.MdiActiveDocument;
            var db = doc.Database;
            var ed = doc.Editor;
            Database oDb = HostApplicationServices.WorkingDatabase;
            Tables oTables = Autodesk.Gis.Map.HostMapApplicationServices.Application.ActiveProject.ODTables;
            Autodesk.Gis.Map.ObjectData.Table oTable;
            FieldDefinitions oODFieldsCol;
            StringCollection oTablesName = oTables.GetTableNames();
            StringCollection oODFieldDef = new StringCollection();

            //Autodesk.Gis.Map.ObjectData.Table oTbl = new Table();
            foreach (string name in oTablesName)
            {
                if (TableName == name)
                
                {
                     oTable = oTables[name];
                     oODFieldsCol = oTable.FieldDefinitions;
                     

                    for (int i = 0; i < oODFieldsCol.Count; i++)
                    {
                        FieldDefinition oDef = oODFieldsCol[i];
                        oODFieldDef.Add(oDef.Name);

                    }
                    
                }
            
            }

            return oODFieldDef;
        }


        public static void OD2DataSet()

        {
            var doc = AcAp.DocumentManager.MdiActiveDocument;
            //var db = doc.Database;
            var ed = doc.Editor;
            Database oDb = doc.Database;
            using (doc.LockDocument())
            {
                Tables oTables = Autodesk.Gis.Map.HostMapApplicationServices.Application.ActiveProject.ODTables;
                // oTablesName = oTables.GetTableNames();

                string oTableName = Form1.ODTableName;
                StringCollection oODFields = Form1.FieldsSelected;

                DictionaryPropertySetDefinitions oDicDataSet = new DictionaryPropertySetDefinitions(oDb);
                PropertySetDefinition oProfDefOD = new PropertySetDefinition();

                using (var tr = oDb.TransactionManager.StartTransaction())
                {

                    CreatePropertyDataSet(oDicDataSet, oTableName, oODFields, oProfDefOD);

                    try
                    {
                        PromptSelectionResult oSSPromp = ed.GetSelection();
                        if (oSSPromp.Status == PromptStatus.OK)
                        {
                            SelectionSet oSS1 = oSSPromp.Value;

                            foreach (SelectedObject oObject in oSS1)
                            {
                                BlockTable oBlkTbl = tr.GetObject(oDb.BlockTableId, OpenMode.ForRead) as BlockTable;
                                BlockTableRecord oBlkTblRec = tr.GetObject(oBlkTbl[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord;
                                Entity oEnt = tr.GetObject(oObject.ObjectId, OpenMode.ForWrite) as Entity;
                                DBObject oDBObject = tr.GetObject(oObject.ObjectId, OpenMode.ForWrite);
                                Records oRecs = oTables.GetObjectRecords(0, oObject.ObjectId, Autodesk.Gis.Map.Constants.OpenMode.OpenForRead, false);

                               
                                    if (oRecs.Count > 0)
                                    {
                                        int i = 0;
                                        StringCollection oODFieldValue = new StringCollection();
                                        for (i = 0; i < oODFields.Count; i++)
                                        {
                                            oODFieldValue.Add("null");
                                        }

                                        foreach (Record oRec in oRecs)

                                        {
                                            Record oRec1 = oRec;
                                            Autodesk.Gis.Map.ObjectData.Table oTable = oTables[oRec1.TableName];

                                            FieldDefinitions oDefs = oTable.FieldDefinitions;
                                            for (int j = 0; j < oODFields.Count; j++)
                                            {
                                                for (i = 0; i < oRec.Count; i++)
                                                {
                                                    FieldDefinition oDef = oDefs[i];
                                                    string oTemp4 = oDef.Name;
                                                    if (oODFields[j] == oDef.Name)
                                                    {
                                                        //MapValue oValue = oDef.DefaultMapValue;
                                                        MapValue oValue = oRec[i];
                                                        oODFieldValue[i] = oValue.StrValue.ToString();                                                        
                                                    }

                                                }
                                            }

                                        }

                                        SetPropValue(oDicDataSet, oTableName, oODFieldValue, oDBObject, oODFields);
                                                                               

                                    }

                                    else

                                    {
                                        ed.WriteMessage("No Object Data Attached🤡" + oObject.ObjectId);

                                    }                                                
                            }
                        }
                    }

                    catch (System.Exception  e)
                    {
                        MessageBox.Show(e.Message);
                        AcAp.ShowAlertDialog("Selection Not Found 🤡");
                       
                        return;                     
                    }
                    
                    tr.Commit();
                }
            }
            
            ed.WriteMessage("ObjectData to Property Data assingned Successfully😀");
            
        }

        // [CommandMethod("PropertyDataSet")]
        //Creating New PropertyData Set for the selected ObjectData Table Name
        public static void CreatePropertyDataSet(DictionaryPropertySetDefinitions oDicDataSet, string oTableName, StringCollection oODFields, PropertySetDefinition oProfDefOD)
        {
            Document oDoc = AcAp.DocumentManager.MdiActiveDocument;
            Editor ed = oDoc.Editor;
            Database oDb = HostApplicationServices.WorkingDatabase;
            using (var tr = oDb.TransactionManager.StartTransaction())
            {

                //oTableName = "FirstPropertyData";
                if (oDicDataSet.Records.Count == 0)
                {
                    AddPropSet(oTableName, oDicDataSet, oODFields);
                    tr.Commit();
                   
                    return;
                }

                else
                {
                    ObjectIdCollection oIDs = oDicDataSet.Records;

                    foreach (ObjectId oID in oIDs)
                    {
                        object oObj = tr.GetObject(oID, OpenMode.ForRead, false, false);

                        PropertySetDefinition oPropDef = oObj as PropertySetDefinition;

                        if (oPropDef.Name == oTableName)
                        {
                            AcAp.ShowAlertDialog("The Property Data Set Already\n Existed in the Current Drawing 🤡\n Remove or Try with New DataSet Name 🤡");
                            
                            return;
                        }
                        else
                        {
                            AddPropSet(oTableName, oDicDataSet, oODFields);
                        }

                    }

                    tr.Commit();
                }

               
            }


        }

        //Adding Propertydefinitions to the Created dataset as per the fields selected in the Modal Dialog
        public static void AddPropSet(string oTableName, DictionaryPropertySetDefinitions oDicDataSet, StringCollection oODFields)
        {

            try
            {
                Document oDoc = AcAp.DocumentManager.MdiActiveDocument;
                Editor ed = oDoc.Editor;
                Database oDb = HostApplicationServices.WorkingDatabase;

                using (var tr = oDb.TransactionManager.StartTransaction())

                {
                    PropertySetDefinition oPropDefOD = new PropertySetDefinition();

                    oDicDataSet.AddNewRecord(oTableName, oPropDefOD);
                    tr.AddNewlyCreatedDBObject(oPropDefOD, true);

                    PropertyDefinition[] oPropDef = new PropertyDefinition[oODFields.Count];
                    for (int i = 0; i < oODFields.Count; i++)
                    {
                        oPropDef[i] = new PropertyDefinition();
                        oPropDef[i].Name = oODFields[i];
                        oPropDef[i].DataType = Autodesk.Aec.PropertyData.DataType.Text;
                        oPropDefOD.Definitions.Add(oPropDef[i]);
                    }

                    ed.WriteMessage("You have added Definition Successfully😀");


                    tr.Commit();
                }
              
            }
            catch
            {
                AcAp.ShowAlertDialog("Error at Adding Property Dataset to the Dictionary🤡");
                
            }
        }


        //assigning the  MapOD Value to propsetdefinition fields
        public static void SetPropValue(DictionaryPropertySetDefinitions oDicDataSet, string oTableName, StringCollection oODFieldValue, DBObject oDBObject, StringCollection oODFields)
        {
            try
            {
                Document oDoc = AcAp.DocumentManager.MdiActiveDocument;
                Editor ed = oDoc.Editor;
                Database oDb = HostApplicationServices.WorkingDatabase;
                using (var tr = oDb.TransactionManager.StartTransaction())
                {
                    PropertySetDefinition oPropDefOD = new PropertySetDefinition();

                    ObjectIdCollection oIDs = oDicDataSet.Records;

                    foreach (ObjectId oID in oIDs)
                    {
                        object oObj = tr.GetObject(oID, OpenMode.ForRead, false, false);

                        PropertySetDefinition oPropDef = oObj as PropertySetDefinition;

                        if (oPropDef.Name == oTableName)
                        {
                            oPropDefOD = oPropDef;
                            PropertyDataServices.AddPropertySet(oDBObject, oPropDefOD.ObjectId);
                        }
                        ObjectIdCollection oObjIDCol = PropertyDataServices.GetPropertySets(oDBObject);
                        foreach (ObjectId oObjID in oObjIDCol)
                        {
                            PropertySet oPropSet = tr.GetObject(oObjID, OpenMode.ForWrite) as PropertySet;
                            if (oPropSet.PropertySetDefinitionName == oTableName)
                            {
                                PropertySetDefinition oProfDefOD = tr.GetObject(oPropSet.PropertySetDefinition, OpenMode.ForWrite) as PropertySetDefinition;
                                PropertyDefinitionCollection oDefCol = oPropDefOD.Definitions;
                                //ObjectIdCollection oDummyCol = new ObjectIdCollection();
                                foreach (PropertyDefinition oDef in oDefCol)
                                {
                                    if (oPropSet.IsWriteEnabled)
                                    {
                                        for (int i = 0; i < oODFields.Count; i++)
                                        {
                                            if (oDef.Name == oODFields[i])
                                            {
                                                int propertyID = oPropSet.PropertyNameToId(oDef.Name);
                                                String oStr = oODFieldValue[i];
                                                oPropSet.SetAt(propertyID, oStr);
                                            }

                                        }


                                    }

                                    else { AcAp.ShowAlertDialog("The PropertyData is lockED🤡"); }

                                }

                            }

                        }


                    }
                    tr.Commit();
                   
                }
            }
            catch
            {
                AcAp.ShowAlertDialog("Error at Set Values to the Property Definitions🤡");
               
            }
        }

        
        
    }

   
}

Message 4 of 4

I'm thinking it might be this line. 

PropertySetDefinition oProfDefOD = tr.GetObject(oPropSet.PropertySetDefinition, OpenMode.ForWrite) as PropertySetDefinition;
PropertyDefinitionCollection oDefCol = oProfDefOD.Definitions;

The original code had a previously declared variable that uses a different PropertySetDefinition. 

 

If I was to take over the code and try to fix the issue this is what my starting point would be. I didn't run the code through a debugger to see if it works and I've commented out the Form1 code. 

 

using System;
using System.Windows.Forms;
using Microsoft.VisualBasic;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.Runtime;
using AcAp = Autodesk.AutoCAD.ApplicationServices.Application;
using Autodesk.AutoCAD.Colors;
using Autodesk.Gis.Map.ObjectData;
using Autodesk.Gis.Map.Project;
using Autodesk.Gis.Map.Utilities;
using Autodesk.Aec.PropertyData.DatabaseServices;

namespace OD2DataSet_EditedVersie
{
    public class Commands
    {
        [CommandMethod("ARCOD2DataSet")]

        public static void ShowForm()
        {
            // var oODTable = new Form1();
            // AcAp.ShowModalDialog(oODTable);

        }

        //Getting ObjectTable available in the current drawing       
        public static StringCollection ODTableList()
        {
            var doc = AcAp.DocumentManager.MdiActiveDocument;
            var db = doc.Database;
            var ed = doc.Editor;
            Database oDb = HostApplicationServices.WorkingDatabase;
            using (Tables oTables = Autodesk.Gis.Map.HostMapApplicationServices.Application.ActiveProject.ODTables)
            {
                StringCollection oTablesName = oTables.GetTableNames();

                return oTablesName;
            }
        }

        //fetching fields of the selected ODTableName by go>> button
        public static StringCollection ODTableField()
        {

            string TableName = "";  // Form1.ODTableName;

            var doc = AcAp.DocumentManager.MdiActiveDocument;
            var db = doc.Database;
            var ed = doc.Editor;
            Database oDb = HostApplicationServices.WorkingDatabase;
            Tables oTables = Autodesk.Gis.Map.HostMapApplicationServices.Application.ActiveProject.ODTables;
            Autodesk.Gis.Map.ObjectData.Table oTable;
            FieldDefinitions oODFieldsCol;
            StringCollection oTablesName = oTables.GetTableNames();
            StringCollection oODFieldDef = new StringCollection();

            //Autodesk.Gis.Map.ObjectData.Table oTbl = new Table();
            foreach (string name in oTablesName)
            {
                if (TableName == name)

                {
                    oTable = oTables[name];
                    oODFieldsCol = oTable.FieldDefinitions;


                    for (int i = 0; i < oODFieldsCol.Count; i++)
                    {
                        FieldDefinition oDef = oODFieldsCol[i];
                        oODFieldDef.Add(oDef.Name);

                    }

                }

            }

            return oODFieldDef;
        }


        public static void OD2DataSet()

        {
            var doc = AcAp.DocumentManager.MdiActiveDocument;
            //var db = doc.Database;
            var ed = doc.Editor;
            Database oDb = doc.Database;
            using (doc.LockDocument())
            using (Tables oTables = Autodesk.Gis.Map.HostMapApplicationServices.Application.ActiveProject.ODTables)
            using (DictionaryPropertySetDefinitions oDicDataSet = new DictionaryPropertySetDefinitions(oDb))
            using (PropertySetDefinition oProfDefOD = new PropertySetDefinition())
            {
                // oTablesName = oTables.GetTableNames();

                string oTableName = ""; //Form1.ODTableName;
                StringCollection oODFields = null; // Form1.FieldsSelected;

                using (var tr = oDb.TransactionManager.StartTransaction())
                {
                    BlockTable oBlkTbl = tr.GetObject(oDb.BlockTableId, OpenMode.ForRead) as BlockTable;
                    BlockTableRecord oBlkTblRec = tr.GetObject(oBlkTbl[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord;

                    CreatePropertyDataSet(oDicDataSet, oTableName, oODFields, oProfDefOD);

                    try
                    {
                        PromptSelectionResult oSSPromp = ed.GetSelection();
                        if (oSSPromp.Status == PromptStatus.OK)
                        {
                            SelectionSet oSS1 = oSSPromp.Value;

                            foreach (SelectedObject oObject in oSS1)
                            {
                                using (DBObject oDBObject = tr.GetObject(oObject.ObjectId, OpenMode.ForWrite))
                                using (Records oRecs = oTables.GetObjectRecords(0, oObject.ObjectId, Autodesk.Gis.Map.Constants.OpenMode.OpenForRead, false))
                                {
                                    if (oRecs.Count > 0)
                                    {
                                        int i = 0;
                                        StringCollection oODFieldValue = new StringCollection();
                                        for (i = 0; i < oODFields.Count; i++)
                                        {
                                            oODFieldValue.Add("null");
                                        }

                                        foreach (Record oRec in oRecs)
                                        {
                                            Autodesk.Gis.Map.ObjectData.Table oTable = oTables[oRec.TableName];

                                            FieldDefinitions oDefs = oTable.FieldDefinitions;
                                            for (int j = 0; j < oODFields.Count; j++)
                                            {
                                                for (i = 0; i < oRec.Count; i++)
                                                {
                                                    FieldDefinition oDef = oDefs[i];
                                                    string oTemp4 = oDef.Name;
                                                    if (oODFields[j] == oDef.Name)
                                                    {
                                                        //MapValue oValue = oDef.DefaultMapValue;
                                                        using (MapValue oValue = oRec[i])
                                                        {
                                                            oODFieldValue[i] = oValue.StrValue.ToString();
                                                        }
                                                    }
                                                }
                                            }
                                        }

                                        SetPropValue(oDicDataSet, oTableName, oODFieldValue, oDBObject, oODFields);
                                        
                                    }
                                    else
                                    {
                                        ed.WriteMessage("No Object Data Attached" + oObject.ObjectId);
                                    }
                                }
                            }
                        }
                    }
                    catch (System.Exception e)
                    {
                        MessageBox.Show(e.Message);
                        AcAp.ShowAlertDialog("Selection Not Found 🤡");
                        return;
                    }

                    tr.Commit();
                }
            }

            ed.WriteMessage("ObjectData to Property Data assingned Successfully😀");

        }

        // [CommandMethod("PropertyDataSet")]
        //Creating New PropertyData Set for the selected ObjectData Table Name
        public static void CreatePropertyDataSet(DictionaryPropertySetDefinitions oDicDataSet, string oTableName, StringCollection oODFields, PropertySetDefinition oProfDefOD)
        {
            Document oDoc = AcAp.DocumentManager.MdiActiveDocument;
            Editor ed = oDoc.Editor;
            Database oDb = HostApplicationServices.WorkingDatabase;
            using (var tr = oDb.TransactionManager.StartTransaction())
            {
                //oTableName = "FirstPropertyData";
                if (oDicDataSet.Records.Count == 0)
                {
                    AddPropSet(oTableName, oDicDataSet, oODFields);
                    tr.Commit();

                    return;
                }
                else
                {
                    ObjectIdCollection oIDs = oDicDataSet.Records;

                    foreach (ObjectId oID in oIDs)
                    {
                        using (PropertySetDefinition oPropDef = tr.GetObject(oID, OpenMode.ForRead, false, false) as PropertySetDefinition)
                        {

                            if (oPropDef.Name == oTableName)
                            {
                                AcAp.ShowAlertDialog("The Property Data Set Already\n Existed in the Current Drawing 🤡\n Remove or Try with New DataSet Name 🤡");

                                return;
                            }
                            else
                            {
                                AddPropSet(oTableName, oDicDataSet, oODFields);
                            }
                        }
                    }

                    tr.Commit();
                }
            }
        }

        //Adding Propertydefinitions to the Created dataset as per the fields selected in the Modal Dialog
        public static void AddPropSet(string oTableName, DictionaryPropertySetDefinitions oDicDataSet, StringCollection oODFields)
        {
            try
            {
                Document oDoc = AcAp.DocumentManager.MdiActiveDocument;
                Editor ed = oDoc.Editor;
                Database oDb = HostApplicationServices.WorkingDatabase;

                using (var tr = oDb.TransactionManager.StartTransaction())
                using (PropertySetDefinition oPropDefOD = new PropertySetDefinition())
                {
                    oDicDataSet.AddNewRecord(oTableName, oPropDefOD);
                    tr.AddNewlyCreatedDBObject(oPropDefOD, true);

                    PropertyDefinition[] oPropDef = new PropertyDefinition[oODFields.Count];
                    for (int i = 0; i < oODFields.Count; i++)
                    {
                        using (oPropDef[i] = new PropertyDefinition())
                        {
                            oPropDef[i].Name = oODFields[i];
                            oPropDef[i].DataType = Autodesk.Aec.PropertyData.DataType.Text;
                            oPropDefOD.Definitions.Add(oPropDef[i]);
                        }
                    }

                    ed.WriteMessage("You have added Definition Successfully😀");
                    
                    tr.Commit();
                }
            }
            catch
            {
                AcAp.ShowAlertDialog("Error at Adding Property Dataset to the Dictionary🤡");

            }
        }


        //assigning the  MapOD Value to propsetdefinition fields
        public static void SetPropValue(DictionaryPropertySetDefinitions oDicDataSet, string oTableName, StringCollection oODFieldValue, DBObject oDBObject, StringCollection oODFields)
        {
            try
            {
                Document oDoc = AcAp.DocumentManager.MdiActiveDocument;
                Editor ed = oDoc.Editor;
                Database oDb = HostApplicationServices.WorkingDatabase;
                using (var tr = oDb.TransactionManager.StartTransaction())
                {
                    ObjectIdCollection oIDs = oDicDataSet.Records;

                    foreach (ObjectId oID in oIDs)
                    {
                        PropertySetDefinition oPropDef = tr.GetObject(oID, OpenMode.ForRead, false, false) as PropertySetDefinition;

                        if (oPropDef.Name == oTableName)
                        {
                            var oPropDefOD = oPropDef;
                            PropertyDataServices.AddPropertySet(oDBObject, oPropDefOD.ObjectId);
                        }

                        ObjectIdCollection oObjIDCol = PropertyDataServices.GetPropertySets(oDBObject);
                        foreach (ObjectId oObjID in oObjIDCol)
                        {
                            using (PropertySet oPropSet = tr.GetObject(oObjID, OpenMode.ForWrite) as PropertySet)
                            {
                                if (oPropSet.PropertySetDefinitionName == oTableName)
                                {
                                    using (PropertySetDefinition oProfDefOD = tr.GetObject(oPropSet.PropertySetDefinition, OpenMode.ForWrite) as PropertySetDefinition)
                                    {
                                        foreach (PropertyDefinition oDef in oProfDefOD.Definitions)
                                        {
                                            if (oPropSet.IsWriteEnabled)
                                            {
                                                for (int i = 0; i < oODFields.Count; i++)
                                                {
                                                    if (oDef.Name == oODFields[i])
                                                    {
                                                        int propertyID = oPropSet.PropertyNameToId(oDef.Name);
                                                        String oStr = oODFieldValue[i];
                                                        oPropSet.SetAt(propertyID, oStr);
                                                    }
                                                }
                                            }
                                            else { AcAp.ShowAlertDialog("The PropertyData is lockED"); }
                                        }
                                    }
                                }
                            }
                        }
                    }
                    tr.Commit();
                }
            }
            catch
            {
                AcAp.ShowAlertDialog("Error at Set Values to the Property Definitions");

            }
        }
    }
}

 

 

 

Civil Reminders
http://blog.civil3dreminders.com/
http://www.CivilReminders.com/
Alumni

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Rail Community


Autodesk Design & Make Report