Issue
3D ソリッド オブジェクトを作成して API でブール演算すると、次のようなエラーメッセージを表示して処理に失敗してしまいます。
ソリッドまたはサーフェス ボディのブール演算に失敗しました。
モデリング操作エラー:
Error Code Number is xxxxxxx (xxxxxxx は数字)
ブール演算を成功させる方法はありますか?
Solution
モデリング操作エラーや、その要因となっているソリッドやサーフェスモデルの破損は、AutoCAD を含むオートデスク製品全般で共用している ACIS 由来のソリッド カーネル Autodesk Shape Manager の精度上の制限が原因となっているのが一般的です。このため、ObjectARX、.NET API、AutoLISP、ActiveX オートメーション(COM API)など、API の種類に関わらず発生することがあります。同様に、AutoCAD の UNION[和] コマンドや SUBTRACT[差] コマンドでも発生するはずです。また、複雑なソリッドやサーフェスモデルの作成時にも発生する場合があります。
AutoCAD 2027 以降のバージョンであれば、Autodesk Assistant がヒントを与えてくれる場合があります。Error Code Number is xxxxxxx ののエラー数字とともに確認することも出来ますので、念のため、確認してみてください。
ソリッドやサーフェスモデルが破損しているか否かは、SOLIDEDIT[ソリッド編集] コマンドの B オプション >> C オプション([ボディ(B)]: [チェック(C)])で確認することが出来ます。まずは、ソリッドやサーフェスモデルが健全かどうかを確認してみてください。
すべてのケースで問題を回避出来る訳ではありませんが、一般に、ソリッドやサーフェスモデル内部情報の破損の可能性を低減する、または、ブール演算時のエラーを低減するには、次のような構造をアドイン アプリケーション内で実装が推奨されています。
次の C# コードは、3D 処理前後で原点を基準に 1/100 に縮尺➔処理➔100 倍に拡大(元の大きさ復元)する参考例です。
...
using (Transaction tr = db.TransactionManager.StartTransaction())
{
Entity ent1 = (Entity)tr.GetObject(pent1.ObjectId, OpenMode.ForRead);
Entity ent2 = (Entity)tr.GetObject(pent2.ObjectId, OpenMode.ForRead);
// 原点(0,0,0)を基準に 1/100 へ縮尺するマトリックス
Matrix3d scaleDownMat = Matrix3d.Scaling(1.0 / 100.0, Point3d.Origin);
// 原点(0,0,0)を基準に 100 倍へ拡大するマトリックス
Matrix3d scaleUpMat = Matrix3d.Scaling(100.0, Point3d.Origin);
// 元オブジェクトは変更しないよう、複製してから縮尺
using (Entity ent1Scaled = (Entity)ent1.Clone())
using (Entity ent2Scaled = (Entity)ent2.Clone())
{
ent1Scaled.TransformBy(scaleDownMat);
ent2Scaled.TransformBy(scaleDownMat);
// 1/100 に縮尺したオブジェクトで 3D 処理(ブール演算・3D オブジェクト作成
// 作成した結果(オブジェクト)を、同じ原点(0,0,0)基準で 100 倍に戻す
entresult.TransformBy(scaleUpMat);
BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
BlockTableRecord ms = (BlockTableRecord)tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite);
ms.AppendEntity(entresult);
tr.AddNewlyCreatedDBObject(entresult, true);
}
tr.Commit();
}
...