Required codign in .net

Required codign in .net

waseefur.rahman
Advocate Advocate
2,143 Views
13 Replies
Message 1 of 14

Required codign in .net

waseefur.rahman
Advocate
Advocate

Hi,

I am a .net learner,

I want to create a coding to copy 3D Solid in Same place with different layer,

(i.e) I am having object in Layer 1,
coding should ask to select object,
then create a copy in layer 2 in same place.
Could any provide me a coding on this?

Thanks & Regards

0 Likes
Accepted solutions (3)
2,144 Views
13 Replies
Replies (13)
Message 2 of 14

Anonymous
Not applicable

The following function can clone any Entity and change i'ts layer.

I also use an additional function to check if the entered layer exists.

 

 

using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.Customization;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.Runtime;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Application = Autodesk.AutoCAD.ApplicationServices.Application;

namespace AutodeskAppStoreTesting
{
    public class Commands : IExtensionApplication
    { 
       [CommandMethod("ChangeLayerOfSelected", CommandFlags.UsePickSet)]
        public static void ChangeLayerOfSelected()
        {
                        Document doc = Application.DocumentManager.MdiActiveDocument;
            Editor ed = doc.Editor;
            Database db = doc.Database;

            ObjectIdCollection Entities = null;

            var PSelection = ed.SelectImplied();
            if (PSelection.Status != PromptStatus.OK || PSelection.Value.Count == 0)
            {
                var Selection = ed.GetSelection(new PromptSelectionOptions()
                {
                    MessageForAdding = "\nSelect Entities to Change Layer",
                });

                if (Selection.Status != PromptStatus.OK) return;

                Entities = new ObjectIdCollection();
                Entities.AddRange(Selection.Value.GetObjectIds());
            }
            else
            {
                Entities = new ObjectIdCollection();
                Entities.AddRange(PSelection.Value.GetObjectIds());
            }

            string LayerName = "";
            var LayerNamePrompt = ed.GetString(new PromptStringOptions("\nEnter Layer Name"));
            if (LayerNamePrompt.Status != PromptStatus.OK) return;

            LayerName = LayerNamePrompt.StringResult;
            MakeSureLayerExists(LayerName);

            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                foreach (ObjectId n in Entities)
                {
                    Entity En = tr.GetObject(n, OpenMode.ForWrite) as Entity;
                    if (En == null) continue;

                    BlockTableRecord Owner = tr.GetObject(En.OwnerId, OpenMode.ForWrite) as BlockTableRecord;
                    if (Owner == null) continue;

                    string OldLayerName = En.Layer;

                    using (Entity NewEn = En.Clone() as Entity)
                    {
                        NewEn.Layer = LayerName;
                        Owner.AppendEntity(NewEn);
                        tr.AddNewlyCreatedDBObject(NewEn,true);
                    }

                    ed.WriteMessage("\nObject of type " + n.ObjectClass.Name + " has been duplicated with its layer changed from \"" + OldLayerName + "\" to \"" + LayerName + "\"");
                }
                tr.Commit();
            }
        }
        private static void MakeSureLayerExists(string LayerName)
        {
            Document doc = Application.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;

            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                var LayerTab = tr.GetObject(db.LayerTableId, OpenMode.ForRead) as LayerTable;

                if (!LayerTab.Has(LayerName))
                {
                    using (var NewLayer = new LayerTableRecord())
                    {
                        NewLayer.Name = LayerName;

                        LayerTab.UpgradeOpen();
                        LayerTab.Add(NewLayer);
                        tr.AddNewlyCreatedDBObject(NewLayer, true);
                    }
                }
                tr.Commit();
            }
        }
    }
    public static class ObjectIdCollectionExtensions
    {
        public static void AddRange(this ObjectIdCollection a, ObjectId[] Range)
        {
            foreach (var n in Range)
            {
                a.Add(n);
            }
        }
    }

 

0 Likes
Message 3 of 14

waseefur.rahman
Advocate
Advocate
Great..
Many thanks,

Could you provide this coding in vb.net please..

Also in coding you Said it's changing the selection to New layer.

I will brief my question
When user selects the object,
Then coding need to create a copy of object to New layer.

Also the selection object should be in same place.

