Revit API Forum
Welcome to Autodesk’s Revit API Forums. Share your knowledge, ask questions, and explore popular Revit API topics.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

TwinMotion Dynamic Link Export Fbx Automatically

7 REPLIES 7
SOLVED
Reply
Message 1 of 8
Anonymous
1933 Views, 7 Replies

TwinMotion Dynamic Link Export Fbx Automatically

 

Hi, I have been trying to export fbx using TwinMotion Dynamic Link. I would like to export fbx files from many revit files, so I would like to know how I can use PostCommand and then operate windows forms on the export panel. I tried to use "SendKeys" but I couldn't make it. 

 

using System;
using Autodesk.Revit.UI;
using Autodesk.Revit.UI.Events;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI.Selection;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using System.Runtime.InteropServices;


namespace TwinMotion
{
    [Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]
    [Autodesk.Revit.DB.Macros.AddInId("1D1D7C97-4450-43CA-A675-22C2FCC465D5")]
	public partial class ThisApplication
	{
    	
		private void Module_Startup(object sender, EventArgs e)
		{

		}

		private void Module_Shutdown(object sender, EventArgs e)
		{

		}
		

		#region Revit Macros generated code
		private void InternalStartup()
		{
			this.Startup += new System.EventHandler(Module_Startup);
			this.Shutdown += new System.EventHandler(Module_Shutdown);
		}
		#endregion

		void OnDialogBoxShowing(object sender, DialogBoxShowingEventArgs args )
		{
			//DialogBoxShowingEventArgs args
			TaskDialogShowingEventArgs e2 = args as TaskDialogShowingEventArgs;
		
			e2.OverrideResult((int)TaskDialogResult.Ok);

		}

		
		public void myMacro()
		{
			Document doc = this.ActiveUIDocument.Document;   
            //Application app = doc.Application;

            //UIApplication uiapp = new UIApplication(app);
            UIApplication uiapp = new UIApplication(Application);
            
            try
            {
            	
            	
                //RevitCommandId id = RevitCommandId.LookupPostableCommandId(PostableCommand.ViewRange);
                RevitCommandId id = RevitCommandId.LookupPostableCommandId(PostableCommand.PlaceAComponent);
                string name = "CustomCtrl_%CustomCtrl_%Twinmotion 2020%Twinmotion Direct Link%ExportButton";
				RevitCommandId id_addin = RevitCommandId.LookupCommandId(name);
                if (id_addin != null)
                    {
                    //TaskDialog.Show("Test", "Found ID");
                    
                    uiapp.DialogBoxShowing += new EventHandler<DialogBoxShowingEventArgs>(OnDialogBoxShowing );
                    uiapp.PostCommand(id_addin);

                    
                    }
            }
 
             
            catch
            {
                TaskDialog.Show("Test", "error");
            }
            finally{
            	
            	
            	uiapp.DialogBoxShowing -= new EventHandler<DialogBoxShowingEventArgs>(OnDialogBoxShowing );
    			
            }

		}

	}
}

 

Labels (3)
7 REPLIES 7
Message 2 of 8
Anonymous
in reply to: Anonymous

I am a very new on Revit API forum. Any advice would be greatly appreciated! 🙂 

Message 3 of 8
jeremytammik
in reply to: Anonymous

Welcome to the Revit API.

 

Unfortunately, the Revit API provides no support for the scenario you describe.

 

The native Windows API does provide all the required functionality to simulate any user input you like.

 

Therefore, you can use the Windows API to drive the required workflow.

 

I used such a mechanism to implement a simple Windows form clicker:

 

https://github.com/jeremytammik/JtClicker

 

You can try to implement something similar for your requirements.

 

However, as said, that has nothing whatsoever to do with the Revit API.

  

I hope this helps.

 

Best regards,

 

Jeremy

 



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder

Message 4 of 8
Anonymous
in reply to: jeremytammik

Hi Jeremy,

 

Thank you for your reply! I am able to export automatically by Windows API as you showed me the example! 

 

