// (C) CodeHimBelonga kdub@theSwamp 2010
//
using System;
using System.Windows.Forms;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.Runtime;
using AcadApp = Autodesk.AutoCAD.ApplicationServices.Application;
[assembly: CommandClass(typeof(kdub_Testing.LittleBoxes))]
namespace kdub_Testing
{
public class LittleBoxes
{
Editor ed = AcadApp.DocumentManager.MdiActiveDocument.Editor;
Database db = HostApplicationServices.WorkingDatabase;
[CommandMethod("HACK3")]
public void HACK3()
{
double spacing = 200.0;
double length = 400.0;
double width = 50.0;
Point3d ptStart = new Point3d();
Point3d ptEnd = new Point3d();
//-1 if ptSide is on left side
//+1 if ptSide is on right side
int hackSide = 0;
bool proceed = GetUserInput(ref ptStart, ref ptEnd, ref hackSide);
if(proceed == false) {
System.Windows.Forms.MessageBox.Show("You Made Boo-Boo Selection",
"Oooops",
MessageBoxButtons.OK,
MessageBoxIcon.Exclamation
);
return;
}
Vector3d v1 = (Vector3d)(ptEnd - ptStart);
double wpLen = v1.Length;
int spacingCount = (int)((wpLen / spacing) - 2);
Vector3d spacingVector = v1.MultiplyBy(spacing / wpLen);
Vector3d firstVec = v1.MultiplyBy(((wpLen - (spacingCount * spacing) - width) / 2) / wpLen);
// draw first box
// describe the PolyLine rectangle corners as vectors relative to the firstCorner
//
Vector3d xLen = v1.DivideBy(v1.Length).MultiplyBy(width);
Vector3d yLen = v1.GetPerpendicularVector().MultiplyBy(-(hackSide * length));
Point3d vertex0 = ptStart.Add(firstVec);
Point3d vertex1 = vertex0 + yLen;
Point3d vertex2 = vertex1 + xLen;
Point3d vertex3 = vertex0 + xLen;
using(Transaction tr = db.TransactionManager.StartTransaction()) {
Polyline polyline = new Polyline();
polyline.AddVertexAt(polyline.NumberOfVertices, new Point2d(vertex0.X, vertex0.Y), 0, 0, 0);
polyline.AddVertexAt(polyline.NumberOfVertices, new Point2d(vertex1.X, vertex1.Y), 0, 0, 0);
polyline.AddVertexAt(polyline.NumberOfVertices, new Point2d(vertex2.X, vertex2.Y), 0, 0, 0);
polyline.AddVertexAt(polyline.NumberOfVertices, new Point2d(vertex3.X, vertex3.Y), 0, 0, 0);
polyline.Closed = true;
ObjectId plRectangle = ExtensionTools.AddToCurrentSpaceAndClose(polyline, db);
ExtensionTools.ArrayInAxis(plRectangle, db, (spacingCount + 1), spacingVector);
tr.Commit();
}
}
}
}
public bool GetUserInput(ref Point3d ptStart, ref Point3d ptEnd, ref int hackSide)
{
// (C) CodeHimBelonga kdub@theSwamp 2010
//
PromptPointResult ppr;
PromptPointOptions ppo = new PromptPointOptions("");
PromptEntityOptions peo = new PromptEntityOptions("\nSelect a PolyLine segment, or[Points]", "Points");
peo.AllowNone = true;
peo.SetRejectMessage("\nIncorrect entity");
peo.AddAllowedClass(typeof(Polyline), true);
peo.Keywords.Default = "Points";
PromptEntityResult per = ed.GetEntity(peo);
switch(per.Status) {
case PromptStatus.Cancel:
return false;
case PromptStatus.OK:
Point3d p0;
Point3d p1;
using(Transaction tr = db.TransactionManager.StartTransaction()) {
Polyline pline = (Polyline)tr.GetObject(per.ObjectId, OpenMode.ForRead);
Point3d pickPt = pickPointOnPline(pline, per.PickedPoint);
double param = pline.GetParameterAtPoint(pickPt);
int index = (int)param;
p0 = pline.GetPoint3dAt(index);
if(pline.Closed == false)
p1 = pline.GetPoint3dAt(index + 1);
else {
try { p1 = pline.GetPoint3dAt(index + 1); } catch { p1 = pline.GetPoint3dAt(0); }
}
if(pickPt.DistanceTo(p0) <= pickPt.DistanceTo(p1)) {
ptStart = p0;
ptEnd = p1;
} else {
ptStart = p1;
ptEnd = p0;
}
tr.Commit();
}
break;
case PromptStatus.Keyword:
switch(per.StringResult) {
case "Points":
// Prompt for the start point
ppo.Message = "\nEnter the start point of the line: ";
ppr = ed.GetPoint(ppo);
ptStart = ppr.Value;
// Exit if the user presses ESC or cancels the command
if(ppr.Status == PromptStatus.Cancel)
return false;
// Prompt for the end point
ppo.Message = "\nEnter the end point of the line: ";
ppo.UseBasePoint = true;
ppo.BasePoint = ptStart;
ppr = ed.GetPoint(ppo);
ptEnd = ppr.Value;
if(ppr.Status == PromptStatus.Cancel)
return false;
break;
default:
return false;
}
break;
}
Matrix3d UCSMatrix = ed.CurrentUserCoordinateSystem;
CoordinateSystem3d UCS = UCSMatrix.CoordinateSystem3d;
Plane xyPlane = new Plane(ptStart, UCS.Xaxis, UCS.Yaxis);
double angle0 = (ptEnd - ptStart).AngleOnPlane(xyPlane);
Int16 osmode = (Int16)AcadApp.GetSystemVariable("OSMODE");
double snapang = (double)AcadApp.GetSystemVariable("SNAPANG");
AcadApp.SetSystemVariable("OSMODE", 1);
AcadApp.SetSystemVariable("SNAPANG", angle0);
Point3d ptSide = new Point3d();
// Prompt for the HackSide
ppo.Message = "\nSelect the hack direction : ";
ppo.UseBasePoint = true;
ppo.BasePoint = ptStart;
ppr = ed.GetPoint(ppo);
ptSide = ppr.Value;
AcadApp.SetSystemVariable("OSMODE", osmode);
AcadApp.SetSystemVariable("SNAPANG", snapang);
if(ppr.Status == PromptStatus.Cancel)
return false;
//-1 if ptSide is on left side
//+1 if ptSide is on right side
hackSide = ExtensionTools.DeflectionSide(ptStart, ptEnd, ptSide);
return true;
}
// Credit to Gile @theSwamp
private Point3d pickPointOnPline(Polyline pl, Point3d pt)
{
pt = pt.TransformBy(ed.CurrentUserCoordinateSystem);
Vector3d vdir = ed.GetCurrentView().ViewDirection;
pt = pt.Project(pl.GetPlane(), vdir);
return pl.GetClosestPointTo(pt, false);
}
ExtensionTools
// (C) CodeHimBelonga kdub@theSwamp 2010
//
using System;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.Runtime;
using AcadApp = Autodesk.AutoCAD.ApplicationServices.Application;
namespace kdub_Testing
{
public static class ExtensionTools
{
/// <summary>
///
/// </summary>
/// <param name="id"></param>
/// <param name="db"></param>
/// <param name="numCols"></param>
/// <param name="displacementVector"></param>
public static void ArrayInAxis(this ObjectId id, Database db, int numCols, Vector3d displacementVector )
{
using(Transaction tr = db.TransactionManager.StartTransaction()) {
BlockTable table = tr.GetObject(db.BlockTableId, OpenMode.ForRead, false) as BlockTable;
BlockTableRecord record = tr.GetObject(table[BlockTableRecord.ModelSpace], OpenMode.ForWrite, false) as BlockTableRecord;
Entity ent = tr.GetObject(id, OpenMode.ForWrite) as Entity;
for(int j = 0; j < numCols; j++) {
Matrix3d transform = Matrix3d.Displacement(new Vector3d(j * displacementVector.X, j * displacementVector.Y, j * displacementVector.Z));
Entity transformedCopy = ent.GetTransformedCopy(transform);
record.AppendEntity(transformedCopy);
tr.AddNewlyCreatedDBObject(transformedCopy, true);
}
ent.Erase();
tr.Commit();
}
}
/// <summary>
///
/// </summary>
/// <param name="ent"></param>
/// <param name="db"></param>
/// <returns></returns>
public static ObjectId AddToCurrentSpaceAndClose(Entity ent, Database db)
{
ObjectId objId;
using(Transaction tr = db.TransactionManager.StartTransaction()) {
objId = AddToCurrentSpace(ent, db, tr);
tr.Commit();
}
return objId;
}
/// <summary>
///
/// </summary>
/// <param name="ent"></param>
/// <param name="db"></param>
/// <param name="tr"></param>
/// <returns></returns>
public static ObjectId AddToCurrentSpace(Entity ent, Database db, Transaction tr)
{
ObjectId objId;
BlockTableRecord btr = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite);
objId = btr.AppendEntity(ent);
tr.AddNewlyCreatedDBObject(ent, true);
return objId;
}
/// <summary>
///
/// </summary>
/// <param name="p1"></param>
/// <param name="p2"></param>
/// <param name="p3"></param>
/// Returns -1 if p3 is on left side of vector p1-p2,
/// or returns +1 if p3 is on right side of vector p1-p2.
/// Points are converted to XY plane.
/// <returns></returns>
public static int DeflectionSide(Point3d p1, Point3d p2, Point3d p3)
{
return DeflectionSide(
new Point2d(p1.X, p1.Y),
new Point2d(p2.X, p2.Y),
new Point2d(p3.X, p3.Y)
);
}
/// <summary>
///
/// </summary>
/// <param name="p1"></param>
/// <param name="p2"></param>
/// <param name="p3"></param>
/// Returns -1 if p3 is on left side of vector p1-p2,
/// or returns +1 if p3 is on right side of vector p1-p2.
/// Points are converted to XY plane.
/// <returns></returns>
public static int DeflectionSide(Point2d p1, Point2d p2, Point2d p3)
{
return (((p2.X - p1.X) * (p3.Y - p1.Y)) - ((p2.Y - p1.Y) * (p3.X - p1.X)) > 0) ? -1 : 1;
}
}
}
ANd the Project/Solution