乐筑天下

搜索
欢迎各位开发者和用户入驻本平台 尊重版权,从我做起,拒绝盗版,拒绝倒卖 签到、发布资源、邀请好友注册,可以获得银币 请注意保管好自己的密码,避免账户资金被盗
查看: 157|回复: 12

Creating an AutoCAD polyline from an exploded region

[复制链接]

3

主题

19

帖子

1

银币

初来乍到

Rank: 1

铜币
31
发表于 2012-7-17 15:39:37 | 显示全部楼层 |阅读模式
'the code came from
'Through the Interface
'by Kean Walmsley
'August 25, 2008
'Creating an AutoCAD polyline from an exploded region using .NET
' Create a plane to convert 3D coords
' into Region coord system
Dim pl As New Plane(New Point3d(0, 0, 0), reg.Normal)
'Code to make the PLine
' The resulting Polyline
Dim p As New Polyline()
' Once we have added all the Polyline's vertices,
' transform it to the original region's plane
p.TransformBy(Matrix3d.PlaneToWorld(pl))
'the above code works if the region was drawn flat with a 0 elevation.
'if the region was drawn in some other elevation then the new pLine
'will not be in the same location as the region was.
'so here is my work around for that, but was wondering if there is a better way of doing it?
'im still trying to learn .net so any help would be great.
'I would prefer to learn the right way, instead of using my work around.
Dim bp As Brep = New Brep(reg)
'get a point for the Region
Dim RegPoint3d As Point3d = bp.Vertices.GetEnumerator().Current.Point
'convert the 3d point to the pline plane
Dim NewPoint2d As Point2d = RegPoint3d.Convert2d(pl)
'convert the 2D point to a 3D point
Dim TempPoint3d As Point3d = New Point3d(NewPoint2d.X, NewPoint2d.Y, 0)
' transform it to the original region's plane
Dim NewPoint3d As Point3d = TempPoint3d.TransformBy(Matrix3d.PlaneToWorld(pl))
'Get Vector3D
Dim NewVector3d As Vector3d = NewPoint3d.GetVectorTo(RegPoint3d)
'move back to the same place were the region was
p.TransformBy(Matrix3d.Displacement(NewVector3d))
回复

使用道具 举报

1

主题

1069

帖子

1050

银币

初露锋芒

Rank: 3Rank: 3Rank: 3

铜币
69
发表于 2012-7-17 16:41:43 | 显示全部楼层
  1. _
  2.         Public Shared Sub CreateRegionFromConnected()
  3.             Dim doc As Document = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument
  4.             Dim ed As Editor = doc.Editor
  5.             Dim db As Database = doc.Database
  6.             Dim objs As New DBObjectCollection()
  7.             Dim regcoll As New DBObjectCollection()
  8.             Using tr As Transaction = db.TransactionManager.StartTransaction()
  9.                 Dim btr As BlockTableRecord = TryCast(tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite), BlockTableRecord)
  10.                 Dim tvs As TypedValue() = New TypedValue() {New TypedValue(0, "line,arc,polyline")}
  11.                 Dim points As New Point3dCollection()
  12.                 Dim sf As New SelectionFilter(tvs)
  13.                 Dim sres As PromptSelectionResult = ed.GetSelection(sf)
  14.                 If sres.Status  PromptStatus.OK Then
  15.                     ed.WriteMessage(vbLf & "Invalid selection!")
  16.                     Return
  17.                 End If
  18.                 For Each selobj As SelectedObject In sres.Value
  19.                     Dim obj As DBObject = TryCast(tr.GetObject(selobj.ObjectId, OpenMode.ForWrite, False), DBObject)
  20.                     objs.Add(obj)
  21.                 Next
  22.                 regcoll = Region.CreateFromCurves(objs)
  23.                 Dim reg As Region = TryCast(regcoll(0), Region)
  24.                 btr.AppendEntity(reg)
  25.                 tr.AddNewlyCreatedDBObject(reg, True)
  26.                 ' you might be want to remove parent objects here  //
  27.                 tr.Commit()
  28.             End Using
  29.         End Sub
回复

使用道具 举报

3

主题

19

帖子

1

银币

初来乍到

Rank: 1

