using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.Runtime;
using System;
namespace Windows
{
public class Commands
{
[CommandMethod("Test")]
public void Test()
{
Document doc = Application.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
Editor ed = doc.Editor;
// prompt for the window polyline
var entOpts
= new PromptEntityOptions
("\nSelect a window: "); entOpts.SetRejectMessage("\nSelected object must be apolyline.");
entOpts
.AddAllowedClass(typeof(Polyline
),
true); var entRes = ed.GetEntity(entOpts);
if (entRes.Status != PromptStatus.OK)
return;
using (Transaction tr = db.TransactionManager.StartTransaction())
{
var window = (Polyline)tr.GetObject(entRes.ObjectId, OpenMode.ForRead);
// get the window center
Extents3d extents = window.GeometricExtents;
Point3d center = extents.MinPoint + (extents.MaxPoint - extents.MinPoint) / 2.0;
// get the normal of the window plane
Point2d pt
= new Point2d
(center
.X, center
.Y); Vector3d normal = window.Normal;
// check if the window is vertical
if (!normal.IsPerpendicularTo(Vector3d.ZAxis))
{
ed.WriteMessage("\nThe window is not vertical.");
return;
}
// get the nnormal angle about XY plane
var angle0
= normal
.AngleOnPlane(new Plane
());
// prompt for the first angle
var angRes = ed.GetAngle("\nAngle 1: ");
if (angRes.Status != PromptStatus.OK)
return;
var angle1 = angRes.Value;
// prompt for the second angle
angRes = ed.GetAngle("\nAngle 2: ");
if (angRes.Status != PromptStatus.OK)
return;
var angle2 = angRes.Value;
var curSpace = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite);
// create the polyline
using (var pline
= new Polyline
(3)) {
// add vertices
pline.AddVertexAt(0, pt, 0.0, 0.0, 0.0);
pline.AddVertexAt(1, Polar(pt, angle0 - angle1, 5000.0), 0.0, 0.0, 0.0);
pline.AddVertexAt(2, Polar(pt, angle0 + angle1, 5000.0), 0.0, 0.0, 0.0);
pline.Closed = true;
// transform the polyline
pline.Elevation = center.Z;
pline.TransformBy(Matrix3d.Rotation(angle2, normal.CrossProduct(Vector3d.ZAxis), center));
// add the polyline to current space block table record
curSpace.AppendEntity(pline);
tr.AddNewlyCreatedDBObject(pline, true);
}
tr.Commit();
}
}
[CommandMethod("CMD")]
public void Cmd()
{
Document doc = Application.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
Editor ed = doc.Editor;
// prompt for the window polyline
var entOpts
= new PromptEntityOptions
("\nSelect a window: "); entOpts.SetRejectMessage("\nSelected object must be apolyline.");
entOpts
.AddAllowedClass(typeof(Polyline
),
true); var entRes = ed.GetEntity(entOpts);
if (entRes.Status != PromptStatus.OK)
return;
using (Transaction tr = db.TransactionManager.StartTransaction())
{
var window = (Polyline)tr.GetObject(entRes.ObjectId, OpenMode.ForRead);
// get the window center
Extents3d extents = window.GeometricExtents;
Point3d center = extents.MinPoint + (extents.MaxPoint - extents.MinPoint) / 2.0;
// get the normal of the window plane
Point2d pt
= new Point2d
(center
.X, center
.Y); Vector3d normal = window.Normal;
// check if the window is vertical
if (!normal.IsPerpendicularTo(Vector3d.ZAxis))
{
ed.WriteMessage("\nThe window is not vertical.");
return;
}
// get the nnormal angle about XY plane
var angle0
= normal
.AngleOnPlane(new Plane
());
// prompt for the first angle
var angRes = ed.GetAngle("\nAngle 1: ");
if (angRes.Status != PromptStatus.OK)
return;
var angle1 = angRes.Value;
// prompt for the second angle
angRes = ed.GetAngle("\nAngle 2: ");
if (angRes.Status != PromptStatus.OK)
return;
var angle2 = angRes.Value;
var curSpace = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite);
// create the polyline
using (var pline
= new Polyline
(3)) {
// add vertices
pline.AddVertexAt(0, pt, 0.0, 0.0, 0.0);
pline.AddVertexAt(1, Polar(pt, angle0 - angle1, 5000.0), 0.0, 0.0, 0.0);
pline.AddVertexAt(2, Polar(pt, angle0 + angle1, 5000.0), 0.0, 0.0, 0.0);
pline.Closed = true;
// transform the polyline
pline.Elevation = center.Z;
pline.TransformBy(Matrix3d.Rotation(angle2, normal.CrossProduct(Vector3d.ZAxis), center));
// project the polyline to XY plane
using (var flattenPline
= new Polyline
(3)) {
flattenPline.AddVertexAt(0, pline.GetPoint3dAt(0).Convert2d(plane), 0.0, 0.0, 0.0);
flattenPline.AddVertexAt(1, pline.GetPoint3dAt(1).Convert2d(plane), 0.0, 0.0, 0.0);
flattenPline.AddVertexAt(2, pline.GetPoint3dAt(2).Convert2d(plane), 0.0, 0.0, 0.0);
flattenPline.Closed = true;
flattenPline.Elevation = center.Z;
var curves
= new DBObjectCollection
();
// create a region form the pojected polyline
curves.Add(flattenPline);
using (var regions = Region.CreateFromCurves(curves))
{
var region = (Region)regions[0];
// create and extruded solid from region
using (var solid
= new Solid3d
()) {
solid.Extrude(region, 5000.0, 0.0);
// slice the solid with the polyline plane
solid.Slice(pline.GetPlane());
// add the solid to current space block table record
curSpace.AppendEntity(solid);
tr.AddNewlyCreatedDBObject(solid, true);
}
}
}
// add the polyline to current space block table record
curSpace.AppendEntity(pline);
tr.AddNewlyCreatedDBObject(pline, true);
}
tr.Commit();
}
}
public Point2d Polar(Point2d basePoint, double angle, double distance)
{
basePoint.X + distance * Math.Cos(angle),
basePoint.Y + distance * Math.Sin(angle));
}
}
}