Importing DWG with Blocks into SketchBlockDefinitions

Importing DWG with Blocks into SketchBlockDefinitions

lstyra
Contributor Contributor
1,021 Views
4 Replies
Message 1 of 5

Importing DWG with Blocks into SketchBlockDefinitions

lstyra
Contributor
Contributor

Hello,

in my plugin I want to mimic the 'import dwg file' command from the sketch menu. There you can tick a checkmark "Create Sketch Blocks" and the Translator Addin will convert all AutoCAD Blocks into Inventor SketchBlockDefinitions.

 

I have tried different TranslationContext.OpenIntoExisting types (Sketch or PartDucument), different TranslationContext.Type's and different NameValueMap / Ini file settings.

 

The Translator Plugin will create SketchBlocks only if I set TranslationContext.OpenIntoExisting to the current PartDocument, but even if I give it the same ini values which I have save while manually importing, the Translotor options dialog will pop up and unfortunatly, the SketchBlocks will be imported into a new document, not the current one.

 

But when I set TranslationContext.OpenIntoExisting to a PlanarSketch, Inventor ignores the "Create Sketch Blocks" switch and therefor will not create the needed SketchBlockDefinitions.

 

So, what's the right way to import AutoCAD Blocks from an DWG into SketchBlockDefinitions of the current PartDocument ?

 

Here's the sample of my code:

 

...
TranslatorAddIn dwgTranslator = (TranslatorAddIn)m_inventorApplication.ApplicationAddIns.get_ItemById("{C24E3AC2-122E-11D5-8E91-0010B541CD80}");
if (dwgTranslator == null)
{
MessageBox.Show("Could not find DwgTranslator AddIn ");
return false;
}
dwgTranslator.Activate();

// create a new Planar Sketch, as context for the import operation
PlanarSketch sketch = skeltonDoc.ComponentDefinition.Sketches.Add(skeltonDoc.ComponentDefinition.WorkPlanes[1]);

TranslationContext translationContext = m_inventorApplication.TransientObjects.CreateTranslationContext();
/*
kUnspecifiedIOMechanism
kDataDropIOMechanism
kFileBrowseIOMechanism
kPasteSpecialIOMechanism
*/
translationContext.Type = IOMechanismEnum.kDataDropIOMechanism;

//translationContext.OpenIntoExisting = skeltonDoc.ComponentDefinition.SketchBlockDefinitions;
//translationContext.OpenIntoExisting = sketch;
translationContext.OpenIntoExisting = skeltonDoc;

NameValueMap options = m_inventorApplication.TransientObjects.CreateNameValueMap();
DataMedium sourceData = m_inventorApplication.TransientObjects.CreateDataMedium();
// FullFileName of the DWG file that has the AutoCAD Block
sourceData.FileName = strBlockDwgFileName;

string strIniFile = @"C:\\Temp\dwgoacadxxx";
options.set_Value("Import_Acad_IniFile", strIniFile);

//dwgTranslator.ShowOpenOptions(sourceData, translationContext, options);

Object sourceObj;
dwgTranslator.Open(sourceData, translationContext, options, out sourceObj);

 

0 Likes
Accepted solutions (1)
1,022 Views
4 Replies
Replies (4)
Message 2 of 5

chandra.shekar.g
Autodesk Support
Autodesk Support

Hi @lstyra,

 

Try the following C# code to import / insert ACAD file(.dwg).

 

Inventor.Application m_inventorApplication = (Inventor.Application)System.Runtime.InteropServices.Marshal.GetActiveObject("Inventor.Application");

PartDocument skeltonDoc = (PartDocument)m_inventorApplication.Documents.Add(DocumentTypeEnum.kPartDocumentObject); Inventor.CommandManager oCmdMgr = m_inventorApplication.CommandManager; // create a new Planar Sketch, as context for the import operation PlanarSketch sketch = skeltonDoc.ComponentDefinition.Sketches.Add(skeltonDoc.ComponentDefinition.WorkPlanes[1]); sketch.Edit();
String sFileName = @"Path and file name of Dwg file"; oCmdMgr.PostPrivateEvent(PrivateEventTypeEnum.kFileNameEvent, sFileName); m_inventorApplication.SilentOperation = true; oCmdMgr.ControlDefinitions["SketchInsertAutoCADFileCmd"].Execute(); m_inventorApplication.SilentOperation = false; sketch.ExitEdit();

Before executing code, Launch Inventor.

 

Please feel free to contact if there is any doubt.

 

If solves problem, click on "Accept as solution" / give a "Kudo".

 