铜币
31
发表于 2012-7-17 17:01:02 | 显示全部楼层
Thank you
回复

使用道具 举报

1

主题

1069

帖子

1050

银币

初露锋芒

Rank: 3Rank: 3Rank: 3

铜币
69
发表于 2012-7-17 17:06:10 | 显示全部楼层
You're welcome
回复

使用道具 举报

2

主题

31

帖子

1

银币

初来乍到

Rank: 1

铜币
39
发表于 2012-7-17 18:43:36 | 显示全部楼层
Exploding a region results in a variety of primitives, but never a polyline.
It doesn't look like Fixo's code will create a polyline, and you need to keep
in mind that regions can contain ACIS curves (splines, ellipses, etc.), that
cannot be joined to form a polyline directly. As long as you know that your
regions are not comprised of ACIS entities, you can just use the PEDIT/Join
subcommand to convert the primitives produced by exploding the region
to a polyline.
回复

使用道具 举报

15

主题

687

帖子

169

银币

中流砥柱

Rank: 25

铜币
582
发表于 2012-7-18 02:27:43 | 显示全部楼层
Hi,
Here's a solution which seems to work wharever the region normal and elevation.
It works with regions containing 'holes' (creates a ployline for the outerloop and one foreach inner loop).
The code uses the PolylineSegment and PolylineSegmentCollection classes defined in the GeometryExtensions library.
[ol]using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.Runtime;
using GeometryExtensions;

namespace RegionToPolyline
{
    public class Commands
    {
        [CommandMethod("Test")]
        public void Test()
        {
            Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
            PromptEntityOptions peo = new PromptEntityOptions("\nSelect a region: ");
            peo.SetRejectMessage("Only a region !");
            peo.AddAllowedClass(typeof(Region), true);
            PromptEntityResult per = ed.GetEntity(peo);
            if (per.Status != PromptStatus.OK) return;
            RegionToPolyline(per.ObjectId, false);
        }

        public ObjectIdCollection RegionToPolyline(ObjectId regId, bool erase)
        {
            Database db = regId.Database;
            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                Region reg = (Region)tr.GetObject(regId, OpenMode.ForRead);
                BlockTableRecord btr = (BlockTableRecord)tr.GetObject(reg.OwnerId, OpenMode.ForWrite);

                Plane plane = new Plane(Point3d.Origin, reg.Normal);
                Extents3d ext = reg.GeometricExtents;
                Point3d pt = new Point3d();

                PolylineSegmentCollection segCol = new PolylineSegmentCollection();
                using (DBObjectCollection segments = new DBObjectCollection())
                {
                    reg.Explode(segments);
                    for (int i = 0; i
                    {
                        DBObject obj = segments;
                        switch (obj.GetType().Name)
                        {
                            case "Line":
                                Line line = (Line)obj;
                                pt = line.StartPoint;
                                LineSegment2d ls = new LineSegment2d(
                                    pt.Convert2d(plane),
                                    line.EndPoint.Convert2d(plane));
                                segCol.Add(new PolylineSegment(ls));
                                break;
                            case "Arc":
                                Arc arc = (Arc)obj;
                                pt = arc.StartPoint;
                                CircularArc2d ca = new CircularArc2d(
                                    pt.Convert2d(plane),
                                    arc.GetPointAtParameter((arc.EndParam - arc.StartParam) / 2.0).Convert2d(plane),
                                    arc.EndPoint.Convert2d(plane));
                                segCol.Add(new PolylineSegment(ca));
                                break;
                            case "Circle":
                                Circle c = (Circle)obj;
                                pt = c.Center;
                                segCol.AddRange(new PolylineSegmentCollection(c));
                                break;
                            case "Ellipse":
                                Ellipse el = (Ellipse)obj;
                                pt = el.Center;
                                segCol.AddRange(new PolylineSegmentCollection(el));
                                break;
                            case "Spline":
                                Spline spl = (Spline)obj;
                                pt = spl.StartPoint;
                                if (reg.Normal.IsParallelTo(Vector3d.ZAxis))
                                {
                                    segCol.AddRange(new PolylineSegmentCollection((Polyline)spl.ToPolyline()));
                                }
                                else
                                {
                                    DBObjectCollection objcol = new DBObjectCollection();
                                    spl.ToPolyline().Explode(objcol);
                                    foreach (DBObject o in objcol)
                                    {
                                        segments.Add(o);
                                    }
                                }
                                break;
                        }
                        obj.Dispose();
                    }
                    if (erase)
                    {
                        reg.UpgradeOpen();
                        reg.Erase();
                    }
                    ObjectIdCollection retVal = new ObjectIdCollection();
                    foreach (PolylineSegmentCollection psc in segCol.Join())
                    {
                        Polyline pl = psc.ToPolyline();
                        pl.TransformBy(Matrix3d.PlaneToWorld(plane));
                        pl.Elevation = pt.TransformBy(Matrix3d.WorldToPlane(plane)).Z;
                        retVal.Add(btr.AppendEntity(pl));
                        tr.AddNewlyCreatedDBObject(pl, true);
                    }
                    tr.Commit();
                    return retVal;
                }
            }
        }
    }
}
[/ol]
回复

