Recent Posts

Pages: 1 ... 4 5 [6] 7 8 ... 10
51
Windows forms / Re: Use dinamically created form in the project
« Last post by bcinnv on March 23, 2013, 08:01:11 AM »
Works great! Thanks!
52
Polylines / Re: Offset curve toward centroid
« Last post by (gile) on March 20, 2013, 07:11:04 PM »
According to Tony Tanzillo's advices at TheSwamp, here's a safer way because of the using of DisposableSet class to insure the newly created polylines to be diposed in case an exception is thrown.

Code: [Select]
using System;
using System.Collections.Generic;
using System.Linq;
using Autodesk.AutoCAD.DatabaseServices;

// With the help of Tony Tanzillo's advices
// http://www.theswamp.org/index.php?topic=31862.msg494503#msg494503

namespace OffsetPolylineSample
{
    /// <summary>
    /// Provides the Offset() extension method for the Polyline type
    /// </summary>
    public static class PolylineExtension
    {
        /// <summary>
        /// Enumeration of offset side options
        /// </summary>
        public enum OffsetSide
        {
            In, Out, Left, Right, Both
        }

        /// <summary>
        /// Offset the source polyline to specified side(s).
        /// </summary>
        /// <param name="source">The polyline to be offseted.</param>
        /// <param name="offsetDist">The offset distance.</param>
        /// <param name="side">The offset side(s).</param>
        /// <returns>A polyline sequence resulting from the offset of the source polyline.</returns>
        public static IEnumerable<Polyline> Offset(this Polyline source, double offsetDist, OffsetSide side)
        {
            offsetDist = Math.Abs(offsetDist);
            using (var plines = new DisposableSet<Polyline>())
            {
                IEnumerable<Polyline> offsetRight = source.GetOffsetCurves(offsetDist).Cast<Polyline>();
                plines.UnionWith(offsetRight);
                IEnumerable<Polyline> offsetLeft = source.GetOffsetCurves(-offsetDist).Cast<Polyline>();
                plines.UnionWith(offsetLeft);
                double areaRight = offsetRight.Select(pline => pline.Area).Sum();
                double areaLeft = offsetLeft.Select(pline => pline.Area).Sum();
                switch (side)
                {
                    case OffsetSide.In:
                        return plines.RemoveRange(
                           areaRight < areaLeft ? offsetRight : offsetLeft);
                    case OffsetSide.Out:
                        return plines.RemoveRange(
                           areaRight < areaLeft ? offsetLeft : offsetRight);
                    case OffsetSide.Left:
                        return plines.RemoveRange(offsetLeft);
                    case OffsetSide.Right:
                        return plines.RemoveRange(offsetRight);
                    case OffsetSide.Both:
                        plines.Clear();
                        return offsetRight.Concat(offsetLeft);
                    default:
                        return null;
                }
            }
        }
    }

    /// <summary>
    /// Represents a set of disposable values.
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class DisposableSet<T> : HashSet<T>, IDisposable
        where T : IDisposable
    {
        /// <summary>
        /// Disposes all items of the current DisposableSet object.
        /// </summary>
        public void Dispose()
        {
            if (base.Count > 0)
            {
                System.Exception last = null;
                foreach (T item in this)
                {
                    if (item != null)
                    {
                        try
                        {
                            item.Dispose();
                        }
                        catch (System.Exception ex)
                        {
                            last = last ?? ex;
                        }
                    }
                }
                this.Clear();
                if (last != null)
                    throw last;
            }
        }

        /// <summary>
        /// Removes all elements in the specified collection from the current DisposableSet object.
        /// </summary>
        /// <param name="items">The collection of items to remove from the current DisposableSet object.</param>
        /// <returns>The collection of items to remove.</returns>
        public IEnumerable<T> RemoveRange(IEnumerable<T> items)
        {
            base.ExceptWith(items);
            return items;
        }
    }
}
53
Polylines / Re: Offset curve toward centroid
« Last post by bcinnv on March 18, 2013, 02:23:53 AM »
YOU GUYS ROCK!
54
Layouts and printing / Plot to multi sheets PDF
« Last post by (gile) on March 17, 2013, 11:22:01 AM »
Hi,

