///<summary> /// Get the centroid of a Region. ///</summary> ///<param name="cur">An optional curve used to define the region.</param> ///<returns>A nullable Point3d containing the centroid of the Region.</returns> public static _AcGe.Point3d? GetCentroid(this _AcDb.Region reg, _AcDb.Curve cur = null) { if (cur == null) { var idc = new _AcDb.DBObjectCollection(); reg.Explode(idc); if (idc.Count == 0) { return(null); } cur = idc[0] as _AcDb.Curve; } if (cur == null) { return(null); } var cs = cur.GetPlane().GetCoordinateSystem(); var o = cs.Origin; var x = cs.Xaxis; var y = cs.Yaxis; var a = reg.AreaProperties(ref o, ref x, ref y); var pl = new _AcGe.Plane(o, x, y); return(pl.EvaluatePoint(a.Centroid)); }
// DBText extensions ///<summary> /// Gets the bounds of a DBText object. ///</summary> ///<param name="fac">Optional multiplier to increase/reduce buffer.</param> ///<returns>A collection of points defining the text's extents.</returns> public static _AcGe.Point3dCollection ExtractBounds( this _AcDb.DBText txt, double fac = 1.0 ) { var pts = new _AcGe.Point3dCollection(); if (txt.Bounds.HasValue && txt.Visible) { // Create a straight version of the text object // and copy across all the relevant properties // (stopped copying AlignmentPoint, as it would // sometimes cause an eNotApplicable error) // We'll create the text at the WCS origin // with no rotation, so it's easier to use its // extents var txt2 = new _AcDb.DBText(); txt2.Normal = _AcGe.Vector3d.ZAxis; txt2.Position = _AcGe.Point3d.Origin; // Other properties are copied from the original txt2.TextString = txt.TextString; txt2.TextStyleId = txt.TextStyleId; txt2.LineWeight = txt.LineWeight; txt2.Thickness = txt2.Thickness; txt2.HorizontalMode = txt.HorizontalMode; txt2.VerticalMode = txt.VerticalMode; txt2.WidthFactor = txt.WidthFactor; txt2.Height = txt.Height; txt2.IsMirroredInX = txt2.IsMirroredInX; txt2.IsMirroredInY = txt2.IsMirroredInY; txt2.Oblique = txt.Oblique; // Get its bounds if it has them defined // (which it should, as the original did) if (txt2.Bounds.HasValue) { var maxPt = txt2.Bounds.Value.MaxPoint; // Only worry about this single case, for now _AcGe.Matrix3d mat = _AcGe.Matrix3d.Identity; if (txt.Justify == _AcDb.AttachmentPoint.MiddleCenter) { mat = _AcGe.Matrix3d.Displacement((_AcGe.Point3d.Origin - maxPt) * 0.5); } // Place all four corners of the bounding box // in an array double minX, minY, maxX, maxY; if (txt.Justify == _AcDb.AttachmentPoint.MiddleCenter) { minX = -maxPt.X * 0.5 * fac; maxX = maxPt.X * 0.5 * fac; minY = -maxPt.Y * 0.5 * fac; maxY = maxPt.Y * 0.5 * fac; } else { minX = 0; minY = 0; maxX = maxPt.X * fac; maxY = maxPt.Y * fac; } var bounds = new _AcGe.Point2d[] { new _AcGe.Point2d(minX, minY), new _AcGe.Point2d(minX, maxY), new _AcGe.Point2d(maxX, maxY), new _AcGe.Point2d(maxX, minY) }; // We're going to get each point's WCS coordinates // using the plane the text is on var pl = new _AcGe.Plane(txt.Position, txt.Normal); // Rotate each point and add its WCS location to the // collection foreach (_AcGe.Point2d pt in bounds) { pts.Add( pl.EvaluatePoint( pt.RotateBy(txt.Rotation, _AcGe.Point2d.Origin) ) ); } } } return(pts); }