void OnDialogBoxShowing(object sender, DialogBoxShowingEventArgs args )
		{
			//DialogBoxShowingEventArgs args
			TaskDialogShowingEventArgs e2 = args as TaskDialogShowingEventArgs;
		
			e2.OverrideResult((int)TaskDialogResult.Ok);

		}

		static async void RunCommands(UIApplication uiapp,RevitCommandId id_addin){
			uiapp.PostCommand(id_addin);
			await Task.Delay(400);
			SendKeys.Send("{ENTER}");
			await Task.Delay(400);
			SendKeys.Send("{ENTER}");
			await Task.Delay(400);
			SendKeys.Send("{ENTER}");
			await Task.Delay(400);
			SendKeys.Send("{ESCAPE}");
			await Task.Delay(400);
			SendKeys.Send("{ESCAPE}");
			
		}
		public void myMacro()
		{
			Document doc = this.ActiveUIDocument.Document;   
            //Application app = doc.Application;

            //UIApplication uiapp = new UIApplication(app);
            UIApplication uiapp = new UIApplication(Application);
            
            try
            {
            	
            	
                //RevitCommandId id = RevitCommandId.LookupPostableCommandId(PostableCommand.ViewRange);
                RevitCommandId id = RevitCommandId.LookupPostableCommandId(PostableCommand.PlaceAComponent);
                string name = "CustomCtrl_%CustomCtrl_%Twinmotion 2020%Twinmotion Direct Link%ExportButton";
				RevitCommandId id_addin = RevitCommandId.LookupCommandId(name);
                if (id_addin != null)
                    {
                    //TaskDialog.Show("Test", "Found ID");
                    
                    uiapp.DialogBoxShowing += new EventHandler<DialogBoxShowingEventArgs>(OnDialogBoxShowing );
                    //uiapp.PostCommand(id_addin);

                    RunCommands(uiapp, id_addin);
                    }
            }
 
             
            catch
            {
                TaskDialog.Show("Test", "error");
            }
            finally{
            	
            	
            	uiapp.DialogBoxShowing -= new EventHandler<DialogBoxShowingEventArgs>(OnDialogBoxShowing );
    			
            }

		}

Best,

 

Yuko 

Message 5 of 8
jeremy_tammik
in reply to: Anonymous

Congratulations on solving this, and thank you very much for your appreciation and above all for sharing your nice clean solution!

  

Jeremy Tammik, Developer Advocacy and Support, The Building Coder, Autodesk Developer Network, ADN Open
Message 6 of 8
patrickmR&N
in reply to: Anonymous

Any thoughts on how to do this with Python?

I just can't seem to get Send Keys to function.  Where are you getting SendKeys from?

Message 7 of 8
onurerMY3Q8
in reply to: patrickmR&N

I found out that SendKeys class is in System.Windows.Forms namespace. You need to add the assembly with the same name to your project if you haven't done so.
Message 8 of 8
onurerMY3Q8
in reply to: Anonymous

Thank you for sharing your solution. It saved me unbelievable amount of time, maybe days or weeks. Thank you VERY VERY MUCH!!!

 

I cleaned the code and made it more readable in case someone needs it. My own Revit plugin calls this Twinmotion macro automatically after Revit starts up.

 

using System.Threading.Tasks;
using Autodesk.Revit.UI;
using System.Windows.Forms;
using Autodesk.Revit.UI.Events;

namespace YourNamespaceHere
{
    public class Class2 : IExternalApplication
    {
        UIControlledApplication UIControlledApplication;

        public Result OnStartup(UIControlledApplication Application)
        {
            UIControlledApplication = Application;
            UIControlledApplication.Idling += Application_Idling;

            return Result.Succeeded;
        }

        public Result OnShutdown(UIControlledApplication Application) => Result.Succeeded;

        void Application_Idling(object Sender, IdlingEventArgs E)
        {
            UIControlledApplication.Idling -= Application_Idling;

            var UIApplication = (UIApplication)Sender;

            MyMacro(UIApplication);

            //TaskDialog.Show("Application_Idling", Sender.GetType().FullName);
        }

        void OnDialogBoxShowing(object Sender, DialogBoxShowingEventArgs Args) => ((TaskDialogShowingEventArgs)Args).OverrideResult((int)TaskDialogResult.Ok);

        static async void RunCommands(UIApplication UIapp, RevitCommandId Id_Addin)
        {
            UIapp.PostCommand(Id_Addin);
            await Task.Delay(400);
            SendKeys.Send("{ENTER}");
            await Task.Delay(400);
            SendKeys.Send("{ENTER}");
            await Task.Delay(400);
            SendKeys.Send("{ENTER}");
            await Task.Delay(400);
            SendKeys.Send("{ESCAPE}");
            await Task.Delay(400);
            SendKeys.Send("{ESCAPE}");
        }

        void MyMacro(UIApplication UIapp)
        {
            try
            {
                var Name = "CustomCtrl_%CustomCtrl_%Twinmotion 2020%Twinmotion Direct Link%ExportButton";
                var Id_Addin = RevitCommandId.LookupCommandId(Name);
                
                if (Id_Addin != null)
                {
                    UIapp.DialogBoxShowing += OnDialogBoxShowing;

                    RunCommands(UIapp, Id_Addin);
                }
            }
            catch
            {
                TaskDialog.Show("Test", "error");
            }
            finally
            {
                UIapp.DialogBoxShowing -= OnDialogBoxShowing;
            }
        }
    }
}

 

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk Customer Advisory Groups


Rail Community