Here's a little class to be used to plot layouts to a single multi sheets PDF file.

Code: [Select]
using System.Collections.Generic;
using System.IO;
using System.Text;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.PlottingServices;
using Autodesk.AutoCAD.Publishing;
using AcAp = Autodesk.AutoCAD.ApplicationServices.Application;

namespace Plottings
{
    public class MultiSheetsPdf
    {
        private string dwgFile, pdfFile, dsdFile, outputDir;
        private int sheetNum;
        IEnumerable<Layout> layouts;

        private const string LOG = "publish.log";

        public MultiSheetsPdfPlot(string pdfFile, IEnumerable<Layout> layouts)
        {
            Database db = HostApplicationServices.WorkingDatabase;
            this.dwgFile = db.Filename;
            this.pdfFile = pdfFile;
            this.outputDir = Path.GetDirectoryName(this.pdfFile);
            this.dsdFile = Path.ChangeExtension(this.pdfFile, "dsd");
            this.layouts = layouts;
        }

        public void Publish()
        {
            if (TryCreateDSD())
            {
                Publisher publisher = AcAp.Publisher;
                PlotProgressDialog plotDlg = new PlotProgressDialog(false, this.sheetNum, true);
                publisher.PublishDsd(this.dsdFile, plotDlg);
                plotDlg.Destroy();
                File.Delete(this.dsdFile);
            }
        }

        private bool TryCreateDSD()
        {
            using (DsdData dsd = new DsdData())
            using (DsdEntryCollection dsdEntries = CreateDsdEntryCollection(this.layouts))
            {
                if (dsdEntries == null || dsdEntries.Count <= 0) return false;

                if (!Directory.Exists(this.outputDir))
                    Directory.CreateDirectory(this.outputDir);

                this.sheetNum = dsdEntries.Count;

                dsd.SetDsdEntryCollection(dsdEntries);

                dsd.SetUnrecognizedData("PwdProtectPublishedDWF", "FALSE");
                dsd.SetUnrecognizedData("PromptForPwd", "FALSE");
                dsd.SheetType = SheetType.MultiDwf;
                dsd.NoOfCopies = 1;
                dsd.DestinationName = this.pdfFile;
                dsd.IsHomogeneous = false;
                dsd.LogFilePath = Path.Combine(this.outputDir, LOG);

                PostProcessDSD(dsd);

                return true;
            }
        }

        private DsdEntryCollection CreateDsdEntryCollection(IEnumerable<Layout> layouts)
        {
            DsdEntryCollection entries = new DsdEntryCollection();

            foreach (Layout layout in layouts)
            {
                DsdEntry dsdEntry = new DsdEntry();
                dsdEntry.DwgName = this.dwgFile;
                dsdEntry.Layout = layout.LayoutName;
                dsdEntry.Title = Path.GetFileNameWithoutExtension(this.dwgFile) + "-" + layout.LayoutName;
                dsdEntry.Nps = layout.TabOrder.ToString();
                entries.Add(dsdEntry);
            }
            return entries;
        }

