[CommandMethod("DIMP")]
public static void DimPline()
{
Document doc = acadApp.DocumentManager.MdiActiveDocument;
Editor ed = doc.Editor;
Database db = doc.Database;
Transaction tr = db.TransactionManager.StartTransaction();
using (tr)
{
try
{
PromptEntityOptions peo
= new PromptEntityOptions
("\nSelect a polyline:"); PromptEntityResult eres = ed.GetEntity(peo);
if (eres.Status != PromptStatus.OK) return;
ObjectId id = eres.ObjectId;
Entity ent = (Entity)tr.GetObject(id, OpenMode.ForRead);
Polyline pl = (Polyline)ent as Polyline;
BlockTableRecord btr =
(BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite);
double sign;
if (IsCCW(pl) == true)
{
sign = -1;
}
else
{
sign = 1;
}
Plane plan = pl.GetPlane();
double gap = (double)acadApp.GetSystemVariable("DIMTXT");// change to suit, may be hard value instead
for (int i = 0; i < pl.NumberOfVertices; i++)
{
switch (pl.GetSegmentType(i))
{
case SegmentType.Line:
LineSegment3d seg = pl.GetLineSegmentAt(i);
Vector3d vec = seg.Direction;
double ang = vec.AngleOnPlane(plan);
Point3d p1 = seg.StartPoint;
Point3d p2 = seg.EndPoint;
Point3d p3 = seg.MidPoint;
p3 = PolarPoint(p3, ang + Math.PI / 2 * sign, gap * 6);// gap * 6 - is offset distance from polyline,change to suit
RotatedDimension dimr
= new RotatedDimension
();
dimr.SetDatabaseDefaults();
dimr.XLine1Point = p1;
dimr.XLine2Point = p2;
dimr.Rotation = ang;
dimr.DimLinePoint = p3;
dimr.DimensionStyle = db.Dimstyle;
dimr.TextRotation = ang;
btr.AppendEntity(dimr);
tr.AddNewlyCreatedDBObject(dimr, true);
break;
case SegmentType.Arc:
CircularArc3d circ = pl.GetArcSegmentAt(i);
Point3d cp = circ.Center;
Point3d mp = circ.EvaluatePoint(0.5);
double rad = circ.Radius;
Point3d sp = circ.StartPoint;
Point3d ep = circ.EndPoint;
Point3d tp = PolarPoint(cp, AngleFromX(cp, mp), rad + gap * 6);// gap * 6 - is offset distance from polyline
// (center, start,end, text point)
ArcDimension adim
= new ArcDimension
( cp, sp, ep, tp, "<>", db.Dimstyle);
if (sign < 0)
{
adim.TextRotation = AngleFromX(sp, ep);
}
else
{
adim.TextRotation = AngleFromX(sp, ep)+ Math.PI;
}
btr.AppendEntity(adim);
tr.AddNewlyCreatedDBObject(adim, true);
break;
default:
break;
}
}
tr.Commit();
}
catch (Autodesk.AutoCAD.Runtime.Exception ex)
{
ed.WriteMessage(ex.Message + "\n" + ex.StackTrace);
}
}
}
/// by Herbert Putz
/// Methode GetAreaDMD( Polyline oPoly)
/// Berechnet die Fläche eines geschlossenen Polygons nach der
/// DoubleMeridianDistance-Methode
/// (-(x1*y2)-(x2*y3)-...(xn*y1)+(y1*x2)+(y2*x3)+...(yn*x1))/2
///
///
/// oPoly ist eine AutoCAD-Polylinie
///
///
/// Flächenwert als Double
/// nArea > 0 --> Fläche im Uhrzeigersinn gezeichnet
/// nArea Fläche gegen den Urzeigersinn gezeichnet
///
public static double GetAreaDMD(Polyline oPoly)
{
int nPoints;
double nArea;
nPoints = oPoly.NumberOfVertices - 1; // -1 weil Nullbasiert
nArea = 0.00;
for (int i = 0; i < nPoints; i++)
{
nArea -=
(oPoly.GetPoint2dAt(i).X * oPoly.GetPoint2dAt(i + 1).Y);
nArea +=
(oPoly.GetPoint2dAt(i).Y * oPoly.GetPoint2dAt(i + 1).X);
} // for ...
nArea -=
(oPoly.GetPoint2dAt(nPoints).X * oPoly.GetPoint2dAt(0).Y);
nArea +=
(oPoly.GetPoint2dAt(nPoints).Y * oPoly.GetPoint2dAt(0).X);
return nArea / 2;
} // GetAreaDMD()
/// <summary>
/// check if polyline direction is counterclockwise
/// </summary>
/// <param name="pline"></param>
/// <returns></returns>
public static bool IsCCW(Polyline pline)
{
double area = GetAreaDMD(pline);
if (area > 0)
{
return false;
}
else
{
return true;
}
}
/// Polar point // credit to Tony Tanzillo
/// </summary>
/// <param name="basepoint"></param>
/// <param name="angle"></param>
/// <param name="distance"></param>
/// <returns></returns>
public static Point3d PolarPoint(Point3d basepoint, double angle, double distance)
{
basepoint.X + (distance * Math.Cos(angle)),
basepoint.Y + (distance * Math.Sin(angle)),
basepoint.Z);
}
public static double AngleFromX(Point3d pt1, Point3d pt2)
{
Plane ucsplane
= new Plane
(new Point3d
(0,
0,
0),
new Vector3d
(0,
0,
1));
Vector3d vec = pt2 - pt1;
double ang = vec.AngleOnPlane(ucsplane);
return ang;
}