Thanks and regards,


CHANDRA SHEKAR G
Developer Advocate
Autodesk Developer Network



0 Likes
Message 3 of 5

lstyra
Contributor
Contributor

Thanks Chandra,

your method works fine.

But it does only work, if the user has previously set the right options (checkmark "Create Sketch Blocks") which might not always be the case.

 

 

0 Likes
Message 4 of 5

chandra.shekar.g
Autodesk Support
Autodesk Support

Hi @lstyra,

 

Currently, as Inventor API is not exposed to insert ACAD (Dwg) file and limitation of Inventor API. It is not possible to check "Create Sketch Blocks".

 

This idea can be posted under Inventor Idea station using following link.

 

https://forums.autodesk.com/t5/inventor-ideas/idb-p/v1232/tab/most-recent

 

Below API sample is to create and insert a Sketch Block Definition into a Part sketch.

 

Public Sub CreateSketchBlockDefinition()
    ' Set a reference to the part document.
    ' This assumes a part document is active.
    Dim oPartDoc As PartDocument
    Set oPartDoc = ThisApplication.ActiveDocument

    ' Create the new sketch block definition.
    Dim oSketchBlockDef As SketchBlockDefinition
    Set oSketchBlockDef = oPartDoc.ComponentDefinition.SketchBlockDefinitions.Add("My Block Def")

    ' Set a reference to the transient geometry object.
    Dim oTransGeom As TransientGeometry
    Set oTransGeom = ThisApplication.TransientGeometry

    ' Draw a 4cm x 3cm rectangle with the corner at (0,0)
    Dim oRectangleLines As SketchEntitiesEnumerator
    Set oRectangleLines = oSketchBlockDef.SketchLines.AddAsTwoPointRectangle( _
                                oTransGeom.CreatePoint2d(0, 0), _
                                oTransGeom.CreatePoint2d(4, 3))

End Sub

Public Sub InsertSketchBlockDefinition()

    ' Set a reference to the part document.
    ' This assumes a part document is active.
    Dim oPartDoc As PartDocument
    Set oPartDoc = ThisApplication.ActiveDocument

    Dim oCompDef As PartComponentDefinition
    Set oCompDef = oPartDoc.ComponentDefinition

    ' Create a new sketch on the X-Y work plane.
    Dim oSketch As PlanarSketch
    Set oSketch = oCompDef.Sketches.Add(oCompDef.WorkPlanes(3))

    ' Set a reference to the definition named "My Block Def"
    Dim oSketchBlockDef As SketchBlockDefinition
    Set oSketchBlockDef = oCompDef.SketchBlockDefinitions.Item("My Block Def")

    Dim oPosition As Point2d
    Set oPosition = ThisApplication.TransientGeometry.CreatePoint2d(10, 10)

    ' Insert the sketch block definition
    Call oSketch.SketchBlocks.AddByDefinition(oSketchBlockDef, oPosition)
End Sub

Please feel free to contact if there is any doubt.

 

If solves problem, click on "Accept as solution" / give a "Kudo".

 

Thanks and regards,


CHANDRA SHEKAR G
Developer Advocate
Autodesk Developer Network



0 Likes
Message 5 of 5

lstyra
Contributor
Contributor
Accepted solution

Hello Chandra,
sad to here that the option to import into SketchBlocks is currently not implemented in the Inventor API.

 

Creating the SketchBlockDefinitions by API is way to slow for my task, compared to the import into SketchBlocks.

 

In my project, I have multiple complex profiles which have to be created as Inventor sketch geometry.
If I would do this by API this will take multiple minutes.

But when I create the profiles as AutoCAD blocks by using a RealDWG dll and import this DWG as SketchBlocks the whole operation will only take 5 seconds.


So this functionality is quite important for me!

 

In the meantime I have found a 'dirty' workaround:

 

I have learned, that the import dialog will read its presets by an inifile named "%TEMP\dwgoacad210.ini". (Hopefully this filename will not be changed in the future...)
So I create this file in advance, with the settings I need ( mainly "CREATE SKETCH BLOCKS=Yes").
Then my code will spawn a second Thread, which will wait for the import dialog to appear.
After that my plugin will use the 'CmdMgr.ControlDefinitions["SketchInsertAutoCADFileCmd"].Execute()' aproach you described, but without the SilentOperation.
When the import dialog is opened, it will read it's presets from the ini file and my special tread will 'press' the 'finish' button.

Quite dirty, but it works 😉

 

 

 