        private void PostProcessDSD(DsdData dsd)
        {
            string str, newStr;
            string tmpFile = Path.Combine(this.outputDir, "temp.dsd");

            dsd.WriteDsd(tmpFile);

            using (StreamReader reader = new StreamReader(tmpFile, Encoding.Default))
            using (StreamWriter writer = new StreamWriter(this.dsdFile, false, Encoding.Default))
            {
                while (!reader.EndOfStream)
                {
                    str = reader.ReadLine();
                    if (str.Contains("Has3DDWF"))
                    {
                        newStr = "Has3DDWF=0";
                    }
                    else if (str.Contains("OriginalSheetPath"))
                    {
                        newStr = "OriginalSheetPath=" + this.dwgFile;
                    }
                    else if (str.Contains("Type"))
                    {
                        newStr = "Type=6";
                    }
                    else if (str.Contains("OUT"))
                    {
                        newStr = "OUT=" + this.outputDir;
                    }
                    else if (str.Contains("IncludeLayer"))
                    {
                        newStr = "IncludeLayer=TRUE";
                    }
                    else if (str.Contains("PromptForDwfName"))
                    {
                        newStr = "PromptForDwfName=FALSE";
                    }
                    else if (str.Contains("LogFilePath"))
                    {
                        newStr = "LogFilePath=" + Path.Combine(this.outputDir, LOG);
                    }
                    else
                    {
                        newStr = str;
                    }
                    writer.WriteLine(newStr);
                }
            }
            File.Delete(tmpFile);
        }
    }
}

Using example which creates a new instance of MultiSheetsPdf passing to the constructor the current drawing file name with "pdf" extension and all layouts except "Model":
Code: [Select]
        [CommandMethod("PlotPdf")]
        public void PlotPdf()
        {
            Database db = HostApplicationServices.WorkingDatabase;
            short bgp = (short)AcAp.GetSystemVariable("BACKGROUNDPLOT");
            try
            {
                AcAp.SetSystemVariable("BACKGROUNDPLOT", 0);
                using (Transaction tr = db.TransactionManager.StartTransaction())
                {
                    List<Layout> layouts = new List<Layout>();
                    DBDictionary layoutDict =
                        (DBDictionary)db.LayoutDictionaryId.GetObject(OpenMode.ForRead);
                    foreach (DBDictionaryEntry entry in layoutDict)
                    {
                        if (entry.Key != "Model")
                        {
                            layouts.Add((Layout)tr.GetObject(entry.Value, OpenMode.ForRead));
                        }
                    }
                    layouts.Sort((l1, l2) => l1.TabOrder.CompareTo(l2.TabOrder));

                    string filename = Path.ChangeExtension(db.Filename, "pdf");

                    MultiSheetsPdf plotter = new MultiSheetsPdf(filename, layouts);
                    plotter.Publish();

                    tr.Commit();
                }
            }
            catch (System.Exception e)
            {
                Editor ed = AcAp.DocumentManager.MdiActiveDocument.Editor;
                ed.WriteMessage("\nError: {0}\n{1}", e.Message, e.StackTrace);
            }
            finally
            {
                AcAp.SetSystemVariable("BACKGROUNDPLOT", bgp);
            }
        }
55
Polylines / Re: Offset curve toward centroid
« Last post by (gile) on March 17, 2013, 09:28:39 AM »
Hi,

To get a Polyline centroid, an easier (and faster) way is to add to your project the GeometryExtensions.dll and simply call the Polyline.Centroid() extension method.

To insure offseting inside a (closed) polyline, you can offset it on both sides and compare the resulting polylines areas.
Here's a little sample which uses this way.

In the PolylineExtension static class, the Polyline.Offset() extension method is defined. This method can be called as an instance method and requires an argument to specify the offset side. This argument is a member of the OffsetSide enum defined in the PolylineExtension class too.

The PolylineExtension class:
Code: [Select]
using System;
using System.Collections.Generic;
using System.Linq;
using Autodesk.AutoCAD.DatabaseServices;

namespace OffsetPolylineSample
{
    /// <summary>
    /// Provides a Offset() extension methode for the Polyline type
    /// </summary>
    public static class PolylineExtension
    {
        /// <summary>
        /// Enumeration of offset side options
        /// </summary>
        public enum OffsetSide { In, Out, Left, Right, Both }

