OCCTMCP

Interação analítica com modelos CAD construídos no kernel CAD OCCT

Documentação

OCCTMCP

Swift Platforms License: LGPL v2.1+

Servidor MCP que dá a LLMs a capacidade de criar, inspecionar e iterar em modelos CAD 3D com OpenCASCADE via a família OCCTSwift.

Parte do ecossistema OCCTSwift — veja o mapa do ecossistema para entender como este pacote se posiciona sobre as camadas de kernel, viewport, bridge e AIS. Estável em SemVer desde v1.0.0.

A implementação em Swift chama o OCCT diretamente em processo (sem subprocesso, sem marshalling JSONL) e expõe 79 ferramentas MCP tipadas que cobrem autoria, leituras de cena, mutação, introspecção, construção, análise, I/O, malha, desenho, seleção/remap, análise de zonas de malha, inspeção de malha, alinhamento, sobreposições de dimensão e a ponte de seleção agente-para-host-de-viewport.

Como Funciona

LLM picks a typed tool (boolean_op, transform_body, render_preview, …)
  → OCCTMCP runs the OCCT operation directly via OCCTSwift / Tools / AIS / Mesh
  → Writes BREP/STEP/PNG + manifest.json + annotations.json
  → OCCTSwiftViewport (optional) auto-reloads the 3D model

Para geometria nova que as ferramentas tipadas não cobrem, a LLM recorre a execute_script: código Swift arbitrário com a API OCCTSwift completa, compilado e executado em processo.

Ferramentas

79 ferramentas, organizadas abaixo. Chame get_api_reference({ category: "mcp_tools" }) para despejar o JSON Schema de cada ferramenta de uma só vez, útil para autodescoberta da LLM. A maioria dos fluxos pode responder "qual é o volume?", "deixe vermelho", "subtraia booleanamente estes", "renderize uma prévia", "adicione uma dimensão entre estas duas faces", "exporte para STEP" e "desenhe isto" sem nunca tocar em execute_script.

Autoria

FerramentaPropósito
execute_scriptEscrever e executar código CAD Swift arbitrário (API OCCTSwift completa)
get_scriptLer o código-fonte do script mais recente
get_api_referenceNavegar pela API OCCTSwift por categoria

Leituras de cena

FerramentaPropósito
get_sceneLer o manifesto atual da cena (corpos, cores, materiais)
export_modelListar caminhos de arquivos BREP / STEP / STL / OBJ exportados
compare_versionsComparar a cena atual vs. N execuções atrás (adicionado / removido / aparência / arquivo alterado)

Mutação de cena

FerramentaPropósito
remove_bodyExcluir um corpo da cena (manifesto + arquivo BREP)
clear_sceneApagar todos os corpos, opcionalmente manter o histórico de diff
rename_bodyAlterar o id de um corpo
set_appearanceAtualizar cor / opacidade / rugosidade / metálico / nome de exibição

Introspecção

