A couple of irritating quirks have come to light here:
It would appear that there is some initialization going on that does not occur with the Editor.GetEntity, hence the problem with “f.SubentityPath”. The initialization is available with Solid3d.GetSubentityPathsAtGraphicsMarker, however, so it is possible to get a valid SubentID from the backside.
The other quirk is that the SubentityId[] requirement for all of the SolidEditing “Faces” methods is not implemented as the documentation states. I can’t find an object/array that is compatible. The SolidEditing “Face” methods do seem to work, and is what I used as a workaround in the sample.
[CommandMethod("mvts")]
public void mvts()
{
Document d = (Document)Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
Editor e = d.Editor;
PromptEntityOptions o = new PromptEntityOptions("select a solid");
o.SetRejectMessage("is not a solid");
o.AddAllowedClass(typeof(Solid3d), true);
PromptEntityResult r = e.GetEntity(o);
if (r.Status == PromptStatus.OK)
{
MoveTopFacesOfSolid2(d, r.ObjectId, 1, Vector3d.ZAxis);
}
}
static public void MoveTopFacesOfSolid2(Document d, ObjectId IdSolid3d, double hfinale, Vector3d vetextr)
{
using (Transaction t = d.TransactionManager.StartTransaction())
{
Solid3d s = t.GetObject(IdSolid3d, OpenMode.ForRead) as Solid3d;
AcBr.Brep brp = new AcBr.Brep(s);
Point3d pt = new Point3d();
Matrix3d mtrx = new Matrix3d();
int numIns = new int();
ObjectId[] ids = null;
FullSubentityPath[] fsP;
for (int i = 1; i < 1000; i++)
{
try
{
fsP = s.GetSubentityPathsAtGraphicsMarker
(SubentityType.Face, i, pt, mtrx, numIns, ids); //If GSM points to face
Autodesk.AutoCAD.BoundaryRepresentation.Face brepFace = new Autodesk.AutoCAD.BoundaryRepresentation.Face(fsP[0]);
if (TestFace(brepFace, vetextr))
{
s.UpgradeOpen();
SubentityId sid = fsP[0].SubentId;
Region reg = s.CopyFace(sid) as Region;
Solid3d s2 = new Solid3d();
s2.Extrude(reg, 1, 0);
s2.SetDatabaseDefaults();
Database m_db = HostApplicationServices.WorkingDatabase;
BlockTableRecord btr = (BlockTableRecord)(t.GetObject(m_db.CurrentSpaceId, OpenMode.ForWrite));
btr.AppendEntity(s2);
t.AddNewlyCreatedDBObject(s2, true);
s.BooleanOperation(BooleanOperationType.BoolUnite, s2);
break;
}
}
catch //If GSM points to non-face
{
continue;
}
}
t.Commit();
}
}
static public bool TestFace(AcBr.Face f, Vector3d vetextr)
{
ExternalBoundedSurface ebs = f.Surface as ExternalBoundedSurface;
if (ebs.IsPlane)
{
Plane BP = ebs.BaseSurface as Plane;
return BP.Normal == vetextr;
}
return false;
}