        /// <summary>
        /// Offset the source polyline to specified side(s).
        /// </summary>
        /// <param name="source">The polyline to be offseted.</param>
        /// <param name="offsetDist">The offset distance.</param>
        /// <param name="side">The offset side(s).</param>
        /// <returns>A polyline sequence resulting from the offset of the source polyline.</returns>
        public static IEnumerable<Polyline> Offset(this Polyline source, double offsetDist, OffsetSide side)
        {
            offsetDist = Math.Abs(offsetDist);
            IEnumerable<Polyline> offsetRight = source.GetOffsetCurves(offsetDist).Cast<Polyline>();
            double areaRight = offsetRight.Select(pline => pline.Area).Sum();
            IEnumerable<Polyline> offsetLeft = source.GetOffsetCurves(-offsetDist).Cast<Polyline>();
            double areaLeft = offsetLeft.Select(pline => pline.Area).Sum();
            switch (side)
            {
                case OffsetSide.In:
                    if (areaRight < areaLeft)
                    {
                        offsetLeft.Dispose();
                        return offsetRight;
                    }
                    else
                    {
                        offsetRight.Dispose();
                        return offsetLeft;
                    }
                case OffsetSide.Out:
                    if (areaRight < areaLeft)
                    {
                        offsetRight.Dispose();
                        return offsetLeft;
                    }
                    else
                    {
                        offsetLeft.Dispose();
                        return offsetRight;
                    }
                case OffsetSide.Left:
                    offsetRight.Dispose();
                    return offsetLeft;
                case OffsetSide.Right:
                    offsetLeft.Dispose();
                    return offsetRight;
                case OffsetSide.Both:
                    return offsetRight.Concat(offsetLeft);
                default:
                    return null;
            }
        }

        private static void Dispose(this IEnumerable<Polyline> plines)
        {
            foreach (Polyline pline in plines)
            {
                pline.Dispose();
            }
        }
    }
}

A testing command:
Code: [Select]
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Runtime;

namespace OffsetPolylineSample
{
    public class CommandMethods
    {
        [CommandMethod("Test", CommandFlags.Modal)]
        public void Test()
        {
            Document doc = Application.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;
            Editor ed = doc.Editor;

            PromptDistanceOptions pdo =
                new PromptDistanceOptions("\nSpecify the offset distance: ");
            pdo.AllowZero = false;
            PromptDoubleResult pdr = ed.GetDistance(pdo);
            if (pdr.Status != PromptStatus.OK) return;
            double offsetDist = pdr.Value;

            PromptKeywordOptions pko =
                new PromptKeywordOptions("\nEnter the offset side [In/Out/Left/Right/Both]", "In Out Left Right Both");
            PromptResult pr = ed.GetKeywords(pko);
            if (pr.Status != PromptStatus.OK) return;
            PolylineExtension.OffsetSide side;
            switch (pr.StringResult)
            {
                case "In": side = PolylineExtension.OffsetSide.In; break;
                case "Out": side = PolylineExtension.OffsetSide.Out; break;
                case "Left": side = PolylineExtension.OffsetSide.Left; break;
                case "Right": side = PolylineExtension.OffsetSide.Right; break;
                default: side = PolylineExtension.OffsetSide.Both; break;
            }

            PromptEntityOptions peo = new PromptEntityOptions("\nSelect a polyline: ");
            peo.SetRejectMessage("Only a polyline !");
            peo.AddAllowedClass(typeof(Polyline), true);

            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                BlockTableRecord btr = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite);
                while (true)
                {
                    PromptEntityResult per = ed.GetEntity(peo);
                    if (per.Status != PromptStatus.OK) break;

                    Polyline pline = (Polyline)tr.GetObject(per.ObjectId, OpenMode.ForRead);
                    foreach (Polyline pl in pline.Offset(offsetDist, side))
                    {
                        btr.AppendEntity(pl);
                        tr.AddNewlyCreatedDBObject(pl, true);
                    }
                    db.TransactionManager.QueueForGraphicsFlush();
                }
                tr.Commit();
            }
        }
    }
}
56
Selection sets / Move selection to origin
« Last post by fixo on March 17, 2013, 07:39:16 AM »
      C#
   
