using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.Geometry;
using System;
[assembly: CommandClass(typeof(SolidSection.Commands))]
namespace SolidSection
{
public class Commands
{
[CommandMethod("SS")]
public void SectionSolid()
{
Document doc =
Application.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
Editor ed = doc.Editor;
// Ask the user to select an entity to section
PromptEntityOptions peo =
new PromptEntityOptions(
"\nSelect entity to section: "
);
peo.SetRejectMessage(
"\nEntity must be a 3D solid, " +
"surface, body or region."
);
peo.AddAllowedClass(typeof(Solid3d), false);
peo.AddAllowedClass(
typeof(Autodesk.AutoCAD.DatabaseServices.Surface),
false
);
peo.AddAllowedClass(typeof(Body), false);
peo.AddAllowedClass(typeof(Region), false);
PromptEntityResult per =
ed.GetEntity(peo);
if (per.Status != PromptStatus.OK)
return;
ObjectId entId =
per.ObjectId;
// Ask the user to define a section plane
Point3dCollection pts =
new Point3dCollection();
PromptPointResult ppr =
ed.GetPoint("\nPick first point for section: ");
if (ppr.Status != PromptStatus.OK)
return;
pts.Add(ppr.Value);
PromptPointOptions ppo =
new PromptPointOptions(
"\nPick end point for section: "
);
ppo.BasePoint = ppr.Value;
ppo.UseBasePoint = true;
ppr =
ed.GetPoint(ppo);
if (ppr.Status != PromptStatus.OK)
return;
pts.Add(ppr.Value);
// Ask what type of section to create
PromptKeywordOptions pko =
new PromptKeywordOptions(
"Enter section type "
);
pko.AllowNone = true;
pko.Keywords.Add("2D");
pko.Keywords.Add("3D");
pko.Keywords.Add("Live");
pko.Keywords.Default = "3D";
PromptResult pkr =
ed.GetKeywords(pko);
if (pkr.Status != PromptStatus.OK)
return;
SectionType st;
if (pkr.StringResult == "2D")
st = SectionType.Section2d;
else if (pkr.StringResult == "Live")
st = SectionType.LiveSection;
else // pkr.StringResult == "3D"
st = SectionType.Section3d;
// Now we're ready to do the real work
Transaction tr =
db.TransactionManager.StartTransaction();
using (tr)
{
try
{
BlockTable bt =
(BlockTable)tr.GetObject(
db.BlockTableId,
OpenMode.ForRead
);
BlockTableRecord ms =
(BlockTableRecord)tr.GetObject(
bt[BlockTableRecord.ModelSpace],
OpenMode.ForWrite
);
// Now let's create our section
Section sec =
new Section(pts, Vector3d.ZAxis);
sec.State = SectionState.Plane;
// The section must be added to the drawing
ObjectId secId =
ms.AppendEntity(sec);
tr.AddNewlyCreatedDBObject(sec, true);
// Set up some of its direct properties
sec.SetHeight(
SectionHeight.HeightAboveSectionLine,
3.0
);
sec.SetHeight(
SectionHeight.HeightBelowSectionLine,
1.0
);
// ... and then its settings
SectionSettings ss =
(SectionSettings)tr.GetObject(
sec.Settings,
OpenMode.ForWrite
);
// Set our section type
ss.CurrentSectionType = st;
// We only set one additional option if "Live"
if (st == SectionType.LiveSection)
//sec.EnableLiveSection(true);
sec.IsLiveSectionEnabled = true;
else
{
// Non-live (i.e. 2D or 3D) settings
ObjectIdCollection oic =
new ObjectIdCollection();
oic.Add(entId);
ss.SetSourceObjects(st, oic);
if (st == SectionType.Section2d)
{
// 2D-specific settings
ss.SetVisibility(
st,
SectionGeometry.BackgroundGeometry,
true
);
ss.SetHiddenLine(
st,
SectionGeometry.BackgroundGeometry,
false
);
}
else if (st == SectionType.Section3d)
{
// 3D-specific settings
ss.SetVisibility(
st,
SectionGeometry.ForegroundGeometry,
true
);
}
// Finish up the common 2D/3D settings
ss.SetGenerationOptions(
st,
SectionGeneration.SourceSelectedObjects |
SectionGeneration.DestinationFile
);
}
// Open up the main entity
Entity ent =
(Entity)tr.GetObject(
entId,
OpenMode.ForRead
);
// Generate the section geometry
Array flEnts, bgEnts, fgEnts, ftEnts, ctEnts;
sec.GenerateSectionGeometry(
ent,
out flEnts,
out bgEnts,
out fgEnts,
out ftEnts,
out ctEnts
);
// Add the geometry to the modelspace
// (start by combining the various arrays,
// so we then have one loop, not four)
int numEnts =
flEnts.Length + fgEnts.Length +
bgEnts.Length + ftEnts.Length +
ctEnts.Length;
// Create the appropriately-sized array
Array ents =
Array.CreateInstance(
typeof(Entity),
numEnts
);
// Copy across the contents of the
// various arrays
int index = 0;
flEnts.CopyTo(ents, index);
index += flEnts.Length;
fgEnts.CopyTo(ents, index);
index += fgEnts.Length;
bgEnts.CopyTo(ents, index);
index += bgEnts.Length;
ftEnts.CopyTo(ents, index);
index += ftEnts.Length;
ctEnts.CopyTo(ents, index);
// Our single loop to add entities
foreach (Entity ent2 in ents)
{
ms.AppendEntity(ent2);
tr.AddNewlyCreatedDBObject(ent2, true);
}
tr.Commit();
}
catch (System.Exception ex)
{
ed.WriteMessage(
"\nException: " + ex.Message
);
}
}
}
}
}