using System;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.EditorInput;
[assembly: CommandClass(typeof(Rivilis.CurveUtils))]
namespace Rivilis
{
public class CurveUtils
{
[CommandMethod("OffsetCurve", CommandFlags.Modal)]
public static void OffsetCurve()
{
Document doc = Application.DocumentManager.MdiActiveDocument;
Editor ed = doc.Editor;
PromptDoubleResult resValueOff = ed.GetDistance("\nВеличина смещения: ");
if (resValueOff.Status != PromptStatus.OK) return;
PromptPointResult resPointOff = ed.GetPoint("\nСторона смещения: ");
if (resPointOff.Status != PromptStatus.OK) return;
PromptEntityOptions prCurv = new PromptEntityOptions("\nВыберите кривую: ");
prCurv.SetRejectMessage("это не кривая");
prCurv.AddAllowedClass(typeof(Curve),false);
PromptEntityResult resCurv = ed.GetEntity(prCurv);
if (resCurv.Status != PromptStatus.OK) return;
using (Transaction tr = doc.TransactionManager.StartTransaction()) {
Curve curve = tr.GetObject(resCurv.ObjectId, OpenMode.ForRead) as Curve;
if (curve != null) {
BlockTableRecord btr = tr.GetObject(curve.BlockId, OpenMode.ForWrite) as BlockTableRecord;
if (btr != null) {
Point3d pDir = (Point3d)(Application.GetSystemVariable("VIEWDIR"));
if (pDir != null) {
Point3d pWCS = resPointOff.Value.TransformBy(ed.CurrentUserCoordinateSystem);
double offset = IsRightDirection(curve, pWCS, pDir.GetAsVector()) ?
resValueOff.Value : -resValueOff.Value;
DBObjectCollection curvCols = curve.GetOffsetCurves(offset);
foreach (DBObject obj in curvCols) {
Curve subCurv = obj as Curve;
if (subCurv != null) {
btr.AppendEntity(subCurv);
tr.AddNewlyCreatedDBObject(subCurv, true);
}
}
}
}
}
tr.Commit();
}
}
// Detect side of point
public static bool IsRightDirection(Curve pCurv, Point3d p, Vector3d vDir)
{
Vector3d vNormal = Vector3d.ZAxis;
if (pCurv.IsPlanar) {
Plane plane = pCurv.GetPlane();
vNormal = plane.Normal;
p = p.Project(plane, vDir);
}
Point3d pNear = pCurv.GetClosestPointTo(p, true);
Vector3d vSide = p - pNear;
Vector3d vDeriv = pCurv.GetFirstDerivative(pNear);
if (vNormal.CrossProduct(vDeriv).DotProduct(vSide) < 0.0)
return true;
else
return false;
}
}
}