Code: [Select]
        [System.Security.SuppressUnmanagedCodeSecurity]
        [DllImport("acad.exe", EntryPoint = "acedCmd", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)]
        extern static private int acedCmd(IntPtr resbuf);

        [CommandMethod("moveToOrig, mto", CommandFlags.UsePickSet | CommandFlags.Redraw)]
        static public void testMoveToOrigin()
        {
            Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
            Editor ed = doc.Editor;
            Database db = doc.Database;
            ResultBuffer rb = new ResultBuffer();
            try
            {

                rb.Add(new TypedValue(5005, "_Zoom"));
                rb.Add(new TypedValue(5005, "_Extents"));
                acedCmd(rb.UnmanagedObject);

                Matrix3d ucs = ed.CurrentUserCoordinateSystem;
                CoordinateSystem3d ccos = ucs.CoordinateSystem3d;
                Point3d orig = ccos.Origin.TransformBy(Matrix3d.Identity);
                // select all objects
                SelectionSet sset = ed.SelectAll().Value;
                if (sset == null) return;
                List<Point3d> pts = new List<Point3d>();
                List<Entity> ents = new List<Entity>();
                Matrix3d mmx = new Matrix3d();
                using (Transaction tr = doc.TransactionManager.StartTransaction())
                {
                    // iterate through selected objects
                    foreach (ObjectId id in sset.GetObjectIds())
                    {

                        Entity ent = (Entity)tr.GetObject(id, OpenMode.ForRead, false);

                        Extents3d ext = ent.GeometricExtents;
                        if (ext != null)
                        {
                            Point3d minpt = ext.MinPoint.TransformBy(Matrix3d.Identity);
                            // collect entities to List for the future work
                            ents.Add(ent);
                            pts.Add(minpt);
                        }
                    }
                    // Get most lower left point of screen
                    Point3d xpt = pts.OrderBy(p => p.X).First();// calculate minimal X value
                    Point3d ypt = pts.OrderBy(p => p.Y).First();// calculate minimal Y value
                 Point3d mp = new Point3d(xpt.X, ypt.Y, orig.Z).TransformBy(Matrix3d.Identity);
                    mmx = Matrix3d.Displacement(orig-mp );
                    // iterate through gathrered entities again
                    foreach (Entity e in ents)
                    {
                        e.UpgradeOpen();
                        // apply transformation matrix
                        e.TransformBy(mmx);
                    }

                    tr.Commit();
                }
            }
            catch (Autodesk.AutoCAD.Runtime.Exception ex)
            {
                ed.WriteMessage("\n" + ex.Message + "\n" + ex.StackTrace);
            }
            finally
            {
                rb = new ResultBuffer();
                rb.Add(new TypedValue(5005, "_Zoom"));
                rb.Add(new TypedValue(5005, "_Extents"));
                acedCmd(rb.UnmanagedObject);
            }
        }

      VB.NET

      
Code: [Select]
<System.Security.SuppressUnmanagedCodeSecurity> _
<DllImport("acad.exe", EntryPoint := "acedCmd", CharSet := CharSet.Unicode, CallingConvention := CallingConvention.Cdecl)> _
Private Shared Function acedCmd(resbuf As IntPtr) As Integer
End Function

<CommandMethod("moveToOrig, mto", CommandFlags.UsePickSet Or CommandFlags.Redraw)> _
Public Shared Sub testMoveToOrigin()
Dim doc As Document = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument
Dim ed As Editor = doc.Editor
Dim db As Database = doc.Database
Dim rb As New ResultBuffer()
Try

rb.Add(New TypedValue(5005, "_Zoom"))
rb.Add(New TypedValue(5005, "_Extents"))
acedCmd(rb.UnmanagedObject)

Dim ucs As Matrix3d = ed.CurrentUserCoordinateSystem
Dim ccos As CoordinateSystem3d = ucs.CoordinateSystem3d
Dim orig As Point3d = ccos.Origin.TransformBy(Matrix3d.Identity)
' select all objects
Dim sset As SelectionSet = ed.SelectAll().Value
If sset Is Nothing Then
Return
End If
Dim pts As New List(Of Point3d)()
Dim ents As New List(Of Entity)()
Dim mmx As New Matrix3d()
Using tr As Transaction = doc.TransactionManager.StartTransaction()
' iterate through selected objects
For Each id As ObjectId In sset.GetObjectIds()

Dim ent As Entity = DirectCast(tr.GetObject(id, OpenMode.ForRead, False), Entity)

Dim ext As Extents3d = ent.GeometricExtents
If ext IsNot Nothing Then
Dim minpt As Point3d = ext.MinPoint.TransformBy(Matrix3d.Identity)
' collect entities to List for the future work
ents.Add(ent)
pts.Add(minpt)
End If
Next
' Get most lower left point of screen
Dim xpt As Point3d = pts.OrderBy(Function(p) p.X).First()
' calculate minimal X value
Dim ypt As Point3d = pts.OrderBy(Function(p) p.Y).First()
' calculate minimal Y value
Dim mp As Point3d = New Point3d(xpt.X, ypt.Y, orig.Z).TransformBy(Matrix3d.Identity)
mmx = Matrix3d.Displacement(orig - mp)
' iterate through gathrered entities again
For Each e As Entity In ents
e.UpgradeOpen()
' apply transformation matrix
e.TransformBy(mmx)
Next

tr.Commit()
End Using
Catch ex As Autodesk.AutoCAD.Runtime.Exception
ed.WriteMessage((vbLf + ex.Message & vbLf) + ex.StackTrace)
Finally
rb = New ResultBuffer()
rb.Add(New TypedValue(5005, "_Zoom"))
rb.Add(New TypedValue(5005, "_Extents"))
acedCmd(rb.UnmanagedObject)
End Try
End Sub
57
Polylines / Re: Offset curve toward centroid
« Last post by bcinnv on March 17, 2013, 12:37:31 AM »
Thanks! But not always centroid I think, it's different for "I" and "moon" shapes.  Should just say Offset Polyline to Inside :). Works wonderfully though!

I do think I found a method to find the actual centroid... perhaps there's a way to find the offset closest to it and keep it?  I'm new at programming but here's the code I came up with to get the centroid for you to "fix" as you see fit :)

Code: [Select]
// get centroid of polygon


namespace BCCGETCENTROIDCOMMAND
{
    public class BCCGETCENTROIDCOM
    {

        [CommandMethod("BCC:CENTROID")]

        public static void BCCGETCENTROID()
        {

            // Get the current document and database

            Document acDoc = Application.DocumentManager.MdiActiveDocument;
            Database acCurDb = acDoc.Database;
            Editor ed = acDoc.Editor;
            Transaction tr = acCurDb.TransactionManager.StartTransaction();

            // Start a transaction

            using (tr)
            {

            SelectionFilter sf = new SelectionFilter(new TypedValue[1] { new TypedValue((int)DxfCode.Start, "LWPolyline") });//<<<--- a selection filter to get text only
            PromptSelectionResult objects = ed.GetSelection(sf);
            if (objects.Status != PromptStatus.OK) return;
            List<Polyline> polylines = new List<Polyline>();

            foreach (ObjectId oid in objects.Value.GetObjectIds())
            {
                DBObject ent = tr.GetObject(oid, OpenMode.ForWrite);
                Polyline p = ent as Polyline;

                // add the polylines to the array
                DBObjectCollection dbobjs = new DBObjectCollection();
                dbobjs.Add(ent);
                // create solid to get region and centroid
                Solid3d Solid = new Solid3d();
                Solid.Extrude(((Region)Region.CreateFromCurves(dbobjs)[0]), 1, 0);
                Point2d centroid = new Point2d(Solid.MassProperties.Centroid.X, Solid.MassProperties.Centroid.Y);
                Solid.Dispose();

                BlockTable acBlkTbl = tr.GetObject(acCurDb.BlockTableId, OpenMode.ForRead) as BlockTable;
                BlockTableRecord acBlkTblRec; acBlkTblRec = tr.GetObject(acBlkTbl[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord;
                DBPoint acPoint = new DBPoint(new Point3d(centroid.X, centroid.Y,0));
                acBlkTblRec.AppendEntity(acPoint);
                tr.AddNewlyCreatedDBObject(acPoint, true);
                acCurDb.Pdmode = 99;
                acCurDb.Pdsize = 1;                     
            }

                // Save the new objects to the database
                tr.Commit();
            }

        }
    }
}

58
Dimensions / Re: Some basic dimensions function
« Last post by fixo on March 16, 2013, 06:54:40 AM »
Ok, will be glad to see your final solution,
Kind regards,
Oleg
59
Dimensions / Re: Some basic dimensions function
« Last post by dockee on March 15, 2013, 09:54:33 PM »
It's not necessary. I find solution. My calculaltion on angle is not right.

When i finalize my project, i Put a picture with the part of code.

Thanks.

60
Blocks / Change text object in block reference
« Last post by fixo on March 15, 2013, 04:57:16 PM »
   C#
Code: [Select]
     
        // Change the text object in the BlockTableRecord by selecting them on screen
        // This method may have any name
        [CommandMethod("cato", CommandFlags.UsePickSet | CommandFlags.Redraw)]
        public static void ChangeTextInBlockDef()
        {
            Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;

            Database db = doc.Database;

            Editor ed = doc.Editor;

            Transaction tr = db.TransactionManager.StartTransaction();
            using (tr)
            {
                doc.TransactionManager.EnableGraphicsFlush(true);
                PromptNestedEntityOptions pno = new PromptNestedEntityOptions("\nSelect text within block instance: ");
                pno.AllowNone = true;
                pno.UseNonInteractivePickPoint = false;
                PromptNestedEntityResult rs = ed.GetNestedEntity(pno);
                if (rs.Status != PromptStatus.OK) return;
                Entity selent = (Entity)tr.GetObject(rs.ObjectId, OpenMode.ForRead);
                ed.WriteMessage("\nSelected type of {0}", selent.GetType().Name);

                PromptStringOptions pso = new PromptStringOptions("\nEnter new text: ");
                pso.AllowSpaces = true;
                PromptResult res;
                res = ed.GetString(pso);
                if (res.Status != PromptStatus.OK) return;
                string newstr = res.StringResult;
                ed.WriteMessage("\nNew Text Entered:\t{0}", newstr);

                BlockTableRecord btrec = tr.GetObject(selent.OwnerId, OpenMode.ForWrite) as BlockTableRecord;
                // prevent work with attributes and embedded blocks
                if (selent.ObjectId.ObjectClass.IsDerivedFrom(RXClass.GetClass(typeof(AttributeReference))) |
                    selent.ObjectId.ObjectClass.IsDerivedFrom(RXClass.GetClass(typeof(BlockReference)))) return;
                if (selent.ObjectId.ObjectClass.IsDerivedFrom(RXClass.GetClass(typeof(DBText))))
                {
                    DBText txt = selent as DBText;
                    string oldstr = txt.TextString;

                    BlockTableRecord owner = (BlockTableRecord)tr.GetObject(txt.OwnerId, OpenMode.ForRead);
                    ed.WriteMessage("\nName:\t{0}", owner.Name);
                    owner.UpgradeOpen();
                    foreach (ObjectId id in owner)
                    {
                        if (!id.ObjectClass.IsDerivedFrom(RXClass.GetClass(typeof(DBText)))) continue;
                        DBObject obj = tr.GetObject(id, OpenMode.ForRead);
                        DBText blktxt = obj as DBText;
                        if (blktxt.TextString != oldstr) continue;
                        blktxt.UpgradeOpen();
                        blktxt.TextString = newstr;

                    }

                    //--------------------------------------------------------------
                    // add other possible types such as mtext, dimension etc here
                    //--------------------------------------------------------------


                    tr.TransactionManager.QueueForGraphicsFlush();

                    doc.TransactionManager.FlushGraphics();

                    tr.Commit();

                    ed.Regen();
                }
            }
        }

   VB.NET
Code: [Select]
        ' Change the text object in the BlockTableRecord by selecting them on screen
        ' This method may have any name
        <CommandMethod("cato", CommandFlags.UsePickSet Or CommandFlags.Redraw)> _
        Public Shared Sub ChangeTextInBlockDef()
            Dim doc As Document = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument

            Dim db As Database = doc.Database

            Dim ed As Editor = doc.Editor

            Dim tr As Transaction = db.TransactionManager.StartTransaction()
            Using tr
                doc.TransactionManager.EnableGraphicsFlush(True)
                Dim pno As New PromptNestedEntityOptions(vbLf & "Select text within block instance: ")
                pno.AllowNone = True
                pno.UseNonInteractivePickPoint = False
                Dim rs As PromptNestedEntityResult = ed.GetNestedEntity(pno)
                If rs.Status <> PromptStatus.OK Then
                    Return
                End If
                Dim selent As Entity = DirectCast(tr.GetObject(rs.ObjectId, OpenMode.ForRead), Entity)
                ed.WriteMessage(vbLf & "Selected type of {0}", selent.[GetType]().Name)

                Dim pso As New PromptStringOptions(vbLf & "Enter new text: ")
                pso.AllowSpaces = True
                Dim res As PromptResult
                res = ed.GetString(pso)
                If res.Status <> PromptStatus.OK Then
                    Return
                End If
                Dim newstr As String = res.StringResult
                ed.WriteMessage(vbLf & "New Text Entered:" & vbTab & "{0}", newstr)

                Dim btrec As BlockTableRecord = TryCast(tr.GetObject(selent.OwnerId, OpenMode.ForWrite), BlockTableRecord)
                ' prevent work with attributes and embedded blocks
                If selent.ObjectId.ObjectClass.IsDerivedFrom(RXClass.GetClass(GetType(AttributeReference))) Or selent.ObjectId.ObjectClass.IsDerivedFrom(RXClass.GetClass(GetType(BlockReference))) Then
                    Return
                End If
                If selent.ObjectId.ObjectClass.IsDerivedFrom(RXClass.GetClass(GetType(DBText))) Then
                    Dim txt As DBText = TryCast(selent, DBText)
                    Dim oldstr As String = txt.TextString

                    Dim owner As BlockTableRecord = DirectCast(tr.GetObject(txt.OwnerId, OpenMode.ForRead), BlockTableRecord)
                    ed.WriteMessage(vbLf & "Name:" & vbTab & "{0}", owner.Name)
                    owner.UpgradeOpen()
                    For Each id As ObjectId In owner
                        If Not id.ObjectClass.IsDerivedFrom(RXClass.GetClass(GetType(DBText))) Then
                            Continue For
                        End If
                        Dim obj As DBObject = tr.GetObject(id, OpenMode.ForRead)
                        Dim blktxt As DBText = TryCast(obj, DBText)
                        If blktxt.TextString <> oldstr Then
                            Continue For
                        End If
                        blktxt.UpgradeOpen()

                        blktxt.TextString = newstr
                    Next

                    '--------------------------------------------------------------
                    ' add other possible types such as mtext, dimension etc here
                    '--------------------------------------------------------------


                    tr.TransactionManager.QueueForGraphicsFlush()

                    doc.TransactionManager.FlushGraphics()

                    tr.Commit()

                    ed.Regen()
                End If
            End Using
        End Sub
Pages: 1 ... 4 5 [6] 7 8 ... 10