FerramentaPropósito
validate_geometryValidação de topologia por corpo (isValid, contagens de erros)
compute_metricsVolume, área, centroide, caixa delimitadora, eixos principais
query_topologyEncontrar faces / arestas / vértices que correspondem a critérios, retornar IDs estáveis. Resultados de arestas (#119) carregam pontos finais (de todos os tipos) mais uma direção unitária para arestas LINE, e circleCenter/radius/axis/startAngle/endAngle para arestas CIRCULAR. Somente-face includeNeighbors (vizinhos com convexidade, limitado por neighborLimit) e oppositeFaces (face plana oposta consultiva, oppositeMethod exata ou bbox) (#199)
measure_distanceDistância mínima + contatos entre dois corpos
measure_deviationDesvio de superfície assinado e espacialmente resolvido entre dois corpos — máx / rms / média / p95 / signedMean (viés sistemático saliente(+)/recessivo(−)) em cada direção + worstPoint, mais uma varredura opcional de média assinada por seção ao longo de um eixo. A métrica de certificação de reconstrução (measure_distance é somente-mínimo). Veja signMode sob QA de desvio e reconstrução para o que o sinal vale contra uma referência aberta de parede fina
measure_vertex_fit (#118)Tabela exata de distâncias por vértice dos próprios vértices de um corpo de malha para a geometria BRep real de um corpo alvo (Shape.vertex(at:).distance(to:), tipo de entidade mais próxima via distanceSolutionDetail): o instrumento de ajuste de vértice que nem measure_distance (corpo-a-corpo, limitado) nem measure_deviation (malha-a-malha, aproximado) fornecem. Tabela pior-N por padrão; includeAllVertices: true para a tabela completa por vértice
recognize_featuresBolsos e furos via heurísticas AAG
inspect_assemblyPercorrer uma árvore de montagem XCAF (STEP / IGES / XBF)

Construção

FerramentaPropósito
apply_featurePerfurar / filetar / chanfrar / extrudar / revolucionar / rosquear / booleano (FeatureSpec)
transform_bodyTransladar / rotacionar / escalar uniformemente (registra histórico de identidade para remap)
boolean_opUnião / subtração / interseção / divisão (registra histórico por entrada para remap)
mirror_or_patternEspelhar / padrão linear / circular → N novos corpos

Análise de engenharia

FerramentaPropósito
check_thicknessAnálise de espessura de parede com sinalizadores de região fina
analyze_clearanceInterferência por pares / folga mínima
heal_shapeCurar geometria importada / não estanque; estatísticas antes/depois

QA de desvio e reconstrução

Comparação assinada e espacialmente resolvida de uma reconstrução contra sua malha de origem. Onde os escalares de measure_deviation podem esconder um erro de forma sistemático (uma seção transversal errada que se anula na média), estes expõem onde e em que direção o candidato se desvia. Renderização puramente em Swift — sem Python/matplotlib.

Qual direção é para fora? measure_deviation, deviation_histogram e signed_deviation_heatmap compartilham um único motor de distância assinada, então compartilham um botão signMode. O sinal de um desvio depende de contra qual triângulo de referência uma amostra é julgada, e contra uma referência aberta, de parede fina (uma varredura bruta / pele STL) o mais próximo é frequentemente o errado: um flanco candidato situado 4,5 mm dentro de uma parede de 2 mm está a apenas 2,5 mm da superfície interna da parede, então essa superfície vence por proximidade e — voltada para a cavidade — reporta +2,5 saliente para uma peça que está 4,5 recessiva. Lado errado, magnitude errada, nada para sinalizar. signMode: "robust" (o padrão desde v1.17.0) rejeita triângulos de referência cuja normal externa se opõe à da própria amostra antes que o sobrevivente mais próximo vença, recuperando ambas as figuras; amostras sem superfície compatível ao alcance são reportadas ambiguous e retidas das estatísticas assinadas em vez de adivinhadas. signMode: "nearest" restaura o sinal bruto de triângulo mais próximo pré-v1.17, que é correto contra uma referência estanque / de superfície única. Um ambiguousFraction próximo de 1,0 significa que o enrolamento da referência está provavelmente invertido em relação ao corpo amostrado; onde nada tem um sinal confiável, as figuras assinadas retornam null em vez de um zero que seria lido como "perfeitamente centrado".

As duas famílias de números respondem perguntas diferentes, e signMode move apenas a segunda:

FamíliaMede atéMovida por signMode?
Não assinada — max / rms / mean / p95 / worstPoint / symmetricHausdorff / maxAbs / withinTolerancea superfície de referência mais próxima, seja ela qual forNão — mesmo significado que pré-v1.17
Assinada — signedMean / signedMin / signedMax / sections / buckets de histograma / cores de mapa de calora superfície à qual a amostra correspondeSim

Contra uma referência estanque, estas são a mesma superfície e as famílias concordam. Contra uma de parede fina aberta, elas divergem de propósito: max: 2.5 ao lado de signedMin: -4.5 diz que a geometria de referência mais próxima é uma parede interna a 2,5 de distância, enquanto a pele à qual aquele flanco pertence está 4,5 acima. Ambas verdadeiras. Uma lacuna entre elas é em si o indício de que a referência é de parede fina.

FerramentaPropósito
deviation_histogramDistribuição de desvio ponto-a-superfície assinada: μ / σ / mediana / p95 / extremos saliente-recessivo, percentual dentro de ±tolerância, histograma de buckets + PNG opcional. Uma média não nula ou forma bimodal ⇒ erro sistemático
cross_section_compareFatiar ambos os corpos em N estações ao longo da sobreposição de extensão de eixo compartilhada; média assinada por seção / RMS / razão de área / deslocamento de centroide + um escalar de forma radial robusto a pose, com PNGs de sobreposição. O modo padrão outerEnvelope compara contra o limite externo da referência por direção angular para que caminhos internos de retorno de janela / moldura de uma peça de parede fina ou varrida não poluam o agregado; cada estação reporta axisCoord (posição mundial ao longo do eixo). Lida com referências de casca aberta (varredura bruta / pele STL) cujas seções são arcos abertos, reporta o intervalo overlap e avisa em estações que fatiaram apenas um corpo. O detector de maior alavancagem de uma seção de forma errada
symmetric_difference_volume (#122)A figura direta de fidelidade geométrica que uma média/RMS de desvio de superfície pode esconder via cancelamento: os dois volumes unilaterais entre um candidato e uma referência (somente-excesso, somente-faltante) e sua soma, via número de enrolamento generalizado de OCCTSwiftMesh (robusto contra referência aberta/não estanque/auto-intersectante, ao contrário da subtração de boolean_op, que falha completamente contra uma). Amostragem Monte Carlo determinística de sequência Halton; reporta erro padrão e uma verificação cruzada de volume BRep exato quando disponível
signed_deviation_heatmapRenderizar a superfície candidata colorida por distância assinada (saliente = vermelho, recessivo = azul) através de um colormap divergente com legenda de barra de cores. Triângulos cujo sinal não pode ser estabelecido contra uma referência aberta/de parede fina renderizam em cinza (ambiguousTriangles/ambiguousFraction, excluídos de signedMin/Max/Mean) em vez de um vermelho/azul de cara ou coroa — veja signMode acima
overlay_renderRenderizar a malha de referência semitransparente sobre o sólido candidato opaco — veja a divergência em 3D

Análise de malha (zonas)

A superfície de inspeção de malha para varreduras brutas / peles STL: dividir a malha de um corpo em zonas de superfície (plano / cilindro / esfera / cone, via crescimento de região diedral do OCCTSwiftMesh + fusão de ajuste de primitiva), então medir o quanto a seção transversal de cada zona permanece constante ao longo de um eixo (um mapa de extensão loftável). Ambos são composição pura de domínio de malha — a lógica de agregação/veredito aqui é independente do motor do próprio OCCTReconstruct, conforme a política de verificação analítica obrigatória.

FerramentaPropósito
segment_mesh_zonesDividir a malha de um corpo em zonas de superfície; cada zona recebe um id estável zone:<bodyId>#<n>, uma primitiva ajustada (tipo/parâmetros/resíduo) e (opcionalmente) uma renderização PNG categórica e/ou seu próprio corpo de cena registrado
zone_continuity_sweepVarrer uma zona (ou corpo inteiro) ao longo de um eixo; reportar execuções máximas dentro da tolerância (extensões loftáveis) e intervalos de desvio entre elas, cada um com extensões axisCoord mundiais e magnitudes
list_zonesInspecionar o registro de zonas (<output_dir>/zones.json)
clear_zonesApagar o registro de zonas, opcionalmente para um corpo
fit_primitives (#107)Relatório de primitiva RANSAC estilo Schnabel (plano/cilindro/esfera/cone), reivindicando inliers GLOBAIS em vez do crescimento de região somente-adjacente-a-aresta de segment_mesh_zones — para que possa unificar uma primitiva (ex.: um cilindro interrompido por um boss) que a tabela de zonas mantém dividida entre regiões. zoneId opcional limita o ajuste a uma zona; strategy: "auto" executa uma disputa diedral-vs-RANSAC e reporta qual venceu. uncoveredFraction (triângulos que nenhuma primitiva reivindicou) e um limite maxPrimitives são reportados como avisos estritamente separados

Inspeção de malha

A superfície de checklist / medição de domínio de malha (Fase 2 da expansão de análise de malha): diagnóstico de integridade, espessura de parede, detecção de simetria reflexiva e alinhamento de dois corpos, tudo trabalhando diretamente na superfície tessalada de um corpo em vez da topologia BREP, para que não degradem em cascas de facetas (uma importação STL bruta) da maneira que check_thickness degrada.

FerramentaFinalidade
mesh_diagnoseRelatório de integridade da lista de verificação de imprimibilidade: estanque, manifold de arestas/vértices, orientável, componentes conectados, loops de contorno, característica de Euler / gênero, contagens de triângulos duplicados/degenerados, sinais de sliver, além de pass/aviso/falha derivados checks[]. Auto-interseção NÃO é verificada (uma limitação do OCCTSwiftMesh a montante)
mesh_thicknessEspessura de parede do domínio da malha via método de raio (normal-oposta, primeiro impacto, mediana opcional com média de cone): o complemento de check_thickness para malhas brutas. Relata a distribuição de espessura, uma seção opcional abaixo do limite e um PNG de histograma opcional
detect_symmetryDetecta simetria reflexiva (plano-espelho): 3 planos candidatos de PCA através do centroide ponderado por área, cada um verificado refletindo pontos amostrados e medindo sua distância residual de volta à superfície. A detecção de simetria rotacional/de eixo é adiada para uma fase posterior
align_bodies (#104)Alinhamento estilo GOM: registra um corpo de origem em um corpo de referência via ICP ponto-a-plano (pré-alinhamento PCA + amostragem de espaço normal + correspondência aparada). mode: "bestFit" (padrão, pipeline completo) ou "preAlign" (somente pose grosseira PCA/bbox). Retorna a transformação recuperada (ordem de linha, translação + rotação eixo-ângulo) e estatísticas residuais; apply: true grava no corpo de origem no lugar com a mesma semântica de histórico de transform_body. As ferramentas de desvio scan-vs-CAD precisam disso antes que seus números signifiquem algo
mesh_curvatureCurvatura discreta por vértice (tensor por face de Rusinkiewicz) sobre a malha soldada do próprio corpo: curvaturas principais k1/k2, média, gaussiana, além de uma renderização colorida (colorBy) e estatísticas limitadas (medianas, flatFraction, highCurvatureFraction). Nenhum corpo de referência necessário
detect_mesh_features (#108)Contornos de recursos de anel de vinco (portas, painéis, retornos de janela, reentrâncias) em uma malha de varredura bruta via detecção de arestas dobradas diedrais: solda a malha, encadeia arestas dobradas que excedem minAngleDegrees em anéis fechados e caminhos abertos (maior primeiro), para malhas onde recognize_features (BREP/AAG) não tem estrutura B-rep para trabalhar. Ciente de junções (interseções Y/T dividem-se limpidamente). Relata o containingZones de cada anel quando segment_mesh_zones já foi executado para o corpo. includePoints: true (#120) também retorna a polilinha de vértices ordenados em coordenadas mundiais de cada anel. Renderização opcional: a superfície mais cada anel como sua própria sobreposição de wireframe colorida categoricamente
fit_edge_chain (#121)Segmenta uma cadeia de pontos 3D ordenada (tipicamente a polilinha de um anel detect_mesh_features) em execuções de linha e arco circular: tipo por segmento, pontos finais, direção unitária (linha) ou centro/raio/eixo/ânguloInicial/ânguloFinal (arco), e resíduos de ajuste. Um STL bruto não tem arestas curvas por construção; um arco existe na malha apenas como um ajuste sobre uma cadeia de arestas de facetas retas, que nem fit_primitives nem segment_mesh_zones (ambos ajustam SUPERFÍCIES, não cadeias de arestas) fornecem. Cadeias de múltiplos raios dividem-se em segmentos separados em vez de colapsar em um círculo médio

Seleção & remapeamento

FerramentaFinalidade
select_topologySeleciona faces / arestas / vértices, obtém um selectionId estável. Âncoras de aresta (#119) carregam pontos finais (todo tipo) mais uma direção unitária para arestas LINE, e circleCenter/raio/eixo/ânguloInicial/ânguloFinal para arestas CIRCULARES
remap_selectionCarrega selectionIds através de mutações do mesmo corpo (baseado em histórico para transform / heal / boolean / apply_feature; heurística de centroide como fallback caso contrário)
find_correspondencesMapeia selectionIds de um corpo de origem para um corpo de destino que é uma transformação conhecida da origem — saídas de mirror_or_pattern são o caso típico
select_by_featureSeleção em massa por tipo de recurso (ex.: todas as arestas de furos)
list_selectionsInspeciona o registro de seleção em memória
clear_selectionsLimpa o registro
get_selection (#189)Lê a seleção atual de um host de viewport ao vivo (<output_dir>/selection.json + host.lock, por SecondMouseAU/OCCTSwiftInteraction#17). Resultado de três estados: noHost vs hostRunning com uma lista de seleção vazia ou populada; cada entrada resolve contra a própria cena deste servidor da mesma forma que select_topology faz e cunha um selectionId componível
highlight_selection (#190)Pede a um host de viewport ao vivo para destacar uma sub-forma (replace/add/remove/xor, espelhando OCCTSwiftAIS.SelectionScheme; target attention por padrão marca o próprio marcador do agente, selection muda o do humano). Escreve highlight_requests/<id>.json, consulta highlight_requests/handled/<id>.json para o resultado real applied/rejected/superseded do host, ou um timeout/noHost explícito

Anotações & sobreposições

FerramentaFinalidade
add_dimensionAdiciona uma dimensão linear / angular / radial; renderiza em render_preview
add_scene_primitiveAdiciona trihedron / workPlane / axis / pointCloud / boundingBox / diffMarker
auto_dimensionQueda de dimensão heurística para as extensões principais
show_bounding_boxAdiciona o AABB de um corpo como sobreposição
diff_overlayVisualiza a diferença entre dois snapshots
remove_scene_annotationRemove uma dimensão ou primitiva por id
list_annotationsInspeciona o sidecar de anotações

I/O

FerramentaFinalidade
read_brepCarrega um .brep do disco para a cena (allowInvalid carrega uma forma de face solta / inválida para medição)
import_fileImportação multi-formato (STEP / IGES / STL / OBJ); montagem XCAF opcional; allowInvalid para reconstruções em andamento
export_sceneExporta para STEP / IGES / BREP / STL / OBJ / glTF / GLB
set_assembly_metadataModifica documento XCAF ou metadados por componente

Malha & visualização

FerramentaFinalidade
generate_meshTessela para triângulos + métricas de qualidade
simplify_meshDecimação de malha QEM para .stl/.obj — envolve o Mesh.simplified do OCCTSwiftMesh (meshoptimizer embutido)
render_previewRenderização PNG única com rótulos de medição e sobreposições de primitivas. Corpos em escala de malha (varreduras importadas, >10k arestas) renderizam via caminho linear em segundos — sobreposições de arestas mantidas até 100k arestas, somente superfície além disso
pick_surface_pointLança um raio emoldurado por render_preview através de um pixel → ponto de superfície mundial + selectionId (utilizável como âncora add_dimension)
generate_drawingDesenho técnico DXF multi-vista ISO 128-30 — bodyId para uma única peça, ou bodyIds (2+) para uma folha de montagem de arranjo geral com lista de peças + balões

Grafo de topologia (baixo nível)

FerramentaFinalidade
graph_validateValida o grafo de topologia de um BREP (caminho bruto)
graph_compactRemove nós de grafo não referenciados; escreve BREP reconstruído
graph_dedupDeduplica geometria de superfície / curva compartilhada
graph_mlExporta topologia + amostras UV/aresta como JSON amigável a ML
graph_selectAdjacência / seleção local de grafo: vizinhos de face (+ convexidade), arestas de face, arestas de vértice, adjacência de face (gAAG), classes de aresta
feature_recognizeBolsos + furos (caminho BREP bruto; recognize_features é o wrapper ciente de cena)

Grafo de reconstrução (leitura/escrita)

LLM leitura/escrita sobre um grafo de reconstrução atribuído — anota decisões por nó e persiste-as. Suportado pelo NodeAttributeStore do OCCTSwift 1.2.0 + GraphSnapshot Codable. Nós são endereçados como <kind>:<index> (ex.: face:3). O motor de reconstrução (ajuste de superfície, detecção de congruência) vive em OCCTReconstruct; estas ferramentas são a camada de anotar-e-persistir — reconstruct_force_fit registra uma substituição para o motor honrar, não re-ajusta aqui.

FerramentaFinalidade
reconstruct_get_graphExporta o grafo atribuído como JSON — contagens de topologia, nós anotados (com atributos reconstruct.*), clusters de instância. Inicia uma sessão a partir de um bodyId ou lê uma existente por sessionId
reconstruct_set_decisionAnota o decidedBy de um nó (geométrico / ml / humano) e/ou aceita-rejeita um ajuste proposto
reconstruct_force_fitSubstitui o tipo de superfície ajustada de um nó (ex.: forçar cylinder)
reconstruct_confirm_instancesConfirma / rejeita um cluster de congruência ("estes N nós são uma definição de peça")
reconstruct_export_sessionEscreve o snapshot da sessão no disco (JSON byte-estável)
reconstruct_import_sessionRecarrega um arquivo de snapshot em uma sessão

Implementações

Este repositório entrega duas implementações lado a lado:

  • Swift (Sources/, Package.swift): o servidor primário. Em processo contra OCCTSwift / OCCTSwiftMesh / OCCTSwiftTools / OCCTSwiftAIS / DrawingComposer usando o SDK MCP oficial Swift. 79 ferramentas. macOS 15+ (a plataforma arm64 do OCCT.xcframework).
  • Node / TypeScript (src/, dist/) — a implementação original. Chama o CLI occtkit para tudo do lado Swift. 37 ferramentas (a superfície pré-v0.4; seleção / remapeamento / anotações são somente Swift). Útil se você não pode executar um binário macOS.

Ambos falam stdio MCP e leem/escrevem o mesmo formato de manifesto.

Pré-requisitos

  • macOS 15+ (para a implementação Swift)
  • Swift 6.1+ / Xcode 16+
  • Somente para a implementação Node: Node.js 18+, além de um clone irmão de OCCTSwiftScripts para que occtkit esteja em $PATH (ou make install)

Configuração

Implementação Swift (recomendada)

git clone https://github.com/SecondMouseAU/OCCTMCP.git
cd OCCTMCP
swift build -c release

No .mcp.json do Claude Code:

{
  "mcpServers": {
    "occtmcp": {
      "command": "/path/to/OCCTMCP/.build/release/occtmcp-server"
    }
  }
}

O pacote Swift é publicado no Swift Package Index.

Implementação Node

git clone https://github.com/SecondMouseAU/OCCTMCP.git
cd OCCTMCP
npm install
npm run build

Em .mcp.json:

{
  "mcpServers": {
    "occtmcp": {
      "command": "node",
      "args": ["/path/to/OCCTMCP/dist/index.js"]
    }
  }
}

Exemplo

O LLM pode criar modelos CAD compondo ferramentas tipadas — a maioria dos fluxos cotidianos nunca toca execute_script:

boolean_op(op: "subtract", aBodyId: "block", bBodyId: "hole", outputBodyId: "drilled")
  → "drilled" body added to the scene
select_topology(bodyId: "drilled", kind: "face", limit: 1)
  → returns selectionId "sel:drilled#face[12]"
add_dimension(kind: "linear", anchors: [...]) ; render_preview()

Para geometria nova, entre em execute_script com a API OCCTSwift completa:

import OCCTSwift
import ScriptHarness

let ctx = ScriptContext()
let C = ScriptContext.Colors.self

let box = Shape.box(width: 40, height: 30, depth: 20)!
let hole = Shape.cylinder(radius: 5, height: 30)!
    .translated(by: SIMD3(20, -1, 10))!
let result = box.subtracting(hole)!
let filleted = result.filleted(radius: 2.0)!

try ctx.add(filleted, id: "part", color: C.steel, name: "Bracket")
try ctx.emit(description: "Filleted bracket with mounting hole")

Categorias de API

A ferramenta get_api_reference fornece documentação para:

  • primitivas — caixa, cilindro, esfera, cone, toro, cunha
  • varreduras — extrusão, revolução, varredura de tubo, loft, regrada
  • booleanas — união, subtração, interseção, seção
  • modificações — filete, chanfro, casca, deslocamento, esboço, defeature
  • transformações — translação, rotação, escala, espelhamento
  • fios — retângulo, círculo, polígono, spline, hélice, deslocamento
  • curvas2d/3d — linha, arco, elipse, bspline, bezier, interpolação
  • superfícies — plano, cilindro, cone, esfera, extrusão, revolução, placa
  • análise — volume, área, distância, limites, validação
  • import_export — STL, STEP, IGES, BREP, OBJ, PLY
  • mcp_tools — o JSON Schema de cada ferramenta MCP (útil para auto-descoberta do LLM)

Versionamento

OCCTMCP segue Semantic Versioning. O port Swift alcançou v1.0.0 em 2026-05-09 — completo em recursos contra a implementação Node original, mais uma camada de ferramentas de seleção / remapeamento / anotação que são somente Swift.

Releases são marcados no GitHub. O branch main é o que o SPI rastreia.

Licença

LGPL-2.1-or-later — mesma do OCCTSwift.