eInvalidInput at Region.CreateFromCurves

eInvalidInput at Region.CreateFromCurves

Anonymous
Not applicable
3,143 Views
2 Replies
Message 1 of 3

eInvalidInput at Region.CreateFromCurves

Anonymous
Not applicable

Hello,

I have migrating tom ARX code into .NET from a plugin I'm still not familiar, which convert drawings to SVG. This function gets the polyline centroid and is using some ideas from the link https://knowledge.autodesk.com/search-result/caas/CloudHelp/cloudhelp/2015/ENU/AutoCAD-NET/files/GUI...

 

Once in a while, especially when I'm trying to convert all layers I see this eInvalidInput exception. (An unhandled exception of type 'Autodesk.AutoCAD.Runtime.Exception' occurred in AcdbMgd.dll)

Not sure why this my be happening. 

 

FYI I'm using this plugin with Autocad 2013 and .NET 4.5.2 

 

Any help will be much appreciated.

 

 

public static SPointF GetPolyCentroid(this Polyline pline)
{
DBObjectCollection plineCollection = new DBObjectCollection();
DBObjectCollection regionCollection = new DBObjectCollection();
plineCollection.Add(pline);

regionCollection = Region.CreateFromCurves(plineCollection);<----Here the exception occurs
Region region = regionCollection[0] as Region;
Point3d centroid;
using (region)
{
//TODO
//https://knowledge.autodesk.com/search-result/caas/CloudHelp/cloudhelp/2015/ENU/AutoCAD-NET/files/GUI...

using (Solid3d solid = new Solid3d())
{
solid.Extrude(region, 2.0, 0.0);
Point3d solidCentroid = solid.MassProperties.Centroid;
centroid = solidCentroid.TransformBy(Matrix3d.Displacement(region.Normal.Negate()));
}
}

if (centroid != null)
return new SPointF(centroid.X, centroid.Y);
else return null;
}

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

_gile
Consultant
Consultant
Accepted solution

Hi,

 

I do not know why you get this error, but there's probably a problem with the polyline as self intersection.

Did you tray to create a region from this polyline in the AutoCAD with the REGION command?

 

Anyway, getting the centroid of a polyline by creating a region and a solid 3D is not very efficient.

You can compute it with some geometry calculations as shown in the following methods (you can also find a similar method in the GeometryExtensions library)

 

        private Point3d GetCentroid(Polyline pl)
        {
            Point2d p0 = pl.GetPoint2dAt(0);
            Point2d cen = new Point2d(0.0, 0.0);
            double area = 0.0;
            double bulge = pl.GetBulgeAt(0);
            int last = pl.NumberOfVertices - 1;
            double tmpArea;
            Point2d tmpPoint;

            if (bulge != 0.0)
            {
                double[] datas = GetArcGeom(pl, bulge, 0, 1);
                area = datas[0];
                cen = new Point2d(datas[1], datas[2]) * datas[0];
            }
            for (int i = 1; i < last; i++)
            {
                tmpArea = TriangleAlgebricArea(p0, pl.GetPoint2dAt(i), pl.GetPoint2dAt(i + 1));
                tmpPoint = TriangleCentroid(p0, pl.GetPoint2dAt(i), pl.GetPoint2dAt(i + 1));
                cen += (tmpPoint * tmpArea).GetAsVector();
                area += tmpArea;
                bulge = pl.GetBulgeAt(i);
                if (bulge != 0.0)
                {
                    double[] datas = GetArcGeom(pl, bulge, i, i + 1);
                    area += datas[0];
                    cen += new Vector2d(datas[1], datas[2]) * datas[0];
                }
            }
            bulge = pl.GetBulgeAt(last);
            if (bulge != 0.0)
            {
                double[] datas = GetArcGeom(pl, bulge, last, 0);
                area += datas[0];
                cen += new Vector2d(datas[1], datas[2]) * datas[0];
            }
            cen = cen.DivideBy(area);
            Point3d result = new Point3d(cen.X, cen.Y, pl.Elevation);
            return result.TransformBy(Matrix3d.PlaneToWorld(pl.Normal));
        }

        private double[] GetArcGeom(Polyline pl, double bulge, int index1, int index2)
        {
            CircularArc2d arc = (pl.GetArcSegment2dAt(index1));
            double arcRadius = arc.Radius;
            Point2d arcCenter = arc.Center;
            double arcAngle = 4.0 * Math.Atan(bulge);
            double tmpArea = ArcAlgebricArea(arcRadius, arcAngle);
            Point2d tmpPoint = ArcCentroid(pl.GetPoint2dAt(index1), pl.GetPoint2dAt(index2), arcCenter, tmpArea);
            return new double[3] { tmpArea, tmpPoint.X, tmpPoint.Y };
        }

        private Point2d TriangleCentroid(Point2d p0, Point2d p1, Point2d p2)
        {
            return (p0 + p1.GetAsVector() + p2.GetAsVector()) / 3.0;
        }

        private double TriangleAlgebricArea(Point2d p0, Point2d p1, Point2d p2)
        {
            return (((p1.X - p0.X) * (p2.Y - p0.Y)) - ((p2.X - p0.X) * (p1.Y - p0.Y))) / 2.0;
        }

        private Point2d ArcCentroid(Point2d start, Point2d end, Point2d cen, double tmpArea)
        {
            double chord = start.GetDistanceTo(end);
            double angle = (end - start).Angle;
            return Polar2d(cen, angle - (Math.PI / 2.0), (chord * chord * chord) / (12.0 * tmpArea));
        }

        private double ArcAlgebricArea(double rad, double ang)
        {
            return rad * rad * (ang - Math.Sin(ang)) / 2.0;
        }

        private Point2d Polar2d(Point2d org, double angle, double distance)
        {
            return org + new Vector2d(distance * Math.Cos(angle), distance * Math.Sin(angle));
        }


Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 3 of 3

Anonymous
Not applicable

Sorry for taking me too long to accept the answer, very helpful as usual. I just didn't have time to give it a try.

 

Thanks once again Gile!

 

Very much appreciated it.

 

0 Likes