Habilitar uma interface USB personalizada para uma impressora 3D
A arquitetura descrita neste tópico habilita o suporte para impressoras 3D de interface USB personalizadas nos ecossistemas de impressão v3 e v4. Um monitor de porta padrão, 3dmon.dll, encaminha comandos de trabalho de impressão 3D para um Windows 3DPrintService em execução com credenciais de serviço local. O serviço carrega e se comunica com uma DLL de parceiro para executar os comandos personalizados necessários para um trabalho de impressão 3D. A DLL do parceiro, bem como os redistribuíveis 3dmon.dll e 3dprintservice.exe são instalados pelo pacote de driver USB do dispositivo. A DLL do parceiro deve implementar e exportar um conjunto de funções para se comunicar com o 3DPrintService. O restante da funcionalidade necessária para interagir com o serviço de spooler de impressão é implementado no 3dmon.dll.
Observação
Essa arquitetura requer que a DLL do parceiro seja de várias instâncias e seguro para thread.
Decisões de arquitetura
O serviço do windows 3DPrintService é usado para carregar e invocar APIs definidas específicas em DLLs fornecidas pelo parceiro durante um fluxo de trabalho de impressão. Essas APIs permitirão a comunicação com a impressora.
Os pacotes de driver do Filtro USB KMDF são publicados no Windows Update para instalação via PnP para uma impressora 3D com suporte. O driver KMDF instala o software do parceiro e cria um nó de dispositivo de impressora 3D. O nó do dispositivo de impressora 3D é instalado usando um driver de impressão v4 publicado pelo parceiro do Windows Update.
Decisões de embalagem
Binários e dependências binárias
A arquitetura usa um driver publicado pelo fabricante do hardware no Windows Update. Esse driver inclui os seguintes binários redistribuíveis fornecidos pela Microsoft e suas dependências:
3dmon.dll
3dprintservice.exe
ms3dprintusb.sys
Driver de filtro USB do modo kernel
O driver KMDF é publicado pelo parceiro e consiste em componentes mostrados no diagrama abaixo. Isso corresponde ao dispositivo com um ID de hardware (normalmente, um VID & PID). O driver cria um nó de dispositivo de impressora 3D na instalação, que aciona a instalação da fila de impressão e dos drivers de segmentação. O parceiro fornece drivers de impressora v4 para o nó do dispositivo de impressora 3D criado.
MS3DPrintUSB.sys
O driver de dispositivo do modo kernel que cria o nó de desenvolvimento da impressora 3D em Enum\3DPrint. Ele é invocado pelo subsistema PnP por meio de uma correspondência direta do VID & PID com base no nó do dispositivo criado pelo Winusb.sys. O arquivo .inf do driver configura a DLL personalizada usada para definir o 3DPrintService (se ainda não estiver instalado no sistema).
3dmon.dll
3DMon.dll é um binário redistribuível do monitor de porta publicado pela Microsoft invocado pelo spooler para se comunicar com a impressora 3D.
3dprintservice.exe
3DPrintService.exe é um binário publicado pela Microsoft instalado como um serviço do Windows durante a instalação do driver. O 3DMon se comunica com este serviço para realizar operações como impressão, bidi e assim por diante com a impressora 3D.
Partnerimpl.dll
Partnerimp.dll é a implementação do parceiro da interface da Microsoft publicada. A DLL se comunica com o dispositivo do parceiro usando seus protocolos. 3DPrintService.exe carrega essa DLL em tempo de execução para conduzir as operações do dispositivo de impressora 3D.
Sequência de uso da impressora
O spooler se comunica com 3dmon.dll que envia comandos para o serviço Windows 3DPrintService
O 3DPrintService.exe é executado com as credenciais de conta de NetworkService
O spooler, via 3dmon.dll, envia comandos para o 3DPrintService sempre que a impressora 3D é usada
O 3DPrintService processa comandos e invoca APIs em tempo de execução em DLLs de implementação fornecidas pelo parceiro
O 3DPrintService entrega as respostas das DLLs fornecidas pelo parceiro de volta ao spooler
Interfaces e Interações
A DLL do parceiro deve exportar as seguintes funções de API:
HRESULT Install([in] LPCWSTR args)
Essa API é opcional e pode ser usada pelo fabricante para instalar software personalizado ou registro para seu dispositivo. Por exemplo, instalação de modelagem incluída no pacote de driver do dispositivo. Essa API é invocada com credenciais SYSTEM para habilitar a instalação.
DWORD PrintApiSupported()
Essa API é usada pelos fabricantes terceirizados para indicar a versão da API do serviço de impressão 3D com suporte. As APIs abaixo são compatíveis com a versão 1 do 3DPrintService.
HRESULT InitializePrint(LPCWSTR pPrinterName, LPCWSTR pPortName, DWORD dwJobId, LPVOID* ppPartnerData)
Essa API é invocada antes de um evento de impressão começar a inicializar a impressora. A impressora pode salvar o estado específico do trabalho no parâmetro ppPartnerData. Essa chamada é análoga a uma invocação do StartDocPort.
jobId: ID do trabalho usado para rastrear o trabalho
portName: nome da porta para a impressora 3D
printerName: nome da impressora para a qual este trabalho de impressão está sendo enviado
ppPartnerData: ponteiro para ponteiro que pode ser usado para armazenar dados específicos do trabalho
HRESULT PrintFile([in] DWORD jobId, [in] LPWSTR portName, [in] LPWSTR printerName, [in] LPWSTR pathToRenderedFile,[in]LPVOID* ppPartnerData)
Essa API é usada por fabricantes terceirizados para imprimir o documento em suas impressoras.
jobId: ID do trabalho usado para rastrear o trabalho
portName: nome da porta para a impressora 3D
printerName: nome da impressora para a qual o trabalho de impressão está sendo enviado
pathToRenderedFile: caminho UNC para o local do arquivo em spool após a execução da renderização. O fabricante terceirizado processa o arquivo desse local e imprime o documento em seu dispositivo
ppPartnerData: ponteiro para ponteiro emitido para armazenar a configuração de dados específicos do parceiro durante a chamada para a API InitializePrint.
printerName pode ser obtido do registro usando o nome da porta. Fabricantes terceirizados podem não conseguir usar o nome da porta para se comunicar com seus dispositivos. O nome da impressora é exclusivo em uma máquina Windows e seu software será capaz de identificar em qual impressora imprimir o trabalho. Todas as impressoras ativas em um computador podem ser encontradas na seguinte chave do registro:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Print\Printers
HRESULT Query(_In_ LPCWSTR command, _In_ LPCWSTR commandData, _Out_ LPWSTR resultBuffer, _Out_ resultBufferSize, , _In_ LPVOID* ppPartnerData)
command: comando string enviado como uma consulta
commandData: argumentos de comando (opcional)
resultBuffer: resultado da invocação de argumentos de consulta>
resultBufferSize: tamanho da string do buffer resultante
ppPartnerData: ponteiro para ponteiro para a instância de DLL do parceiro atual
O serviço 3Dprint invoca a DLL do parceiro para obter o tamanho do buffer a ser alocado para o comando.
Depois de alocar memória para manter a cadeia de caracteres de resposta, a DLL será invocada novamente para obter o resultado real.
A DLL pode usar os dados da instância de uma chamada anterior IntializePrint() para se comunicar com o dispositivo sem abrir um novo canal de comunicação sempre que a função Query() for chamada.
Essa API é usada para se comunicar com a impressora para obter informações sobre a configuração do dispositivo, o progresso da impressão ou para notificar a DLL do parceiro sobre eventos de desconexão do dispositivo.
Os comandos abaixo devem ser suportados pelo fabricante:
Comando | CommandData | Saída | Comentários |
---|---|---|---|
\\Printer.3DPrint:JobStatus | Trabalho iniciado = {"Status": "ok"}, Status a ser usado na conclusão {"Status": "Concluído"} | O spooler exibirá qualquer valor retornado na interface do usuário da fila de impressão. Isso permite que o dispositivo exiba informações relevantes durante uma impressão na interface do usuário da fila de impressão. O dispositivo pode retornar uma cadeia de caracteres arbitrária aqui (por exemplo, "Ocupado" ou "33% concluído") e isso será exibido literalmente no status do trabalho da fila de impressão. | |
\\Printer.3DPrint:JobCancel | {"Status": "Concluído"} | O spooler invocará esse comando quando um usuário cancelar uma impressão. A DLL do parceiro retorna esse valor quando o cancelamento foi bem-sucedido e os identificadores e threads foram fechados. | |
\\Printer.Capabilities:Data | Cadeia de caracteres XML em conformidade com o esquema PrintDeviceCapabilites (PDC). | A consulta PDC é invocada por aplicativos que desejam obter mais informações sobre a impressora. Os dados são usados para descrever as funcionalidades do dispositivo e podem incluir as configurações do segmentador de dados se o driver depender do segmentador de dados da Microsoft. Veja abaixo um exemplo de PDC. | |
\\Printer.3DPrint:Disconnect | {"Status": "OK"} | Essa consulta é disparada sempre que há uma desconexão PnP do dispositivo da impressora. Os parceiros podem realizar todas as ações necessárias, por exemplo, fechar todos os identificadores abertos para permitir a reconexão adequada. | |
\\Printer.3DPrint:Connect | {"Status":"OK"} | Essa consulta é disparada sempre que há uma conexão PnP do dispositivo da impressora. Os parceiros podem realizar as ações necessárias. |
Funcionalidades do dispositivo de impressão XML
As seguintes funcionalidades do dispositivo de impressão XML podem ser usados como exemplo:
<?xml version="1.0"?>
<PrintDeviceCapabilities
xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="https://www.w3.org/2001/XMLSchema"
xmlns:xml="https://www.w3.org/XML/1998/namespace"
xmlns:psk="https://schemas.microsoft.com/windows/2003/08/printing/printschemakeywords"
xmlns:psk3d="https://schemas.microsoft.com/3dmanufacturing/2013/01/pskeywords3d"
xmlns:psk3dx="https://schemas.microsoft.com/3dmanufacturing/2014/11/pskeywords3dextended"
xmlns:pskv="https://schemas.microsoft.com/3dmanufacturing/2014/11/pskeywordsvendor"
xmlns:psf="https://schemas.microsoft.com/windows/2003/08/printing/printschemaframework"
xmlns:psf2="https://schemas.microsoft.com/windows/2013/12/printing/printschemaframework2"
xmlns="https://schemas.microsoft.com/windows/2013/12/printing/printschemaframework2"
version="2">
<CapabilitiesChangeID xsi:type="xsd:string">{9F58AF07-DCB6-4865-8CA3-A52EA5DCB05F}</CapabilitiesChangeID>
<psk3d:Job3DOutputArea psf2:psftype="Property">
<psk3d:Job3DOutputAreaWidth>150001</psk3d:Job3DOutputAreaWidth>
<psk3d:Job3DOutputAreaDepth>150001</psk3d:Job3DOutputAreaDepth>
<psk3d:Job3DOutputAreaHeight>150001</psk3d:Job3DOutputAreaHeight>
</psk3d:Job3DOutputArea>
<psk3d:Job3DMaterials psf2:psftype="Property">
<psk3dx:MaterialPLA>
<psk:DisplayName>PLA</psk:DisplayName>
<psk3d:Job3DMaterialType>psk3d:PLA</psk3d:Job3DMaterialType>
<psk3d:MaterialColor>#FFFFFFFF</psk3d:MaterialColor>
<psk3dx:platformtemperature>0</psk3dx:platformtemperature>
<psk3dx:filamentdiameter>1750</psk3dx:filamentdiameter>
<psk3dx:filamentcalibrationoverride>1.0</psk3dx:filamentcalibrationoverride>
<psk3dx:extrudertemperature>207</psk3dx:extrudertemperature>
<psk3dx:SpeedFactor>1.0</psk3dx:SpeedFactor>
<psk3dx:SetupCommands>
<!-- Executed during pre-commands: nozzle pre-heating, priming, etc -->
<psk3dx:command>M104 S207 T1</psk3dx:command>
<psk3dx:command>M140 S50</psk3dx:command>
</psk3dx:SetupCommands>
<psk3dx:SelectCommands>
<!-- Executed during printing: T0/T1 selection, nozzle wiping sequence,turn fan on/off/gradual, retract the material, temperature, etc-->
<psk3dx:command>; PLA on</psk3dx:command>
<psk3dx:command>M108 T1</psk3dx:command>
</psk3dx:SelectCommands>
<psk3dx:DeselectCommands>
<!-- Executed during printing: retract the material, park the nozzle, reduce temperature, etc -->
<psk3dx:command>; PLA off</psk3dx:command>
</psk3dx:DeselectCommands>
</psk3dx:MaterialPLA>
</psk3d:Job3DMaterials>
<psk3dx:customStatus>Slicing</psk3dx:customStatus>
<psk3dx:userprompt>Confirm the 3D printer is calibrated and ready for the next print</psk3dx:userprompt>
<!— Additional Slicer settings follow (optional) -->
</PrintDeviceCapabilities>
Para impressoras 3D que não possuem display integrado e botões para permitir que o usuário interaja com o dispositivo no início da impressão, recomendamos o retorno de um xml PDC com uma mensagem de prompt do usuário adequada definida, conforme mostrado acima em psdk3dx:userPrompt. Isso evita iniciar uma nova impressão em cima de uma existente. A mensagem de status personalizada <psk3dx:customStatus> é usada para exibir qualquer mensagem durante o fatiamento.
HRESULT Cleanup(LPCWSTR pPrinterName, LPCWSTR pPortName, DWORD dwJobId, LPVOID* ppPartnerData)
dwJobId: ID do trabalho usado para rastrear o trabalho no spooler
pPortName: nome da porta para a impressora 3D
pPrinterName: nome da impressora para a qual este trabalho de impressão está sendo enviado
ppPartnerData: ponteiro para ponteiro que contém a configuração de dados específicos do trabalho durante uma invocação da API InitializePrint
A limpeza é invocada na conclusão bem-sucedida de um trabalho de impressão ou na conclusão de uma consulta de cancelamento em um trabalho de impressão. Ele fornece uma oportunidade para a DLL do parceiro limpar os recursos que foram inicializados para essa impressão.
HRESULT UnInstall([in]LPCWSTR args)
Essa API é chamada ao desinstalar o dispositivo de impressora 3D e fornece um mecanismo para o fabricante desinstalar o software que pode ter instalado.