.NET

.NET

Reply
Active Contributor
xdbk07
Posts: 42
Registered: ‎11-06-2012
Message 1 of 5 (821 Views)
Accepted Solution

Offset polyline by pick point on side like autocad

821 Views, 4 Replies
02-03-2013 05:32 PM

Hi pro,

 

Please let me know how to offset a opened polyline by pick point on side of opened polyline.

 

Thanks,

With minimum error checking. Only as idea.

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("\nOffset value: ");
if (resValueOff.Status != PromptStatus.OK) return;
PromptPointResult resPointOff = ed.GetPoint("\nOffset side: ");
if (resPointOff.Status != PromptStatus.OK) return;
PromptEntityOptions prCurv = new PromptEntityOptions("\nSelect curve: ");
prCurv.SetRejectMessage("not a Curve");
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;
}
}
}

 

 

Moderator
Alexander.Rivilis
Posts: 1,450
Registered: ‎04-09-2008
Message 2 of 5 (803 Views)

Re: Offset polyline by pick point on side like autocad

02-04-2013 02:16 AM in reply to: xdbk07

With minimum error checking. Only as idea.

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("\nOffset value: ");
      if (resValueOff.Status != PromptStatus.OK) return;
      PromptPointResult  resPointOff = ed.GetPoint("\nOffset side: ");
      if (resPointOff.Status != PromptStatus.OK) return;
      PromptEntityOptions prCurv = new PromptEntityOptions("\nSelect curve: ");
      prCurv.SetRejectMessage("not a Curve");
      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;
    }
  }
}

 

 


Пожалуйста не забывайте про Утвердить в качестве решения! Утвердить в качестве решения и Give Kudos!Баллы
Please remember to Accept Solution! Accept as Solution and Give Kudos!Kudos

*Expert Elite*
Hallex
Posts: 1,569
Registered: ‎10-08-2008
Message 3 of 5 (794 Views)

Re: Offset polyline by pick point on side like autocad

02-04-2013 03:34 AM in reply to: Alexander.Rivilis

Nice solution

Hats off

Cheers :smileyhappy:

_____________________________________
C6309D9E0751D165D0934D0621DFF27919
Active Contributor
xdbk07
Posts: 42
Registered: ‎11-06-2012
Message 4 of 5 (769 Views)

Re: Offset polyline by pick point on side like autocad

02-05-2013 12:05 AM in reply to: Alexander.Rivilis

 

Great.It worked OK.

Thank Rivilis,

Valued Contributor
tanerpro
Posts: 83
Registered: ‎10-07-2005
Message 5 of 5 (247 Views)

Re: Offset polyline by pick point on side like autocad

05-27-2014 10:32 AM in reply to: xdbk07

Hello Rivilis,

Thank you for the code, it works perfect with polyline and circle I tried but works inverse in case of line.

How can I solve this?

Regards,

 

Windows 7 (x64)
AutoCAD 2012 (x64)
Post to the Community

Have questions about Autodesk products? Ask the community.

New Post
Announcements
Do you have 60 seconds to spare? The Autodesk Community Team is revamping our site ranking system and we want your feedback! Please click here to launch the 5 question survey. As always your input is greatly appreciated.