Thank you very much Rene (and thanks to Fixo too) this solved my problem.
Edit : new release
using System.Windows.Forms;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.Runtime;
using AcApp = Autodesk.AutoCAD.ApplicationServices.Application;
namespace VanillaMPolygon
{
public class MpgClass : IExtensionApplication
{
void IExtensionApplication.Initialize()
{
string ver = AcApp.GetSystemVariable("ACADVER").ToString().Substring(0, 2);
Autodesk.AutoCAD.Runtime.SystemObjects.DynamicLinker.LoadModule("AcMPolygonObj" + ver + ".dbx", false, false);
}
void IExtensionApplication.Terminate()
{
}
[CommandMethod("PL2MPG")]
public void PL2MPG()
{
Editor ed = AcApp.DocumentManager.MdiActiveDocument.Editor;
try
{
Database db = HostApplicationServices.WorkingDatabase;
TypedValue[] filter = { new TypedValue(-4, "<or"),
new TypedValue(0, "CIRCLE"),
new TypedValue(-4, "<and"),
new TypedValue(0, "LWPOLYLINE"),
new TypedValue(-4, "&"),
new TypedValue(70, 1),
new TypedValue(-4, "and>"),
new TypedValue(-4, "<and"),
new TypedValue(0, "POLYLINE"),
new TypedValue(-4, "&"),
new TypedValue(70, 1),
new TypedValue(-4, "<not"),
new TypedValue(-4, "&"),
new TypedValue(70, 120),
new TypedValue(-4, "not>"),
new TypedValue(-4, "and>"),
new TypedValue(-4, "or>"),
};
SelectionFilter selFilter = new SelectionFilter(filter);
PromptSelectionResult result = ed.GetSelection(selFilter);
if (result.Status != PromptStatus.OK)
return;
ObjectId[] selSet = result.Value.GetObjectIds();
double elev;
Vector3d norm;
if (!isValidSelSet(selSet, out elev, out norm))
return;
double scale = (double)AcApp.GetSystemVariable("HPSCALE");
PromptStringOptions pso = new PromptStringOptions("\nEnter the pattern name or a dot (.) for none: ");
pso.AllowSpaces = false;
pso.DefaultValue = (string)AcApp.GetSystemVariable("HPNAME");
PromptResult psr = ed.GetString(pso);
if (psr.Status != PromptStatus.OK)
return;
string pat = psr.StringResult.ToUpper();
if (pat != ".")
{
try
{
AcApp.SetSystemVariable("HPNAME", pat);
if ((pat != "SOLID") && (pat != "_SOLID"))
{
PromptDoubleOptions pdo = new PromptDoubleOptions("\nEnter the pattern scale: ");
pdo.AllowNegative = false;
pdo.AllowZero = false;
pdo.AllowNone = true;
pdo.DefaultValue = scale;
PromptDoubleResult pdr = ed.GetDouble(pdo);
if (pdr.Status != PromptStatus.OK)
return;
scale = pdr.Value;
AcApp.SetSystemVariable("HPSCALE", scale);
}
}
catch
{
ed.WriteMessage("\nInvalid pattern: " + pat);
pat = ".";
return;
}
}
PromptKeywordOptions pko = new PromptKeywordOptions("\nErase source objects ? [Yes/No]: ", "Yes No");
pko.AllowNone = true;
pko.Keywords.Default = "No";
psr = ed.GetKeywords(pko);
if (psr.Status != PromptStatus.OK)
return;
using (Transaction tr = db.TransactionManager.StartTransaction())
{
BlockTableRecord btr = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite);
MPolygon mPolygon = new MPolygon();
Entity ent;
btr.AppendEntity(mPolygon);
tr.AddNewlyCreatedDBObject(mPolygon, true);
mPolygon.UpgradeOpen();
mPolygon.PatternScale = scale;
if (pat != ".")
mPolygon.SetPattern(HatchPatternType.PreDefined, pat);
mPolygon.DowngradeOpen();
foreach (ObjectId objId in selSet)
{
ent = (Entity)objId.GetObject(OpenMode.ForRead);
if (ent is Polyline)
mPolygon.AppendLoopFromBoundary((Polyline)ent, true, 1E-12);
else if (ent is Circle)
mPolygon.AppendLoopFromBoundary((Circle)ent, true, 1E-12);
else
mPolygon.AppendLoopFromBoundary((Polyline2d)ent, true, 1E-12);
}
mPolygon.BalanceTree();
mPolygon.Elevation = elev;
mPolygon.Normal = norm;
if (mPolygon.PatternName != "") mPolygon.EvaluateHatch(true);
int cnt = 0;
if (psr.StringResult == "Yes")
foreach (ObjectId obj in selSet)
{
try
{
ent = (Entity)obj.GetObject(OpenMode.ForWrite);
ent.Erase();
}
catch
{
cnt++;
}
}
if (0 < cnt)
{
string msg = cnt == 1 ?
" object on locked layer will not be erased" :
" objects on locked layer will not be erased";
MessageBox.Show(
cnt.ToString() + msg,
"PL2MPG",
MessageBoxButtons.OK,
MessageBoxIcon.Exclamation);
}
tr.Commit();
}
}
catch (Autodesk.AutoCAD.Runtime.Exception ex)
{
ed.WriteMessage("Error: " + ex.Message);
}
catch (System.Exception ex)
{
ed.WriteMessage("Error: " + ex.Message);
}
}
private bool isValidSelSet(ObjectId[] selSet, out double elev, out Vector3d norm)
{
Editor ed = AcApp.DocumentManager.MdiActiveDocument.Editor;
Database db = HostApplicationServices.WorkingDatabase;
Polyline pl;
Circle circ;
Polyline2d p2d;
Tolerance tol = new Tolerance(1E-12, 1E-12);
using (Transaction tr = db.TransactionManager.StartTransaction())
{
Entity ent = (Entity)selSet[0].GetObject(OpenMode.ForRead);
pl = ent as Polyline;
if (pl != null)
{
elev = pl.Elevation;
norm = pl.Normal;
}
else
{
circ = ent as Circle;
if (circ != null)
{
elev = circ.Center.TransformBy(Matrix3d.WorldToPlane(circ.Normal)).Z;
norm = circ.Normal;
}
else
{
p2d = ent as Polyline2d;
elev = p2d.Elevation;
norm = p2d.Normal;
}
}
for (int i = 1; i < selSet.Length; i++)
{
ent = (Entity)selSet[i].GetObject(OpenMode.ForRead);
pl = ent as Polyline;
if (pl != null)
{
if ((elev - pl.Elevation) > 1E-12)
{
ed.WriteMessage("\nThe objects doesn't have the same elevation.");
tr.Commit();
return false;
}
else if (!norm.IsEqualTo(pl.Normal, tol))
{
ed.WriteMessage("\nThe objects doesn't have the same normal.");
tr.Commit();
return false;
}
}
else
{
circ = ent as Circle;
if (circ != null)
{
if ((elev - circ.Center.TransformBy(Matrix3d.WorldToPlane(circ.Normal)).Z) > 1E-12)
{
ed.WriteMessage("\nThe objects doesn't have the same elevation..");
tr.Commit();
return false;
}
else if (!norm.IsEqualTo(circ.Normal, tol))
{
ed.WriteMessage("\nThe objects doesn't have the same normal.");
tr.Commit();
return false;
}
}
else
{
p2d = ent as Polyline2d;
if ((elev - p2d.Elevation) > 1e-12)
{
ed.WriteMessage("\nThe objects doesn't have the same elevation.");
tr.Commit();
return false;
}
else if (!norm.IsEqualTo(p2d.Normal, tol))
{
ed.WriteMessage("\nThe objects doesn't have the same normal.");
tr.Commit();
return false;
}
}
}
}
tr.Commit();
return true;
}
}
}
}