使用道具 举报

3

主题

19

帖子

1

银币

初来乍到

Rank: 1

铜币
31
发表于 2012-7-18 07:54:26 | 显示全部楼层
thank you all for all the information and guidance
回复

使用道具 举报

0

主题

1

帖子

1

银币

初来乍到

Rank: 1

铜币
1
发表于 2012-10-15 12:55:17 | 显示全部楼层
My version (mod) on LISP
  1. ;;1D_Inciner
  2. (defun c:R2 (/           *error*  oldEcho  Ent      curSet   ;2:04 07.04.2011 Retopl mod by 1D
  3.                   curObj   ObjArr   curMemb  errFlag  actDoc   item
  4.                   ss MT i MT1 ss1
  5.                  )
  6.   (vl-load-com)
  7.   (defun *error* (msg)
  8.     (vla-EndUndoMark actDoc)
  9.     (setvar "CMDECHO" oldEcho)
  10.     (princ msg)
  11.     (princ)
  12.   ) ;_ end of *error*
  13. (defun r2plc (ss / );
  14. (setq i 0); chesk curSet selset for empty entries
  15. (repeat (sslength ss)
  16.              (if
  17.              (not (vlax-ename->vla-object (ssname ss i)))
  18.              (setq ss (ssdel (ssname ss i) ss)))
  19.                 (setq i (1+ i))
  20. );repeat
  21. (setq Ent (ssname ss (setq item (1- item))));___ entity
  22. (setq curObj (vlax-ename->vla-object Ent)); ___VLA entity
  23.   
  24. (if (vlax-write-enabled-p curObj)
  25. (progn
  26.           (setq        curSet nil
  27.                 curSet (ssadd)
  28.                 ObjArr (vlax-safearray->list
  29.                          (vlax-variant-value
  30.                            (vla-Explode curObj)
  31.                          )
  32.                        )
  33.           )
  34.                 (vla-delete curObj); ___explode to ObjArr
  35.           (foreach memb        ObjArr
  36.             (setq memb (vlax-vla-object->ename memb))
  37.             (if        (member
  38.                   (cdr (assoc 0 (entget Memb)))
  39.                   '("LINE" "ARC" "LWPOLYLINE")
  40.                 )
  41.               (setq curSet (ssadd Memb CurSet));___Curset from linearc chunks
  42.             ) ;_ end if
  43. (if (member
  44. (cdr (assoc 0 (entget Memb)))
  45. '("REGION")
  46. )
  47.    (progn              
  48.    (setq ss1 (ssadd Memb ss1));___ss1 from Reg
  49.    )
  50. );if
  51.           ) ;_ end foreach
  52. (if (> (sslength ss1) 0)
  53. (setq i 0); chesk ss1 selset for empty entries
  54. (repeat (sslength ss1)
  55.              (if
  56.              (not (vlax-ename->vla-object (ssname ss1 i)))
  57.              (setq ss1 (ssdel (ssname ss1 i) ss1)))
  58.              (setq i (1+ i))
  59.              ));___clean ss1
  60. (if (> (sslength curSet) 0)
  61. (setq i 0); chesk curSet selset for empty entries
  62. (repeat (sslength curSet)
  63.              (if
  64.              (not (vlax-ename->vla-object (ssname curSet i)))
  65.              (setq curSet (ssdel (ssname curSet i) curSet)))
  66.                 (setq i (1+ i))
  67.              ));___clean curset
  68. (if (> (sslength curSet) 0)
  69.             (progn
  70.                 (command "_.ucs" "_ob" (ssname curSet 0))
  71.                 (command "_.pedit" (ssname curSet 0) "_j" CurSet "" "")
  72.               (while (> (getvar "CMDACTIVE") 0) (command ""))
  73.               (command "_.ucs" "_p")
  74.                 (setq MT curSet i 0)
  75. (repeat (sslength MT)
  76. (setq MT1 (ssname MT i))
  77. (setq i (1+ i)
  78. VSS (ssadd MT1 VSS))
  79. )
  80. ;;(command "_.chprop" MT "" "_C" 12 "")
  81. (princ "\n>>")
  82. ) ;_ end progn
  83. );if
  84.           
  85. ) ;_ end progn
  86. );if
  87. );defun r2plc
  88. ; MAIN PART
  89. (setvar "DRAWORDERCTL" 0)
  90. (setq oldEcho (getvar "CMDECHO") actDoc (vla-get-ActiveDocument (vlax-get-acad-object)))
  91. (vla-StartUndoMark actDoc)
  92. (setvar "CMDECHO" 0)
  93. (setvar "PEDITACCEPT" 1)
  94. (setvar "UCSFOLLOW" 0)
  95. (setq VSS nil VSS (ssadd)); lines/arc chunks collector
  96. (setq ss1 nil ss1 (ssadd)); complex region's chunks collector
  97. (princ "select regions")
  98. (if (setq ss (ssget
  99. ;"_X"
  100.     (list '(0 . "REGION") (cons 410 (getvar "CTAB")))
  101. ));setq
  102. (progn
  103.         (repeat (setq item (sslength ss))
  104.         (r2plc ss));repeat
  105.         
  106.         (if (> (sslength ss1) 0)
  107.             (progn
  108.             (princ "\nAddictive Regions:")
  109.             (princ (sslength ss1))
  110.                  (repeat (setq item (sslength ss1))
  111.                  (r2plc ss1));repeat
  112.             ) ;_ end progn
  113.         );if
  114. );progn
  115. );if
  116. (setq i 0); chesk VSS selset for empty entries and joining chunks
  117. (repeat (sslength VSS)
  118.              (if
  119.              (vlax-ename->vla-object (ssname VSS i))
  120.              (vl-cmdf "_PEDIT" "_M" VSS "" "_J" "_J" "_B" 0 "")
  121.              )
  122.              (setq i (1+ i))
  123. );repeat
  124. (princ "\nComplete")
  125.   (setvar "CMDECHO" oldEcho)
  126. (setvar "DRAWORDERCTL" 3)
  127.   (vla-EndUndoMark actDoc)
  128.   (princ)
  129. )
回复

使用道具 举报

0

主题

2

帖子

1

银币

初来乍到

Rank: 1

铜币
2
发表于 2013-6-11 07:23:13 | 显示全部楼层
Hi Inciner or anybody else that may be able to help.
Regarding your Lisp, I tried it and it worked very well indeed. So many thanks for that.
However after running it, I then experienced a problem with another Lisp that I regularly use called Pre_Cal.lsp, which allows you to select closed lines by window, and turns the selection into a polyline or region depending on your choice.
I now get this text on the command line after running Pre_Cal.lsp: -
"Command: pre_cal
Initializing...
Select first corner:
Select other corner:
Invalid option keyword.
Function cancelled"
Here is the Pre_Cal.lsp Code: -
  1. (defun c:pre_cal ( / f_pt o_pt n r blk_oj sub_oj li_oj pli_oj hat_oj p_line sp kw)
  2.    
  3.    
  4.    (setvar "cmdecho" 0)
  5.    (setq f_pt (getpoint "\nSelect first corner: "))
  6.    (setq o_pt (getcorner f_pt "\nSelect other corner: "))
  7.    (princ "\n")
  8.    
  9.    (setq blk_oj (ssget "w" f_pt o_pt '((2 . "UCLOSE"))))   
  10.    (if (/= nil blk_oj)
  11.       (command "_erase" blk_oj "")
  12.    )
  13.    
  14.    (repeat 2
  15.       (setq blk_oj (ssget "w" f_pt o_pt
  16.       '((-4 . ""))))
  17.       
  18.       (if (/= nil blk_oj)
  19.          (command "_explode" blk_oj)
  20.       )
  21.    )
  22.    
  23.    (setq hat_oj (ssget "w" f_pt o_pt '((0 . "HATCH"))))   
  24.    (if (/= nil hat_oj)
  25.       (command "_erase" hat_oj "")
  26.    )
  27.    
  28.    (setq pli_oj (ssget "w" f_pt o_pt '((0 . "LWPOLYLINE"))))
  29.    (if (/= nil pli_oj) (command "_explode" pli_oj))
  30.    
  31.    (setq li_oj (ssget "w" f_pt o_pt
  32.    '((-4 . ""))))
  33.    
  34.    (while (/= nil li_oj)
  35.       (setq sub_oj (ssname li_oj 0))  
  36.       (command "_pedit" sub_oj "y" "J" (ssget "w" f_pt o_pt) "" "X")
  37.       (setq li_oj (ssget "w" f_pt o_pt
  38.       '((-4 . ""))))
  39.    )
  40.    
  41.    (setq pli_oj (ssget "w" f_pt o_pt '((0 . "LWPOLYLINE"))))
  42.    
  43.    (setq n 0 r 1)
  44.    (if (/= nil pli_oj)
  45.       (progn
  46.          
  47.          (repeat (sslength pli_oj)
  48.             (setq p_line (entget (ssname pli_oj n)))
  49.             (if (= 0 (cdr (assoc 70 p_line)))
  50.                (progn
  51.                   (setq r nil)
  52.                   (setq sp (cdr (assoc 10 p_line)))
  53.                   (command "_insert" "uclose" sp "" "" "")
  54.                )
  55.             )
  56.             (setq n (1+ n))
  57.          )
  58.       )
  59.    )
  60.    (if (= nil r)
  61.       (progn
  62.          (setq blk_oj (ssget "w" f_pt o_pt '((0 . "LWPOLYLINE"))))
  63.          (while (/= blk_oj nil)
  64.             (command "_explode" blk_oj)
  65.             (setq blk_oj (ssget "w" f_pt o_pt '((0 . "LWPOLYLINE"))))
  66.          )
  67.          (princ "*ERROR* : Found at least one polyline is not closed !")
  68.       )
  69.       (progn
  70.          (initget "Polyline  Region")
  71.          (setq kw (getkword "\nGenerate Region/:"))
  72.          (if (= kw "Region")
  73.             (command "_region" (ssget "w" f_pt o_pt
  74.                '((-4 . ""))) ""
  75.             )
  76.             (progn
  77.                (setq pli_oj (ssget "w" f_pt o_pt '((0 . "LWPOLYLINE"))))
  78.                (setq kw (strcat (itoa (sslength pli_oj)) " Polyline is generated"))
  79.                 (princ kw)
  80.             )         
  81.          )
  82.       )
  83.    )
  84.    (setvar "cmdecho" 1)
  85.    (princ)   
  86. )

I wonder if anybody might be able to pinpoint why this error has started to occur only since I ran the lisp by Inciner.
Could it be some variable that has been re-set?
Unfortunately, I am not fluent in lisp, so unable to pick through it myself. I would be grateful for any help.
Thanks.
回复

使用道具 举报

0

主题

2

帖子

1

银币

初来乍到

Rank: 1

铜币
2
发表于 2013-6-11 22:29:04 | 显示全部楼层
I am happy to say that I think I have solved this problem.
The Region to Polyline lisp appears to change the default value of "peditaccept" to 1.
I changed it back to default 0, and now my Pre_Cal.lsp works again.

回复

使用道具 举报

发表回复

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

本版积分规则

  • 微信公众平台

  • 扫描访问手机版

  • 点击图片下载手机App

QQ|关于我们|小黑屋|乐筑天下 繁体中文

GMT+8, 2025-2-5 04:00 , Processed in 0.236566 second(s), 72 queries .

© 2020-2025 乐筑天下

联系客服 关注微信 帮助中心 下载APP 返回顶部 返回列表