質問
Inventorの2D図面に配置したView内の各コンポーネントを、AutoCAD図面のブロックにする方法はありますか?
回答
次のStepでInventorとAutoCADのAPIを用いてInventorの2D図面を加工することで、2D図面に配置したView内の各コンポーネントをAutoCADのブロック化することが可能です。 ただし、2D図面でViewとして配置したアセンブリの直下のコンポーネントの単位でのみブロック化が可能です。サブアセンブリ配下のコンポーネントについては個別のブロックとすることは出来ません。 Step 1.Inventor 2D図面を構成する図形(CurveやFaceやEdge 等)を、図形の元となるコンポーネント毎に層を作成して分類 Step 2.1で加工した図面をInventorの出力機能を用いてAutoCAD図面として出力 Step 3.2で出力したAutoCAD図面で、各層の図形をブロック化して配置 Step 1.Inventor 2D図面を構成する図形(CurveやFaceやEdge 等)を、図形の元となるコンポーネント毎に層を作成して分類 InventorのAPIで、DrawingView.DrawingCurves( [ModelObject] As Variant ) As DrawingCurvesEnumerator プロパティを利用してInventor 2D図面を構成する図形(CurveやFaceやEdge 等)を、図形の元となるコンポーネント毎に層を作成して分類します。 以下は、この処理を行うVBAのコードです。実行にはVBAエディタから「ツール」-「参照設定」にて「Microsoft Scripting Runtime」の参照設定が必要です。
Option Explicit
Sub ClassifyDrawingCurvesToOccurenceLayer()
ThisApplication.ScreenUpdating = False
If ThisApplication.ActiveDocumentType <> kDrawingDocumentObject Then
MsgBox "This macro is for drawing document."
Exit Sub
End If
Dim oDoc As DrawingDocument
Set oDoc = ThisApplication.ActiveDocument
Dim oTO As TransientObjects
Set oTO = ThisApplication.TransientObjects
Dim oSheet As Sheet
Dim oDrawingView As DrawingView
Dim layerNameObjDic As Scripting.Dictionary
Set layerNameObjDic = New Scripting.Dictionary
Dim oTrans As Transaction
Set oTrans = ThisApplication.TransactionManager.StartTransaction(ThisApplication.ActiveDocument, "AssignOccurencesToLayer")
For Each oSheet In oDoc.Sheets
For Each oDrawingView In oSheet.DrawingViews
Dim refAssyDef As ComponentDefinition
If oDrawingView.ReferencedDocumentDescriptor.ReferencedDocumentType = kPresentationDocumentObject Then
Set refAssyDef = oDrawingView.ReferencedDocumentDescriptor.ReferencedDocument.ReferencedDocuments(1).ComponentDefinition
ElseIf oDrawingView.ReferencedFile.DocumentType = kAssemblyDocumentObject Then
Set refAssyDef = oDrawingView.ReferencedFile.DocumentDescriptor.ReferencedDocument.ComponentDefinition
End If
Dim oComponentOccurence As ComponentOccurrence
For Each oComponentOccurence In refAssyDef.Occurrences
Dim oDrawingCurve As DrawingCurve
For Each oDrawingCurve In oDrawingView.DrawingCurves(oComponentOccurence)
Dim oLayer As Layer
Dim LayerName As String
Set oLayer = Nothing
Dim oSeg As DrawingCurveSegment
For Each oSeg In oDrawingCurve.Segments
Dim ComponentOccurenceName As String
ComponentOccurenceName = oComponentOccurence.Name
ComponentOccurenceName = Replace(ComponentOccurenceName, ":", "#")
LayerName = "Occurence:" & ComponentOccurenceName
If oLayer Is Nothing Then
Set oLayer = GetOrCreateLayer(LayerName, oSeg.Layer, oDoc)
End If
Dim objColl As ObjectCollection
If Not layerNameObjDic.Exists(LayerName) Then
Set objColl = oTO.CreateObjectCollection
layerNameObjDic.Add LayerName, objColl
Else
Set objColl = layerNameObjDic.Item(LayerName)
End If
objColl.Add oSeg
Next
Next
Next
Dim key As Variant
For Each key In layerNameObjDic.Keys
Set objColl = layerNameObjDic.Item(key)
Set oLayer = oDoc.StylesManager.Layers.Item(key)
Call oDrawingView.Parent.ChangeLayer(objColl, oLayer)
objColl.Clear
Next
layerNameObjDic.RemoveAll
Next
Next
oTrans.End
ThisApplication.ScreenUpdating = True
End Sub
Function GetOrCreateLayer(LayerName As String, sourceLayer As Layer, oDoc As DrawingDocument)
Set GetOrCreateLayer = Nothing
Dim oNewLayer As Layer
On Error Resume Next
Set oNewLayer = oDoc.StylesManager.Layers.Item(LayerName)
On Error GoTo 0
If oNewLayer Is Nothing Then
Set oNewLayer = sourceLayer.Copy(LayerName)
End If
Set GetOrCreateLayer = oNewLayer
End Function
Step 2.Step 1で加工した図面をInventorの出力機能を用いてAutoCAD図面として出力
InventorのDWG Translator Addinを用いてAutoCAD図面を出力します。
以下のVBAのサンプルコードの実行には、 <Path to ini file>を使用する出力設定Iniファイルに、<Path to output dwg file>を出力するDWGファイルのパス(拡張子.dwg付き)に置き換えが必要です。
なお、出力設定のIniファイルは、InventoのGUIから、「ファイル」-「コピーを名前を付けて保存」で、「コピーを名前を付けて保存」ダイアログで、「保存先のファイルの種類」として「AutoCAD DWGファイル(*.dwg)」を選択して、「オプション」ボタンを押下して「DWG図面ファイルのエクスポートオプション」ダイアログを起動し、ダイアログ内の「設定を保存」ボタンから作成が可能です。
Public Sub DWGOutUsingTranslatorAddIn()
Dim oDWGAddIn As TranslatorAddIn
Set oDWGAddIn = ThisApplication.ApplicationAddIns.ItemById("{C24E3AC2-122E-11D5-8E91-0010B541CD80}")
If oDWGAddIn Is Nothing Then
MsgBox "The DWG add-in could not be found."
Exit Sub
End If
If Not oDWGAddIn.Activated Then
oDWGAddIn.Activate
End If
Dim oNameValueMap As NameValueMap
Set oNameValueMap = ThisApplication.TransientObjects.CreateNameValueMap
Dim strIniFile As String
strIniFile = "Path to output dwg file"
Call oNameValueMap.Add("Export_Acad_IniFile", strIniFile)
Dim oContext As TranslationContext
Set oContext = ThisApplication.TransientObjects.CreateTranslationContext
oContext.Type = kFileBrowseIOMechanism
Dim oOutputFile As DataMedium
Set oOutputFile = ThisApplication.TransientObjects.CreateDataMedium
oOutputFile.FileName = "Path to output dwg file"
Call oDWGAddIn.SaveCopyAs(ThisApplication.ActiveDocument, oContext, oNameValueMap, oOutputFile)
End Sub
Step 3.2で出力したAutoCAD図面で、各層の図形をブロック化して配置 Step 2で出力したAutoCAD図面で、名前がOccurenceで始まる各層にある図形をブロック化してブロックインスタンスを配置、元図形を削除します。
[CommandMethod("Convert2Block")]
public void Convert2Block()
{
Document activeDoc = Application.DocumentManager.MdiActiveDocument;
Database db = activeDoc.Database;
Editor ed = activeDoc.Editor;
ed.Command("._Zoom", "A");
using (Transaction tr = db.TransactionManager.StartTransaction())
{
BlockTable bt = tr.GetObject(db.BlockTableId, OpenMode.ForWrite) as BlockTable;
BlockTableRecord modelSpaceBTR = tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord;
SymbolTable symTable = (SymbolTable)tr.GetObject(db.LayerTableId, OpenMode.ForRead);
foreach (ObjectId id in symTable)
{
LayerTableRecord symbol = tr.GetObject(id, OpenMode.ForRead) as LayerTableRecord;
if (!symbol.Name.StartsWith("Occurence"))
{
continue;
}
String name = symbol.Name;
name = name.Replace("#", @"`#");
// Create a TypedValue array to define the filter criteria
TypedValue[] acTypValAr = new TypedValue[1];
acTypValAr.SetValue(new TypedValue((int)DxfCode.LayerName, name), 0);
// Assign the filter criteria to a SelectionFilter object
SelectionFilter acSelFtr = new SelectionFilter(acTypValAr);
// Request for objects to be selected in the drawing area
PromptSelectionResult acSSPrompt;
acSSPrompt = ed.SelectCrossingWindow(db.Extmin, db.Extmax, acSelFtr);
// If the prompt status is OK, objects were selected
if (acSSPrompt.Status != PromptStatus.OK)
{
continue;
}
SelectionSet acSSet = acSSPrompt.Value;
ed.WriteMessage("\nNumber of objects in {0} selected: {1}", symbol.Name, acSSet.Count.ToString());
ObjectId[] ids = acSSet.GetObjectIds();
//add a block table record with name
if (!bt.Has(symbol.Name))
{
//create new
BlockTableRecord record = new BlockTableRecord();
record.Name = symbol.Name;
bt.Add(record);
tr.AddNewlyCreatedDBObject(record, true);
}
else
{
continue;
}
ObjectId blockId = bt[symbol.Name];
//copy the select entities to block by using deepclone.
ObjectIdCollection collection = new ObjectIdCollection(ids);
IdMapping mapping = new IdMapping();
db.DeepCloneObjects(collection, blockId, mapping, false);
//erase select entities
foreach(ObjectId entid in ids)
{
Entity ent = tr.GetObject(entid, OpenMode.ForWrite) as Entity;
if (ent != null)
{
ent.Erase(true);
}
}
// create a new block reference
using (var br = new BlockReference(new Point3d(0,0,0), bt[symbol.Name]))
{
modelSpaceBTR.AppendEntity(br);
tr.AddNewlyCreatedDBObject(br, true);
}
}
ed.Regen();
tr.Commit();
}
}
記事全体を表示