'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))
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.
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]