質問
AutoCAD .net APIで寸法拘束パラメータとユーザ定義パラメータをグループ化するグループフィルタを作成する方法はありますか。
回答
AutoCADのデータ構造として、グループフィルタはAssocNetworkのXData(拡張データ)にアプリケーション 名ACAD_NETWORK_GROUPSにて定義されます。グループフィルタの情報は、アプリケーションACAD_NETWORK_GROUPSの開始エントリ(1001,ACAD_NETWORK_GROUPS)に続いて、(1070,1)(1000, グループフィルタ名1)(1070,2)(1000, グループフィルタ名2)の形でデータを保持します。
ここで、Dxfグループ コード1070の値はグループフィルタの内部Idを、Dxfグループ コード1000の値はグループフィルタ名に対応します。
例えば拡張データの内容が(1001,ACAD_NETWORK_GROUPS)(1070,1)(1000, グループフィルタ1)(1070,2)(1000, グループフィルタ2)の場合、グループフィルタとして”グループフィルタ1”と”グループフィルタ2”が定義されており、それぞれの内部Idが1と2である状態となります。
グループフィルタ内のパラメータについては、上述の内部Idをパラメータ側から参照する形でAssocVariableのxDataに保存されている形となります。 AssocVariableのxDataにはアプリケーション名PARAMETER_GROUPSにて、(1001,PARAMETER_GROUPS)(1070,1)(1070,2)といった形でデータが保持されておりDxfグループコード1070の値が上述のグループフィルタのIdとなります。
このため、グループフィルタ(パラメータグループ)を新規作成する場合は、AssocNetworkのxDataに追加をする形となります。 また、既存のグループフィルタ内のパラメータを取得する場合には、AssocNetworkのxDataから対象のグループフィルタのIdを取得したのちに、各AssocVariableのxDataを参照して、PARAMETER_GROUPSアプリケーションに対象のグループフィルタのIdを持つデータがあるかを確認する形となります。
以下は新規のグループフィルタを作成するサンプルコードとなります。
[CommandMethod("AddFilterGroup")]
public static void AddFilterGroup()
{
Document dc = Application.DocumentManager.MdiActiveDocument;
Database db = dc.Database;
Editor ed = dc.Editor;
ObjectId networkId = AssocNetwork.GetInstanceFromObject(db.CurrentSpaceId, false, true, "ACAD_ASSOCNETWORK");
if (networkId == ObjectId.Null)
return;
const string APP_NAME = "ACAD_NETWORK_GROUPS";
PromptResult pr = ed.GetString("Type filter name to create.");
string groupFilterName = pr.StringResult;
using (Transaction tx = db.TransactionManager.StartTransaction())
{
RegAppTable regTable = (RegAppTable)tx.GetObject(db.RegAppTableId, OpenMode.ForRead);
if (!regTable.Has(APP_NAME))
{
regTable.UpgradeOpen();
RegAppTableRecord app = new RegAppTableRecord();
app.Name = APP_NAME;
regTable.Add(app);
tx.AddNewlyCreatedDBObject(app, true);
}
using (AssocNetwork network = tx.GetObject(networkId, OpenMode.ForWrite, false) as AssocNetwork)
{
ResultBuffer rb = network.XData;
if (rb != null)
{
IEnumerator enu = rb.GetEnumerator();
while (enu.MoveNext())
{
TypedValue wk = (TypedValue)enu.Current;
ed.WriteMessage("\n" + wk.TypeCode.ToString() + " = " + wk.Value.ToString());
}
int nextIndex = 1;
var wrapper = rb.Cast<TypedValue>();
//Find "ACAD_NETWORK_GROUPS" in xData
if (0 != wrapper.Where<TypedValue>(
tv => tv.Value.ToString() == APP_NAME && tv.TypeCode == 1001).Count<TypedValue>()) {
//if there is "ACAD_NETWORK_GROUPS" in xData, check duplication of filter.
bool inTargetApp = false;
if (0 != wrapper.Where(tv =>{
if (inTargetApp)
{
if (tv.TypeCode == 1000 && tv.Value.ToString() == groupFilterName)
{
return true;
}
else if (tv.TypeCode == 1001)
{
inTargetApp = false;
}
}
else
{
if (tv.Value.ToString() == APP_NAME && tv.TypeCode == 1001)
{
inTargetApp = true;
}
}
return false;
}).Count())
{
//abort if there is same filter name.
ed.WriteMessage("\nThe group fileter already exists.");
tx.Abort();
return;
}
else
{
inTargetApp = false;
nextIndex = wrapper.Max<TypedValue>(tv =>
{
if (inTargetApp)
{
if (tv.TypeCode == 1070)
{
return Convert.ToInt32(tv.Value);
}
else if (tv.TypeCode == 1001)
{
inTargetApp = false;
}
}
else
{
if (tv.Value.ToString() == APP_NAME && tv.TypeCode == 1001)
{
inTargetApp = true;
}
}
return 0;
}
) + 1;
rb = new ResultBuffer();
inTargetApp = false;
bool added = false;
foreach (var tv in wrapper)
{
if (inTargetApp)
{
//start of next application
if (tv.TypeCode == 1001)
{
inTargetApp = false;
added = true;
rb.Add(new TypedValue(1070, nextIndex));
rb.Add(new TypedValue(1000, groupFilterName));
}
rb.Add(tv);
}
else
{
rb.Add(tv);
if (tv.Value.ToString() == APP_NAME && tv.TypeCode == 1001)
{
inTargetApp = true;
}
}
}
if(!added)
{
rb.Add(new TypedValue(1070, nextIndex));
rb.Add(new TypedValue(1000, groupFilterName));
}
}
}
else
{
//Add "ACAD_NETWORK_GROUPS" if not found.
rb.Add(new TypedValue(1001, APP_NAME));
rb.Add(new TypedValue(1070, nextIndex));
rb.Add(new TypedValue(1000, groupFilterName));
}
network.XData = rb;
}
else
{
network.XData = new ResultBuffer(new TypedValue(1001, APP_NAME), new TypedValue(1070, 1), new TypedValue(1000, groupFilterName));
}
}
tx.Commit();
}
ed.Command("PARAMETERS");
}
また、以下は指定したパラメータグループに含まれているパラメータを確認するサンプルコードとなります。
[CommandMethod("GetFilterGroupParameters")]
public static void GetFilterGroupParameters()
{
Document dc = Application.DocumentManager.MdiActiveDocument;
Database db = dc.Database;
Editor ed = dc.Editor;
ObjectId networkId = AssocNetwork.GetInstanceFromObject(db.CurrentSpaceId, false, true, "ACAD_ASSOCNETWORK");
if (networkId == ObjectId.Null)
return;
const string APP_NAME = "ACAD_NETWORK_GROUPS";
PromptResult pr = ed.GetString("Type filter name to get parameters.");
string groupFilterName = pr.StringResult;
using (Transaction tx = db.TransactionManager.StartTransaction())
{
RegAppTable regTable = (RegAppTable)tx.GetObject(db.RegAppTableId, OpenMode.ForRead);
if (!regTable.Has(APP_NAME))
{
ed.WriteMessage("\n There is no spcified parameter group.");
return;
}
using (AssocNetwork network = tx.GetObject(networkId, OpenMode.ForWrite, false) as AssocNetwork)
{
ResultBuffer rb = network.XData;
if (rb == null)
{
ed.WriteMessage("\n There is no spcified parameter group.");
return;
}
IEnumerator enu = rb.GetEnumerator();
while (enu.MoveNext())
{
TypedValue wk = (TypedValue)enu.Current;
ed.WriteMessage("\n" + wk.TypeCode.ToString() + " = " + wk.Value.ToString());
}
var wrapper = rb.Cast<TypedValue>();
bool inTargetApp = false;
int targetIndex = 0;
bool found = false;
foreach(var tv in wrapper)
if (inTargetApp)
{
if(tv.TypeCode == 1070)
{
targetIndex = Convert.ToInt32(tv.Value);
}
else if(tv.TypeCode == 1000 && tv.Value.ToString() == groupFilterName)
{
found = true;
break;
}
}
else
{
if (tv.Value.ToString() == APP_NAME && tv.TypeCode == 1001)
{
inTargetApp = true;
}
}
}
if (!found)
{
ed.WriteMessage("\n There is no spcified parameter group.");
return;
}
//Now iterate though AssocActions to find variable which has targetIndex in it's xData.
foreach (ObjectId actionId in network.GetActions)
{
if (actionId == ObjectId.Null)
continue;
DBObject obj = tx.GetObject(actionId, OpenMode.ForRead);
if (actionId.ObjectClass.IsDerivedFrom(RXObject.GetClass(typeof(AssocVariable))))
{
AssocVariable var = obj as AssocVariable;
ed.WriteMessage("\n - AssocVariable " + var.Name + " = " + var.Expression);
ResultBuffer pRb = var.XData;
if (pRb != null)
{
var pWrapper = pRb.Cast<TypedValue>();
//loop thourough result buffer to find typedvalue with (1070, targetIndex).
inTargetApp = false;
foreach (var tv in pWrapper)
{
if (inTargetApp)
{
if (tv.TypeCode == 1070 && targetIndex == Convert.ToInt32(tv.Value))
{
ed.WriteMessage(" is referenced by specified group.");
}
else if(tv.TypeCode == 1001)
{
inTargetApp = false;
}
}
else
{
if (tv.Value.ToString() == "PARAMETER_GROUPS" && tv.TypeCode == 1001)
{
inTargetApp = true;
}
}
}
}
}
}
}
tx.Commit();
}
}
記事全体を表示