namespace PTO
{/// <summary>
/// https://www.keanw.com/2013/12/disabling-snapping-to-specific-autocad-objects-using-net-part-1.html
/// </summary>
public class ViborSnap
{
public static bool m_isNotifyEnabled = false;
const string regAppName = "TTIF_SNAP";
private static OSOverrule _osOverrule = null;
// Object Snap Overrule to prevent snapping to objects
// with certain XData attached
public class OSOverrule : OsnapOverrule
{
public OSOverrule()
{
// Tell AutoCAD to filter on our application name
// (this should mean our overrule only gets called
// on objects possessing XData with this name)
SetXDataFilter(regAppName);
}
public override void GetObjectSnapPoints(
Entity ent,
ObjectSnapModes mode,
IntPtr gsm,
Point3d pick,
Point3d last,
Matrix3d view,
Point3dCollection snap,
IntegerCollection geomIds
) { }
public override void GetObjectSnapPoints(
Entity ent,
ObjectSnapModes mode,
IntPtr gsm,
Point3d pick,
Point3d last,
Matrix3d view,
Point3dCollection snaps,
IntegerCollection geomIds,
Matrix3d insertion
) { }
public override bool IsContentSnappable(Entity entity)
{
return false;
}
}
private static void ToggleOverruling(bool on)
{
if (on)
{
if (_osOverrule == null)
{
_osOverrule = new OSOverrule();
ObjectOverrule.AddOverrule( RXObject.GetClass(typeof(Entity)), _osOverrule, false );
}
ObjectOverrule.Overruling = true;
}
else
{
if (_osOverrule != null)
{
ObjectOverrule.RemoveOverrule(RXObject.GetClass(typeof(Entity)), _osOverrule);
_osOverrule.Dispose();
_osOverrule = null;
}
// I don't like doing this and so have commented it out:
// there's too much risk of stomping on other overrules...
// ObjectOverrule.Overruling = false;
}
}
[CommandMethod("ИгнорSnapSelection_On")]
public static void DisableSnapping()
{
var doc = Application.DocumentManager.MdiActiveDocument;
var db = doc.Database;
var ed = doc.Editor;
// Start by getting the entities to disable snapping for.
// If none selected, turn off the overrule
using (Transaction tr = db.TransactionManager.StartTransaction())
{
// получаем ссылку на пространство модели (ModelSpace)
BlockTableRecord ms = (BlockTableRecord)tr.GetObject(SymbolUtilityServices.GetBlockModelSpaceId(db), OpenMode.ForRead);
// "пробегаем" по всем объектам в пространстве модели
foreach (ObjectId id in ms)
{
// приводим каждый из них к типу Entity
Entity entity = (Entity)tr.GetObject(id, OpenMode.ForRead);
}
ToggleOverruling(true);
// Start a transaction to modify the entities' XData
// Make sure our RegAppID is in the table
var rat =
(RegAppTable)tr.GetObject(db.RegAppTableId, OpenMode.ForRead);
if (!rat.Has(regAppName))
{
rat.UpgradeOpen();
var ratr = new RegAppTableRecord();
ratr.Name = regAppName;
rat.Add(ratr);
tr.AddNewlyCreatedDBObject(ratr, true);
}
// Create the XData and set it on the object
using (
var rb =
new ResultBuffer(
new TypedValue((int)DxfCode.ExtendedDataRegAppName, regAppName),
new TypedValue((int)DxfCode.ExtendedDataInteger16,1)
)
)
{
foreach (ObjectId so in ms)
{
foreach (string sLayerName_for in FiltrPerem.namelayerCreate)//работает только при списке из одного значения
{
var ent =
tr.GetObject(so, OpenMode.ForWrite, false, true) as Entity;
if (ent != null && ent.Layer.ToString() != sLayerName_for)
{
ent.XData = rb;
}
}
}
};
tr.Commit();
}
}
[CommandMethod("ИгнорSnapSelection_Off")]
public static void EnableSnapping()
{
var doc = Application.DocumentManager.MdiActiveDocument;
var db = doc.Database;
var ed = doc.Editor;
// Start a transaction to modify the entities' XData
using (Transaction tr = db.TransactionManager.StartTransaction())
{
// получаем ссылку на пространство модели (ModelSpace)
BlockTableRecord ms = (BlockTableRecord)tr.GetObject(SymbolUtilityServices.GetBlockModelSpaceId(db), OpenMode.ForRead);
// "пробегаем" по всем объектам в пространстве модели
foreach (ObjectId id in ms)
{
// приводим каждый из них к типу Entity
Entity entity = (Entity)tr.GetObject(id, OpenMode.ForRead);
}
// Create a ResultBuffer and use it to remove the XData
// from the object
using (
var rb =
new ResultBuffer(
new TypedValue(
(int)DxfCode.ExtendedDataRegAppName, regAppName
)
)
)
{
foreach (ObjectId so in ms)
{
foreach (string sLayerName_for in FiltrPerem.namelayerCreate)
{
var ent =
tr.GetObject(so, OpenMode.ForWrite, false, true) as Entity;//Тут ошибка для объекта на заблокированном слое
if (ent != null)
{
ent.XData = rb;
}
}
}
};
tr.Commit();
}
}
}
}