Partilhar via


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.

Driver de filtro USB KMDF.

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.

Diagrama que mostra o fluxo de comunicação do dispositivo para operações de 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.

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.