Oups !, il y a une petite erreur dans le Titre....
Et si on parlait de à Revit? ... via Dynamo
Voici un exemple d'utilisation conjointe du moteur de reconnaissance vocale du Framework .Net et des "ExternalEvent" de l'API Revit
Les opérations sont issues de l'énumération PostableCommand, elles sont déclenchées via des Évents (classe API ExternalEvent) qui sont eux même encapsulés dans des objets (via un héritage de Classe).
Note 1 : dans l'exemple ci-dessus, les commandes vocales seront "MirrorProject", "Space", etc…
Note 2 : pourquoi passer par des Events ?
Les PostableCommands doivent être exécutés dans le Thread principal (API context)
"Posts the command to the Revit message queue to be invoked when control returns from the current API context."
Note 3 : il faut que le moteur de reconnaissance vocale soit encapsulé dans un Thread continu, ici, on utilise la boucle d'événements (Even Loop) d'un objet Winform (avec une fenêtre non bloquante .Show() ), cela évite de construire un nouveau Thread.
Note 4 : l'exemple ci-dessous utilise le TTS anglais, si la reconnaissance vocale anglaise est disponible sur votre Windows, vous pouvez, pour de meilleurs résultats, remplacer cette ligne :
self.sre = SpeechRecognitionEngine()
par celle-ci
self.sre = SpeechRecognitionEngine(greatBritainCulture)
Néanmoins, une customisation de la classe EventUtils reste possible pour l'adapter à un moteur vocal Français (via un dictionnaire de correspondance par exemple).
le code IronPython:
#coding: utf-8
#written by Cyril POUPIN
#v5
import sys
import clr
import System
clr.AddReference('RevitAPI')
import Autodesk
from Autodesk.Revit.DB import *
clr.AddReference('RevitAPIUI')
from Autodesk.Revit.UI import *
clr.AddReference("System.Drawing")
clr.AddReference("System.Windows.Forms")
import System.Drawing
import System.Windows.Forms
from System.Drawing import *
from System.Windows.Forms import *
from System import Array
clr.AddReference("System.Speech, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35")
from System.Speech.Recognition import (SpeechRecognitionEngine, GrammarBuilder, Grammar, Choices, RecognizeMode)
from System.Speech.Synthesis import SpeechSynthesizer, VoiceGender, VoiceAge
class ModExtEvent(IExternalEventHandler):
def __init__(self, comandePostable):
self._comandePostable = comandePostable
self.name = comandePostable.ToString()
def Execute(self, _uiap):
_uiap.PostCommand(RevitCommandId.LookupPostableCommandId(self._comandePostable))
def GetName(self):
return self.name
class EventUtils(ModExtEvent):
def __init__(self, comandePostable):
ModExtEvent.__init__(self, comandePostable)
self.ext_event = ExternalEvent.Create(self)
class Form1(Form):
def __init__(self, lstObj_handler):
lstName = Array[System.String]( [x.name for x in lstObj_handler])
self.lstComandName = lstName[:]
self._lstObj_handler = lstObj_handler
greatBritainCulture = System.Globalization.CultureInfo("en-GB")
self.sre = SpeechRecognitionEngine()
self.sre.SetInputToDefaultAudioDevice()
self.sre.UnloadAllGrammars()
gb = GrammarBuilder()
gb.Append(Choices(lstName))
self.sre.LoadGrammar(Grammar(gb))
self.sre.MaxAlternates = 1
self.spk = SpeechSynthesizer()
self.spk .SelectVoiceByHints(VoiceGender.Female, VoiceAge.Senior, 0, greatBritainCulture)
self.InitializeComponent()
def InitializeComponent(self):
self.spk.Speak("Start Speech Recognition Engine")
self._buttonStop = System.Windows.Forms.Button()
self._listBox1 = System.Windows.Forms.ListBox()
self._label1 = System.Windows.Forms.Label()
self.SuspendLayout()
self.sre.SpeechRecognized += self.OnSpeechRecognized
self.sre.RecognizeAsync(RecognizeMode.Multiple)
#
# buttonStop
self._buttonStop.Location = System.Drawing.Point(51, 190)
self._buttonStop.Name = "buttonStop"
self._buttonStop.Size = System.Drawing.Size(178, 50)
self._buttonStop.TabIndex = 0
self._buttonStop.Text = "Stop Engine"
self._buttonStop.UseVisualStyleBackColor = True
self._buttonStop.Click += self.ButtonStopClick
#
# listBox1
self._listBox1.FormattingEnabled = True
self._listBox1.Items.AddRange(System.Array[System.Object](self.lstComandName))
self._listBox1.Location = System.Drawing.Point(51, 34)
self._listBox1.Name = "listBox1"
self._listBox1.Size = System.Drawing.Size(178, 134)
self._listBox1.TabIndex = 1
#
# label1
self._label1.Location = System.Drawing.Point(51, 5)
self._label1.Name = "label1"
self._label1.Size = System.Drawing.Size(178, 23)
self._label1.TabIndex = 2
self._label1.Text = "List Voice Commands available"
#
# Form1
self.ClientSize = System.Drawing.Size(284, 252)
self.Controls.Add(self._label1)
self.Controls.Add(self._listBox1)
self.Controls.Add(self._buttonStop)
self.Name = "SpeechRecognition"
self.Text = "Speech Recognition"
self.ResumeLayout(False)
def ButtonStopClick(self, sender, e):
self.spk.Speak("Stop Speech Recognition Engine, see you soon!")
for objEvent in self._lstObj_handler:
objEvent.ext_event.Dispose()
self.sre.Dispose()
self.spk.Dispose()
self.Close()
def OnSpeechRecognized(self, sender, e):
self.sre.RecognizeAsyncStop()
self.spk.Speak(e.Result.Text + "Command Processing")
for objEvent in self._lstObj_handler:
if e.Result.Text == objEvent.name:
objEvent.ext_event.Raise()
self.sre.RecognizeAsync(RecognizeMode.Multiple)
lstEnumsPCmd = System.Enum.GetNames(PostableCommand)
lstObj_handler = [EventUtils(eval("PostableCommand." + nameCommand)) for nameCommand in IN[0] if nameCommand in lstEnumsPCmd ]
objForm = Form1(lstObj_handler)
objForm.Show()
OUT = objForm.lstComandName, lstEnumsPCmd
0 commentaires:
Enregistrer un commentaire