(i.e) We can take the coping & pasting pick point as same (0,0,0)



0 Likes
Message 4 of 14

Anonymous
Not applicable

The posted code will create a copy in the same position of the selected objects to only then change the layer of the new objects.

 

ALthough VB.NET and C# have different syntaxes, they can be easily translated with almost no problem using a simple code converter.

Personally I prefer Telerik's. Web-based free and pretty accurate...

 

Below the converted code:

Imports Autodesk.AutoCAD.ApplicationServices
Imports Autodesk.AutoCAD.Customization
Imports Autodesk.AutoCAD.DatabaseServices
Imports Autodesk.AutoCAD.EditorInput
Imports Autodesk.AutoCAD.Geometry
Imports Autodesk.AutoCAD.Runtime
Imports System.Collections.Generic
Imports System.Configuration
Imports System.Diagnostics
Imports System.IO
Imports System.Linq
Imports System.Text
Imports System.Windows.Forms
Imports Application = Autodesk.AutoCAD.ApplicationServices.Application

Namespace AutodeskAppStoreTesting
    Public Class Commands
        Implements IExtensionApplication
        <CommandMethod("ChangeLayerOfSelected", CommandFlags.UsePickSet)> _
        Public Shared Sub ChangeLayerOfSelected()
            Dim doc As Document = Application.DocumentManager.MdiActiveDocument
            Dim ed As Editor = doc.Editor
            Dim db As Database = doc.Database

            Dim Entities As ObjectIdCollection = Nothing

            Dim PSelection = ed.SelectImplied()
            If PSelection.Status <> PromptStatus.OK OrElse PSelection.Value.Count = 0 Then
                Dim Selection = ed.GetSelection(New PromptSelectionOptions() With { _
                    Key .MessageForAdding = vbLf & "Select Entities to Change Layer" _
                })

                If Selection.Status <> PromptStatus.OK Then
                    Return
                End If

                Entities = New ObjectIdCollection()
                Entities.AddRange(Selection.Value.GetObjectIds())
            Else
                Entities = New ObjectIdCollection()
                Entities.AddRange(PSelection.Value.GetObjectIds())
            End If

            Dim LayerName As String = ""
            Dim LayerNamePrompt = ed.GetString(New PromptStringOptions(vbLf & "Enter Layer Name"))
            If LayerNamePrompt.Status <> PromptStatus.OK Then
                Return
            End If

            LayerName = LayerNamePrompt.StringResult
            MakeSureLayerExists(LayerName)

            Using tr As Transaction = db.TransactionManager.StartTransaction()
                For Each n As ObjectId In Entities
                    Dim En As Entity = TryCast(tr.GetObject(n, OpenMode.ForWrite), Entity)
                    If En Is Nothing Then
                        Continue For
                    End If

                    Dim Owner As BlockTableRecord = TryCast(tr.GetObject(En.OwnerId, OpenMode.ForWrite), BlockTableRecord)
                    If Owner Is Nothing Then
                        Continue For
                    End If

                    Dim OldLayerName As String = En.Layer

                    Using NewEn As Entity = TryCast(En.Clone(), Entity)
                        NewEn.Layer = LayerName
                        Owner.AppendEntity(NewEn)
                        tr.AddNewlyCreatedDBObject(NewEn, True)
                    End Using

                    ed.WriteMessage((Convert.ToString((Convert.ToString(vbLf & "Object of type " + n.ObjectClass.Name + " has been duplicated with its layer changed from """) & OldLayerName) + """ to """) & LayerName) + """")
                Next
                tr.Commit()
            End Using
        End Sub
        Private Shared Sub MakeSureLayerExists(LayerName As String)
            Dim doc As Document = Application.DocumentManager.MdiActiveDocument
            Dim db As Database = doc.Database

            Using tr As Transaction = db.TransactionManager.StartTransaction()
                Dim LayerTab = TryCast(tr.GetObject(db.LayerTableId, OpenMode.ForRead), LayerTable)

                If Not LayerTab.Has(LayerName) Then
                    Using NewLayer = New LayerTableRecord()
                        NewLayer.Name = LayerName

                        LayerTab.UpgradeOpen()
                        LayerTab.Add(NewLayer)
                        tr.AddNewlyCreatedDBObject(NewLayer, True)
                    End Using
                End If
                tr.Commit()
            End Using
        End Sub
    End Class
    Public NotInheritable Class ObjectIdCollectionExtensions
        Private Sub New()
        End Sub
        <System.Runtime.CompilerServices.Extension> _
        Public Shared Sub AddRange(a As ObjectIdCollection, Range As ObjectId())
            For Each n As var In Range
                a.Add(n)
            Next
        End Sub
    End Class
End Namespace

'=======================================================
'Service provided by Telerik (www.telerik.com)
'Conversion powered by NRefactory.
'Twitter: @telerik
'Facebook: facebook.com/telerik
'=======================================================

 

0 Likes
Message 5 of 14

waseefur.rahman
Advocate
Advocate

Many Thanks,

I am getting errors, attached image,


Could please tell me what to do?

0 Likes
Message 6 of 14

waseefur.rahman
Advocate
Advocate

i have tried with this code,

its copying the selected object in same layer with different color

 

could you tell me in this code how paste the object in different layer.

 

Also attached a dwg file, shows the output required

 

 

<CommandMethod("cp")>

Public Shared Sub CopyMove()

Dim doc As Document = Application.DocumentManager.MdiActiveDocument

Dim db As Database = doc.Database

Dim ed As Editor = doc.Editor

Dim peo As New PromptEntityOptions(vbLf & "Select object:")

Dim per As PromptEntityResult = ed.GetEntity(peo)

If per.Status <> PromptStatus.OK Then

Return

End If

Dim startPT As Point3d = per.PickedPoint

Dim EndPT As Point3d = per.PickedPoint

Using tr As Transaction = db.TransactionManager.StartTransaction()

Dim btr As BlockTableRecord = CType(tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite), BlockTableRecord)

Dim sourceId As ObjectId = per.ObjectId

Dim EntitySource As Entity = CType(tr.GetObject(sourceId, OpenMode.ForWrite), Entity)

Dim ids As New ObjectIdCollection()

ids.Add(sourceId)

db.DeepCloneObjects(ids, db.CurrentSpaceId, New IdMapping, False)

Dim EntityCopy As Entity = CType(tr.GetObject(ids(0), OpenMode.ForRead), Entity)

EntityCopy.UpgradeOpen()

EntityCopy.TransformBy(Matrix3d.Displacement(startPT.GetVectorTo(EndPT)))

EntityCopy.ColorIndex = 2

tr.Commit()

End Using

End Sub

 

 

0 Likes
Message 7 of 14

Anonymous
Not applicable
Accepted solution

Hello,

 

In order to make the method I've sent work you must add this Extensions Class to the same namespace:

 

    Public NotInheritable Class ObjectIdCollectionExtensions
        Private Sub New()
        End Sub
        <System.Runtime.CompilerServices.Extension> _
        Public Shared Sub AddRange(a As ObjectIdCollection, Range As ObjectId())
            For Each n As var In Range
                a.Add(n)
            Next
        End Sub
    End Class

 

If you want to use the method you've sent you just need a few adjustments:

<CommandMethod("cp")>
Public Shared Sub CopyMove()
Dim doc As Document = Application.DocumentManager.MdiActiveDocument
Dim db As Database = doc.Database
Dim ed As Editor = doc.Editor
Dim peo As New PromptEntityOptions(vbLf & "Select object:")
Dim per As PromptEntityResult = ed.GetEntity(peo)
If per.Status <> PromptStatus.OK Then
Return
End If
Dim LayerName As String = ""
Dim LayerNamePrompt = ed.GetString(New PromptStringOptions(vbLf & "Enter Layer Name"))
If LayerNamePrompt.Status <> PromptStatus.OK Then
Return
End If
Dim startPT As Point3d = per.PickedPoint
Dim EndPT As Point3d = per.PickedPoint
Using tr As Transaction = db.TransactionManager.StartTransaction()
Dim btr As BlockTableRecord = CType(tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite), BlockTableRecord)
Dim sourceId As ObjectId = per.ObjectId
Dim EntitySource As Entity = CType(tr.GetObject(sourceId, OpenMode.ForWrite), Entity)
Dim ids As New ObjectIdCollection()
ids.Add(sourceId)
db.DeepCloneObjects(ids, db.CurrentSpaceId, New IdMapping, False)
Dim EntityCopy As Entity = CType(tr.GetObject(ids(0), OpenMode.ForRead), Entity)
EntityCopy.UpgradeOpen()
EntityCopy.TransformBy(Matrix3d.Displacement(startPT.GetVectorTo(EndPT)))
EntityCopy.ColorIndex = 2
EntityCopy.Layer = LayerName
tr.Commit()
End Using
End Sub

Private Shared Sub MakeSureLayerExists(LayerName As String) Dim doc As Document = Application.DocumentManager.MdiActiveDocument Dim db As Database = doc.Database Using tr As Transaction = db.TransactionManager.StartTransaction() Dim LayerTab = TryCast(tr.GetObject(db.LayerTableId, OpenMode.ForRead), LayerTable) If Not LayerTab.Has(LayerName) Then Using NewLayer = New LayerTableRecord() NewLayer.Name = LayerName LayerTab.UpgradeOpen() LayerTab.Add(NewLayer) tr.AddNewlyCreatedDBObject(NewLayer, True) End Using End If tr.Commit() End Using End Sub

 

0 Likes
Message 8 of 14

waseefur.rahman
Advocate
Advocate

Hi,

i have also tried with this coding, but didn't getting solution

also attached a error snap.

 

Imports Autodesk.AutoCAD.DatabaseServices

Imports Autodesk.AutoCAD.Runtime

Imports Autodesk.AutoCAD.Geometry

Imports Autodesk.AutoCAD.EditorInput

Imports Autodesk.AutoCAD.Interop

 

Imports Autodesk.AutoCAD.ApplicationServices

Public ReadOnly Property ThisDrawing() As AcadDocument

Get

Return Autodesk.AutoCAD.ApplicationServices.DocumentExtension.GetAcadDocument(Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument)

End Get

End Property

 

Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click

 

Dim tu As AcadUtility

 

 

tu = ThisDrawing.Utility

 

ThisDrawing.SendCommand("COPYTOLAYER" & vbCr & tu.Get(, "Select objects to copy") & vbCr & "N" & vbCr & "Layer2" & vbCr)

 

End Sub

 

0 Likes
Message 9 of 14

waseefur.rahman
Advocate
Advocate

Many Thanks,
it works...

Could you Please tell me how to do it with "COPYTOLAYER" command in coding

 

I have tried with this code but it dosent work

 

 

Imports Autodesk.AutoCAD.ApplicationServices

Imports Autodesk.AutoCAD.Interop

Imports Autodesk.AutoCAD.Interop.Common

Imports Autodesk.AutoCAD.DatabaseServices

Imports Autodesk.AutoCAD.EditorInput

Imports Autodesk.AutoCAD.Geometry

 

Public ReadOnly Property ThisDrawing() As AcadDocument

Get

Return Autodesk.AutoCAD.ApplicationServices.DocumentExtension.GetAcadDocument(Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument)

End Get

End Property

 

Private Sub Create_Copy_Click(sender As Object, e As EventArgs) Handles Create_Copy.Click

 

Dim tu As AcadUtility

tu = ThisDrawing.Utility

ThisDrawing.SendCommand("COPYTOLAYER" & vbCr & tu.GetEntity & vbCr & "N" & vbCr & "Cutback Extruction" & vbCr)

 

End Sub

 

 

0 Likes
Message 10 of 14

_gile
Consultant
Consultant
Accepted solution

Hi,

 

SendCommand expects a string as argument and there're none implicit cast from AcadUtils.GetEntity() returned value and the String type.

 

If your're targetting AutoCAD 2015 or later, you can use the Editor.Command() method, for prior versions, you can use the Tony Tanzillo's wrapper for the non public RunCommand() method which works the same way.

 

Assuming the dialog is shown as modal dialog and the "Cutback Extruction" layer already exists in the document.

 

C#

        private void button1_Click(object sender, EventArgs e)
        {
            var doc = AcAp.DocumentManager.MdiActiveDocument;
            var ed = doc.Editor;
            var selection = ed.GetSelection();
            if (selection.Status == PromptStatus.OK)
                ed.Command("_COPYTOLAYER", selection.Value, "", "Cutback Extruction", "");
        }

VB

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Dim doc As Document = AcApp.DocumentManager.MdiActiveDocument
        Dim ed As Editor = doc.Editor
        Dim selection As PromptSelectionResult = ed.GetSelection()
        If selection.Status = PromptStatus.OK Then
            ed.Command("_COPYTOLAYER", selection.Value, "", "Cutback Extruction", "")
        End If
    End Sub

But, as shown by @Anonymous, it's not so difficult to mimic the "COPYTOLAYER" command.

 

C#

        private void button2_Click(object sender, EventArgs e)
        {
            var doc = AcAp.DocumentManager.MdiActiveDocument;
            var db = doc.Database;
            var ed = doc.Editor;

            var selection = ed.GetSelection();
            if (selection.Status == PromptStatus.OK) return;
            try
            {
                var ids = new ObjectIdCollection(selection.Value.GetObjectIds());
                var mapping = new IdMapping();
                db.DeepCloneObjects(ids, SymbolUtilityServices.GetBlockModelSpaceId(db), mapping, false);
                using (var tr = db.TransactionManager.StartTransaction())
                {
                    foreach (IdPair item in mapping)
                    {
                        if (item.IsCloned && item.IsPrimary)
                        {
                            var entity = (Entity)tr.GetObject(item.Value, OpenMode.ForWrite);
                            entity.Layer = "Cutback Extruction";
                        }
                    }
                    tr.Commit();
                }
            }
            catch (Autodesk.AutoCAD.Runtime.Exception ex)
            {
                ed.WriteMessage("\n" + ex.Message);
            }
        }

VB

    Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
        Dim doc As Document = AcApp.DocumentManager.MdiActiveDocument
        Dim db As Database = doc.Database
        Dim ed As Editor = doc.Editor

        Dim selection As PromptSelectionResult = ed.GetSelection()
        If selection.Status <> PromptStatus.OK Then
            Return
        End If
        Try
            Dim ids As ObjectIdCollection = New ObjectIdCollection(selection.Value.GetObjectIds())
            Dim mapping As IdMapping = New IdMapping()
            db.DeepCloneObjects(ids, SymbolUtilityServices.GetBlockModelSpaceId(db), mapping, False)
            Using tr As Transaction = db.TransactionManager.StartTransaction()
                For Each item As IdPair In mapping
                    If item.IsCloned AndAlso item.IsPrimary Then
                        Dim entity As Entity = DirectCast(tr.GetObject(item.Value, OpenMode.ForWrite), Entity)
                        entity.Layer = "Cutback Extruction"
                    End If
                Next
                tr.Commit()
            End Using
        Catch ex As Autodesk.AutoCAD.Runtime.Exception
            ed.WriteMessage(vbLf + ex.Message)
        End Try
    End Sub

 



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 11 of 14

waseefur.rahman
Advocate
Advocate

Hi gile,

Many thanks for Your response,

The code by chavesgalinari, has been working Fine

 

But I have been trying the above through "COPYTOLAYER" command in coding.

 

while running code I got this error attached (Capture 23)
could you please guide what to do to achive it

0 Likes
Message 12 of 14

_gile
Consultant
Consultant

In which context do you run this code? Editor.Command() must be called in document context.

In other words, how do you call this code? from a dialog? if so, the dialog have to be shown as Modal dialog.



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 13 of 14

waseefur.rahman
Advocate
Advocate

Sorry,
I didn't get you,

Are you asking me how I am running this code?

I have been running this code through from, where I am having a button to call this code.

0 Likes
Message 14 of 14

_gile
Consultant
Consultant
Accepted solution

How do you display this form? as modal or modeless?

 

If you're using:

form.Show()

or, better (see this thread😞

Autodesk.AutoCAD.ApplicationServices.Application.ShowModelessDialog(form)

you use a modeless dialog which does not execute in document context, so you cannot directly use Editor.Command() from this kind of dialog.

 

 

On the other hand if you use (not so good):

form.showDialog()

or (better):

Autodesk.AutoCAD.ApplicationServices.Application.ShowModalDialog(form)

you use a modal dialog which executes in document context and so can call Editor.Command() directly.



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes