找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 1165|回复: 3

[分享] Offset curve toward centroid

[复制链接]

已领礼包: 859个

财富等级: 财运亨通

发表于 2014-6-7 01:03:10 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
        [CommandMethod("OFT")]
        public static void OffsetTowardCentroid()
        {
            Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;

            Editor ed = doc.Editor;

            Database db = doc.Database;

            Transaction tr = doc.TransactionManager.StartTransaction();

                using (tr)
                {
                    try
                    {
                        BlockTableRecord btr = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite);

                        PromptEntityOptions peo = new PromptEntityOptions("\nSelect curve to Offset Toward: ");

                        peo.SetRejectMessage("\nSelect curve only: ");

                        peo.AddAllowedClass(typeof(Line), true);

                        peo.AddAllowedClass(typeof(Arc), true);

                        peo.AddAllowedClass(typeof(Circle), true);

                        peo.AddAllowedClass(typeof(Ellipse), true);

                        peo.AddAllowedClass(typeof(Polyline), true);

                        peo.AddAllowedClass(typeof(Spline), true);

                        PromptEntityResult pres = ed.GetEntity(peo);

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

                        Entity ent = (Entity)tr.GetObject(pres.ObjectId, OpenMode.ForRead);

                        // add the polylines to the array
                        DBObjectCollection dbobjs = new DBObjectCollection();
                        dbobjs.Add(ent);
                        // create the region
                        Region objreg = new Region();

                        DBObjectCollection objRegions = new DBObjectCollection();

                        objRegions = Region.CreateFromCurves(dbobjs);

                        objreg = objRegions[0] as Region;
                        
                        Curve curv = ent as Curve;

                        PromptDoubleResult dres = ed.GetDouble("\nDistance for Offset: ");

                        double dist = dres.Value;

                        DBObjectCollection ids = curv.GetOffsetCurves(dist);
                        DBObjectCollection ids2 = curv.GetOffsetCurves(-1 * dist);
                       double leg= ((ids[0]) as Curve).Area;
                       double leg2 = ((ids2[0]) as Curve).Area;
                       if (leg - leg2 < 0)
                       {
                           foreach (Entity oEnt in ids)
                           {
                               btr.AppendEntity(oEnt);
                               tr.AddNewlyCreatedDBObject(oEnt, true);
                           }
                       }
                       else
                       {

                           foreach (Entity oEnt in ids2)
                           {
                               btr.AppendEntity(oEnt);
                               tr.AddNewlyCreatedDBObject(oEnt, true);
                           }
                       }
                       
                       objRegions.Dispose();
                       ids.Dispose();
                       ids2.Dispose();
                       doc.TransactionManager.FlushGraphics();
                        tr.Commit();
                        ed.UpdateScreen();
                    }

                    catch (Autodesk.AutoCAD.Runtime.Exception ex)
                    {
                        ed.WriteMessage("\nError: {0}\nTrace: {1}", ex.Message, ex.StackTrace);
                    }
                }
            }
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

已领礼包: 859个

财富等级: 财运亨通

 楼主| 发表于 2014-6-7 01:03:45 | 显示全部楼层
// 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();
            }

        }
    }
}
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 859个

财富等级: 财运亨通

 楼主| 发表于 2014-6-7 01:04:42 | 显示全部楼层
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();
            }
        }
    }
}

论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 859个

财富等级: 财运亨通

 楼主| 发表于 2014-6-7 01:05:54 | 显示全部楼层
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;
        }
    }
}
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|申请友链|Archiver|手机版|小黑屋|辽公网安备|晓东CAD家园 ( 辽ICP备15016793号 )

GMT+8, 2024-12-18 23:41 , Processed in 0.392798 second(s), 33 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表