private const int WM_LBUTTONDOWN = 0x0201;
private const int WM_LBUTTONUP = 0x0202;
Thread m_pushFinishButtonThread;
public bool m_bWorkerRunning = true;

[DllImport("user32.dll")]
public static extern int SendMessage(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam);
[DllImport("User32.dll")]
public static extern IntPtr FindWindow(String lpClassName, String lpWindowName);
[DllImport("user32.dll", SetLastError = true)]
public static extern IntPtr FindWindowEx(IntPtr parentHandle, IntPtr childAfter, string className, string windowTitle);

public void pushFinishButtonThread()
{
    do
    {
        IntPtr hwnd;
        IntPtr hwndChild = IntPtr.Zero;
        
        // find the import dialogs main window (my window name is german, so you have to adapt for every language you need to support)
        string strWindowTitle = "Importoptionen für Layer und Objekte";        
        hwnd = FindWindow(null, strWindowTitle);
        
        // the next lines are only if you have to support multiple languages...
        if (hwnd == IntPtr.Zero)
        {
            strWindowTitle = "english window name";
            hwnd = FindWindow(null, strWindowTitle);
        }
        if (hwnd == IntPtr.Zero)
        {
            strWindowTitle = "french window name";
            hwnd = FindWindow(null, strWindowTitle);
        }
        if (hwnd == IntPtr.Zero)
        {
            strWindowTitle = "italian window name";
            hwnd = FindWindow(null, strWindowTitle);
        }

        // only go here if we have found the dialog window
        if (hwnd != IntPtr.Zero)
        {
            //Get a handle for the "Finish button" button
            hwndChild = FindWindowEx(hwnd, IntPtr.Zero, "Button", "Fertig stellen");
            if (hwndChild == IntPtr.Zero)
            {
                hwndChild = FindWindowEx(hwnd, IntPtr.Zero, "Button", "english finish button text");
            }
            if (hwndChild == IntPtr.Zero)
            {
                hwndChild = FindWindowEx(hwnd, IntPtr.Zero, "Button", "french finish button text");
            }
            if (hwndChild == IntPtr.Zero)
            {
                hwndChild = FindWindowEx(hwnd, IntPtr.Zero, "Button", "italian finish button text");
            }            

            if (hwndChild == IntPtr.Zero)
            {
                m_Logger.log(LogFileManager.eReason.kInfo, "could not find Finish button");                        
            }
            else
            {
                // do a 'button press'
                SendMessage(hwndChild, WM_LBUTTONDOWN, IntPtr.Zero, IntPtr.Zero);
                SendMessage(hwndChild, WM_LBUTTONUP, IntPtr.Zero, IntPtr.Zero);
                SendMessage(hwndChild, WM_LBUTTONDOWN, IntPtr.Zero, IntPtr.Zero);
                SendMessage(hwndChild, WM_LBUTTONUP, IntPtr.Zero, IntPtr.Zero);                
                m_Logger.log(LogFileManager.eReason.kInfo, "pushFinishButtonThread finished it's job");
                return;
            }            
        }
        // wait a bit
        Thread.Sleep(50);
        // repeat when dialog window not found
    } while (m_bWorkerRunning == true);
    m_Logger.log(LogFileManager.eReason.kInfo, "pushFinishButtonThread finished without cancel");
}        

void ImportIntoSketchBlock(...)
{
    ...
    PlanarSketch sketch = skeltonDoc.ComponentDefinition.Sketches.Add(skeltonDoc.ComponentDefinition.WorkPlanes[1]);

    
    //strIniFile = @"C:\Users\user\AppData\Local\Temp\dwgoacad210.ini";
    string strIniFile = this.createDWGExportIni(m_inventorApplication, null);   

    try
    {
        sketch.Edit();
        // create the Thread function
        m_pushFinishButtonThread = new Thread(pushFinishButtonThread);      
        // start the Thread function
        m_pushFinishButtonThread.Start();
        m_inventorApplication.CommandManager.PostPrivateEvent(PrivateEventTypeEnum.kFileNameEvent, strBlockDwgFileName);
        
        m_inventorApplication.CommandManager.ControlDefinitions["SketchInsertAutoCADFileCmd"].Execute();        
    }
    catch (Exception ex) {; }
    finally
    {
        // Stop Thread
        m_bWorkerRunning = false;
        Thread.Sleep(500);
        m_pushFinishButtonThread.Abort();
        sketch.ExitEdit();
        //setDwgTranslatorLastUsedIniFile(strOldIniFile);
        System.IO.File.Delete(strIniFile);
    }
}

 

regards

Ludger

0 Likes