Hi kaefer
Actually this tool is for distrubuting Hollowcore slabs in the selected room. Now in room for each column user can specify custom offset. So using Bryco's suggestions. I show user form once the column polyline is selected and user can input each side offset (usually it is only 2 sides since column is at any corner of room) and also user defines the point of direction and once pressed ok I use the following code to create new polyline uniting regions from all the polylines that are created for each side.
var ed = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor;
var db = HostApplicationServices.WorkingDatabase;
var ucs = ed.CurrentUserCoordinateSystem;
var cs = ucs.CoordinateSystem3d;
var pn = new Plane(Point3d.Origin, cs.Zaxis);
var customColumn = this.rhCustomColumn.Element.AsObject as CustomColumn;
var vertices = customColumn.Vertices.Where(x => x.Offset > 0 && x.DPX != null && x.DPY != null);
using (var transaction = db.TransactionManager.StartTransaction())
{
var polyline =
(Polyline)
transaction.GetObject(ArxUtility.GetObjectId(customColumn.Handle2), OpenMode.ForWrite);
var regionList = new List<Autodesk.AutoCAD.DatabaseServices.Region>();
foreach (var cv in vertices)
{
var u1 = new Point3d(cv.SP2X == null ? cv.StartPointX : cv.SP2X.Value,
cv.SP2Y == null ? cv.StartPointY : cv.SP2Y.Value, 0.0);
var u2 = new Point3d(cv.EP2X == null ? cv.EndPointX : cv.EP2X.Value,
cv.EP2Y == null ? cv.EndPointY : cv.EP2Y.Value, 0.0);
if (u1.Z != u2.Z)
u2 = new Point3d(u2.X, u2.Y, u1.Z);
//Add pline
var nPolyline = new Polyline(7) { Normal = cs.Zaxis, Elevation = -new Plane(cs.Origin, cs.Zaxis).Coefficients.D };
if (u1.Z != 0)
nPolyline.Elevation = nPolyline.Elevation + u1.Z;
var p1 = u1.TransformBy(ucs).Convert2d(pn);
var p2 = u2.TransformBy(ucs).Convert2d(pn);
nPolyline.AddVertexAt(0, p1, 0, 0, 0);
nPolyline.AddVertexAt(1, p2, 0, 0, 0);
var v = (p2 - p1).GetNormal().RotateBy(Math.PI * 0.5);
var dOffset = cv.Offset;
if (dOffset < 0)
dOffset = dOffset * -1;
var sidePoint = new Point3d(cv.DPX.Value, cv.DPY.Value, 0.0);
var iOffset = this.isLeftMath(p1, p2, sidePoint.TransformBy(ucs).Convert2d(pn));
v = v * iOffset * dOffset;
var pt1 = p1.Add(v);
var pt2 = p2.Add(v);
nPolyline.AddVertexAt(2, p2.Add(v), 0, 0, 0);
nPolyline.AddVertexAt(3, p1.Add(v), 0, 0, 0);
nPolyline.Closed = true;
var nRegion = RegionManager.Convert2Region(nPolyline as Curve);
regionList.Add(nRegion);
this.ChangePoints(customColumn, cv, pt1, pt2);
}
var oRegion = RegionManager.Convert2Region(polyline as Curve);
foreach (var region in regionList)
oRegion.BooleanOperation(BooleanOperationType.BoolUnite, region);
var finalPolyline = EntityManager.GeneratePolyline(oRegion, true)[0];
finalPolyline.Layer = "_Obstructions2";
var id = BlockManager.AddEntity(finalPolyline);
EntityManager.SendEntitiesBackWard(transaction, new ObjectIdCollection(new ObjectId[] { id }));
EntityManager.DeleteEntity(ArxUtility.GetObjectId(customColumn.Handle2), transaction);
customColumn.Handle2 = id.Handle.ToString();
transaction.Commit();
}
ed.Regen();
But now I will look at what you have shown.
Somehow I don't want to take the direction from the user. (i.e. I want to avoid following code from Bryco's suggestions)
Pres = ed.GetPoint("\nSpecify point on side to offset:");
if (Pres.Status != PromptStatus.OK) return;
int iOffset = isLeft(P1, P2, Pres.Value.TransformBy(ucs).Convert2d(pn));
if (iOffset == 0) //means all points are linear
{
MessageBox.Show("The offset point must not be on the line:");
goto Retry;
}