Files
freecad-robust-mcp-fc111/latest/api/bridge/index.html
T

13278 lines
1.8 MiB
Plaintext

<!DOCTYPE html><html lang="en" class="no-js"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><meta name="description" content="FreeCAD Robust MCP Suite - MCP Server, Bridge Workbench, and Macros for AI assistant integration"><link href="https://github.com/spkane/freecad-addon-robust-mcp-server/latest/api/bridge/" rel="canonical"><link href="../server/" rel="prev"><link href="../config/" rel="next"><link rel="icon" href="../../assets/images/favicon.png"><meta name="generator" content="mkdocs-1.6.1, mkdocs-material-9.7.1"><title>Bridge - FreeCAD Robust MCP Suite</title><link rel="stylesheet" href="../../assets/stylesheets/main.484c7ddc.min.css"><link rel="stylesheet" href="../../assets/stylesheets/palette.ab4e12ef.min.css"><link rel="preconnect" href="https://fonts.gstatic.com" crossorigin><link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,300i,400,400i,700,700i%7CRoboto+Mono:400,400i,700,700i&amp;display=fallback"><style>:root{--md-text-font:"Roboto";--md-code-font:"Roboto Mono"}</style><link rel="stylesheet" href="../../css/timeago.css"><link rel="stylesheet" href="../../assets/_mkdocstrings.css"><script>__md_scope=new URL("../..",location),__md_hash=e=>[...e].reduce(((e,_)=>(e<<5)-e+_.charCodeAt(0)),0),__md_get=(e,_=localStorage,t=__md_scope)=>JSON.parse(_.getItem(t.pathname+"."+e)),__md_set=(e,_,t=localStorage,a=__md_scope)=>{try{t.setItem(a.pathname+"."+e,JSON.stringify(_))}catch(e){}}</script><link href="../../assets/stylesheets/glightbox.min.css" rel="stylesheet"><script src="../../assets/javascripts/glightbox.min.js"></script><style id="glightbox-style">
html.glightbox-open { overflow: initial; height: 100%; }
.gslide-title { margin-top: 0px; user-select: text; }
.gslide-desc { color: #666; user-select: text; }
.gslide-image img { background: white; }
.gscrollbar-fixer { padding-right: 15px; }
.gdesc-inner { font-size: 0.75rem; }
body[data-md-color-scheme="slate"] .gdesc-inner { background: var(--md-default-bg-color); }
body[data-md-color-scheme="slate"] .gslide-title { color: var(--md-default-fg-color); }
body[data-md-color-scheme="slate"] .gslide-desc { color: var(--md-default-fg-color); }
</style></head> <body dir="ltr" data-md-color-scheme="slate" data-md-color-primary="deep-purple" data-md-color-accent="purple"> <input class="md-toggle" data-md-toggle="drawer" type="checkbox" id="__drawer" autocomplete="off"> <input class="md-toggle" data-md-toggle="search" type="checkbox" id="__search" autocomplete="off"> <label class="md-overlay" for="__drawer"></label> <div data-md-component="skip"> <a href="#bridge-api-reference" class="md-skip"> Skip to content </a> </div> <div data-md-component="announce"> </div> <div data-md-color-scheme="default" data-md-component="outdated" hidden> </div> <header class="md-header" data-md-component="header"> <nav class="md-header__inner md-grid" aria-label="Header"> <a href="../.." title="FreeCAD Robust MCP Suite" class="md-header__button md-logo" aria-label="FreeCAD Robust MCP Suite" data-md-component="logo"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 8a3 3 0 0 0 3-3 3 3 0 0 0-3-3 3 3 0 0 0-3 3 3 3 0 0 0 3 3m0 3.54C9.64 9.35 6.5 8 3 8v11c3.5 0 6.64 1.35 9 3.54 2.36-2.19 5.5-3.54 9-3.54V8c-3.5 0-6.64 1.35-9 3.54"></path></svg> </a> <label class="md-header__button md-icon" for="__drawer"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M3 6h18v2H3zm0 5h18v2H3zm0 5h18v2H3z"></path></svg> </label> <div class="md-header__title" data-md-component="header-title"> <div class="md-header__ellipsis"> <div class="md-header__topic"> <span class="md-ellipsis"> FreeCAD Robust MCP Suite </span> </div> <div class="md-header__topic" data-md-component="header-topic"> <span class="md-ellipsis"> Bridge </span> </div> </div> </div> <form class="md-header__option" data-md-component="palette"> <input class="md-option" data-md-color-media data-md-color-scheme="slate" data-md-color-primary="deep-purple" data-md-color-accent="purple" aria-label="Switch to light mode" type="radio" name="__palette" id="__palette_0"> <label class="md-header__button md-icon" title="Switch to light mode" for="__palette_1" hidden> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 18c-.89 0-1.74-.2-2.5-.55C11.56 16.5 13 14.42 13 12s-1.44-4.5-3.5-5.45C10.26 6.2 11.11 6 12 6a6 6 0 0 1 6 6 6 6 0 0 1-6 6m8-9.31V4h-4.69L12 .69 8.69 4H4v4.69L.69 12 4 15.31V20h4.69L12 23.31 15.31 20H20v-4.69L23.31 12z"></path></svg> </label> <input class="md-option" data-md-color-media data-md-color-scheme="default" data-md-color-primary="deep-purple" data-md-color-accent="purple" aria-label="Switch to dark mode" type="radio" name="__palette" id="__palette_1"> <label class="md-header__button md-icon" title="Switch to dark mode" for="__palette_0" hidden> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 8a4 4 0 0 0-4 4 4 4 0 0 0 4 4 4 4 0 0 0 4-4 4 4 0 0 0-4-4m0 10a6 6 0 0 1-6-6 6 6 0 0 1 6-6 6 6 0 0 1 6 6 6 6 0 0 1-6 6m8-9.31V4h-4.69L12 .69 8.69 4H4v4.69L.69 12 4 15.31V20h4.69L12 23.31 15.31 20H20v-4.69L23.31 12z"></path></svg> </label> </form> <script>var palette=__md_get("__palette");if(palette&&palette.color){if("(prefers-color-scheme)"===palette.color.media){var media=matchMedia("(prefers-color-scheme: light)"),input=document.querySelector(media.matches?"[data-md-color-media='(prefers-color-scheme: light)']":"[data-md-color-media='(prefers-color-scheme: dark)']");palette.color.media=input.getAttribute("data-md-color-media"),palette.color.scheme=input.getAttribute("data-md-color-scheme"),palette.color.primary=input.getAttribute("data-md-color-primary"),palette.color.accent=input.getAttribute("data-md-color-accent")}for(var[key,value]of Object.entries(palette.color))document.body.setAttribute("data-md-color-"+key,value)}</script> <label class="md-header__button md-icon" for="__search"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5"></path></svg> </label> <div class="md-search" data-md-component="search" role="dialog"> <label class="md-search__overlay" for="__search"></label> <div class="md-search__inner" role="search"> <form class="md-search__form" name="search"> <input type="text" class="md-search__input" name="query" aria-label="Search" placeholder="Search" autocapitalize="off" autocorrect="off" autocomplete="off" spellcheck="false" data-md-component="search-query" required> <label class="md-search__icon md-icon" for="__search"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5"></path></svg> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11z"></path></svg> </label> <nav class="md-search__options" aria-label="Search"> <a href="javascript:void(0)" class="md-search__icon md-icon" title="Share" aria-label="Share" data-clipboard data-clipboard-text data-md-component="search-share" tabindex="-1"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M18 16.08c-.76 0-1.44.3-1.96.77L8.91 12.7c.05-.23.09-.46.09-.7s-.04-.47-.09-.7l7.05-4.11c.54.5 1.25.81 2.04.81a3 3 0 0 0 3-3 3 3 0 0 0-3-3 3 3 0 0 0-3 3c0 .24.04.47.09.7L8.04 9.81C7.5 9.31 6.79 9 6 9a3 3 0 0 0-3 3 3 3 0 0 0 3 3c.79 0 1.5-.31 2.04-.81l7.12 4.15c-.05.21-.08.43-.08.66 0 1.61 1.31 2.91 2.92 2.91s2.92-1.3 2.92-2.91A2.92 2.92 0 0 0 18 16.08"></path></svg> </a> <button type="reset" class="md-search__icon md-icon" title="Clear" aria-label="Clear" tabindex="-1"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"></path></svg> </button> </nav> <div class="md-search__suggest" data-md-component="search-suggest"></div> </form> <div class="md-search__output"> <div class="md-search__scrollwrap" tabindex="0" data-md-scrollfix> <div class="md-search-result" data-md-component="search-result"> <div class="md-search-result__meta"> Initializing search </div> <ol class="md-search-result__list" role="presentation"></ol> </div> </div> </div> </div> </div> <div class="md-header__source"> <a href="https://github.com/spkane/freecad-addon-robust-mcp-server" title="Go to repository" class="md-source" data-md-component="source"> <div class="md-source__icon md-icon"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!-- Font Awesome Free 7.1.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc.--><path d="M173.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6m-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3m44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9M252.8 8C114.1 8 8 113.3 8 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C436.2 457.8 504 362.9 504 252 504 113.3 391.5 8 252.8 8M105.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1m-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7m32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1m-11.4-14.7c-1.6 1-1.6 3.6 0 5.9s4.3 3.3 5.6 2.3c1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2"></path></svg> </div> <div class="md-source__repository"> spkane/freecad-addon-robust-mcp-server </div> </a> </div> </nav> </header> <div class="md-container" data-md-component="container"> <nav class="md-tabs" aria-label="Tabs" data-md-component="tabs"> <div class="md-grid"> <ul class="md-tabs__list"> <li class="md-tabs__item"> <a href="../.." class="md-tabs__link"> Home </a> </li> <li class="md-tabs__item"> <a href="../../getting-started/installation/" class="md-tabs__link"> Getting Started </a> </li> <li class="md-tabs__item"> <a href="../../guide/connection-modes/" class="md-tabs__link"> User Guide </a> </li> <li class="md-tabs__item"> <a href="../../COMPARISON/" class="md-tabs__link"> Comparisons </a> </li> <li class="md-tabs__item md-tabs__item--active"> <a href="../server/" class="md-tabs__link"> API Reference </a> </li> <li class="md-tabs__item"> <a href="../../development/contributing/" class="md-tabs__link"> Development </a> </li> </ul> </div> </nav> <main class="md-main" data-md-component="main"> <div class="md-main__inner md-grid"> <div class="md-sidebar md-sidebar--primary" data-md-component="sidebar" data-md-type="navigation"> <div class="md-sidebar__scrollwrap"> <div class="md-sidebar__inner"> <nav class="md-nav md-nav--primary md-nav--lifted" aria-label="Navigation" data-md-level="0"> <label class="md-nav__title" for="__drawer"> <a href="../.." title="FreeCAD Robust MCP Suite" class="md-nav__button md-logo" aria-label="FreeCAD Robust MCP Suite" data-md-component="logo"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 8a3 3 0 0 0 3-3 3 3 0 0 0-3-3 3 3 0 0 0-3 3 3 3 0 0 0 3 3m0 3.54C9.64 9.35 6.5 8 3 8v11c3.5 0 6.64 1.35 9 3.54 2.36-2.19 5.5-3.54 9-3.54V8c-3.5 0-6.64 1.35-9 3.54"></path></svg> </a> FreeCAD Robust MCP Suite </label> <div class="md-nav__source"> <a href="https://github.com/spkane/freecad-addon-robust-mcp-server" title="Go to repository" class="md-source" data-md-component="source"> <div class="md-source__icon md-icon"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!-- Font Awesome Free 7.1.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc.--><path d="M173.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6m-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3m44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9M252.8 8C114.1 8 8 113.3 8 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C436.2 457.8 504 362.9 504 252 504 113.3 391.5 8 252.8 8M105.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1m-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7m32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1m-11.4-14.7c-1.6 1-1.6 3.6 0 5.9s4.3 3.3 5.6 2.3c1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2"></path></svg> </div> <div class="md-source__repository"> spkane/freecad-addon-robust-mcp-server </div> </a> </div> <ul class="md-nav__list" data-md-scrollfix> <li class="md-nav__item"> <a href="../.." class="md-nav__link"> <span class="md-ellipsis"> Home </span> </a> </li> <li class="md-nav__item md-nav__item--nested"> <input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_2"> <label class="md-nav__link" for="__nav_2" id="__nav_2_label" tabindex="0"> <span class="md-ellipsis"> Getting Started </span> <span class="md-nav__icon md-icon"></span> </label> <nav class="md-nav" data-md-level="1" aria-labelledby="__nav_2_label" aria-expanded="false"> <label class="md-nav__title" for="__nav_2"> <span class="md-nav__icon md-icon"></span> Getting Started </label> <ul class="md-nav__list" data-md-scrollfix> <li class="md-nav__item"> <a href="../../getting-started/installation/" class="md-nav__link"> <span class="md-ellipsis"> Installation </span> </a> </li> <li class="md-nav__item"> <a href="../../getting-started/configuration/" class="md-nav__link"> <span class="md-ellipsis"> Configuration </span> </a> </li> <li class="md-nav__item"> <a href="../../getting-started/quickstart/" class="md-nav__link"> <span class="md-ellipsis"> Quick Start </span> </a> </li> </ul> </nav> </li> <li class="md-nav__item md-nav__item--nested"> <input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_3"> <label class="md-nav__link" for="__nav_3" id="__nav_3_label" tabindex="0"> <span class="md-ellipsis"> User Guide </span> <span class="md-nav__icon md-icon"></span> </label> <nav class="md-nav" data-md-level="1" aria-labelledby="__nav_3_label" aria-expanded="false"> <label class="md-nav__title" for="__nav_3"> <span class="md-nav__icon md-icon"></span> User Guide </label> <ul class="md-nav__list" data-md-scrollfix> <li class="md-nav__item"> <a href="../../guide/connection-modes/" class="md-nav__link"> <span class="md-ellipsis"> Connection Modes </span> </a> </li> <li class="md-nav__item"> <a href="../../guide/workbench/" class="md-nav__link"> <span class="md-ellipsis"> Robust MCP Bridge Workbench </span> </a> </li> <li class="md-nav__item"> <a href="../../guide/macros/" class="md-nav__link"> <span class="md-ellipsis"> MCP Macro Tools </span> </a> </li> <li class="md-nav__item"> <a href="../../guide/tools/" class="md-nav__link"> <span class="md-ellipsis"> Tools Overview </span> </a> </li> <li class="md-nav__item"> <a href="../../guide/resources/" class="md-nav__link"> <span class="md-ellipsis"> MCP Resources </span> </a> </li> <li class="md-nav__item"> <a href="../../USER_GUIDE/" class="md-nav__link"> <span class="md-ellipsis"> Detailed User Guide </span> </a> </li> <li class="md-nav__item"> <a href="../../MCP_TOOLS_REFERENCE/" class="md-nav__link"> <span class="md-ellipsis"> Tools Reference </span> </a> </li> </ul> </nav> </li> <li class="md-nav__item md-nav__item--nested"> <input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_4"> <label class="md-nav__link" for="__nav_4" id="__nav_4_label" tabindex="0"> <span class="md-ellipsis"> Comparisons </span> <span class="md-nav__icon md-icon"></span> </label> <nav class="md-nav" data-md-level="1" aria-labelledby="__nav_4_label" aria-expanded="false"> <label class="md-nav__title" for="__nav_4"> <span class="md-nav__icon md-icon"></span> Comparisons </label> <ul class="md-nav__list" data-md-scrollfix> <li class="md-nav__item"> <a href="../../COMPARISON/" class="md-nav__link"> <span class="md-ellipsis"> Other Implementations </span> </a> </li> </ul> </nav> </li> <li class="md-nav__item md-nav__item--active md-nav__item--section md-nav__item--nested"> <input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_5" checked> <label class="md-nav__link" for="__nav_5" id="__nav_5_label" tabindex> <span class="md-ellipsis"> API Reference </span> <span class="md-nav__icon md-icon"></span> </label> <nav class="md-nav" data-md-level="1" aria-labelledby="__nav_5_label" aria-expanded="true"> <label class="md-nav__title" for="__nav_5"> <span class="md-nav__icon md-icon"></span> API Reference </label> <ul class="md-nav__list" data-md-scrollfix> <li class="md-nav__item"> <a href="../server/" class="md-nav__link"> <span class="md-ellipsis"> Server </span> </a> </li> <li class="md-nav__item md-nav__item--active"> <input class="md-nav__toggle md-toggle" type="checkbox" id="__toc"> <label class="md-nav__link md-nav__link--active" for="__toc"> <span class="md-ellipsis"> Bridge </span> <span class="md-nav__icon md-icon"></span> </label> <a href="./" class="md-nav__link md-nav__link--active"> <span class="md-ellipsis"> Bridge </span> </a> <nav class="md-nav md-nav--secondary" aria-label="Table of contents"> <label class="md-nav__title" for="__toc"> <span class="md-nav__icon md-icon"></span> Table of contents </label> <ul class="md-nav__list" data-md-component="toc" data-md-scrollfix> <li class="md-nav__item"> <a href="#base-classes" class="md-nav__link"> <span class="md-ellipsis"> Base Classes </span> </a> </li> <li class="md-nav__item"> <a href="#freecad_mcp.bridge.base" class="md-nav__link"> <span class="md-ellipsis"> base </span> </a> <nav class="md-nav" aria-label="base"> <ul class="md-nav__list"> <li class="md-nav__item"> <a href="#freecad_mcp.bridge.base-classes" class="md-nav__link"> <span class="md-ellipsis"> Classes </span> </a> </li> </ul> </nav> </li> <li class="md-nav__item"> <a href="#xml-rpc-bridge" class="md-nav__link"> <span class="md-ellipsis"> XML-RPC Bridge </span> </a> </li> <li class="md-nav__item"> <a href="#freecad_mcp.bridge.xmlrpc" class="md-nav__link"> <span class="md-ellipsis"> xmlrpc </span> </a> <nav class="md-nav" aria-label="xmlrpc"> <ul class="md-nav__list"> <li class="md-nav__item"> <a href="#freecad_mcp.bridge.xmlrpc-classes" class="md-nav__link"> <span class="md-ellipsis"> Classes </span> </a> </li> </ul> </nav> </li> <li class="md-nav__item"> <a href="#socket-bridge" class="md-nav__link"> <span class="md-ellipsis"> Socket Bridge </span> </a> </li> <li class="md-nav__item"> <a href="#freecad_mcp.bridge.socket" class="md-nav__link"> <span class="md-ellipsis"> socket </span> </a> <nav class="md-nav" aria-label="socket"> <ul class="md-nav__list"> <li class="md-nav__item"> <a href="#freecad_mcp.bridge.socket-classes" class="md-nav__link"> <span class="md-ellipsis"> Classes </span> </a> </li> </ul> </nav> </li> <li class="md-nav__item"> <a href="#embedded-bridge" class="md-nav__link"> <span class="md-ellipsis"> Embedded Bridge </span> </a> </li> <li class="md-nav__item"> <a href="#freecad_mcp.bridge.embedded" class="md-nav__link"> <span class="md-ellipsis"> embedded </span> </a> <nav class="md-nav" aria-label="embedded"> <ul class="md-nav__list"> <li class="md-nav__item"> <a href="#freecad_mcp.bridge.embedded-classes" class="md-nav__link"> <span class="md-ellipsis"> Classes </span> </a> </li> </ul> </nav> </li> </ul> </nav> </li> <li class="md-nav__item"> <a href="../config/" class="md-nav__link"> <span class="md-ellipsis"> Config </span> </a> </li> </ul> </nav> </li> <li class="md-nav__item md-nav__item--nested"> <input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_6"> <label class="md-nav__link" for="__nav_6" id="__nav_6_label" tabindex="0"> <span class="md-ellipsis"> Development </span> <span class="md-nav__icon md-icon"></span> </label> <nav class="md-nav" data-md-level="1" aria-labelledby="__nav_6_label" aria-expanded="false"> <label class="md-nav__title" for="__nav_6"> <span class="md-nav__icon md-icon"></span> Development </label> <ul class="md-nav__list" data-md-scrollfix> <li class="md-nav__item"> <a href="../../development/contributing/" class="md-nav__link"> <span class="md-ellipsis"> Contributing </span> </a> </li> <li class="md-nav__item"> <a href="../../development/architecture/" class="md-nav__link"> <span class="md-ellipsis"> Architecture </span> </a> </li> <li class="md-nav__item"> <a href="../../development/architecture-detailed/" class="md-nav__link"> <span class="md-ellipsis"> Detailed Architecture </span> </a> </li> <li class="md-nav__item"> <a href="../../development/releasing/" class="md-nav__link"> <span class="md-ellipsis"> Release Process </span> </a> </li> <li class="md-nav__item"> <a href="../../development/mkdocs-guide/" class="md-nav__link"> <span class="md-ellipsis"> MkDocs Guide </span> </a> </li> </ul> </nav> </li> </ul> </nav> </div> </div> </div> <div class="md-sidebar md-sidebar--secondary" data-md-component="sidebar" data-md-type="toc"> <div class="md-sidebar__scrollwrap"> <div class="md-sidebar__inner"> <nav class="md-nav md-nav--secondary" aria-label="Table of contents"> <label class="md-nav__title" for="__toc"> <span class="md-nav__icon md-icon"></span> Table of contents </label> <ul class="md-nav__list" data-md-component="toc" data-md-scrollfix> <li class="md-nav__item"> <a href="#base-classes" class="md-nav__link"> <span class="md-ellipsis"> Base Classes </span> </a> </li> <li class="md-nav__item"> <a href="#freecad_mcp.bridge.base" class="md-nav__link"> <span class="md-ellipsis"> base </span> </a> <nav class="md-nav" aria-label="base"> <ul class="md-nav__list"> <li class="md-nav__item"> <a href="#freecad_mcp.bridge.base-classes" class="md-nav__link"> <span class="md-ellipsis"> Classes </span> </a> </li> </ul> </nav> </li> <li class="md-nav__item"> <a href="#xml-rpc-bridge" class="md-nav__link"> <span class="md-ellipsis"> XML-RPC Bridge </span> </a> </li> <li class="md-nav__item"> <a href="#freecad_mcp.bridge.xmlrpc" class="md-nav__link"> <span class="md-ellipsis"> xmlrpc </span> </a> <nav class="md-nav" aria-label="xmlrpc"> <ul class="md-nav__list"> <li class="md-nav__item"> <a href="#freecad_mcp.bridge.xmlrpc-classes" class="md-nav__link"> <span class="md-ellipsis"> Classes </span> </a> </li> </ul> </nav> </li> <li class="md-nav__item"> <a href="#socket-bridge" class="md-nav__link"> <span class="md-ellipsis"> Socket Bridge </span> </a> </li> <li class="md-nav__item"> <a href="#freecad_mcp.bridge.socket" class="md-nav__link"> <span class="md-ellipsis"> socket </span> </a> <nav class="md-nav" aria-label="socket"> <ul class="md-nav__list"> <li class="md-nav__item"> <a href="#freecad_mcp.bridge.socket-classes" class="md-nav__link"> <span class="md-ellipsis"> Classes </span> </a> </li> </ul> </nav> </li> <li class="md-nav__item"> <a href="#embedded-bridge" class="md-nav__link"> <span class="md-ellipsis"> Embedded Bridge </span> </a> </li> <li class="md-nav__item"> <a href="#freecad_mcp.bridge.embedded" class="md-nav__link"> <span class="md-ellipsis"> embedded </span> </a> <nav class="md-nav" aria-label="embedded"> <ul class="md-nav__list"> <li class="md-nav__item"> <a href="#freecad_mcp.bridge.embedded-classes" class="md-nav__link"> <span class="md-ellipsis"> Classes </span> </a> </li> </ul> </nav> </li> </ul> </nav> </div> </div> </div> <div class="md-content" data-md-component="content"> <article class="md-content__inner md-typeset"> <h1 id="bridge-api-reference">Bridge API Reference<a class="headerlink" href="#bridge-api-reference" title="Permanent link">¶</a></h1> <p>The bridge module provides the communication layer between the Robust MCP Server and FreeCAD.</p> <h2 id="base-classes">Base Classes<a class="headerlink" href="#base-classes" title="Permanent link">¶</a></h2> <div class="doc doc-object doc-module"> <h2 id="freecad_mcp.bridge.base" class="doc doc-heading"> <code>freecad_mcp.bridge.base</code> <a href="#freecad_mcp.bridge.base" class="headerlink" title="Permanent link">¶</a></h2> <div class="doc doc-contents first"> <p>Abstract bridge interface for FreeCAD communication.</p> <p>This module defines the abstract base class and data types for all FreeCAD bridge implementations. Bridges provide the communication layer between the Robust MCP Server and FreeCAD instances.</p> <p>Based on learnings from existing implementations: - neka-nat: Queue-based thread safety for GUI operations - jango: Multiple connection modes with recovery - contextform: Comprehensive CAD operations</p> <div class="doc doc-children"> <h3 id="freecad_mcp.bridge.base-classes">Classes<a href="#freecad_mcp.bridge.base-classes" class="headerlink" title="Permanent link">¶</a></h3> <div class="doc doc-object doc-class"> <h4 id="freecad_mcp.bridge.base.ConnectionStatus" class="doc doc-heading"> <code>ConnectionStatus</code> <span class="doc doc-labels"> <small class="doc doc-label doc-label-dataclass"><code>dataclass</code></small> </span> <a href="#freecad_mcp.bridge.base.ConnectionStatus" class="headerlink" title="Permanent link">¶</a></h4> <div class="doc doc-contents "> <p>Status of the FreeCAD connection.</p> <p><span class="doc-section-title">Attributes:</span></p> <table> <thead> <tr> <th>Name</th> <th>Type</th> <th>Description</th> </tr> </thead> <tbody> <tr class="doc-section-item"> <td><code><span title="freecad_mcp.bridge.base.ConnectionStatus.connected">connected</span></code></td> <td> <code><span title="bool">bool</span></code> </td> <td> <div class="doc-md-description"> <p>Whether connection is established.</p> </div> </td> </tr> <tr class="doc-section-item"> <td><code><span title="freecad_mcp.bridge.base.ConnectionStatus.mode">mode</span></code></td> <td> <code><span title="str">str</span></code> </td> <td> <div class="doc-md-description"> <p>Connection mode (embedded, xmlrpc, socket).</p> </div> </td> </tr> <tr class="doc-section-item"> <td><code><span title="freecad_mcp.bridge.base.ConnectionStatus.freecad_version">freecad_version</span></code></td> <td> <code><span title="str">str</span></code> </td> <td> <div class="doc-md-description"> <p>FreeCAD version string.</p> </div> </td> </tr> <tr class="doc-section-item"> <td><code><span title="freecad_mcp.bridge.base.ConnectionStatus.gui_available">gui_available</span></code></td> <td> <code><span title="bool">bool</span></code> </td> <td> <div class="doc-md-description"> <p>Whether GUI is available.</p> </div> </td> </tr> <tr class="doc-section-item"> <td><code><span title="freecad_mcp.bridge.base.ConnectionStatus.last_ping_ms">last_ping_ms</span></code></td> <td> <code><span title="float">float</span></code> </td> <td> <div class="doc-md-description"> <p>Last ping latency in milliseconds.</p> </div> </td> </tr> <tr class="doc-section-item"> <td><code><span title="freecad_mcp.bridge.base.ConnectionStatus.error">error</span></code></td> <td> <code><span title="str">str</span> | None</code> </td> <td> <div class="doc-md-description"> <p>Connection error message if any.</p> </div> </td> </tr> </tbody> </table> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/base.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-206">206</a></span>
<span class="normal"><a href="#__codelineno-0-207">207</a></span>
<span class="normal"><a href="#__codelineno-0-208">208</a></span>
<span class="normal"><a href="#__codelineno-0-209">209</a></span>
<span class="normal"><a href="#__codelineno-0-210">210</a></span>
<span class="normal"><a href="#__codelineno-0-211">211</a></span>
<span class="normal"><a href="#__codelineno-0-212">212</a></span>
<span class="normal"><a href="#__codelineno-0-213">213</a></span>
<span class="normal"><a href="#__codelineno-0-214">214</a></span>
<span class="normal"><a href="#__codelineno-0-215">215</a></span>
<span class="normal"><a href="#__codelineno-0-216">216</a></span>
<span class="normal"><a href="#__codelineno-0-217">217</a></span>
<span class="normal"><a href="#__codelineno-0-218">218</a></span>
<span class="normal"><a href="#__codelineno-0-219">219</a></span>
<span class="normal"><a href="#__codelineno-0-220">220</a></span>
<span class="normal"><a href="#__codelineno-0-221">221</a></span>
<span class="normal"><a href="#__codelineno-0-222">222</a></span>
<span class="normal"><a href="#__codelineno-0-223">223</a></span>
<span class="normal"><a href="#__codelineno-0-224">224</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-206"><a id="__codelineno-0-206" name="__codelineno-0-206"></a><span class="nd">@dataclass</span>
</span><span id="__span-0-207"><a id="__codelineno-0-207" name="__codelineno-0-207"></a><span class="k">class</span><span class="w"> </span><span class="nc">ConnectionStatus</span><span class="p">:</span>
</span><span id="__span-0-208"><a id="__codelineno-0-208" name="__codelineno-0-208"></a><span class="w"> </span><span class="sd">"""Status of the FreeCAD connection.</span>
</span><span id="__span-0-209"><a id="__codelineno-0-209" name="__codelineno-0-209"></a>
</span><span id="__span-0-210"><a id="__codelineno-0-210" name="__codelineno-0-210"></a><span class="sd"> Attributes:</span>
</span><span id="__span-0-211"><a id="__codelineno-0-211" name="__codelineno-0-211"></a><span class="sd"> connected: Whether connection is established.</span>
</span><span id="__span-0-212"><a id="__codelineno-0-212" name="__codelineno-0-212"></a><span class="sd"> mode: Connection mode (embedded, xmlrpc, socket).</span>
</span><span id="__span-0-213"><a id="__codelineno-0-213" name="__codelineno-0-213"></a><span class="sd"> freecad_version: FreeCAD version string.</span>
</span><span id="__span-0-214"><a id="__codelineno-0-214" name="__codelineno-0-214"></a><span class="sd"> gui_available: Whether GUI is available.</span>
</span><span id="__span-0-215"><a id="__codelineno-0-215" name="__codelineno-0-215"></a><span class="sd"> last_ping_ms: Last ping latency in milliseconds.</span>
</span><span id="__span-0-216"><a id="__codelineno-0-216" name="__codelineno-0-216"></a><span class="sd"> error: Connection error message if any.</span>
</span><span id="__span-0-217"><a id="__codelineno-0-217" name="__codelineno-0-217"></a><span class="sd"> """</span>
</span><span id="__span-0-218"><a id="__codelineno-0-218" name="__codelineno-0-218"></a>
</span><span id="__span-0-219"><a id="__codelineno-0-219" name="__codelineno-0-219"></a> <span class="n">connected</span><span class="p">:</span> <span class="nb">bool</span>
</span><span id="__span-0-220"><a id="__codelineno-0-220" name="__codelineno-0-220"></a> <span class="n">mode</span><span class="p">:</span> <span class="nb">str</span>
</span><span id="__span-0-221"><a id="__codelineno-0-221" name="__codelineno-0-221"></a> <span class="n">freecad_version</span><span class="p">:</span> <span class="nb">str</span> <span class="o">=</span> <span class="s2">""</span>
</span><span id="__span-0-222"><a id="__codelineno-0-222" name="__codelineno-0-222"></a> <span class="n">gui_available</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">False</span>
</span><span id="__span-0-223"><a id="__codelineno-0-223" name="__codelineno-0-223"></a> <span class="n">last_ping_ms</span><span class="p">:</span> <span class="nb">float</span> <span class="o">=</span> <span class="mi">0</span>
</span><span id="__span-0-224"><a id="__codelineno-0-224" name="__codelineno-0-224"></a> <span class="n">error</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> <div class="doc doc-children"> </div> </div> </div> <div class="doc doc-object doc-class"> <h4 id="freecad_mcp.bridge.base.DocumentInfo" class="doc doc-heading"> <code>DocumentInfo</code> <span class="doc doc-labels"> <small class="doc doc-label doc-label-dataclass"><code>dataclass</code></small> </span> <a href="#freecad_mcp.bridge.base.DocumentInfo" class="headerlink" title="Permanent link">¶</a></h4> <div class="doc doc-contents "> <p>Information about a FreeCAD document.</p> <p><span class="doc-section-title">Attributes:</span></p> <table> <thead> <tr> <th>Name</th> <th>Type</th> <th>Description</th> </tr> </thead> <tbody> <tr class="doc-section-item"> <td><code><span title="freecad_mcp.bridge.base.DocumentInfo.name">name</span></code></td> <td> <code><span title="str">str</span></code> </td> <td> <div class="doc-md-description"> <p>Internal document name (identifier).</p> </div> </td> </tr> <tr class="doc-section-item"> <td><code><span title="freecad_mcp.bridge.base.DocumentInfo.label">label</span></code></td> <td> <code><span title="str">str</span></code> </td> <td> <div class="doc-md-description"> <p>Display label (may differ from name).</p> </div> </td> </tr> <tr class="doc-section-item"> <td><code><span title="freecad_mcp.bridge.base.DocumentInfo.path">path</span></code></td> <td> <code><span title="str">str</span> | None</code> </td> <td> <div class="doc-md-description"> <p>File path if saved, None otherwise.</p> </div> </td> </tr> <tr class="doc-section-item"> <td><code><span title="freecad_mcp.bridge.base.DocumentInfo.objects">objects</span></code></td> <td> <code><span title="list">list</span>[<span title="str">str</span>]</code> </td> <td> <div class="doc-md-description"> <p>List of object names in the document.</p> </div> </td> </tr> <tr class="doc-section-item"> <td><code><span title="freecad_mcp.bridge.base.DocumentInfo.is_modified">is_modified</span></code></td> <td> <code><span title="bool">bool</span></code> </td> <td> <div class="doc-md-description"> <p>Whether document has unsaved changes.</p> </div> </td> </tr> <tr class="doc-section-item"> <td><code><span title="freecad_mcp.bridge.base.DocumentInfo.active_object">active_object</span></code></td> <td> <code><span title="str">str</span> | None</code> </td> <td> <div class="doc-md-description"> <p>Name of the currently active object.</p> </div> </td> </tr> </tbody> </table> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/base.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-67">67</a></span>
<span class="normal"><a href="#__codelineno-0-68">68</a></span>
<span class="normal"><a href="#__codelineno-0-69">69</a></span>
<span class="normal"><a href="#__codelineno-0-70">70</a></span>
<span class="normal"><a href="#__codelineno-0-71">71</a></span>
<span class="normal"><a href="#__codelineno-0-72">72</a></span>
<span class="normal"><a href="#__codelineno-0-73">73</a></span>
<span class="normal"><a href="#__codelineno-0-74">74</a></span>
<span class="normal"><a href="#__codelineno-0-75">75</a></span>
<span class="normal"><a href="#__codelineno-0-76">76</a></span>
<span class="normal"><a href="#__codelineno-0-77">77</a></span>
<span class="normal"><a href="#__codelineno-0-78">78</a></span>
<span class="normal"><a href="#__codelineno-0-79">79</a></span>
<span class="normal"><a href="#__codelineno-0-80">80</a></span>
<span class="normal"><a href="#__codelineno-0-81">81</a></span>
<span class="normal"><a href="#__codelineno-0-82">82</a></span>
<span class="normal"><a href="#__codelineno-0-83">83</a></span>
<span class="normal"><a href="#__codelineno-0-84">84</a></span>
<span class="normal"><a href="#__codelineno-0-85">85</a></span>
<span class="normal"><a href="#__codelineno-0-86">86</a></span>
<span class="normal"><a href="#__codelineno-0-87">87</a></span>
<span class="normal"><a href="#__codelineno-0-88">88</a></span>
<span class="normal"><a href="#__codelineno-0-89">89</a></span>
<span class="normal"><a href="#__codelineno-0-90">90</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-67"><a id="__codelineno-0-67" name="__codelineno-0-67"></a><span class="nd">@dataclass</span>
</span><span id="__span-0-68"><a id="__codelineno-0-68" name="__codelineno-0-68"></a><span class="k">class</span><span class="w"> </span><span class="nc">DocumentInfo</span><span class="p">:</span>
</span><span id="__span-0-69"><a id="__codelineno-0-69" name="__codelineno-0-69"></a><span class="w"> </span><span class="sd">"""Information about a FreeCAD document.</span>
</span><span id="__span-0-70"><a id="__codelineno-0-70" name="__codelineno-0-70"></a>
</span><span id="__span-0-71"><a id="__codelineno-0-71" name="__codelineno-0-71"></a><span class="sd"> Attributes:</span>
</span><span id="__span-0-72"><a id="__codelineno-0-72" name="__codelineno-0-72"></a><span class="sd"> name: Internal document name (identifier).</span>
</span><span id="__span-0-73"><a id="__codelineno-0-73" name="__codelineno-0-73"></a><span class="sd"> label: Display label (may differ from name).</span>
</span><span id="__span-0-74"><a id="__codelineno-0-74" name="__codelineno-0-74"></a><span class="sd"> path: File path if saved, None otherwise.</span>
</span><span id="__span-0-75"><a id="__codelineno-0-75" name="__codelineno-0-75"></a><span class="sd"> objects: List of object names in the document.</span>
</span><span id="__span-0-76"><a id="__codelineno-0-76" name="__codelineno-0-76"></a><span class="sd"> is_modified: Whether document has unsaved changes.</span>
</span><span id="__span-0-77"><a id="__codelineno-0-77" name="__codelineno-0-77"></a><span class="sd"> active_object: Name of the currently active object.</span>
</span><span id="__span-0-78"><a id="__codelineno-0-78" name="__codelineno-0-78"></a><span class="sd"> """</span>
</span><span id="__span-0-79"><a id="__codelineno-0-79" name="__codelineno-0-79"></a>
</span><span id="__span-0-80"><a id="__codelineno-0-80" name="__codelineno-0-80"></a> <span class="n">name</span><span class="p">:</span> <span class="nb">str</span>
</span><span id="__span-0-81"><a id="__codelineno-0-81" name="__codelineno-0-81"></a> <span class="n">label</span><span class="p">:</span> <span class="nb">str</span> <span class="o">=</span> <span class="s2">""</span>
</span><span id="__span-0-82"><a id="__codelineno-0-82" name="__codelineno-0-82"></a> <span class="n">path</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span>
</span><span id="__span-0-83"><a id="__codelineno-0-83" name="__codelineno-0-83"></a> <span class="n">objects</span><span class="p">:</span> <span class="nb">list</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span> <span class="o">=</span> <span class="n">field</span><span class="p">(</span><span class="n">default_factory</span><span class="o">=</span><span class="nb">list</span><span class="p">)</span>
</span><span id="__span-0-84"><a id="__codelineno-0-84" name="__codelineno-0-84"></a> <span class="n">is_modified</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">False</span>
</span><span id="__span-0-85"><a id="__codelineno-0-85" name="__codelineno-0-85"></a> <span class="n">active_object</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span>
</span><span id="__span-0-86"><a id="__codelineno-0-86" name="__codelineno-0-86"></a>
</span><span id="__span-0-87"><a id="__codelineno-0-87" name="__codelineno-0-87"></a> <span class="k">def</span><span class="w"> </span><span class="nf">__post_init__</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kc">None</span><span class="p">:</span>
</span><span id="__span-0-88"><a id="__codelineno-0-88" name="__codelineno-0-88"></a><span class="w"> </span><span class="sd">"""Set label to name if not provided."""</span>
</span><span id="__span-0-89"><a id="__codelineno-0-89" name="__codelineno-0-89"></a> <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">label</span><span class="p">:</span>
</span><span id="__span-0-90"><a id="__codelineno-0-90" name="__codelineno-0-90"></a> <span class="bp">self</span><span class="o">.</span><span class="n">label</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">name</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> <div class="doc doc-children"> <h5 id="freecad_mcp.bridge.base.DocumentInfo-functions">Functions<a href="#freecad_mcp.bridge.base.DocumentInfo-functions" class="headerlink" title="Permanent link">¶</a></h5> <div class="doc doc-object doc-function"> <h6 id="freecad_mcp.bridge.base.DocumentInfo.__post_init__" class="doc doc-heading"> <code class="highlight language-python"><span class="n">__post_init__</span><span class="p">()</span></code> <a href="#freecad_mcp.bridge.base.DocumentInfo.__post_init__" class="headerlink" title="Permanent link">¶</a></h6> <div class="doc doc-contents "> <p>Set label to name if not provided.</p> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/base.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-87">87</a></span>
<span class="normal"><a href="#__codelineno-0-88">88</a></span>
<span class="normal"><a href="#__codelineno-0-89">89</a></span>
<span class="normal"><a href="#__codelineno-0-90">90</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-87"><a id="__codelineno-0-87" name="__codelineno-0-87"></a><span class="k">def</span><span class="w"> </span><span class="nf">__post_init__</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kc">None</span><span class="p">:</span>
</span><span id="__span-0-88"><a id="__codelineno-0-88" name="__codelineno-0-88"></a><span class="w"> </span><span class="sd">"""Set label to name if not provided."""</span>
</span><span id="__span-0-89"><a id="__codelineno-0-89" name="__codelineno-0-89"></a> <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">label</span><span class="p">:</span>
</span><span id="__span-0-90"><a id="__codelineno-0-90" name="__codelineno-0-90"></a> <span class="bp">self</span><span class="o">.</span><span class="n">label</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">name</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> </div> </div> </div> </div> </div> <div class="doc doc-object doc-class"> <h4 id="freecad_mcp.bridge.base.ExecutionResult" class="doc doc-heading"> <code>ExecutionResult</code> <span class="doc doc-labels"> <small class="doc doc-label doc-label-dataclass"><code>dataclass</code></small> </span> <a href="#freecad_mcp.bridge.base.ExecutionResult" class="headerlink" title="Permanent link">¶</a></h4> <div class="doc doc-contents "> <p>Result of Python code execution in FreeCAD.</p> <p><span class="doc-section-title">Attributes:</span></p> <table> <thead> <tr> <th>Name</th> <th>Type</th> <th>Description</th> </tr> </thead> <tbody> <tr class="doc-section-item"> <td><code><span title="freecad_mcp.bridge.base.ExecutionResult.success">success</span></code></td> <td> <code><span title="bool">bool</span></code> </td> <td> <div class="doc-md-description"> <p>Whether execution completed without errors.</p> </div> </td> </tr> <tr class="doc-section-item"> <td><code><span title="freecad_mcp.bridge.base.ExecutionResult.result">result</span></code></td> <td> <code><span title="typing.Any">Any</span></code> </td> <td> <div class="doc-md-description"> <p>The value assigned to <code>_result_</code> variable, or None.</p> </div> </td> </tr> <tr class="doc-section-item"> <td><code><span title="freecad_mcp.bridge.base.ExecutionResult.stdout">stdout</span></code></td> <td> <code><span title="str">str</span></code> </td> <td> <div class="doc-md-description"> <p>Captured standard output.</p> </div> </td> </tr> <tr class="doc-section-item"> <td><code><span title="freecad_mcp.bridge.base.ExecutionResult.stderr">stderr</span></code></td> <td> <code><span title="str">str</span></code> </td> <td> <div class="doc-md-description"> <p>Captured standard error.</p> </div> </td> </tr> <tr class="doc-section-item"> <td><code><span title="freecad_mcp.bridge.base.ExecutionResult.execution_time_ms">execution_time_ms</span></code></td> <td> <code><span title="float">float</span></code> </td> <td> <div class="doc-md-description"> <p>Time taken in milliseconds.</p> </div> </td> </tr> <tr class="doc-section-item"> <td><code><span title="freecad_mcp.bridge.base.ExecutionResult.error_type">error_type</span></code></td> <td> <code><span title="str">str</span> | None</code> </td> <td> <div class="doc-md-description"> <p>Type of exception if failed, None otherwise.</p> </div> </td> </tr> <tr class="doc-section-item"> <td><code><span title="freecad_mcp.bridge.base.ExecutionResult.error_traceback">error_traceback</span></code></td> <td> <code><span title="str">str</span> | None</code> </td> <td> <div class="doc-md-description"> <p>Full traceback if failed, None otherwise.</p> </div> </td> </tr> </tbody> </table> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/base.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-44">44</a></span>
<span class="normal"><a href="#__codelineno-0-45">45</a></span>
<span class="normal"><a href="#__codelineno-0-46">46</a></span>
<span class="normal"><a href="#__codelineno-0-47">47</a></span>
<span class="normal"><a href="#__codelineno-0-48">48</a></span>
<span class="normal"><a href="#__codelineno-0-49">49</a></span>
<span class="normal"><a href="#__codelineno-0-50">50</a></span>
<span class="normal"><a href="#__codelineno-0-51">51</a></span>
<span class="normal"><a href="#__codelineno-0-52">52</a></span>
<span class="normal"><a href="#__codelineno-0-53">53</a></span>
<span class="normal"><a href="#__codelineno-0-54">54</a></span>
<span class="normal"><a href="#__codelineno-0-55">55</a></span>
<span class="normal"><a href="#__codelineno-0-56">56</a></span>
<span class="normal"><a href="#__codelineno-0-57">57</a></span>
<span class="normal"><a href="#__codelineno-0-58">58</a></span>
<span class="normal"><a href="#__codelineno-0-59">59</a></span>
<span class="normal"><a href="#__codelineno-0-60">60</a></span>
<span class="normal"><a href="#__codelineno-0-61">61</a></span>
<span class="normal"><a href="#__codelineno-0-62">62</a></span>
<span class="normal"><a href="#__codelineno-0-63">63</a></span>
<span class="normal"><a href="#__codelineno-0-64">64</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-44"><a id="__codelineno-0-44" name="__codelineno-0-44"></a><span class="nd">@dataclass</span>
</span><span id="__span-0-45"><a id="__codelineno-0-45" name="__codelineno-0-45"></a><span class="k">class</span><span class="w"> </span><span class="nc">ExecutionResult</span><span class="p">:</span>
</span><span id="__span-0-46"><a id="__codelineno-0-46" name="__codelineno-0-46"></a><span class="w"> </span><span class="sd">"""Result of Python code execution in FreeCAD.</span>
</span><span id="__span-0-47"><a id="__codelineno-0-47" name="__codelineno-0-47"></a>
</span><span id="__span-0-48"><a id="__codelineno-0-48" name="__codelineno-0-48"></a><span class="sd"> Attributes:</span>
</span><span id="__span-0-49"><a id="__codelineno-0-49" name="__codelineno-0-49"></a><span class="sd"> success: Whether execution completed without errors.</span>
</span><span id="__span-0-50"><a id="__codelineno-0-50" name="__codelineno-0-50"></a><span class="sd"> result: The value assigned to `_result_` variable, or None.</span>
</span><span id="__span-0-51"><a id="__codelineno-0-51" name="__codelineno-0-51"></a><span class="sd"> stdout: Captured standard output.</span>
</span><span id="__span-0-52"><a id="__codelineno-0-52" name="__codelineno-0-52"></a><span class="sd"> stderr: Captured standard error.</span>
</span><span id="__span-0-53"><a id="__codelineno-0-53" name="__codelineno-0-53"></a><span class="sd"> execution_time_ms: Time taken in milliseconds.</span>
</span><span id="__span-0-54"><a id="__codelineno-0-54" name="__codelineno-0-54"></a><span class="sd"> error_type: Type of exception if failed, None otherwise.</span>
</span><span id="__span-0-55"><a id="__codelineno-0-55" name="__codelineno-0-55"></a><span class="sd"> error_traceback: Full traceback if failed, None otherwise.</span>
</span><span id="__span-0-56"><a id="__codelineno-0-56" name="__codelineno-0-56"></a><span class="sd"> """</span>
</span><span id="__span-0-57"><a id="__codelineno-0-57" name="__codelineno-0-57"></a>
</span><span id="__span-0-58"><a id="__codelineno-0-58" name="__codelineno-0-58"></a> <span class="n">success</span><span class="p">:</span> <span class="nb">bool</span>
</span><span id="__span-0-59"><a id="__codelineno-0-59" name="__codelineno-0-59"></a> <span class="n">result</span><span class="p">:</span> <span class="n">Any</span>
</span><span id="__span-0-60"><a id="__codelineno-0-60" name="__codelineno-0-60"></a> <span class="n">stdout</span><span class="p">:</span> <span class="nb">str</span>
</span><span id="__span-0-61"><a id="__codelineno-0-61" name="__codelineno-0-61"></a> <span class="n">stderr</span><span class="p">:</span> <span class="nb">str</span>
</span><span id="__span-0-62"><a id="__codelineno-0-62" name="__codelineno-0-62"></a> <span class="n">execution_time_ms</span><span class="p">:</span> <span class="nb">float</span>
</span><span id="__span-0-63"><a id="__codelineno-0-63" name="__codelineno-0-63"></a> <span class="n">error_type</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span>
</span><span id="__span-0-64"><a id="__codelineno-0-64" name="__codelineno-0-64"></a> <span class="n">error_traceback</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> <div class="doc doc-children"> </div> </div> </div> <div class="doc doc-object doc-class"> <h4 id="freecad_mcp.bridge.base.FreecadBridge" class="doc doc-heading"> <code>FreecadBridge</code> <a href="#freecad_mcp.bridge.base.FreecadBridge" class="headerlink" title="Permanent link">¶</a></h4> <div class="doc doc-contents "> <p class="doc doc-class-bases"> Bases: <code><span title="abc.ABC">ABC</span></code></p> <p>Abstract base class for FreeCAD bridges.</p> <p>A bridge provides communication between the Robust MCP Server and a FreeCAD instance. Implementations may run FreeCAD in-process (embedded), communicate via XML-RPC, or use JSON-RPC over sockets.</p> <details class="thread-safety" open> <summary>Thread Safety</summary> <p>GUI operations must be executed on the main thread. Implementations should use queue-based communication for thread safety (learned from neka-nat implementation).</p> </details> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/base.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-227">227</a></span>
<span class="normal"><a href="#__codelineno-0-228">228</a></span>
<span class="normal"><a href="#__codelineno-0-229">229</a></span>
<span class="normal"><a href="#__codelineno-0-230">230</a></span>
<span class="normal"><a href="#__codelineno-0-231">231</a></span>
<span class="normal"><a href="#__codelineno-0-232">232</a></span>
<span class="normal"><a href="#__codelineno-0-233">233</a></span>
<span class="normal"><a href="#__codelineno-0-234">234</a></span>
<span class="normal"><a href="#__codelineno-0-235">235</a></span>
<span class="normal"><a href="#__codelineno-0-236">236</a></span>
<span class="normal"><a href="#__codelineno-0-237">237</a></span>
<span class="normal"><a href="#__codelineno-0-238">238</a></span>
<span class="normal"><a href="#__codelineno-0-239">239</a></span>
<span class="normal"><a href="#__codelineno-0-240">240</a></span>
<span class="normal"><a href="#__codelineno-0-241">241</a></span>
<span class="normal"><a href="#__codelineno-0-242">242</a></span>
<span class="normal"><a href="#__codelineno-0-243">243</a></span>
<span class="normal"><a href="#__codelineno-0-244">244</a></span>
<span class="normal"><a href="#__codelineno-0-245">245</a></span>
<span class="normal"><a href="#__codelineno-0-246">246</a></span>
<span class="normal"><a href="#__codelineno-0-247">247</a></span>
<span class="normal"><a href="#__codelineno-0-248">248</a></span>
<span class="normal"><a href="#__codelineno-0-249">249</a></span>
<span class="normal"><a href="#__codelineno-0-250">250</a></span>
<span class="normal"><a href="#__codelineno-0-251">251</a></span>
<span class="normal"><a href="#__codelineno-0-252">252</a></span>
<span class="normal"><a href="#__codelineno-0-253">253</a></span>
<span class="normal"><a href="#__codelineno-0-254">254</a></span>
<span class="normal"><a href="#__codelineno-0-255">255</a></span>
<span class="normal"><a href="#__codelineno-0-256">256</a></span>
<span class="normal"><a href="#__codelineno-0-257">257</a></span>
<span class="normal"><a href="#__codelineno-0-258">258</a></span>
<span class="normal"><a href="#__codelineno-0-259">259</a></span>
<span class="normal"><a href="#__codelineno-0-260">260</a></span>
<span class="normal"><a href="#__codelineno-0-261">261</a></span>
<span class="normal"><a href="#__codelineno-0-262">262</a></span>
<span class="normal"><a href="#__codelineno-0-263">263</a></span>
<span class="normal"><a href="#__codelineno-0-264">264</a></span>
<span class="normal"><a href="#__codelineno-0-265">265</a></span>
<span class="normal"><a href="#__codelineno-0-266">266</a></span>
<span class="normal"><a href="#__codelineno-0-267">267</a></span>
<span class="normal"><a href="#__codelineno-0-268">268</a></span>
<span class="normal"><a href="#__codelineno-0-269">269</a></span>
<span class="normal"><a href="#__codelineno-0-270">270</a></span>
<span class="normal"><a href="#__codelineno-0-271">271</a></span>
<span class="normal"><a href="#__codelineno-0-272">272</a></span>
<span class="normal"><a href="#__codelineno-0-273">273</a></span>
<span class="normal"><a href="#__codelineno-0-274">274</a></span>
<span class="normal"><a href="#__codelineno-0-275">275</a></span>
<span class="normal"><a href="#__codelineno-0-276">276</a></span>
<span class="normal"><a href="#__codelineno-0-277">277</a></span>
<span class="normal"><a href="#__codelineno-0-278">278</a></span>
<span class="normal"><a href="#__codelineno-0-279">279</a></span>
<span class="normal"><a href="#__codelineno-0-280">280</a></span>
<span class="normal"><a href="#__codelineno-0-281">281</a></span>
<span class="normal"><a href="#__codelineno-0-282">282</a></span>
<span class="normal"><a href="#__codelineno-0-283">283</a></span>
<span class="normal"><a href="#__codelineno-0-284">284</a></span>
<span class="normal"><a href="#__codelineno-0-285">285</a></span>
<span class="normal"><a href="#__codelineno-0-286">286</a></span>
<span class="normal"><a href="#__codelineno-0-287">287</a></span>
<span class="normal"><a href="#__codelineno-0-288">288</a></span>
<span class="normal"><a href="#__codelineno-0-289">289</a></span>
<span class="normal"><a href="#__codelineno-0-290">290</a></span>
<span class="normal"><a href="#__codelineno-0-291">291</a></span>
<span class="normal"><a href="#__codelineno-0-292">292</a></span>
<span class="normal"><a href="#__codelineno-0-293">293</a></span>
<span class="normal"><a href="#__codelineno-0-294">294</a></span>
<span class="normal"><a href="#__codelineno-0-295">295</a></span>
<span class="normal"><a href="#__codelineno-0-296">296</a></span>
<span class="normal"><a href="#__codelineno-0-297">297</a></span>
<span class="normal"><a href="#__codelineno-0-298">298</a></span>
<span class="normal"><a href="#__codelineno-0-299">299</a></span>
<span class="normal"><a href="#__codelineno-0-300">300</a></span>
<span class="normal"><a href="#__codelineno-0-301">301</a></span>
<span class="normal"><a href="#__codelineno-0-302">302</a></span>
<span class="normal"><a href="#__codelineno-0-303">303</a></span>
<span class="normal"><a href="#__codelineno-0-304">304</a></span>
<span class="normal"><a href="#__codelineno-0-305">305</a></span>
<span class="normal"><a href="#__codelineno-0-306">306</a></span>
<span class="normal"><a href="#__codelineno-0-307">307</a></span>
<span class="normal"><a href="#__codelineno-0-308">308</a></span>
<span class="normal"><a href="#__codelineno-0-309">309</a></span>
<span class="normal"><a href="#__codelineno-0-310">310</a></span>
<span class="normal"><a href="#__codelineno-0-311">311</a></span>
<span class="normal"><a href="#__codelineno-0-312">312</a></span>
<span class="normal"><a href="#__codelineno-0-313">313</a></span>
<span class="normal"><a href="#__codelineno-0-314">314</a></span>
<span class="normal"><a href="#__codelineno-0-315">315</a></span>
<span class="normal"><a href="#__codelineno-0-316">316</a></span>
<span class="normal"><a href="#__codelineno-0-317">317</a></span>
<span class="normal"><a href="#__codelineno-0-318">318</a></span>
<span class="normal"><a href="#__codelineno-0-319">319</a></span>
<span class="normal"><a href="#__codelineno-0-320">320</a></span>
<span class="normal"><a href="#__codelineno-0-321">321</a></span>
<span class="normal"><a href="#__codelineno-0-322">322</a></span>
<span class="normal"><a href="#__codelineno-0-323">323</a></span>
<span class="normal"><a href="#__codelineno-0-324">324</a></span>
<span class="normal"><a href="#__codelineno-0-325">325</a></span>
<span class="normal"><a href="#__codelineno-0-326">326</a></span>
<span class="normal"><a href="#__codelineno-0-327">327</a></span>
<span class="normal"><a href="#__codelineno-0-328">328</a></span>
<span class="normal"><a href="#__codelineno-0-329">329</a></span>
<span class="normal"><a href="#__codelineno-0-330">330</a></span>
<span class="normal"><a href="#__codelineno-0-331">331</a></span>
<span class="normal"><a href="#__codelineno-0-332">332</a></span>
<span class="normal"><a href="#__codelineno-0-333">333</a></span>
<span class="normal"><a href="#__codelineno-0-334">334</a></span>
<span class="normal"><a href="#__codelineno-0-335">335</a></span>
<span class="normal"><a href="#__codelineno-0-336">336</a></span>
<span class="normal"><a href="#__codelineno-0-337">337</a></span>
<span class="normal"><a href="#__codelineno-0-338">338</a></span>
<span class="normal"><a href="#__codelineno-0-339">339</a></span>
<span class="normal"><a href="#__codelineno-0-340">340</a></span>
<span class="normal"><a href="#__codelineno-0-341">341</a></span>
<span class="normal"><a href="#__codelineno-0-342">342</a></span>
<span class="normal"><a href="#__codelineno-0-343">343</a></span>
<span class="normal"><a href="#__codelineno-0-344">344</a></span>
<span class="normal"><a href="#__codelineno-0-345">345</a></span>
<span class="normal"><a href="#__codelineno-0-346">346</a></span>
<span class="normal"><a href="#__codelineno-0-347">347</a></span>
<span class="normal"><a href="#__codelineno-0-348">348</a></span>
<span class="normal"><a href="#__codelineno-0-349">349</a></span>
<span class="normal"><a href="#__codelineno-0-350">350</a></span>
<span class="normal"><a href="#__codelineno-0-351">351</a></span>
<span class="normal"><a href="#__codelineno-0-352">352</a></span>
<span class="normal"><a href="#__codelineno-0-353">353</a></span>
<span class="normal"><a href="#__codelineno-0-354">354</a></span>
<span class="normal"><a href="#__codelineno-0-355">355</a></span>
<span class="normal"><a href="#__codelineno-0-356">356</a></span>
<span class="normal"><a href="#__codelineno-0-357">357</a></span>
<span class="normal"><a href="#__codelineno-0-358">358</a></span>
<span class="normal"><a href="#__codelineno-0-359">359</a></span>
<span class="normal"><a href="#__codelineno-0-360">360</a></span>
<span class="normal"><a href="#__codelineno-0-361">361</a></span>
<span class="normal"><a href="#__codelineno-0-362">362</a></span>
<span class="normal"><a href="#__codelineno-0-363">363</a></span>
<span class="normal"><a href="#__codelineno-0-364">364</a></span>
<span class="normal"><a href="#__codelineno-0-365">365</a></span>
<span class="normal"><a href="#__codelineno-0-366">366</a></span>
<span class="normal"><a href="#__codelineno-0-367">367</a></span>
<span class="normal"><a href="#__codelineno-0-368">368</a></span>
<span class="normal"><a href="#__codelineno-0-369">369</a></span>
<span class="normal"><a href="#__codelineno-0-370">370</a></span>
<span class="normal"><a href="#__codelineno-0-371">371</a></span>
<span class="normal"><a href="#__codelineno-0-372">372</a></span>
<span class="normal"><a href="#__codelineno-0-373">373</a></span>
<span class="normal"><a href="#__codelineno-0-374">374</a></span>
<span class="normal"><a href="#__codelineno-0-375">375</a></span>
<span class="normal"><a href="#__codelineno-0-376">376</a></span>
<span class="normal"><a href="#__codelineno-0-377">377</a></span>
<span class="normal"><a href="#__codelineno-0-378">378</a></span>
<span class="normal"><a href="#__codelineno-0-379">379</a></span>
<span class="normal"><a href="#__codelineno-0-380">380</a></span>
<span class="normal"><a href="#__codelineno-0-381">381</a></span>
<span class="normal"><a href="#__codelineno-0-382">382</a></span>
<span class="normal"><a href="#__codelineno-0-383">383</a></span>
<span class="normal"><a href="#__codelineno-0-384">384</a></span>
<span class="normal"><a href="#__codelineno-0-385">385</a></span>
<span class="normal"><a href="#__codelineno-0-386">386</a></span>
<span class="normal"><a href="#__codelineno-0-387">387</a></span>
<span class="normal"><a href="#__codelineno-0-388">388</a></span>
<span class="normal"><a href="#__codelineno-0-389">389</a></span>
<span class="normal"><a href="#__codelineno-0-390">390</a></span>
<span class="normal"><a href="#__codelineno-0-391">391</a></span>
<span class="normal"><a href="#__codelineno-0-392">392</a></span>
<span class="normal"><a href="#__codelineno-0-393">393</a></span>
<span class="normal"><a href="#__codelineno-0-394">394</a></span>
<span class="normal"><a href="#__codelineno-0-395">395</a></span>
<span class="normal"><a href="#__codelineno-0-396">396</a></span>
<span class="normal"><a href="#__codelineno-0-397">397</a></span>
<span class="normal"><a href="#__codelineno-0-398">398</a></span>
<span class="normal"><a href="#__codelineno-0-399">399</a></span>
<span class="normal"><a href="#__codelineno-0-400">400</a></span>
<span class="normal"><a href="#__codelineno-0-401">401</a></span>
<span class="normal"><a href="#__codelineno-0-402">402</a></span>
<span class="normal"><a href="#__codelineno-0-403">403</a></span>
<span class="normal"><a href="#__codelineno-0-404">404</a></span>
<span class="normal"><a href="#__codelineno-0-405">405</a></span>
<span class="normal"><a href="#__codelineno-0-406">406</a></span>
<span class="normal"><a href="#__codelineno-0-407">407</a></span>
<span class="normal"><a href="#__codelineno-0-408">408</a></span>
<span class="normal"><a href="#__codelineno-0-409">409</a></span>
<span class="normal"><a href="#__codelineno-0-410">410</a></span>
<span class="normal"><a href="#__codelineno-0-411">411</a></span>
<span class="normal"><a href="#__codelineno-0-412">412</a></span>
<span class="normal"><a href="#__codelineno-0-413">413</a></span>
<span class="normal"><a href="#__codelineno-0-414">414</a></span>
<span class="normal"><a href="#__codelineno-0-415">415</a></span>
<span class="normal"><a href="#__codelineno-0-416">416</a></span>
<span class="normal"><a href="#__codelineno-0-417">417</a></span>
<span class="normal"><a href="#__codelineno-0-418">418</a></span>
<span class="normal"><a href="#__codelineno-0-419">419</a></span>
<span class="normal"><a href="#__codelineno-0-420">420</a></span>
<span class="normal"><a href="#__codelineno-0-421">421</a></span>
<span class="normal"><a href="#__codelineno-0-422">422</a></span>
<span class="normal"><a href="#__codelineno-0-423">423</a></span>
<span class="normal"><a href="#__codelineno-0-424">424</a></span>
<span class="normal"><a href="#__codelineno-0-425">425</a></span>
<span class="normal"><a href="#__codelineno-0-426">426</a></span>
<span class="normal"><a href="#__codelineno-0-427">427</a></span>
<span class="normal"><a href="#__codelineno-0-428">428</a></span>
<span class="normal"><a href="#__codelineno-0-429">429</a></span>
<span class="normal"><a href="#__codelineno-0-430">430</a></span>
<span class="normal"><a href="#__codelineno-0-431">431</a></span>
<span class="normal"><a href="#__codelineno-0-432">432</a></span>
<span class="normal"><a href="#__codelineno-0-433">433</a></span>
<span class="normal"><a href="#__codelineno-0-434">434</a></span>
<span class="normal"><a href="#__codelineno-0-435">435</a></span>
<span class="normal"><a href="#__codelineno-0-436">436</a></span>
<span class="normal"><a href="#__codelineno-0-437">437</a></span>
<span class="normal"><a href="#__codelineno-0-438">438</a></span>
<span class="normal"><a href="#__codelineno-0-439">439</a></span>
<span class="normal"><a href="#__codelineno-0-440">440</a></span>
<span class="normal"><a href="#__codelineno-0-441">441</a></span>
<span class="normal"><a href="#__codelineno-0-442">442</a></span>
<span class="normal"><a href="#__codelineno-0-443">443</a></span>
<span class="normal"><a href="#__codelineno-0-444">444</a></span>
<span class="normal"><a href="#__codelineno-0-445">445</a></span>
<span class="normal"><a href="#__codelineno-0-446">446</a></span>
<span class="normal"><a href="#__codelineno-0-447">447</a></span>
<span class="normal"><a href="#__codelineno-0-448">448</a></span>
<span class="normal"><a href="#__codelineno-0-449">449</a></span>
<span class="normal"><a href="#__codelineno-0-450">450</a></span>
<span class="normal"><a href="#__codelineno-0-451">451</a></span>
<span class="normal"><a href="#__codelineno-0-452">452</a></span>
<span class="normal"><a href="#__codelineno-0-453">453</a></span>
<span class="normal"><a href="#__codelineno-0-454">454</a></span>
<span class="normal"><a href="#__codelineno-0-455">455</a></span>
<span class="normal"><a href="#__codelineno-0-456">456</a></span>
<span class="normal"><a href="#__codelineno-0-457">457</a></span>
<span class="normal"><a href="#__codelineno-0-458">458</a></span>
<span class="normal"><a href="#__codelineno-0-459">459</a></span>
<span class="normal"><a href="#__codelineno-0-460">460</a></span>
<span class="normal"><a href="#__codelineno-0-461">461</a></span>
<span class="normal"><a href="#__codelineno-0-462">462</a></span>
<span class="normal"><a href="#__codelineno-0-463">463</a></span>
<span class="normal"><a href="#__codelineno-0-464">464</a></span>
<span class="normal"><a href="#__codelineno-0-465">465</a></span>
<span class="normal"><a href="#__codelineno-0-466">466</a></span>
<span class="normal"><a href="#__codelineno-0-467">467</a></span>
<span class="normal"><a href="#__codelineno-0-468">468</a></span>
<span class="normal"><a href="#__codelineno-0-469">469</a></span>
<span class="normal"><a href="#__codelineno-0-470">470</a></span>
<span class="normal"><a href="#__codelineno-0-471">471</a></span>
<span class="normal"><a href="#__codelineno-0-472">472</a></span>
<span class="normal"><a href="#__codelineno-0-473">473</a></span>
<span class="normal"><a href="#__codelineno-0-474">474</a></span>
<span class="normal"><a href="#__codelineno-0-475">475</a></span>
<span class="normal"><a href="#__codelineno-0-476">476</a></span>
<span class="normal"><a href="#__codelineno-0-477">477</a></span>
<span class="normal"><a href="#__codelineno-0-478">478</a></span>
<span class="normal"><a href="#__codelineno-0-479">479</a></span>
<span class="normal"><a href="#__codelineno-0-480">480</a></span>
<span class="normal"><a href="#__codelineno-0-481">481</a></span>
<span class="normal"><a href="#__codelineno-0-482">482</a></span>
<span class="normal"><a href="#__codelineno-0-483">483</a></span>
<span class="normal"><a href="#__codelineno-0-484">484</a></span>
<span class="normal"><a href="#__codelineno-0-485">485</a></span>
<span class="normal"><a href="#__codelineno-0-486">486</a></span>
<span class="normal"><a href="#__codelineno-0-487">487</a></span>
<span class="normal"><a href="#__codelineno-0-488">488</a></span>
<span class="normal"><a href="#__codelineno-0-489">489</a></span>
<span class="normal"><a href="#__codelineno-0-490">490</a></span>
<span class="normal"><a href="#__codelineno-0-491">491</a></span>
<span class="normal"><a href="#__codelineno-0-492">492</a></span>
<span class="normal"><a href="#__codelineno-0-493">493</a></span>
<span class="normal"><a href="#__codelineno-0-494">494</a></span>
<span class="normal"><a href="#__codelineno-0-495">495</a></span>
<span class="normal"><a href="#__codelineno-0-496">496</a></span>
<span class="normal"><a href="#__codelineno-0-497">497</a></span>
<span class="normal"><a href="#__codelineno-0-498">498</a></span>
<span class="normal"><a href="#__codelineno-0-499">499</a></span>
<span class="normal"><a href="#__codelineno-0-500">500</a></span>
<span class="normal"><a href="#__codelineno-0-501">501</a></span>
<span class="normal"><a href="#__codelineno-0-502">502</a></span>
<span class="normal"><a href="#__codelineno-0-503">503</a></span>
<span class="normal"><a href="#__codelineno-0-504">504</a></span>
<span class="normal"><a href="#__codelineno-0-505">505</a></span>
<span class="normal"><a href="#__codelineno-0-506">506</a></span>
<span class="normal"><a href="#__codelineno-0-507">507</a></span>
<span class="normal"><a href="#__codelineno-0-508">508</a></span>
<span class="normal"><a href="#__codelineno-0-509">509</a></span>
<span class="normal"><a href="#__codelineno-0-510">510</a></span>
<span class="normal"><a href="#__codelineno-0-511">511</a></span>
<span class="normal"><a href="#__codelineno-0-512">512</a></span>
<span class="normal"><a href="#__codelineno-0-513">513</a></span>
<span class="normal"><a href="#__codelineno-0-514">514</a></span>
<span class="normal"><a href="#__codelineno-0-515">515</a></span>
<span class="normal"><a href="#__codelineno-0-516">516</a></span>
<span class="normal"><a href="#__codelineno-0-517">517</a></span>
<span class="normal"><a href="#__codelineno-0-518">518</a></span>
<span class="normal"><a href="#__codelineno-0-519">519</a></span>
<span class="normal"><a href="#__codelineno-0-520">520</a></span>
<span class="normal"><a href="#__codelineno-0-521">521</a></span>
<span class="normal"><a href="#__codelineno-0-522">522</a></span>
<span class="normal"><a href="#__codelineno-0-523">523</a></span>
<span class="normal"><a href="#__codelineno-0-524">524</a></span>
<span class="normal"><a href="#__codelineno-0-525">525</a></span>
<span class="normal"><a href="#__codelineno-0-526">526</a></span>
<span class="normal"><a href="#__codelineno-0-527">527</a></span>
<span class="normal"><a href="#__codelineno-0-528">528</a></span>
<span class="normal"><a href="#__codelineno-0-529">529</a></span>
<span class="normal"><a href="#__codelineno-0-530">530</a></span>
<span class="normal"><a href="#__codelineno-0-531">531</a></span>
<span class="normal"><a href="#__codelineno-0-532">532</a></span>
<span class="normal"><a href="#__codelineno-0-533">533</a></span>
<span class="normal"><a href="#__codelineno-0-534">534</a></span>
<span class="normal"><a href="#__codelineno-0-535">535</a></span>
<span class="normal"><a href="#__codelineno-0-536">536</a></span>
<span class="normal"><a href="#__codelineno-0-537">537</a></span>
<span class="normal"><a href="#__codelineno-0-538">538</a></span>
<span class="normal"><a href="#__codelineno-0-539">539</a></span>
<span class="normal"><a href="#__codelineno-0-540">540</a></span>
<span class="normal"><a href="#__codelineno-0-541">541</a></span>
<span class="normal"><a href="#__codelineno-0-542">542</a></span>
<span class="normal"><a href="#__codelineno-0-543">543</a></span>
<span class="normal"><a href="#__codelineno-0-544">544</a></span>
<span class="normal"><a href="#__codelineno-0-545">545</a></span>
<span class="normal"><a href="#__codelineno-0-546">546</a></span>
<span class="normal"><a href="#__codelineno-0-547">547</a></span>
<span class="normal"><a href="#__codelineno-0-548">548</a></span>
<span class="normal"><a href="#__codelineno-0-549">549</a></span>
<span class="normal"><a href="#__codelineno-0-550">550</a></span>
<span class="normal"><a href="#__codelineno-0-551">551</a></span>
<span class="normal"><a href="#__codelineno-0-552">552</a></span>
<span class="normal"><a href="#__codelineno-0-553">553</a></span>
<span class="normal"><a href="#__codelineno-0-554">554</a></span>
<span class="normal"><a href="#__codelineno-0-555">555</a></span>
<span class="normal"><a href="#__codelineno-0-556">556</a></span>
<span class="normal"><a href="#__codelineno-0-557">557</a></span>
<span class="normal"><a href="#__codelineno-0-558">558</a></span>
<span class="normal"><a href="#__codelineno-0-559">559</a></span>
<span class="normal"><a href="#__codelineno-0-560">560</a></span>
<span class="normal"><a href="#__codelineno-0-561">561</a></span>
<span class="normal"><a href="#__codelineno-0-562">562</a></span>
<span class="normal"><a href="#__codelineno-0-563">563</a></span>
<span class="normal"><a href="#__codelineno-0-564">564</a></span>
<span class="normal"><a href="#__codelineno-0-565">565</a></span>
<span class="normal"><a href="#__codelineno-0-566">566</a></span>
<span class="normal"><a href="#__codelineno-0-567">567</a></span>
<span class="normal"><a href="#__codelineno-0-568">568</a></span>
<span class="normal"><a href="#__codelineno-0-569">569</a></span>
<span class="normal"><a href="#__codelineno-0-570">570</a></span>
<span class="normal"><a href="#__codelineno-0-571">571</a></span>
<span class="normal"><a href="#__codelineno-0-572">572</a></span>
<span class="normal"><a href="#__codelineno-0-573">573</a></span>
<span class="normal"><a href="#__codelineno-0-574">574</a></span>
<span class="normal"><a href="#__codelineno-0-575">575</a></span>
<span class="normal"><a href="#__codelineno-0-576">576</a></span>
<span class="normal"><a href="#__codelineno-0-577">577</a></span>
<span class="normal"><a href="#__codelineno-0-578">578</a></span>
<span class="normal"><a href="#__codelineno-0-579">579</a></span>
<span class="normal"><a href="#__codelineno-0-580">580</a></span>
<span class="normal"><a href="#__codelineno-0-581">581</a></span>
<span class="normal"><a href="#__codelineno-0-582">582</a></span>
<span class="normal"><a href="#__codelineno-0-583">583</a></span>
<span class="normal"><a href="#__codelineno-0-584">584</a></span>
<span class="normal"><a href="#__codelineno-0-585">585</a></span>
<span class="normal"><a href="#__codelineno-0-586">586</a></span>
<span class="normal"><a href="#__codelineno-0-587">587</a></span>
<span class="normal"><a href="#__codelineno-0-588">588</a></span>
<span class="normal"><a href="#__codelineno-0-589">589</a></span>
<span class="normal"><a href="#__codelineno-0-590">590</a></span>
<span class="normal"><a href="#__codelineno-0-591">591</a></span>
<span class="normal"><a href="#__codelineno-0-592">592</a></span>
<span class="normal"><a href="#__codelineno-0-593">593</a></span>
<span class="normal"><a href="#__codelineno-0-594">594</a></span>
<span class="normal"><a href="#__codelineno-0-595">595</a></span>
<span class="normal"><a href="#__codelineno-0-596">596</a></span>
<span class="normal"><a href="#__codelineno-0-597">597</a></span>
<span class="normal"><a href="#__codelineno-0-598">598</a></span>
<span class="normal"><a href="#__codelineno-0-599">599</a></span>
<span class="normal"><a href="#__codelineno-0-600">600</a></span>
<span class="normal"><a href="#__codelineno-0-601">601</a></span>
<span class="normal"><a href="#__codelineno-0-602">602</a></span>
<span class="normal"><a href="#__codelineno-0-603">603</a></span>
<span class="normal"><a href="#__codelineno-0-604">604</a></span>
<span class="normal"><a href="#__codelineno-0-605">605</a></span>
<span class="normal"><a href="#__codelineno-0-606">606</a></span>
<span class="normal"><a href="#__codelineno-0-607">607</a></span>
<span class="normal"><a href="#__codelineno-0-608">608</a></span>
<span class="normal"><a href="#__codelineno-0-609">609</a></span>
<span class="normal"><a href="#__codelineno-0-610">610</a></span>
<span class="normal"><a href="#__codelineno-0-611">611</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-227"><a id="__codelineno-0-227" name="__codelineno-0-227"></a><span class="k">class</span><span class="w"> </span><span class="nc">FreecadBridge</span><span class="p">(</span><span class="n">ABC</span><span class="p">):</span>
</span><span id="__span-0-228"><a id="__codelineno-0-228" name="__codelineno-0-228"></a><span class="w"> </span><span class="sd">"""Abstract base class for FreeCAD bridges.</span>
</span><span id="__span-0-229"><a id="__codelineno-0-229" name="__codelineno-0-229"></a>
</span><span id="__span-0-230"><a id="__codelineno-0-230" name="__codelineno-0-230"></a><span class="sd"> A bridge provides communication between the Robust MCP Server and a FreeCAD</span>
</span><span id="__span-0-231"><a id="__codelineno-0-231" name="__codelineno-0-231"></a><span class="sd"> instance. Implementations may run FreeCAD in-process (embedded),</span>
</span><span id="__span-0-232"><a id="__codelineno-0-232" name="__codelineno-0-232"></a><span class="sd"> communicate via XML-RPC, or use JSON-RPC over sockets.</span>
</span><span id="__span-0-233"><a id="__codelineno-0-233" name="__codelineno-0-233"></a>
</span><span id="__span-0-234"><a id="__codelineno-0-234" name="__codelineno-0-234"></a><span class="sd"> Thread Safety:</span>
</span><span id="__span-0-235"><a id="__codelineno-0-235" name="__codelineno-0-235"></a><span class="sd"> GUI operations must be executed on the main thread. Implementations</span>
</span><span id="__span-0-236"><a id="__codelineno-0-236" name="__codelineno-0-236"></a><span class="sd"> should use queue-based communication for thread safety (learned from</span>
</span><span id="__span-0-237"><a id="__codelineno-0-237" name="__codelineno-0-237"></a><span class="sd"> neka-nat implementation).</span>
</span><span id="__span-0-238"><a id="__codelineno-0-238" name="__codelineno-0-238"></a><span class="sd"> """</span>
</span><span id="__span-0-239"><a id="__codelineno-0-239" name="__codelineno-0-239"></a>
</span><span id="__span-0-240"><a id="__codelineno-0-240" name="__codelineno-0-240"></a> <span class="nd">@abstractmethod</span>
</span><span id="__span-0-241"><a id="__codelineno-0-241" name="__codelineno-0-241"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">connect</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kc">None</span><span class="p">:</span>
</span><span id="__span-0-242"><a id="__codelineno-0-242" name="__codelineno-0-242"></a><span class="w"> </span><span class="sd">"""Establish connection to FreeCAD.</span>
</span><span id="__span-0-243"><a id="__codelineno-0-243" name="__codelineno-0-243"></a>
</span><span id="__span-0-244"><a id="__codelineno-0-244" name="__codelineno-0-244"></a><span class="sd"> Raises:</span>
</span><span id="__span-0-245"><a id="__codelineno-0-245" name="__codelineno-0-245"></a><span class="sd"> ConnectionError: If connection cannot be established.</span>
</span><span id="__span-0-246"><a id="__codelineno-0-246" name="__codelineno-0-246"></a><span class="sd"> """</span>
</span><span id="__span-0-247"><a id="__codelineno-0-247" name="__codelineno-0-247"></a>
</span><span id="__span-0-248"><a id="__codelineno-0-248" name="__codelineno-0-248"></a> <span class="nd">@abstractmethod</span>
</span><span id="__span-0-249"><a id="__codelineno-0-249" name="__codelineno-0-249"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">disconnect</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kc">None</span><span class="p">:</span>
</span><span id="__span-0-250"><a id="__codelineno-0-250" name="__codelineno-0-250"></a><span class="w"> </span><span class="sd">"""Close connection to FreeCAD.</span>
</span><span id="__span-0-251"><a id="__codelineno-0-251" name="__codelineno-0-251"></a>
</span><span id="__span-0-252"><a id="__codelineno-0-252" name="__codelineno-0-252"></a><span class="sd"> Should be called during cleanup to release resources.</span>
</span><span id="__span-0-253"><a id="__codelineno-0-253" name="__codelineno-0-253"></a><span class="sd"> """</span>
</span><span id="__span-0-254"><a id="__codelineno-0-254" name="__codelineno-0-254"></a>
</span><span id="__span-0-255"><a id="__codelineno-0-255" name="__codelineno-0-255"></a> <span class="nd">@abstractmethod</span>
</span><span id="__span-0-256"><a id="__codelineno-0-256" name="__codelineno-0-256"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">is_connected</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">bool</span><span class="p">:</span>
</span><span id="__span-0-257"><a id="__codelineno-0-257" name="__codelineno-0-257"></a><span class="w"> </span><span class="sd">"""Check if bridge is connected to FreeCAD.</span>
</span><span id="__span-0-258"><a id="__codelineno-0-258" name="__codelineno-0-258"></a>
</span><span id="__span-0-259"><a id="__codelineno-0-259" name="__codelineno-0-259"></a><span class="sd"> Returns:</span>
</span><span id="__span-0-260"><a id="__codelineno-0-260" name="__codelineno-0-260"></a><span class="sd"> True if connected, False otherwise.</span>
</span><span id="__span-0-261"><a id="__codelineno-0-261" name="__codelineno-0-261"></a><span class="sd"> """</span>
</span><span id="__span-0-262"><a id="__codelineno-0-262" name="__codelineno-0-262"></a>
</span><span id="__span-0-263"><a id="__codelineno-0-263" name="__codelineno-0-263"></a> <span class="nd">@abstractmethod</span>
</span><span id="__span-0-264"><a id="__codelineno-0-264" name="__codelineno-0-264"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">ping</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">float</span><span class="p">:</span>
</span><span id="__span-0-265"><a id="__codelineno-0-265" name="__codelineno-0-265"></a><span class="w"> </span><span class="sd">"""Ping FreeCAD to check connection and measure latency.</span>
</span><span id="__span-0-266"><a id="__codelineno-0-266" name="__codelineno-0-266"></a>
</span><span id="__span-0-267"><a id="__codelineno-0-267" name="__codelineno-0-267"></a><span class="sd"> Returns:</span>
</span><span id="__span-0-268"><a id="__codelineno-0-268" name="__codelineno-0-268"></a><span class="sd"> Round-trip time in milliseconds.</span>
</span><span id="__span-0-269"><a id="__codelineno-0-269" name="__codelineno-0-269"></a>
</span><span id="__span-0-270"><a id="__codelineno-0-270" name="__codelineno-0-270"></a><span class="sd"> Raises:</span>
</span><span id="__span-0-271"><a id="__codelineno-0-271" name="__codelineno-0-271"></a><span class="sd"> ConnectionError: If not connected.</span>
</span><span id="__span-0-272"><a id="__codelineno-0-272" name="__codelineno-0-272"></a><span class="sd"> """</span>
</span><span id="__span-0-273"><a id="__codelineno-0-273" name="__codelineno-0-273"></a>
</span><span id="__span-0-274"><a id="__codelineno-0-274" name="__codelineno-0-274"></a> <span class="nd">@abstractmethod</span>
</span><span id="__span-0-275"><a id="__codelineno-0-275" name="__codelineno-0-275"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">get_status</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">ConnectionStatus</span><span class="p">:</span>
</span><span id="__span-0-276"><a id="__codelineno-0-276" name="__codelineno-0-276"></a><span class="w"> </span><span class="sd">"""Get detailed connection status.</span>
</span><span id="__span-0-277"><a id="__codelineno-0-277" name="__codelineno-0-277"></a>
</span><span id="__span-0-278"><a id="__codelineno-0-278" name="__codelineno-0-278"></a><span class="sd"> Returns:</span>
</span><span id="__span-0-279"><a id="__codelineno-0-279" name="__codelineno-0-279"></a><span class="sd"> ConnectionStatus with full status information.</span>
</span><span id="__span-0-280"><a id="__codelineno-0-280" name="__codelineno-0-280"></a><span class="sd"> """</span>
</span><span id="__span-0-281"><a id="__codelineno-0-281" name="__codelineno-0-281"></a>
</span><span id="__span-0-282"><a id="__codelineno-0-282" name="__codelineno-0-282"></a> <span class="c1"># =========================================================================</span>
</span><span id="__span-0-283"><a id="__codelineno-0-283" name="__codelineno-0-283"></a> <span class="c1"># Code Execution</span>
</span><span id="__span-0-284"><a id="__codelineno-0-284" name="__codelineno-0-284"></a> <span class="c1"># =========================================================================</span>
</span><span id="__span-0-285"><a id="__codelineno-0-285" name="__codelineno-0-285"></a>
</span><span id="__span-0-286"><a id="__codelineno-0-286" name="__codelineno-0-286"></a> <span class="nd">@abstractmethod</span>
</span><span id="__span-0-287"><a id="__codelineno-0-287" name="__codelineno-0-287"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">execute_python</span><span class="p">(</span>
</span><span id="__span-0-288"><a id="__codelineno-0-288" name="__codelineno-0-288"></a> <span class="bp">self</span><span class="p">,</span>
</span><span id="__span-0-289"><a id="__codelineno-0-289" name="__codelineno-0-289"></a> <span class="n">code</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span>
</span><span id="__span-0-290"><a id="__codelineno-0-290" name="__codelineno-0-290"></a> <span class="n">timeout_ms</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">30000</span><span class="p">,</span>
</span><span id="__span-0-291"><a id="__codelineno-0-291" name="__codelineno-0-291"></a> <span class="p">)</span> <span class="o">-&gt;</span> <span class="n">ExecutionResult</span><span class="p">:</span>
</span><span id="__span-0-292"><a id="__codelineno-0-292" name="__codelineno-0-292"></a><span class="w"> </span><span class="sd">"""Execute Python code in FreeCAD context.</span>
</span><span id="__span-0-293"><a id="__codelineno-0-293" name="__codelineno-0-293"></a>
</span><span id="__span-0-294"><a id="__codelineno-0-294" name="__codelineno-0-294"></a><span class="sd"> The code runs with access to FreeCAD modules (FreeCAD, App, Gui).</span>
</span><span id="__span-0-295"><a id="__codelineno-0-295" name="__codelineno-0-295"></a><span class="sd"> To return a value, assign it to the `_result_` variable.</span>
</span><span id="__span-0-296"><a id="__codelineno-0-296" name="__codelineno-0-296"></a>
</span><span id="__span-0-297"><a id="__codelineno-0-297" name="__codelineno-0-297"></a><span class="sd"> Args:</span>
</span><span id="__span-0-298"><a id="__codelineno-0-298" name="__codelineno-0-298"></a><span class="sd"> code: Python code to execute.</span>
</span><span id="__span-0-299"><a id="__codelineno-0-299" name="__codelineno-0-299"></a><span class="sd"> timeout_ms: Maximum execution time in milliseconds.</span>
</span><span id="__span-0-300"><a id="__codelineno-0-300" name="__codelineno-0-300"></a>
</span><span id="__span-0-301"><a id="__codelineno-0-301" name="__codelineno-0-301"></a><span class="sd"> Returns:</span>
</span><span id="__span-0-302"><a id="__codelineno-0-302" name="__codelineno-0-302"></a><span class="sd"> ExecutionResult with success status, output, and any errors.</span>
</span><span id="__span-0-303"><a id="__codelineno-0-303" name="__codelineno-0-303"></a><span class="sd"> """</span>
</span><span id="__span-0-304"><a id="__codelineno-0-304" name="__codelineno-0-304"></a>
</span><span id="__span-0-305"><a id="__codelineno-0-305" name="__codelineno-0-305"></a> <span class="c1"># =========================================================================</span>
</span><span id="__span-0-306"><a id="__codelineno-0-306" name="__codelineno-0-306"></a> <span class="c1"># Document Management</span>
</span><span id="__span-0-307"><a id="__codelineno-0-307" name="__codelineno-0-307"></a> <span class="c1"># =========================================================================</span>
</span><span id="__span-0-308"><a id="__codelineno-0-308" name="__codelineno-0-308"></a>
</span><span id="__span-0-309"><a id="__codelineno-0-309" name="__codelineno-0-309"></a> <span class="nd">@abstractmethod</span>
</span><span id="__span-0-310"><a id="__codelineno-0-310" name="__codelineno-0-310"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">get_documents</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">list</span><span class="p">[</span><span class="n">DocumentInfo</span><span class="p">]:</span>
</span><span id="__span-0-311"><a id="__codelineno-0-311" name="__codelineno-0-311"></a><span class="w"> </span><span class="sd">"""Get list of open documents.</span>
</span><span id="__span-0-312"><a id="__codelineno-0-312" name="__codelineno-0-312"></a>
</span><span id="__span-0-313"><a id="__codelineno-0-313" name="__codelineno-0-313"></a><span class="sd"> Returns:</span>
</span><span id="__span-0-314"><a id="__codelineno-0-314" name="__codelineno-0-314"></a><span class="sd"> List of DocumentInfo for each open document.</span>
</span><span id="__span-0-315"><a id="__codelineno-0-315" name="__codelineno-0-315"></a><span class="sd"> """</span>
</span><span id="__span-0-316"><a id="__codelineno-0-316" name="__codelineno-0-316"></a>
</span><span id="__span-0-317"><a id="__codelineno-0-317" name="__codelineno-0-317"></a> <span class="nd">@abstractmethod</span>
</span><span id="__span-0-318"><a id="__codelineno-0-318" name="__codelineno-0-318"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">get_active_document</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">DocumentInfo</span> <span class="o">|</span> <span class="kc">None</span><span class="p">:</span>
</span><span id="__span-0-319"><a id="__codelineno-0-319" name="__codelineno-0-319"></a><span class="w"> </span><span class="sd">"""Get the active document.</span>
</span><span id="__span-0-320"><a id="__codelineno-0-320" name="__codelineno-0-320"></a>
</span><span id="__span-0-321"><a id="__codelineno-0-321" name="__codelineno-0-321"></a><span class="sd"> Returns:</span>
</span><span id="__span-0-322"><a id="__codelineno-0-322" name="__codelineno-0-322"></a><span class="sd"> DocumentInfo for active document, or None if no document is active.</span>
</span><span id="__span-0-323"><a id="__codelineno-0-323" name="__codelineno-0-323"></a><span class="sd"> """</span>
</span><span id="__span-0-324"><a id="__codelineno-0-324" name="__codelineno-0-324"></a>
</span><span id="__span-0-325"><a id="__codelineno-0-325" name="__codelineno-0-325"></a> <span class="nd">@abstractmethod</span>
</span><span id="__span-0-326"><a id="__codelineno-0-326" name="__codelineno-0-326"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">create_document</span><span class="p">(</span>
</span><span id="__span-0-327"><a id="__codelineno-0-327" name="__codelineno-0-327"></a> <span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">label</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span>
</span><span id="__span-0-328"><a id="__codelineno-0-328" name="__codelineno-0-328"></a> <span class="p">)</span> <span class="o">-&gt;</span> <span class="n">DocumentInfo</span><span class="p">:</span>
</span><span id="__span-0-329"><a id="__codelineno-0-329" name="__codelineno-0-329"></a><span class="w"> </span><span class="sd">"""Create a new document.</span>
</span><span id="__span-0-330"><a id="__codelineno-0-330" name="__codelineno-0-330"></a>
</span><span id="__span-0-331"><a id="__codelineno-0-331" name="__codelineno-0-331"></a><span class="sd"> Args:</span>
</span><span id="__span-0-332"><a id="__codelineno-0-332" name="__codelineno-0-332"></a><span class="sd"> name: Internal document name (no spaces).</span>
</span><span id="__span-0-333"><a id="__codelineno-0-333" name="__codelineno-0-333"></a><span class="sd"> label: Display label (optional, defaults to name).</span>
</span><span id="__span-0-334"><a id="__codelineno-0-334" name="__codelineno-0-334"></a>
</span><span id="__span-0-335"><a id="__codelineno-0-335" name="__codelineno-0-335"></a><span class="sd"> Returns:</span>
</span><span id="__span-0-336"><a id="__codelineno-0-336" name="__codelineno-0-336"></a><span class="sd"> DocumentInfo for the created document.</span>
</span><span id="__span-0-337"><a id="__codelineno-0-337" name="__codelineno-0-337"></a><span class="sd"> """</span>
</span><span id="__span-0-338"><a id="__codelineno-0-338" name="__codelineno-0-338"></a>
</span><span id="__span-0-339"><a id="__codelineno-0-339" name="__codelineno-0-339"></a> <span class="nd">@abstractmethod</span>
</span><span id="__span-0-340"><a id="__codelineno-0-340" name="__codelineno-0-340"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">open_document</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">path</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">DocumentInfo</span><span class="p">:</span>
</span><span id="__span-0-341"><a id="__codelineno-0-341" name="__codelineno-0-341"></a><span class="w"> </span><span class="sd">"""Open an existing document.</span>
</span><span id="__span-0-342"><a id="__codelineno-0-342" name="__codelineno-0-342"></a>
</span><span id="__span-0-343"><a id="__codelineno-0-343" name="__codelineno-0-343"></a><span class="sd"> Args:</span>
</span><span id="__span-0-344"><a id="__codelineno-0-344" name="__codelineno-0-344"></a><span class="sd"> path: Path to the .FCStd file.</span>
</span><span id="__span-0-345"><a id="__codelineno-0-345" name="__codelineno-0-345"></a>
</span><span id="__span-0-346"><a id="__codelineno-0-346" name="__codelineno-0-346"></a><span class="sd"> Returns:</span>
</span><span id="__span-0-347"><a id="__codelineno-0-347" name="__codelineno-0-347"></a><span class="sd"> DocumentInfo for the opened document.</span>
</span><span id="__span-0-348"><a id="__codelineno-0-348" name="__codelineno-0-348"></a>
</span><span id="__span-0-349"><a id="__codelineno-0-349" name="__codelineno-0-349"></a><span class="sd"> Raises:</span>
</span><span id="__span-0-350"><a id="__codelineno-0-350" name="__codelineno-0-350"></a><span class="sd"> FileNotFoundError: If file doesn't exist.</span>
</span><span id="__span-0-351"><a id="__codelineno-0-351" name="__codelineno-0-351"></a><span class="sd"> ValueError: If file is not a valid FreeCAD document.</span>
</span><span id="__span-0-352"><a id="__codelineno-0-352" name="__codelineno-0-352"></a><span class="sd"> """</span>
</span><span id="__span-0-353"><a id="__codelineno-0-353" name="__codelineno-0-353"></a>
</span><span id="__span-0-354"><a id="__codelineno-0-354" name="__codelineno-0-354"></a> <span class="nd">@abstractmethod</span>
</span><span id="__span-0-355"><a id="__codelineno-0-355" name="__codelineno-0-355"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">save_document</span><span class="p">(</span>
</span><span id="__span-0-356"><a id="__codelineno-0-356" name="__codelineno-0-356"></a> <span class="bp">self</span><span class="p">,</span>
</span><span id="__span-0-357"><a id="__codelineno-0-357" name="__codelineno-0-357"></a> <span class="n">doc_name</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-358"><a id="__codelineno-0-358" name="__codelineno-0-358"></a> <span class="n">path</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-359"><a id="__codelineno-0-359" name="__codelineno-0-359"></a> <span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">str</span><span class="p">:</span>
</span><span id="__span-0-360"><a id="__codelineno-0-360" name="__codelineno-0-360"></a><span class="w"> </span><span class="sd">"""Save a document.</span>
</span><span id="__span-0-361"><a id="__codelineno-0-361" name="__codelineno-0-361"></a>
</span><span id="__span-0-362"><a id="__codelineno-0-362" name="__codelineno-0-362"></a><span class="sd"> Args:</span>
</span><span id="__span-0-363"><a id="__codelineno-0-363" name="__codelineno-0-363"></a><span class="sd"> doc_name: Document name (uses active if None).</span>
</span><span id="__span-0-364"><a id="__codelineno-0-364" name="__codelineno-0-364"></a><span class="sd"> path: Save path (uses existing path if None).</span>
</span><span id="__span-0-365"><a id="__codelineno-0-365" name="__codelineno-0-365"></a>
</span><span id="__span-0-366"><a id="__codelineno-0-366" name="__codelineno-0-366"></a><span class="sd"> Returns:</span>
</span><span id="__span-0-367"><a id="__codelineno-0-367" name="__codelineno-0-367"></a><span class="sd"> Path where document was saved.</span>
</span><span id="__span-0-368"><a id="__codelineno-0-368" name="__codelineno-0-368"></a>
</span><span id="__span-0-369"><a id="__codelineno-0-369" name="__codelineno-0-369"></a><span class="sd"> Raises:</span>
</span><span id="__span-0-370"><a id="__codelineno-0-370" name="__codelineno-0-370"></a><span class="sd"> ValueError: If document not found or no path specified for new doc.</span>
</span><span id="__span-0-371"><a id="__codelineno-0-371" name="__codelineno-0-371"></a><span class="sd"> """</span>
</span><span id="__span-0-372"><a id="__codelineno-0-372" name="__codelineno-0-372"></a>
</span><span id="__span-0-373"><a id="__codelineno-0-373" name="__codelineno-0-373"></a> <span class="nd">@abstractmethod</span>
</span><span id="__span-0-374"><a id="__codelineno-0-374" name="__codelineno-0-374"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">close_document</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">doc_name</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kc">None</span><span class="p">:</span>
</span><span id="__span-0-375"><a id="__codelineno-0-375" name="__codelineno-0-375"></a><span class="w"> </span><span class="sd">"""Close a document.</span>
</span><span id="__span-0-376"><a id="__codelineno-0-376" name="__codelineno-0-376"></a>
</span><span id="__span-0-377"><a id="__codelineno-0-377" name="__codelineno-0-377"></a><span class="sd"> Args:</span>
</span><span id="__span-0-378"><a id="__codelineno-0-378" name="__codelineno-0-378"></a><span class="sd"> doc_name: Document name (uses active if None).</span>
</span><span id="__span-0-379"><a id="__codelineno-0-379" name="__codelineno-0-379"></a><span class="sd"> """</span>
</span><span id="__span-0-380"><a id="__codelineno-0-380" name="__codelineno-0-380"></a>
</span><span id="__span-0-381"><a id="__codelineno-0-381" name="__codelineno-0-381"></a> <span class="c1"># =========================================================================</span>
</span><span id="__span-0-382"><a id="__codelineno-0-382" name="__codelineno-0-382"></a> <span class="c1"># Object Management</span>
</span><span id="__span-0-383"><a id="__codelineno-0-383" name="__codelineno-0-383"></a> <span class="c1"># =========================================================================</span>
</span><span id="__span-0-384"><a id="__codelineno-0-384" name="__codelineno-0-384"></a>
</span><span id="__span-0-385"><a id="__codelineno-0-385" name="__codelineno-0-385"></a> <span class="nd">@abstractmethod</span>
</span><span id="__span-0-386"><a id="__codelineno-0-386" name="__codelineno-0-386"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">get_objects</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">doc_name</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">list</span><span class="p">[</span><span class="n">ObjectInfo</span><span class="p">]:</span>
</span><span id="__span-0-387"><a id="__codelineno-0-387" name="__codelineno-0-387"></a><span class="w"> </span><span class="sd">"""Get all objects in a document.</span>
</span><span id="__span-0-388"><a id="__codelineno-0-388" name="__codelineno-0-388"></a>
</span><span id="__span-0-389"><a id="__codelineno-0-389" name="__codelineno-0-389"></a><span class="sd"> Args:</span>
</span><span id="__span-0-390"><a id="__codelineno-0-390" name="__codelineno-0-390"></a><span class="sd"> doc_name: Document name (uses active if None).</span>
</span><span id="__span-0-391"><a id="__codelineno-0-391" name="__codelineno-0-391"></a>
</span><span id="__span-0-392"><a id="__codelineno-0-392" name="__codelineno-0-392"></a><span class="sd"> Returns:</span>
</span><span id="__span-0-393"><a id="__codelineno-0-393" name="__codelineno-0-393"></a><span class="sd"> List of ObjectInfo for each object.</span>
</span><span id="__span-0-394"><a id="__codelineno-0-394" name="__codelineno-0-394"></a><span class="sd"> """</span>
</span><span id="__span-0-395"><a id="__codelineno-0-395" name="__codelineno-0-395"></a>
</span><span id="__span-0-396"><a id="__codelineno-0-396" name="__codelineno-0-396"></a> <span class="nd">@abstractmethod</span>
</span><span id="__span-0-397"><a id="__codelineno-0-397" name="__codelineno-0-397"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">get_object</span><span class="p">(</span>
</span><span id="__span-0-398"><a id="__codelineno-0-398" name="__codelineno-0-398"></a> <span class="bp">self</span><span class="p">,</span>
</span><span id="__span-0-399"><a id="__codelineno-0-399" name="__codelineno-0-399"></a> <span class="n">obj_name</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span>
</span><span id="__span-0-400"><a id="__codelineno-0-400" name="__codelineno-0-400"></a> <span class="n">doc_name</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-401"><a id="__codelineno-0-401" name="__codelineno-0-401"></a> <span class="p">)</span> <span class="o">-&gt;</span> <span class="n">ObjectInfo</span><span class="p">:</span>
</span><span id="__span-0-402"><a id="__codelineno-0-402" name="__codelineno-0-402"></a><span class="w"> </span><span class="sd">"""Get detailed object information.</span>
</span><span id="__span-0-403"><a id="__codelineno-0-403" name="__codelineno-0-403"></a>
</span><span id="__span-0-404"><a id="__codelineno-0-404" name="__codelineno-0-404"></a><span class="sd"> Args:</span>
</span><span id="__span-0-405"><a id="__codelineno-0-405" name="__codelineno-0-405"></a><span class="sd"> obj_name: Name of the object.</span>
</span><span id="__span-0-406"><a id="__codelineno-0-406" name="__codelineno-0-406"></a><span class="sd"> doc_name: Document name (uses active if None).</span>
</span><span id="__span-0-407"><a id="__codelineno-0-407" name="__codelineno-0-407"></a>
</span><span id="__span-0-408"><a id="__codelineno-0-408" name="__codelineno-0-408"></a><span class="sd"> Returns:</span>
</span><span id="__span-0-409"><a id="__codelineno-0-409" name="__codelineno-0-409"></a><span class="sd"> ObjectInfo with full object details.</span>
</span><span id="__span-0-410"><a id="__codelineno-0-410" name="__codelineno-0-410"></a>
</span><span id="__span-0-411"><a id="__codelineno-0-411" name="__codelineno-0-411"></a><span class="sd"> Raises:</span>
</span><span id="__span-0-412"><a id="__codelineno-0-412" name="__codelineno-0-412"></a><span class="sd"> ValueError: If object not found.</span>
</span><span id="__span-0-413"><a id="__codelineno-0-413" name="__codelineno-0-413"></a><span class="sd"> """</span>
</span><span id="__span-0-414"><a id="__codelineno-0-414" name="__codelineno-0-414"></a>
</span><span id="__span-0-415"><a id="__codelineno-0-415" name="__codelineno-0-415"></a> <span class="nd">@abstractmethod</span>
</span><span id="__span-0-416"><a id="__codelineno-0-416" name="__codelineno-0-416"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">create_object</span><span class="p">(</span>
</span><span id="__span-0-417"><a id="__codelineno-0-417" name="__codelineno-0-417"></a> <span class="bp">self</span><span class="p">,</span>
</span><span id="__span-0-418"><a id="__codelineno-0-418" name="__codelineno-0-418"></a> <span class="n">type_id</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span>
</span><span id="__span-0-419"><a id="__codelineno-0-419" name="__codelineno-0-419"></a> <span class="n">name</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-420"><a id="__codelineno-0-420" name="__codelineno-0-420"></a> <span class="n">properties</span><span class="p">:</span> <span class="nb">dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Any</span><span class="p">]</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-421"><a id="__codelineno-0-421" name="__codelineno-0-421"></a> <span class="n">doc_name</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-422"><a id="__codelineno-0-422" name="__codelineno-0-422"></a> <span class="p">)</span> <span class="o">-&gt;</span> <span class="n">ObjectInfo</span><span class="p">:</span>
</span><span id="__span-0-423"><a id="__codelineno-0-423" name="__codelineno-0-423"></a><span class="w"> </span><span class="sd">"""Create a new object.</span>
</span><span id="__span-0-424"><a id="__codelineno-0-424" name="__codelineno-0-424"></a>
</span><span id="__span-0-425"><a id="__codelineno-0-425" name="__codelineno-0-425"></a><span class="sd"> Args:</span>
</span><span id="__span-0-426"><a id="__codelineno-0-426" name="__codelineno-0-426"></a><span class="sd"> type_id: FreeCAD type ID (e.g., "Part::Box", "Part::Cylinder").</span>
</span><span id="__span-0-427"><a id="__codelineno-0-427" name="__codelineno-0-427"></a><span class="sd"> name: Object name (auto-generated if None).</span>
</span><span id="__span-0-428"><a id="__codelineno-0-428" name="__codelineno-0-428"></a><span class="sd"> properties: Initial property values.</span>
</span><span id="__span-0-429"><a id="__codelineno-0-429" name="__codelineno-0-429"></a><span class="sd"> doc_name: Target document (uses active if None).</span>
</span><span id="__span-0-430"><a id="__codelineno-0-430" name="__codelineno-0-430"></a>
</span><span id="__span-0-431"><a id="__codelineno-0-431" name="__codelineno-0-431"></a><span class="sd"> Returns:</span>
</span><span id="__span-0-432"><a id="__codelineno-0-432" name="__codelineno-0-432"></a><span class="sd"> ObjectInfo for the created object.</span>
</span><span id="__span-0-433"><a id="__codelineno-0-433" name="__codelineno-0-433"></a><span class="sd"> """</span>
</span><span id="__span-0-434"><a id="__codelineno-0-434" name="__codelineno-0-434"></a>
</span><span id="__span-0-435"><a id="__codelineno-0-435" name="__codelineno-0-435"></a> <span class="nd">@abstractmethod</span>
</span><span id="__span-0-436"><a id="__codelineno-0-436" name="__codelineno-0-436"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">edit_object</span><span class="p">(</span>
</span><span id="__span-0-437"><a id="__codelineno-0-437" name="__codelineno-0-437"></a> <span class="bp">self</span><span class="p">,</span>
</span><span id="__span-0-438"><a id="__codelineno-0-438" name="__codelineno-0-438"></a> <span class="n">obj_name</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span>
</span><span id="__span-0-439"><a id="__codelineno-0-439" name="__codelineno-0-439"></a> <span class="n">properties</span><span class="p">:</span> <span class="nb">dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Any</span><span class="p">],</span>
</span><span id="__span-0-440"><a id="__codelineno-0-440" name="__codelineno-0-440"></a> <span class="n">doc_name</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-441"><a id="__codelineno-0-441" name="__codelineno-0-441"></a> <span class="p">)</span> <span class="o">-&gt;</span> <span class="n">ObjectInfo</span><span class="p">:</span>
</span><span id="__span-0-442"><a id="__codelineno-0-442" name="__codelineno-0-442"></a><span class="w"> </span><span class="sd">"""Edit object properties.</span>
</span><span id="__span-0-443"><a id="__codelineno-0-443" name="__codelineno-0-443"></a>
</span><span id="__span-0-444"><a id="__codelineno-0-444" name="__codelineno-0-444"></a><span class="sd"> Args:</span>
</span><span id="__span-0-445"><a id="__codelineno-0-445" name="__codelineno-0-445"></a><span class="sd"> obj_name: Name of the object to edit.</span>
</span><span id="__span-0-446"><a id="__codelineno-0-446" name="__codelineno-0-446"></a><span class="sd"> properties: Property values to set.</span>
</span><span id="__span-0-447"><a id="__codelineno-0-447" name="__codelineno-0-447"></a><span class="sd"> doc_name: Document name (uses active if None).</span>
</span><span id="__span-0-448"><a id="__codelineno-0-448" name="__codelineno-0-448"></a>
</span><span id="__span-0-449"><a id="__codelineno-0-449" name="__codelineno-0-449"></a><span class="sd"> Returns:</span>
</span><span id="__span-0-450"><a id="__codelineno-0-450" name="__codelineno-0-450"></a><span class="sd"> Updated ObjectInfo.</span>
</span><span id="__span-0-451"><a id="__codelineno-0-451" name="__codelineno-0-451"></a>
</span><span id="__span-0-452"><a id="__codelineno-0-452" name="__codelineno-0-452"></a><span class="sd"> Raises:</span>
</span><span id="__span-0-453"><a id="__codelineno-0-453" name="__codelineno-0-453"></a><span class="sd"> ValueError: If object not found.</span>
</span><span id="__span-0-454"><a id="__codelineno-0-454" name="__codelineno-0-454"></a><span class="sd"> """</span>
</span><span id="__span-0-455"><a id="__codelineno-0-455" name="__codelineno-0-455"></a>
</span><span id="__span-0-456"><a id="__codelineno-0-456" name="__codelineno-0-456"></a> <span class="nd">@abstractmethod</span>
</span><span id="__span-0-457"><a id="__codelineno-0-457" name="__codelineno-0-457"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">delete_object</span><span class="p">(</span>
</span><span id="__span-0-458"><a id="__codelineno-0-458" name="__codelineno-0-458"></a> <span class="bp">self</span><span class="p">,</span>
</span><span id="__span-0-459"><a id="__codelineno-0-459" name="__codelineno-0-459"></a> <span class="n">obj_name</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span>
</span><span id="__span-0-460"><a id="__codelineno-0-460" name="__codelineno-0-460"></a> <span class="n">doc_name</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-461"><a id="__codelineno-0-461" name="__codelineno-0-461"></a> <span class="p">)</span> <span class="o">-&gt;</span> <span class="kc">None</span><span class="p">:</span>
</span><span id="__span-0-462"><a id="__codelineno-0-462" name="__codelineno-0-462"></a><span class="w"> </span><span class="sd">"""Delete an object.</span>
</span><span id="__span-0-463"><a id="__codelineno-0-463" name="__codelineno-0-463"></a>
</span><span id="__span-0-464"><a id="__codelineno-0-464" name="__codelineno-0-464"></a><span class="sd"> Args:</span>
</span><span id="__span-0-465"><a id="__codelineno-0-465" name="__codelineno-0-465"></a><span class="sd"> obj_name: Name of the object to delete.</span>
</span><span id="__span-0-466"><a id="__codelineno-0-466" name="__codelineno-0-466"></a><span class="sd"> doc_name: Document name (uses active if None).</span>
</span><span id="__span-0-467"><a id="__codelineno-0-467" name="__codelineno-0-467"></a>
</span><span id="__span-0-468"><a id="__codelineno-0-468" name="__codelineno-0-468"></a><span class="sd"> Raises:</span>
</span><span id="__span-0-469"><a id="__codelineno-0-469" name="__codelineno-0-469"></a><span class="sd"> ValueError: If object not found.</span>
</span><span id="__span-0-470"><a id="__codelineno-0-470" name="__codelineno-0-470"></a><span class="sd"> """</span>
</span><span id="__span-0-471"><a id="__codelineno-0-471" name="__codelineno-0-471"></a>
</span><span id="__span-0-472"><a id="__codelineno-0-472" name="__codelineno-0-472"></a> <span class="c1"># =========================================================================</span>
</span><span id="__span-0-473"><a id="__codelineno-0-473" name="__codelineno-0-473"></a> <span class="c1"># View and Screenshot</span>
</span><span id="__span-0-474"><a id="__codelineno-0-474" name="__codelineno-0-474"></a> <span class="c1"># =========================================================================</span>
</span><span id="__span-0-475"><a id="__codelineno-0-475" name="__codelineno-0-475"></a>
</span><span id="__span-0-476"><a id="__codelineno-0-476" name="__codelineno-0-476"></a> <span class="nd">@abstractmethod</span>
</span><span id="__span-0-477"><a id="__codelineno-0-477" name="__codelineno-0-477"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">get_screenshot</span><span class="p">(</span>
</span><span id="__span-0-478"><a id="__codelineno-0-478" name="__codelineno-0-478"></a> <span class="bp">self</span><span class="p">,</span>
</span><span id="__span-0-479"><a id="__codelineno-0-479" name="__codelineno-0-479"></a> <span class="n">view_angle</span><span class="p">:</span> <span class="n">ViewAngle</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-480"><a id="__codelineno-0-480" name="__codelineno-0-480"></a> <span class="n">width</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">800</span><span class="p">,</span>
</span><span id="__span-0-481"><a id="__codelineno-0-481" name="__codelineno-0-481"></a> <span class="n">height</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">600</span><span class="p">,</span>
</span><span id="__span-0-482"><a id="__codelineno-0-482" name="__codelineno-0-482"></a> <span class="n">doc_name</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-483"><a id="__codelineno-0-483" name="__codelineno-0-483"></a> <span class="p">)</span> <span class="o">-&gt;</span> <span class="n">ScreenshotResult</span><span class="p">:</span>
</span><span id="__span-0-484"><a id="__codelineno-0-484" name="__codelineno-0-484"></a><span class="w"> </span><span class="sd">"""Capture a screenshot of the 3D view.</span>
</span><span id="__span-0-485"><a id="__codelineno-0-485" name="__codelineno-0-485"></a>
</span><span id="__span-0-486"><a id="__codelineno-0-486" name="__codelineno-0-486"></a><span class="sd"> Args:</span>
</span><span id="__span-0-487"><a id="__codelineno-0-487" name="__codelineno-0-487"></a><span class="sd"> view_angle: View angle to set before capture.</span>
</span><span id="__span-0-488"><a id="__codelineno-0-488" name="__codelineno-0-488"></a><span class="sd"> width: Image width in pixels.</span>
</span><span id="__span-0-489"><a id="__codelineno-0-489" name="__codelineno-0-489"></a><span class="sd"> height: Image height in pixels.</span>
</span><span id="__span-0-490"><a id="__codelineno-0-490" name="__codelineno-0-490"></a><span class="sd"> doc_name: Document name (uses active if None).</span>
</span><span id="__span-0-491"><a id="__codelineno-0-491" name="__codelineno-0-491"></a>
</span><span id="__span-0-492"><a id="__codelineno-0-492" name="__codelineno-0-492"></a><span class="sd"> Returns:</span>
</span><span id="__span-0-493"><a id="__codelineno-0-493" name="__codelineno-0-493"></a><span class="sd"> ScreenshotResult with image data or error.</span>
</span><span id="__span-0-494"><a id="__codelineno-0-494" name="__codelineno-0-494"></a><span class="sd"> """</span>
</span><span id="__span-0-495"><a id="__codelineno-0-495" name="__codelineno-0-495"></a>
</span><span id="__span-0-496"><a id="__codelineno-0-496" name="__codelineno-0-496"></a> <span class="nd">@abstractmethod</span>
</span><span id="__span-0-497"><a id="__codelineno-0-497" name="__codelineno-0-497"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">set_view</span><span class="p">(</span>
</span><span id="__span-0-498"><a id="__codelineno-0-498" name="__codelineno-0-498"></a> <span class="bp">self</span><span class="p">,</span>
</span><span id="__span-0-499"><a id="__codelineno-0-499" name="__codelineno-0-499"></a> <span class="n">view_angle</span><span class="p">:</span> <span class="n">ViewAngle</span><span class="p">,</span>
</span><span id="__span-0-500"><a id="__codelineno-0-500" name="__codelineno-0-500"></a> <span class="n">doc_name</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-501"><a id="__codelineno-0-501" name="__codelineno-0-501"></a> <span class="p">)</span> <span class="o">-&gt;</span> <span class="kc">None</span><span class="p">:</span>
</span><span id="__span-0-502"><a id="__codelineno-0-502" name="__codelineno-0-502"></a><span class="w"> </span><span class="sd">"""Set the 3D view angle.</span>
</span><span id="__span-0-503"><a id="__codelineno-0-503" name="__codelineno-0-503"></a>
</span><span id="__span-0-504"><a id="__codelineno-0-504" name="__codelineno-0-504"></a><span class="sd"> Args:</span>
</span><span id="__span-0-505"><a id="__codelineno-0-505" name="__codelineno-0-505"></a><span class="sd"> view_angle: View angle to set.</span>
</span><span id="__span-0-506"><a id="__codelineno-0-506" name="__codelineno-0-506"></a><span class="sd"> doc_name: Document name (uses active if None).</span>
</span><span id="__span-0-507"><a id="__codelineno-0-507" name="__codelineno-0-507"></a><span class="sd"> """</span>
</span><span id="__span-0-508"><a id="__codelineno-0-508" name="__codelineno-0-508"></a>
</span><span id="__span-0-509"><a id="__codelineno-0-509" name="__codelineno-0-509"></a> <span class="c1"># =========================================================================</span>
</span><span id="__span-0-510"><a id="__codelineno-0-510" name="__codelineno-0-510"></a> <span class="c1"># Macros</span>
</span><span id="__span-0-511"><a id="__codelineno-0-511" name="__codelineno-0-511"></a> <span class="c1"># =========================================================================</span>
</span><span id="__span-0-512"><a id="__codelineno-0-512" name="__codelineno-0-512"></a>
</span><span id="__span-0-513"><a id="__codelineno-0-513" name="__codelineno-0-513"></a> <span class="nd">@abstractmethod</span>
</span><span id="__span-0-514"><a id="__codelineno-0-514" name="__codelineno-0-514"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">get_macros</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">list</span><span class="p">[</span><span class="n">MacroInfo</span><span class="p">]:</span>
</span><span id="__span-0-515"><a id="__codelineno-0-515" name="__codelineno-0-515"></a><span class="w"> </span><span class="sd">"""Get list of available macros.</span>
</span><span id="__span-0-516"><a id="__codelineno-0-516" name="__codelineno-0-516"></a>
</span><span id="__span-0-517"><a id="__codelineno-0-517" name="__codelineno-0-517"></a><span class="sd"> Returns:</span>
</span><span id="__span-0-518"><a id="__codelineno-0-518" name="__codelineno-0-518"></a><span class="sd"> List of MacroInfo for each macro.</span>
</span><span id="__span-0-519"><a id="__codelineno-0-519" name="__codelineno-0-519"></a><span class="sd"> """</span>
</span><span id="__span-0-520"><a id="__codelineno-0-520" name="__codelineno-0-520"></a>
</span><span id="__span-0-521"><a id="__codelineno-0-521" name="__codelineno-0-521"></a> <span class="nd">@abstractmethod</span>
</span><span id="__span-0-522"><a id="__codelineno-0-522" name="__codelineno-0-522"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">run_macro</span><span class="p">(</span>
</span><span id="__span-0-523"><a id="__codelineno-0-523" name="__codelineno-0-523"></a> <span class="bp">self</span><span class="p">,</span>
</span><span id="__span-0-524"><a id="__codelineno-0-524" name="__codelineno-0-524"></a> <span class="n">macro_name</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span>
</span><span id="__span-0-525"><a id="__codelineno-0-525" name="__codelineno-0-525"></a> <span class="n">args</span><span class="p">:</span> <span class="nb">dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Any</span><span class="p">]</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-526"><a id="__codelineno-0-526" name="__codelineno-0-526"></a> <span class="p">)</span> <span class="o">-&gt;</span> <span class="n">ExecutionResult</span><span class="p">:</span>
</span><span id="__span-0-527"><a id="__codelineno-0-527" name="__codelineno-0-527"></a><span class="w"> </span><span class="sd">"""Run a macro by name.</span>
</span><span id="__span-0-528"><a id="__codelineno-0-528" name="__codelineno-0-528"></a>
</span><span id="__span-0-529"><a id="__codelineno-0-529" name="__codelineno-0-529"></a><span class="sd"> Args:</span>
</span><span id="__span-0-530"><a id="__codelineno-0-530" name="__codelineno-0-530"></a><span class="sd"> macro_name: Macro name (without .FCMacro extension).</span>
</span><span id="__span-0-531"><a id="__codelineno-0-531" name="__codelineno-0-531"></a><span class="sd"> args: Arguments to pass to the macro.</span>
</span><span id="__span-0-532"><a id="__codelineno-0-532" name="__codelineno-0-532"></a>
</span><span id="__span-0-533"><a id="__codelineno-0-533" name="__codelineno-0-533"></a><span class="sd"> Returns:</span>
</span><span id="__span-0-534"><a id="__codelineno-0-534" name="__codelineno-0-534"></a><span class="sd"> ExecutionResult from macro execution.</span>
</span><span id="__span-0-535"><a id="__codelineno-0-535" name="__codelineno-0-535"></a><span class="sd"> """</span>
</span><span id="__span-0-536"><a id="__codelineno-0-536" name="__codelineno-0-536"></a>
</span><span id="__span-0-537"><a id="__codelineno-0-537" name="__codelineno-0-537"></a> <span class="nd">@abstractmethod</span>
</span><span id="__span-0-538"><a id="__codelineno-0-538" name="__codelineno-0-538"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">create_macro</span><span class="p">(</span>
</span><span id="__span-0-539"><a id="__codelineno-0-539" name="__codelineno-0-539"></a> <span class="bp">self</span><span class="p">,</span>
</span><span id="__span-0-540"><a id="__codelineno-0-540" name="__codelineno-0-540"></a> <span class="n">name</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span>
</span><span id="__span-0-541"><a id="__codelineno-0-541" name="__codelineno-0-541"></a> <span class="n">code</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span>
</span><span id="__span-0-542"><a id="__codelineno-0-542" name="__codelineno-0-542"></a> <span class="n">description</span><span class="p">:</span> <span class="nb">str</span> <span class="o">=</span> <span class="s2">""</span><span class="p">,</span>
</span><span id="__span-0-543"><a id="__codelineno-0-543" name="__codelineno-0-543"></a> <span class="p">)</span> <span class="o">-&gt;</span> <span class="n">MacroInfo</span><span class="p">:</span>
</span><span id="__span-0-544"><a id="__codelineno-0-544" name="__codelineno-0-544"></a><span class="w"> </span><span class="sd">"""Create a new macro.</span>
</span><span id="__span-0-545"><a id="__codelineno-0-545" name="__codelineno-0-545"></a>
</span><span id="__span-0-546"><a id="__codelineno-0-546" name="__codelineno-0-546"></a><span class="sd"> Args:</span>
</span><span id="__span-0-547"><a id="__codelineno-0-547" name="__codelineno-0-547"></a><span class="sd"> name: Macro name (without extension).</span>
</span><span id="__span-0-548"><a id="__codelineno-0-548" name="__codelineno-0-548"></a><span class="sd"> code: Python code for the macro.</span>
</span><span id="__span-0-549"><a id="__codelineno-0-549" name="__codelineno-0-549"></a><span class="sd"> description: Macro description.</span>
</span><span id="__span-0-550"><a id="__codelineno-0-550" name="__codelineno-0-550"></a>
</span><span id="__span-0-551"><a id="__codelineno-0-551" name="__codelineno-0-551"></a><span class="sd"> Returns:</span>
</span><span id="__span-0-552"><a id="__codelineno-0-552" name="__codelineno-0-552"></a><span class="sd"> MacroInfo for the created macro.</span>
</span><span id="__span-0-553"><a id="__codelineno-0-553" name="__codelineno-0-553"></a><span class="sd"> """</span>
</span><span id="__span-0-554"><a id="__codelineno-0-554" name="__codelineno-0-554"></a>
</span><span id="__span-0-555"><a id="__codelineno-0-555" name="__codelineno-0-555"></a> <span class="c1"># =========================================================================</span>
</span><span id="__span-0-556"><a id="__codelineno-0-556" name="__codelineno-0-556"></a> <span class="c1"># Workbenches</span>
</span><span id="__span-0-557"><a id="__codelineno-0-557" name="__codelineno-0-557"></a> <span class="c1"># =========================================================================</span>
</span><span id="__span-0-558"><a id="__codelineno-0-558" name="__codelineno-0-558"></a>
</span><span id="__span-0-559"><a id="__codelineno-0-559" name="__codelineno-0-559"></a> <span class="nd">@abstractmethod</span>
</span><span id="__span-0-560"><a id="__codelineno-0-560" name="__codelineno-0-560"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">get_workbenches</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">list</span><span class="p">[</span><span class="n">WorkbenchInfo</span><span class="p">]:</span>
</span><span id="__span-0-561"><a id="__codelineno-0-561" name="__codelineno-0-561"></a><span class="w"> </span><span class="sd">"""Get list of available workbenches.</span>
</span><span id="__span-0-562"><a id="__codelineno-0-562" name="__codelineno-0-562"></a>
</span><span id="__span-0-563"><a id="__codelineno-0-563" name="__codelineno-0-563"></a><span class="sd"> Returns:</span>
</span><span id="__span-0-564"><a id="__codelineno-0-564" name="__codelineno-0-564"></a><span class="sd"> List of WorkbenchInfo for each workbench.</span>
</span><span id="__span-0-565"><a id="__codelineno-0-565" name="__codelineno-0-565"></a><span class="sd"> """</span>
</span><span id="__span-0-566"><a id="__codelineno-0-566" name="__codelineno-0-566"></a>
</span><span id="__span-0-567"><a id="__codelineno-0-567" name="__codelineno-0-567"></a> <span class="nd">@abstractmethod</span>
</span><span id="__span-0-568"><a id="__codelineno-0-568" name="__codelineno-0-568"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">activate_workbench</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">workbench_name</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kc">None</span><span class="p">:</span>
</span><span id="__span-0-569"><a id="__codelineno-0-569" name="__codelineno-0-569"></a><span class="w"> </span><span class="sd">"""Activate a workbench.</span>
</span><span id="__span-0-570"><a id="__codelineno-0-570" name="__codelineno-0-570"></a>
</span><span id="__span-0-571"><a id="__codelineno-0-571" name="__codelineno-0-571"></a><span class="sd"> Args:</span>
</span><span id="__span-0-572"><a id="__codelineno-0-572" name="__codelineno-0-572"></a><span class="sd"> workbench_name: Workbench internal name.</span>
</span><span id="__span-0-573"><a id="__codelineno-0-573" name="__codelineno-0-573"></a>
</span><span id="__span-0-574"><a id="__codelineno-0-574" name="__codelineno-0-574"></a><span class="sd"> Raises:</span>
</span><span id="__span-0-575"><a id="__codelineno-0-575" name="__codelineno-0-575"></a><span class="sd"> ValueError: If workbench not found.</span>
</span><span id="__span-0-576"><a id="__codelineno-0-576" name="__codelineno-0-576"></a><span class="sd"> """</span>
</span><span id="__span-0-577"><a id="__codelineno-0-577" name="__codelineno-0-577"></a>
</span><span id="__span-0-578"><a id="__codelineno-0-578" name="__codelineno-0-578"></a> <span class="c1"># =========================================================================</span>
</span><span id="__span-0-579"><a id="__codelineno-0-579" name="__codelineno-0-579"></a> <span class="c1"># Version and Environment</span>
</span><span id="__span-0-580"><a id="__codelineno-0-580" name="__codelineno-0-580"></a> <span class="c1"># =========================================================================</span>
</span><span id="__span-0-581"><a id="__codelineno-0-581" name="__codelineno-0-581"></a>
</span><span id="__span-0-582"><a id="__codelineno-0-582" name="__codelineno-0-582"></a> <span class="nd">@abstractmethod</span>
</span><span id="__span-0-583"><a id="__codelineno-0-583" name="__codelineno-0-583"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">get_freecad_version</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Any</span><span class="p">]:</span>
</span><span id="__span-0-584"><a id="__codelineno-0-584" name="__codelineno-0-584"></a><span class="w"> </span><span class="sd">"""Get FreeCAD version information.</span>
</span><span id="__span-0-585"><a id="__codelineno-0-585" name="__codelineno-0-585"></a>
</span><span id="__span-0-586"><a id="__codelineno-0-586" name="__codelineno-0-586"></a><span class="sd"> Returns:</span>
</span><span id="__span-0-587"><a id="__codelineno-0-587" name="__codelineno-0-587"></a><span class="sd"> Dictionary with version, build_date, python_version, gui_available.</span>
</span><span id="__span-0-588"><a id="__codelineno-0-588" name="__codelineno-0-588"></a><span class="sd"> """</span>
</span><span id="__span-0-589"><a id="__codelineno-0-589" name="__codelineno-0-589"></a>
</span><span id="__span-0-590"><a id="__codelineno-0-590" name="__codelineno-0-590"></a> <span class="nd">@abstractmethod</span>
</span><span id="__span-0-591"><a id="__codelineno-0-591" name="__codelineno-0-591"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">is_gui_available</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">bool</span><span class="p">:</span>
</span><span id="__span-0-592"><a id="__codelineno-0-592" name="__codelineno-0-592"></a><span class="w"> </span><span class="sd">"""Check if FreeCAD GUI is available.</span>
</span><span id="__span-0-593"><a id="__codelineno-0-593" name="__codelineno-0-593"></a>
</span><span id="__span-0-594"><a id="__codelineno-0-594" name="__codelineno-0-594"></a><span class="sd"> Returns:</span>
</span><span id="__span-0-595"><a id="__codelineno-0-595" name="__codelineno-0-595"></a><span class="sd"> True if GUI is available, False for headless mode.</span>
</span><span id="__span-0-596"><a id="__codelineno-0-596" name="__codelineno-0-596"></a><span class="sd"> """</span>
</span><span id="__span-0-597"><a id="__codelineno-0-597" name="__codelineno-0-597"></a>
</span><span id="__span-0-598"><a id="__codelineno-0-598" name="__codelineno-0-598"></a> <span class="c1"># =========================================================================</span>
</span><span id="__span-0-599"><a id="__codelineno-0-599" name="__codelineno-0-599"></a> <span class="c1"># Console</span>
</span><span id="__span-0-600"><a id="__codelineno-0-600" name="__codelineno-0-600"></a> <span class="c1"># =========================================================================</span>
</span><span id="__span-0-601"><a id="__codelineno-0-601" name="__codelineno-0-601"></a>
</span><span id="__span-0-602"><a id="__codelineno-0-602" name="__codelineno-0-602"></a> <span class="nd">@abstractmethod</span>
</span><span id="__span-0-603"><a id="__codelineno-0-603" name="__codelineno-0-603"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">get_console_output</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">lines</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">100</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">list</span><span class="p">[</span><span class="nb">str</span><span class="p">]:</span>
</span><span id="__span-0-604"><a id="__codelineno-0-604" name="__codelineno-0-604"></a><span class="w"> </span><span class="sd">"""Get recent console output.</span>
</span><span id="__span-0-605"><a id="__codelineno-0-605" name="__codelineno-0-605"></a>
</span><span id="__span-0-606"><a id="__codelineno-0-606" name="__codelineno-0-606"></a><span class="sd"> Args:</span>
</span><span id="__span-0-607"><a id="__codelineno-0-607" name="__codelineno-0-607"></a><span class="sd"> lines: Maximum number of lines to return.</span>
</span><span id="__span-0-608"><a id="__codelineno-0-608" name="__codelineno-0-608"></a>
</span><span id="__span-0-609"><a id="__codelineno-0-609" name="__codelineno-0-609"></a><span class="sd"> Returns:</span>
</span><span id="__span-0-610"><a id="__codelineno-0-610" name="__codelineno-0-610"></a><span class="sd"> List of console output lines, most recent last.</span>
</span><span id="__span-0-611"><a id="__codelineno-0-611" name="__codelineno-0-611"></a><span class="sd"> """</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> <div class="doc doc-children"> <h5 id="freecad_mcp.bridge.base.FreecadBridge-functions">Functions<a href="#freecad_mcp.bridge.base.FreecadBridge-functions" class="headerlink" title="Permanent link">¶</a></h5> <div class="doc doc-object doc-function"> <h6 id="freecad_mcp.bridge.base.FreecadBridge.activate_workbench" class="doc doc-heading"> <code class="highlight language-python"><span class="n">activate_workbench</span><span class="p">(</span><span class="n">workbench_name</span><span class="p">)</span></code> <span class="doc doc-labels"> <small class="doc doc-label doc-label-abstractmethod"><code>abstractmethod</code></small> <small class="doc doc-label doc-label-async"><code>async</code></small> </span> <a href="#freecad_mcp.bridge.base.FreecadBridge.activate_workbench" class="headerlink" title="Permanent link">¶</a></h6> <div class="doc doc-contents "> <p>Activate a workbench.</p> <p><span class="doc-section-title">Parameters:</span></p> <table> <thead> <tr> <th>Name</th> <th>Type</th> <th>Description</th> <th>Default</th> </tr> </thead> <tbody> <tr class="doc-section-item"> <td> <code>workbench_name</code> </td> <td> <code><span title="str">str</span></code> </td> <td> <div class="doc-md-description"> <p>Workbench internal name.</p> </div> </td> <td> <em>required</em> </td> </tr> </tbody> </table> <p><span class="doc-section-title">Raises:</span></p> <table> <thead> <tr> <th>Type</th> <th>Description</th> </tr> </thead> <tbody> <tr class="doc-section-item"> <td> <code><span title="ValueError">ValueError</span></code> </td> <td> <div class="doc-md-description"> <p>If workbench not found.</p> </div> </td> </tr> </tbody> </table> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/base.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-567">567</a></span>
<span class="normal"><a href="#__codelineno-0-568">568</a></span>
<span class="normal"><a href="#__codelineno-0-569">569</a></span>
<span class="normal"><a href="#__codelineno-0-570">570</a></span>
<span class="normal"><a href="#__codelineno-0-571">571</a></span>
<span class="normal"><a href="#__codelineno-0-572">572</a></span>
<span class="normal"><a href="#__codelineno-0-573">573</a></span>
<span class="normal"><a href="#__codelineno-0-574">574</a></span>
<span class="normal"><a href="#__codelineno-0-575">575</a></span>
<span class="normal"><a href="#__codelineno-0-576">576</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-567"><a id="__codelineno-0-567" name="__codelineno-0-567"></a><span class="nd">@abstractmethod</span>
</span><span id="__span-0-568"><a id="__codelineno-0-568" name="__codelineno-0-568"></a><span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">activate_workbench</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">workbench_name</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kc">None</span><span class="p">:</span>
</span><span id="__span-0-569"><a id="__codelineno-0-569" name="__codelineno-0-569"></a><span class="w"> </span><span class="sd">"""Activate a workbench.</span>
</span><span id="__span-0-570"><a id="__codelineno-0-570" name="__codelineno-0-570"></a>
</span><span id="__span-0-571"><a id="__codelineno-0-571" name="__codelineno-0-571"></a><span class="sd"> Args:</span>
</span><span id="__span-0-572"><a id="__codelineno-0-572" name="__codelineno-0-572"></a><span class="sd"> workbench_name: Workbench internal name.</span>
</span><span id="__span-0-573"><a id="__codelineno-0-573" name="__codelineno-0-573"></a>
</span><span id="__span-0-574"><a id="__codelineno-0-574" name="__codelineno-0-574"></a><span class="sd"> Raises:</span>
</span><span id="__span-0-575"><a id="__codelineno-0-575" name="__codelineno-0-575"></a><span class="sd"> ValueError: If workbench not found.</span>
</span><span id="__span-0-576"><a id="__codelineno-0-576" name="__codelineno-0-576"></a><span class="sd"> """</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> </div> </div> <div class="doc doc-object doc-function"> <h6 id="freecad_mcp.bridge.base.FreecadBridge.close_document" class="doc doc-heading"> <code class="highlight language-python"><span class="n">close_document</span><span class="p">(</span><span class="n">doc_name</span><span class="o">=</span><span class="kc">None</span><span class="p">)</span></code> <span class="doc doc-labels"> <small class="doc doc-label doc-label-abstractmethod"><code>abstractmethod</code></small> <small class="doc doc-label doc-label-async"><code>async</code></small> </span> <a href="#freecad_mcp.bridge.base.FreecadBridge.close_document" class="headerlink" title="Permanent link">¶</a></h6> <div class="doc doc-contents "> <p>Close a document.</p> <p><span class="doc-section-title">Parameters:</span></p> <table> <thead> <tr> <th>Name</th> <th>Type</th> <th>Description</th> <th>Default</th> </tr> </thead> <tbody> <tr class="doc-section-item"> <td> <code>doc_name</code> </td> <td> <code><span title="str">str</span> | None</code> </td> <td> <div class="doc-md-description"> <p>Document name (uses active if None).</p> </div> </td> <td> <code>None</code> </td> </tr> </tbody> </table> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/base.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-373">373</a></span>
<span class="normal"><a href="#__codelineno-0-374">374</a></span>
<span class="normal"><a href="#__codelineno-0-375">375</a></span>
<span class="normal"><a href="#__codelineno-0-376">376</a></span>
<span class="normal"><a href="#__codelineno-0-377">377</a></span>
<span class="normal"><a href="#__codelineno-0-378">378</a></span>
<span class="normal"><a href="#__codelineno-0-379">379</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-373"><a id="__codelineno-0-373" name="__codelineno-0-373"></a><span class="nd">@abstractmethod</span>
</span><span id="__span-0-374"><a id="__codelineno-0-374" name="__codelineno-0-374"></a><span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">close_document</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">doc_name</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kc">None</span><span class="p">:</span>
</span><span id="__span-0-375"><a id="__codelineno-0-375" name="__codelineno-0-375"></a><span class="w"> </span><span class="sd">"""Close a document.</span>
</span><span id="__span-0-376"><a id="__codelineno-0-376" name="__codelineno-0-376"></a>
</span><span id="__span-0-377"><a id="__codelineno-0-377" name="__codelineno-0-377"></a><span class="sd"> Args:</span>
</span><span id="__span-0-378"><a id="__codelineno-0-378" name="__codelineno-0-378"></a><span class="sd"> doc_name: Document name (uses active if None).</span>
</span><span id="__span-0-379"><a id="__codelineno-0-379" name="__codelineno-0-379"></a><span class="sd"> """</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> </div> </div> <div class="doc doc-object doc-function"> <h6 id="freecad_mcp.bridge.base.FreecadBridge.connect" class="doc doc-heading"> <code class="highlight language-python"><span class="n">connect</span><span class="p">()</span></code> <span class="doc doc-labels"> <small class="doc doc-label doc-label-abstractmethod"><code>abstractmethod</code></small> <small class="doc doc-label doc-label-async"><code>async</code></small> </span> <a href="#freecad_mcp.bridge.base.FreecadBridge.connect" class="headerlink" title="Permanent link">¶</a></h6> <div class="doc doc-contents "> <p>Establish connection to FreeCAD.</p> <p><span class="doc-section-title">Raises:</span></p> <table> <thead> <tr> <th>Type</th> <th>Description</th> </tr> </thead> <tbody> <tr class="doc-section-item"> <td> <code><span title="ConnectionError">ConnectionError</span></code> </td> <td> <div class="doc-md-description"> <p>If connection cannot be established.</p> </div> </td> </tr> </tbody> </table> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/base.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-240">240</a></span>
<span class="normal"><a href="#__codelineno-0-241">241</a></span>
<span class="normal"><a href="#__codelineno-0-242">242</a></span>
<span class="normal"><a href="#__codelineno-0-243">243</a></span>
<span class="normal"><a href="#__codelineno-0-244">244</a></span>
<span class="normal"><a href="#__codelineno-0-245">245</a></span>
<span class="normal"><a href="#__codelineno-0-246">246</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-240"><a id="__codelineno-0-240" name="__codelineno-0-240"></a><span class="nd">@abstractmethod</span>
</span><span id="__span-0-241"><a id="__codelineno-0-241" name="__codelineno-0-241"></a><span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">connect</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kc">None</span><span class="p">:</span>
</span><span id="__span-0-242"><a id="__codelineno-0-242" name="__codelineno-0-242"></a><span class="w"> </span><span class="sd">"""Establish connection to FreeCAD.</span>
</span><span id="__span-0-243"><a id="__codelineno-0-243" name="__codelineno-0-243"></a>
</span><span id="__span-0-244"><a id="__codelineno-0-244" name="__codelineno-0-244"></a><span class="sd"> Raises:</span>
</span><span id="__span-0-245"><a id="__codelineno-0-245" name="__codelineno-0-245"></a><span class="sd"> ConnectionError: If connection cannot be established.</span>
</span><span id="__span-0-246"><a id="__codelineno-0-246" name="__codelineno-0-246"></a><span class="sd"> """</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> </div> </div> <div class="doc doc-object doc-function"> <h6 id="freecad_mcp.bridge.base.FreecadBridge.create_document" class="doc doc-heading"> <code class="highlight language-python"><span class="n">create_document</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">label</span><span class="o">=</span><span class="kc">None</span><span class="p">)</span></code> <span class="doc doc-labels"> <small class="doc doc-label doc-label-abstractmethod"><code>abstractmethod</code></small> <small class="doc doc-label doc-label-async"><code>async</code></small> </span> <a href="#freecad_mcp.bridge.base.FreecadBridge.create_document" class="headerlink" title="Permanent link">¶</a></h6> <div class="doc doc-contents "> <p>Create a new document.</p> <p><span class="doc-section-title">Parameters:</span></p> <table> <thead> <tr> <th>Name</th> <th>Type</th> <th>Description</th> <th>Default</th> </tr> </thead> <tbody> <tr class="doc-section-item"> <td> <code>name</code> </td> <td> <code><span title="str">str</span></code> </td> <td> <div class="doc-md-description"> <p>Internal document name (no spaces).</p> </div> </td> <td> <em>required</em> </td> </tr> <tr class="doc-section-item"> <td> <code>label</code> </td> <td> <code><span title="str">str</span> | None</code> </td> <td> <div class="doc-md-description"> <p>Display label (optional, defaults to name).</p> </div> </td> <td> <code>None</code> </td> </tr> </tbody> </table> <p><span class="doc-section-title">Returns:</span></p> <table> <thead> <tr> <th>Type</th> <th>Description</th> </tr> </thead> <tbody> <tr class="doc-section-item"> <td> <code><a class="autorefs autorefs-internal" title="DocumentInfo
dataclass
(freecad_mcp.bridge.base.DocumentInfo)" href="#freecad_mcp.bridge.base.DocumentInfo">DocumentInfo</a></code> </td> <td> <div class="doc-md-description"> <p>DocumentInfo for the created document.</p> </div> </td> </tr> </tbody> </table> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/base.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-325">325</a></span>
<span class="normal"><a href="#__codelineno-0-326">326</a></span>
<span class="normal"><a href="#__codelineno-0-327">327</a></span>
<span class="normal"><a href="#__codelineno-0-328">328</a></span>
<span class="normal"><a href="#__codelineno-0-329">329</a></span>
<span class="normal"><a href="#__codelineno-0-330">330</a></span>
<span class="normal"><a href="#__codelineno-0-331">331</a></span>
<span class="normal"><a href="#__codelineno-0-332">332</a></span>
<span class="normal"><a href="#__codelineno-0-333">333</a></span>
<span class="normal"><a href="#__codelineno-0-334">334</a></span>
<span class="normal"><a href="#__codelineno-0-335">335</a></span>
<span class="normal"><a href="#__codelineno-0-336">336</a></span>
<span class="normal"><a href="#__codelineno-0-337">337</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-325"><a id="__codelineno-0-325" name="__codelineno-0-325"></a><span class="nd">@abstractmethod</span>
</span><span id="__span-0-326"><a id="__codelineno-0-326" name="__codelineno-0-326"></a><span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">create_document</span><span class="p">(</span>
</span><span id="__span-0-327"><a id="__codelineno-0-327" name="__codelineno-0-327"></a> <span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">label</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span>
</span><span id="__span-0-328"><a id="__codelineno-0-328" name="__codelineno-0-328"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">DocumentInfo</span><span class="p">:</span>
</span><span id="__span-0-329"><a id="__codelineno-0-329" name="__codelineno-0-329"></a><span class="w"> </span><span class="sd">"""Create a new document.</span>
</span><span id="__span-0-330"><a id="__codelineno-0-330" name="__codelineno-0-330"></a>
</span><span id="__span-0-331"><a id="__codelineno-0-331" name="__codelineno-0-331"></a><span class="sd"> Args:</span>
</span><span id="__span-0-332"><a id="__codelineno-0-332" name="__codelineno-0-332"></a><span class="sd"> name: Internal document name (no spaces).</span>
</span><span id="__span-0-333"><a id="__codelineno-0-333" name="__codelineno-0-333"></a><span class="sd"> label: Display label (optional, defaults to name).</span>
</span><span id="__span-0-334"><a id="__codelineno-0-334" name="__codelineno-0-334"></a>
</span><span id="__span-0-335"><a id="__codelineno-0-335" name="__codelineno-0-335"></a><span class="sd"> Returns:</span>
</span><span id="__span-0-336"><a id="__codelineno-0-336" name="__codelineno-0-336"></a><span class="sd"> DocumentInfo for the created document.</span>
</span><span id="__span-0-337"><a id="__codelineno-0-337" name="__codelineno-0-337"></a><span class="sd"> """</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> </div> </div> <div class="doc doc-object doc-function"> <h6 id="freecad_mcp.bridge.base.FreecadBridge.create_macro" class="doc doc-heading"> <code class="highlight language-python"><span class="n">create_macro</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">code</span><span class="p">,</span> <span class="n">description</span><span class="o">=</span><span class="s1">''</span><span class="p">)</span></code> <span class="doc doc-labels"> <small class="doc doc-label doc-label-abstractmethod"><code>abstractmethod</code></small> <small class="doc doc-label doc-label-async"><code>async</code></small> </span> <a href="#freecad_mcp.bridge.base.FreecadBridge.create_macro" class="headerlink" title="Permanent link">¶</a></h6> <div class="doc doc-contents "> <p>Create a new macro.</p> <p><span class="doc-section-title">Parameters:</span></p> <table> <thead> <tr> <th>Name</th> <th>Type</th> <th>Description</th> <th>Default</th> </tr> </thead> <tbody> <tr class="doc-section-item"> <td> <code>name</code> </td> <td> <code><span title="str">str</span></code> </td> <td> <div class="doc-md-description"> <p>Macro name (without extension).</p> </div> </td> <td> <em>required</em> </td> </tr> <tr class="doc-section-item"> <td> <code>code</code> </td> <td> <code><span title="str">str</span></code> </td> <td> <div class="doc-md-description"> <p>Python code for the macro.</p> </div> </td> <td> <em>required</em> </td> </tr> <tr class="doc-section-item"> <td> <code>description</code> </td> <td> <code><span title="str">str</span></code> </td> <td> <div class="doc-md-description"> <p>Macro description.</p> </div> </td> <td> <code>''</code> </td> </tr> </tbody> </table> <p><span class="doc-section-title">Returns:</span></p> <table> <thead> <tr> <th>Type</th> <th>Description</th> </tr> </thead> <tbody> <tr class="doc-section-item"> <td> <code><a class="autorefs autorefs-internal" title="MacroInfo
dataclass
(freecad_mcp.bridge.base.MacroInfo)" href="#freecad_mcp.bridge.base.MacroInfo">MacroInfo</a></code> </td> <td> <div class="doc-md-description"> <p>MacroInfo for the created macro.</p> </div> </td> </tr> </tbody> </table> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/base.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-537">537</a></span>
<span class="normal"><a href="#__codelineno-0-538">538</a></span>
<span class="normal"><a href="#__codelineno-0-539">539</a></span>
<span class="normal"><a href="#__codelineno-0-540">540</a></span>
<span class="normal"><a href="#__codelineno-0-541">541</a></span>
<span class="normal"><a href="#__codelineno-0-542">542</a></span>
<span class="normal"><a href="#__codelineno-0-543">543</a></span>
<span class="normal"><a href="#__codelineno-0-544">544</a></span>
<span class="normal"><a href="#__codelineno-0-545">545</a></span>
<span class="normal"><a href="#__codelineno-0-546">546</a></span>
<span class="normal"><a href="#__codelineno-0-547">547</a></span>
<span class="normal"><a href="#__codelineno-0-548">548</a></span>
<span class="normal"><a href="#__codelineno-0-549">549</a></span>
<span class="normal"><a href="#__codelineno-0-550">550</a></span>
<span class="normal"><a href="#__codelineno-0-551">551</a></span>
<span class="normal"><a href="#__codelineno-0-552">552</a></span>
<span class="normal"><a href="#__codelineno-0-553">553</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-537"><a id="__codelineno-0-537" name="__codelineno-0-537"></a><span class="nd">@abstractmethod</span>
</span><span id="__span-0-538"><a id="__codelineno-0-538" name="__codelineno-0-538"></a><span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">create_macro</span><span class="p">(</span>
</span><span id="__span-0-539"><a id="__codelineno-0-539" name="__codelineno-0-539"></a> <span class="bp">self</span><span class="p">,</span>
</span><span id="__span-0-540"><a id="__codelineno-0-540" name="__codelineno-0-540"></a> <span class="n">name</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span>
</span><span id="__span-0-541"><a id="__codelineno-0-541" name="__codelineno-0-541"></a> <span class="n">code</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span>
</span><span id="__span-0-542"><a id="__codelineno-0-542" name="__codelineno-0-542"></a> <span class="n">description</span><span class="p">:</span> <span class="nb">str</span> <span class="o">=</span> <span class="s2">""</span><span class="p">,</span>
</span><span id="__span-0-543"><a id="__codelineno-0-543" name="__codelineno-0-543"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">MacroInfo</span><span class="p">:</span>
</span><span id="__span-0-544"><a id="__codelineno-0-544" name="__codelineno-0-544"></a><span class="w"> </span><span class="sd">"""Create a new macro.</span>
</span><span id="__span-0-545"><a id="__codelineno-0-545" name="__codelineno-0-545"></a>
</span><span id="__span-0-546"><a id="__codelineno-0-546" name="__codelineno-0-546"></a><span class="sd"> Args:</span>
</span><span id="__span-0-547"><a id="__codelineno-0-547" name="__codelineno-0-547"></a><span class="sd"> name: Macro name (without extension).</span>
</span><span id="__span-0-548"><a id="__codelineno-0-548" name="__codelineno-0-548"></a><span class="sd"> code: Python code for the macro.</span>
</span><span id="__span-0-549"><a id="__codelineno-0-549" name="__codelineno-0-549"></a><span class="sd"> description: Macro description.</span>
</span><span id="__span-0-550"><a id="__codelineno-0-550" name="__codelineno-0-550"></a>
</span><span id="__span-0-551"><a id="__codelineno-0-551" name="__codelineno-0-551"></a><span class="sd"> Returns:</span>
</span><span id="__span-0-552"><a id="__codelineno-0-552" name="__codelineno-0-552"></a><span class="sd"> MacroInfo for the created macro.</span>
</span><span id="__span-0-553"><a id="__codelineno-0-553" name="__codelineno-0-553"></a><span class="sd"> """</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> </div> </div> <div class="doc doc-object doc-function"> <h6 id="freecad_mcp.bridge.base.FreecadBridge.create_object" class="doc doc-heading"> <code class="highlight language-python"><span class="n">create_object</span><span class="p">(</span><span class="n">type_id</span><span class="p">,</span> <span class="n">name</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">properties</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">doc_name</span><span class="o">=</span><span class="kc">None</span><span class="p">)</span></code> <span class="doc doc-labels"> <small class="doc doc-label doc-label-abstractmethod"><code>abstractmethod</code></small> <small class="doc doc-label doc-label-async"><code>async</code></small> </span> <a href="#freecad_mcp.bridge.base.FreecadBridge.create_object" class="headerlink" title="Permanent link">¶</a></h6> <div class="doc doc-contents "> <p>Create a new object.</p> <p><span class="doc-section-title">Parameters:</span></p> <table> <thead> <tr> <th>Name</th> <th>Type</th> <th>Description</th> <th>Default</th> </tr> </thead> <tbody> <tr class="doc-section-item"> <td> <code>type_id</code> </td> <td> <code><span title="str">str</span></code> </td> <td> <div class="doc-md-description"> <p>FreeCAD type ID (e.g., "Part::Box", "Part::Cylinder").</p> </div> </td> <td> <em>required</em> </td> </tr> <tr class="doc-section-item"> <td> <code>name</code> </td> <td> <code><span title="str">str</span> | None</code> </td> <td> <div class="doc-md-description"> <p>Object name (auto-generated if None).</p> </div> </td> <td> <code>None</code> </td> </tr> <tr class="doc-section-item"> <td> <code>properties</code> </td> <td> <code><span title="dict">dict</span>[<span title="str">str</span>, <span title="typing.Any">Any</span>] | None</code> </td> <td> <div class="doc-md-description"> <p>Initial property values.</p> </div> </td> <td> <code>None</code> </td> </tr> <tr class="doc-section-item"> <td> <code>doc_name</code> </td> <td> <code><span title="str">str</span> | None</code> </td> <td> <div class="doc-md-description"> <p>Target document (uses active if None).</p> </div> </td> <td> <code>None</code> </td> </tr> </tbody> </table> <p><span class="doc-section-title">Returns:</span></p> <table> <thead> <tr> <th>Type</th> <th>Description</th> </tr> </thead> <tbody> <tr class="doc-section-item"> <td> <code><a class="autorefs autorefs-internal" title="ObjectInfo
dataclass
(freecad_mcp.bridge.base.ObjectInfo)" href="#freecad_mcp.bridge.base.ObjectInfo">ObjectInfo</a></code> </td> <td> <div class="doc-md-description"> <p>ObjectInfo for the created object.</p> </div> </td> </tr> </tbody> </table> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/base.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-415">415</a></span>
<span class="normal"><a href="#__codelineno-0-416">416</a></span>
<span class="normal"><a href="#__codelineno-0-417">417</a></span>
<span class="normal"><a href="#__codelineno-0-418">418</a></span>
<span class="normal"><a href="#__codelineno-0-419">419</a></span>
<span class="normal"><a href="#__codelineno-0-420">420</a></span>
<span class="normal"><a href="#__codelineno-0-421">421</a></span>
<span class="normal"><a href="#__codelineno-0-422">422</a></span>
<span class="normal"><a href="#__codelineno-0-423">423</a></span>
<span class="normal"><a href="#__codelineno-0-424">424</a></span>
<span class="normal"><a href="#__codelineno-0-425">425</a></span>
<span class="normal"><a href="#__codelineno-0-426">426</a></span>
<span class="normal"><a href="#__codelineno-0-427">427</a></span>
<span class="normal"><a href="#__codelineno-0-428">428</a></span>
<span class="normal"><a href="#__codelineno-0-429">429</a></span>
<span class="normal"><a href="#__codelineno-0-430">430</a></span>
<span class="normal"><a href="#__codelineno-0-431">431</a></span>
<span class="normal"><a href="#__codelineno-0-432">432</a></span>
<span class="normal"><a href="#__codelineno-0-433">433</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-415"><a id="__codelineno-0-415" name="__codelineno-0-415"></a><span class="nd">@abstractmethod</span>
</span><span id="__span-0-416"><a id="__codelineno-0-416" name="__codelineno-0-416"></a><span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">create_object</span><span class="p">(</span>
</span><span id="__span-0-417"><a id="__codelineno-0-417" name="__codelineno-0-417"></a> <span class="bp">self</span><span class="p">,</span>
</span><span id="__span-0-418"><a id="__codelineno-0-418" name="__codelineno-0-418"></a> <span class="n">type_id</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span>
</span><span id="__span-0-419"><a id="__codelineno-0-419" name="__codelineno-0-419"></a> <span class="n">name</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-420"><a id="__codelineno-0-420" name="__codelineno-0-420"></a> <span class="n">properties</span><span class="p">:</span> <span class="nb">dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Any</span><span class="p">]</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-421"><a id="__codelineno-0-421" name="__codelineno-0-421"></a> <span class="n">doc_name</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-422"><a id="__codelineno-0-422" name="__codelineno-0-422"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">ObjectInfo</span><span class="p">:</span>
</span><span id="__span-0-423"><a id="__codelineno-0-423" name="__codelineno-0-423"></a><span class="w"> </span><span class="sd">"""Create a new object.</span>
</span><span id="__span-0-424"><a id="__codelineno-0-424" name="__codelineno-0-424"></a>
</span><span id="__span-0-425"><a id="__codelineno-0-425" name="__codelineno-0-425"></a><span class="sd"> Args:</span>
</span><span id="__span-0-426"><a id="__codelineno-0-426" name="__codelineno-0-426"></a><span class="sd"> type_id: FreeCAD type ID (e.g., "Part::Box", "Part::Cylinder").</span>
</span><span id="__span-0-427"><a id="__codelineno-0-427" name="__codelineno-0-427"></a><span class="sd"> name: Object name (auto-generated if None).</span>
</span><span id="__span-0-428"><a id="__codelineno-0-428" name="__codelineno-0-428"></a><span class="sd"> properties: Initial property values.</span>
</span><span id="__span-0-429"><a id="__codelineno-0-429" name="__codelineno-0-429"></a><span class="sd"> doc_name: Target document (uses active if None).</span>
</span><span id="__span-0-430"><a id="__codelineno-0-430" name="__codelineno-0-430"></a>
</span><span id="__span-0-431"><a id="__codelineno-0-431" name="__codelineno-0-431"></a><span class="sd"> Returns:</span>
</span><span id="__span-0-432"><a id="__codelineno-0-432" name="__codelineno-0-432"></a><span class="sd"> ObjectInfo for the created object.</span>
</span><span id="__span-0-433"><a id="__codelineno-0-433" name="__codelineno-0-433"></a><span class="sd"> """</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> </div> </div> <div class="doc doc-object doc-function"> <h6 id="freecad_mcp.bridge.base.FreecadBridge.delete_object" class="doc doc-heading"> <code class="highlight language-python"><span class="n">delete_object</span><span class="p">(</span><span class="n">obj_name</span><span class="p">,</span> <span class="n">doc_name</span><span class="o">=</span><span class="kc">None</span><span class="p">)</span></code> <span class="doc doc-labels"> <small class="doc doc-label doc-label-abstractmethod"><code>abstractmethod</code></small> <small class="doc doc-label doc-label-async"><code>async</code></small> </span> <a href="#freecad_mcp.bridge.base.FreecadBridge.delete_object" class="headerlink" title="Permanent link">¶</a></h6> <div class="doc doc-contents "> <p>Delete an object.</p> <p><span class="doc-section-title">Parameters:</span></p> <table> <thead> <tr> <th>Name</th> <th>Type</th> <th>Description</th> <th>Default</th> </tr> </thead> <tbody> <tr class="doc-section-item"> <td> <code>obj_name</code> </td> <td> <code><span title="str">str</span></code> </td> <td> <div class="doc-md-description"> <p>Name of the object to delete.</p> </div> </td> <td> <em>required</em> </td> </tr> <tr class="doc-section-item"> <td> <code>doc_name</code> </td> <td> <code><span title="str">str</span> | None</code> </td> <td> <div class="doc-md-description"> <p>Document name (uses active if None).</p> </div> </td> <td> <code>None</code> </td> </tr> </tbody> </table> <p><span class="doc-section-title">Raises:</span></p> <table> <thead> <tr> <th>Type</th> <th>Description</th> </tr> </thead> <tbody> <tr class="doc-section-item"> <td> <code><span title="ValueError">ValueError</span></code> </td> <td> <div class="doc-md-description"> <p>If object not found.</p> </div> </td> </tr> </tbody> </table> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/base.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-456">456</a></span>
<span class="normal"><a href="#__codelineno-0-457">457</a></span>
<span class="normal"><a href="#__codelineno-0-458">458</a></span>
<span class="normal"><a href="#__codelineno-0-459">459</a></span>
<span class="normal"><a href="#__codelineno-0-460">460</a></span>
<span class="normal"><a href="#__codelineno-0-461">461</a></span>
<span class="normal"><a href="#__codelineno-0-462">462</a></span>
<span class="normal"><a href="#__codelineno-0-463">463</a></span>
<span class="normal"><a href="#__codelineno-0-464">464</a></span>
<span class="normal"><a href="#__codelineno-0-465">465</a></span>
<span class="normal"><a href="#__codelineno-0-466">466</a></span>
<span class="normal"><a href="#__codelineno-0-467">467</a></span>
<span class="normal"><a href="#__codelineno-0-468">468</a></span>
<span class="normal"><a href="#__codelineno-0-469">469</a></span>
<span class="normal"><a href="#__codelineno-0-470">470</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-456"><a id="__codelineno-0-456" name="__codelineno-0-456"></a><span class="nd">@abstractmethod</span>
</span><span id="__span-0-457"><a id="__codelineno-0-457" name="__codelineno-0-457"></a><span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">delete_object</span><span class="p">(</span>
</span><span id="__span-0-458"><a id="__codelineno-0-458" name="__codelineno-0-458"></a> <span class="bp">self</span><span class="p">,</span>
</span><span id="__span-0-459"><a id="__codelineno-0-459" name="__codelineno-0-459"></a> <span class="n">obj_name</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span>
</span><span id="__span-0-460"><a id="__codelineno-0-460" name="__codelineno-0-460"></a> <span class="n">doc_name</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-461"><a id="__codelineno-0-461" name="__codelineno-0-461"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="kc">None</span><span class="p">:</span>
</span><span id="__span-0-462"><a id="__codelineno-0-462" name="__codelineno-0-462"></a><span class="w"> </span><span class="sd">"""Delete an object.</span>
</span><span id="__span-0-463"><a id="__codelineno-0-463" name="__codelineno-0-463"></a>
</span><span id="__span-0-464"><a id="__codelineno-0-464" name="__codelineno-0-464"></a><span class="sd"> Args:</span>
</span><span id="__span-0-465"><a id="__codelineno-0-465" name="__codelineno-0-465"></a><span class="sd"> obj_name: Name of the object to delete.</span>
</span><span id="__span-0-466"><a id="__codelineno-0-466" name="__codelineno-0-466"></a><span class="sd"> doc_name: Document name (uses active if None).</span>
</span><span id="__span-0-467"><a id="__codelineno-0-467" name="__codelineno-0-467"></a>
</span><span id="__span-0-468"><a id="__codelineno-0-468" name="__codelineno-0-468"></a><span class="sd"> Raises:</span>
</span><span id="__span-0-469"><a id="__codelineno-0-469" name="__codelineno-0-469"></a><span class="sd"> ValueError: If object not found.</span>
</span><span id="__span-0-470"><a id="__codelineno-0-470" name="__codelineno-0-470"></a><span class="sd"> """</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> </div> </div> <div class="doc doc-object doc-function"> <h6 id="freecad_mcp.bridge.base.FreecadBridge.disconnect" class="doc doc-heading"> <code class="highlight language-python"><span class="n">disconnect</span><span class="p">()</span></code> <span class="doc doc-labels"> <small class="doc doc-label doc-label-abstractmethod"><code>abstractmethod</code></small> <small class="doc doc-label doc-label-async"><code>async</code></small> </span> <a href="#freecad_mcp.bridge.base.FreecadBridge.disconnect" class="headerlink" title="Permanent link">¶</a></h6> <div class="doc doc-contents "> <p>Close connection to FreeCAD.</p> <p>Should be called during cleanup to release resources.</p> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/base.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-248">248</a></span>
<span class="normal"><a href="#__codelineno-0-249">249</a></span>
<span class="normal"><a href="#__codelineno-0-250">250</a></span>
<span class="normal"><a href="#__codelineno-0-251">251</a></span>
<span class="normal"><a href="#__codelineno-0-252">252</a></span>
<span class="normal"><a href="#__codelineno-0-253">253</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-248"><a id="__codelineno-0-248" name="__codelineno-0-248"></a><span class="nd">@abstractmethod</span>
</span><span id="__span-0-249"><a id="__codelineno-0-249" name="__codelineno-0-249"></a><span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">disconnect</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kc">None</span><span class="p">:</span>
</span><span id="__span-0-250"><a id="__codelineno-0-250" name="__codelineno-0-250"></a><span class="w"> </span><span class="sd">"""Close connection to FreeCAD.</span>
</span><span id="__span-0-251"><a id="__codelineno-0-251" name="__codelineno-0-251"></a>
</span><span id="__span-0-252"><a id="__codelineno-0-252" name="__codelineno-0-252"></a><span class="sd"> Should be called during cleanup to release resources.</span>
</span><span id="__span-0-253"><a id="__codelineno-0-253" name="__codelineno-0-253"></a><span class="sd"> """</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> </div> </div> <div class="doc doc-object doc-function"> <h6 id="freecad_mcp.bridge.base.FreecadBridge.edit_object" class="doc doc-heading"> <code class="highlight language-python"><span class="n">edit_object</span><span class="p">(</span><span class="n">obj_name</span><span class="p">,</span> <span class="n">properties</span><span class="p">,</span> <span class="n">doc_name</span><span class="o">=</span><span class="kc">None</span><span class="p">)</span></code> <span class="doc doc-labels"> <small class="doc doc-label doc-label-abstractmethod"><code>abstractmethod</code></small> <small class="doc doc-label doc-label-async"><code>async</code></small> </span> <a href="#freecad_mcp.bridge.base.FreecadBridge.edit_object" class="headerlink" title="Permanent link">¶</a></h6> <div class="doc doc-contents "> <p>Edit object properties.</p> <p><span class="doc-section-title">Parameters:</span></p> <table> <thead> <tr> <th>Name</th> <th>Type</th> <th>Description</th> <th>Default</th> </tr> </thead> <tbody> <tr class="doc-section-item"> <td> <code>obj_name</code> </td> <td> <code><span title="str">str</span></code> </td> <td> <div class="doc-md-description"> <p>Name of the object to edit.</p> </div> </td> <td> <em>required</em> </td> </tr> <tr class="doc-section-item"> <td> <code>properties</code> </td> <td> <code><span title="dict">dict</span>[<span title="str">str</span>, <span title="typing.Any">Any</span>]</code> </td> <td> <div class="doc-md-description"> <p>Property values to set.</p> </div> </td> <td> <em>required</em> </td> </tr> <tr class="doc-section-item"> <td> <code>doc_name</code> </td> <td> <code><span title="str">str</span> | None</code> </td> <td> <div class="doc-md-description"> <p>Document name (uses active if None).</p> </div> </td> <td> <code>None</code> </td> </tr> </tbody> </table> <p><span class="doc-section-title">Returns:</span></p> <table> <thead> <tr> <th>Type</th> <th>Description</th> </tr> </thead> <tbody> <tr class="doc-section-item"> <td> <code><a class="autorefs autorefs-internal" title="ObjectInfo
dataclass
(freecad_mcp.bridge.base.ObjectInfo)" href="#freecad_mcp.bridge.base.ObjectInfo">ObjectInfo</a></code> </td> <td> <div class="doc-md-description"> <p>Updated ObjectInfo.</p> </div> </td> </tr> </tbody> </table> <p><span class="doc-section-title">Raises:</span></p> <table> <thead> <tr> <th>Type</th> <th>Description</th> </tr> </thead> <tbody> <tr class="doc-section-item"> <td> <code><span title="ValueError">ValueError</span></code> </td> <td> <div class="doc-md-description"> <p>If object not found.</p> </div> </td> </tr> </tbody> </table> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/base.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-435">435</a></span>
<span class="normal"><a href="#__codelineno-0-436">436</a></span>
<span class="normal"><a href="#__codelineno-0-437">437</a></span>
<span class="normal"><a href="#__codelineno-0-438">438</a></span>
<span class="normal"><a href="#__codelineno-0-439">439</a></span>
<span class="normal"><a href="#__codelineno-0-440">440</a></span>
<span class="normal"><a href="#__codelineno-0-441">441</a></span>
<span class="normal"><a href="#__codelineno-0-442">442</a></span>
<span class="normal"><a href="#__codelineno-0-443">443</a></span>
<span class="normal"><a href="#__codelineno-0-444">444</a></span>
<span class="normal"><a href="#__codelineno-0-445">445</a></span>
<span class="normal"><a href="#__codelineno-0-446">446</a></span>
<span class="normal"><a href="#__codelineno-0-447">447</a></span>
<span class="normal"><a href="#__codelineno-0-448">448</a></span>
<span class="normal"><a href="#__codelineno-0-449">449</a></span>
<span class="normal"><a href="#__codelineno-0-450">450</a></span>
<span class="normal"><a href="#__codelineno-0-451">451</a></span>
<span class="normal"><a href="#__codelineno-0-452">452</a></span>
<span class="normal"><a href="#__codelineno-0-453">453</a></span>
<span class="normal"><a href="#__codelineno-0-454">454</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-435"><a id="__codelineno-0-435" name="__codelineno-0-435"></a><span class="nd">@abstractmethod</span>
</span><span id="__span-0-436"><a id="__codelineno-0-436" name="__codelineno-0-436"></a><span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">edit_object</span><span class="p">(</span>
</span><span id="__span-0-437"><a id="__codelineno-0-437" name="__codelineno-0-437"></a> <span class="bp">self</span><span class="p">,</span>
</span><span id="__span-0-438"><a id="__codelineno-0-438" name="__codelineno-0-438"></a> <span class="n">obj_name</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span>
</span><span id="__span-0-439"><a id="__codelineno-0-439" name="__codelineno-0-439"></a> <span class="n">properties</span><span class="p">:</span> <span class="nb">dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Any</span><span class="p">],</span>
</span><span id="__span-0-440"><a id="__codelineno-0-440" name="__codelineno-0-440"></a> <span class="n">doc_name</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-441"><a id="__codelineno-0-441" name="__codelineno-0-441"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">ObjectInfo</span><span class="p">:</span>
</span><span id="__span-0-442"><a id="__codelineno-0-442" name="__codelineno-0-442"></a><span class="w"> </span><span class="sd">"""Edit object properties.</span>
</span><span id="__span-0-443"><a id="__codelineno-0-443" name="__codelineno-0-443"></a>
</span><span id="__span-0-444"><a id="__codelineno-0-444" name="__codelineno-0-444"></a><span class="sd"> Args:</span>
</span><span id="__span-0-445"><a id="__codelineno-0-445" name="__codelineno-0-445"></a><span class="sd"> obj_name: Name of the object to edit.</span>
</span><span id="__span-0-446"><a id="__codelineno-0-446" name="__codelineno-0-446"></a><span class="sd"> properties: Property values to set.</span>
</span><span id="__span-0-447"><a id="__codelineno-0-447" name="__codelineno-0-447"></a><span class="sd"> doc_name: Document name (uses active if None).</span>
</span><span id="__span-0-448"><a id="__codelineno-0-448" name="__codelineno-0-448"></a>
</span><span id="__span-0-449"><a id="__codelineno-0-449" name="__codelineno-0-449"></a><span class="sd"> Returns:</span>
</span><span id="__span-0-450"><a id="__codelineno-0-450" name="__codelineno-0-450"></a><span class="sd"> Updated ObjectInfo.</span>
</span><span id="__span-0-451"><a id="__codelineno-0-451" name="__codelineno-0-451"></a>
</span><span id="__span-0-452"><a id="__codelineno-0-452" name="__codelineno-0-452"></a><span class="sd"> Raises:</span>
</span><span id="__span-0-453"><a id="__codelineno-0-453" name="__codelineno-0-453"></a><span class="sd"> ValueError: If object not found.</span>
</span><span id="__span-0-454"><a id="__codelineno-0-454" name="__codelineno-0-454"></a><span class="sd"> """</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> </div> </div> <div class="doc doc-object doc-function"> <h6 id="freecad_mcp.bridge.base.FreecadBridge.execute_python" class="doc doc-heading"> <code class="highlight language-python"><span class="n">execute_python</span><span class="p">(</span><span class="n">code</span><span class="p">,</span> <span class="n">timeout_ms</span><span class="o">=</span><span class="mi">30000</span><span class="p">)</span></code> <span class="doc doc-labels"> <small class="doc doc-label doc-label-abstractmethod"><code>abstractmethod</code></small> <small class="doc doc-label doc-label-async"><code>async</code></small> </span> <a href="#freecad_mcp.bridge.base.FreecadBridge.execute_python" class="headerlink" title="Permanent link">¶</a></h6> <div class="doc doc-contents "> <p>Execute Python code in FreeCAD context.</p> <p>The code runs with access to FreeCAD modules (FreeCAD, App, Gui). To return a value, assign it to the <code>_result_</code> variable.</p> <p><span class="doc-section-title">Parameters:</span></p> <table> <thead> <tr> <th>Name</th> <th>Type</th> <th>Description</th> <th>Default</th> </tr> </thead> <tbody> <tr class="doc-section-item"> <td> <code>code</code> </td> <td> <code><span title="str">str</span></code> </td> <td> <div class="doc-md-description"> <p>Python code to execute.</p> </div> </td> <td> <em>required</em> </td> </tr> <tr class="doc-section-item"> <td> <code>timeout_ms</code> </td> <td> <code><span title="int">int</span></code> </td> <td> <div class="doc-md-description"> <p>Maximum execution time in milliseconds.</p> </div> </td> <td> <code>30000</code> </td> </tr> </tbody> </table> <p><span class="doc-section-title">Returns:</span></p> <table> <thead> <tr> <th>Type</th> <th>Description</th> </tr> </thead> <tbody> <tr class="doc-section-item"> <td> <code><a class="autorefs autorefs-internal" title="ExecutionResult
dataclass
(freecad_mcp.bridge.base.ExecutionResult)" href="#freecad_mcp.bridge.base.ExecutionResult">ExecutionResult</a></code> </td> <td> <div class="doc-md-description"> <p>ExecutionResult with success status, output, and any errors.</p> </div> </td> </tr> </tbody> </table> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/base.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-286">286</a></span>
<span class="normal"><a href="#__codelineno-0-287">287</a></span>
<span class="normal"><a href="#__codelineno-0-288">288</a></span>
<span class="normal"><a href="#__codelineno-0-289">289</a></span>
<span class="normal"><a href="#__codelineno-0-290">290</a></span>
<span class="normal"><a href="#__codelineno-0-291">291</a></span>
<span class="normal"><a href="#__codelineno-0-292">292</a></span>
<span class="normal"><a href="#__codelineno-0-293">293</a></span>
<span class="normal"><a href="#__codelineno-0-294">294</a></span>
<span class="normal"><a href="#__codelineno-0-295">295</a></span>
<span class="normal"><a href="#__codelineno-0-296">296</a></span>
<span class="normal"><a href="#__codelineno-0-297">297</a></span>
<span class="normal"><a href="#__codelineno-0-298">298</a></span>
<span class="normal"><a href="#__codelineno-0-299">299</a></span>
<span class="normal"><a href="#__codelineno-0-300">300</a></span>
<span class="normal"><a href="#__codelineno-0-301">301</a></span>
<span class="normal"><a href="#__codelineno-0-302">302</a></span>
<span class="normal"><a href="#__codelineno-0-303">303</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-286"><a id="__codelineno-0-286" name="__codelineno-0-286"></a><span class="nd">@abstractmethod</span>
</span><span id="__span-0-287"><a id="__codelineno-0-287" name="__codelineno-0-287"></a><span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">execute_python</span><span class="p">(</span>
</span><span id="__span-0-288"><a id="__codelineno-0-288" name="__codelineno-0-288"></a> <span class="bp">self</span><span class="p">,</span>
</span><span id="__span-0-289"><a id="__codelineno-0-289" name="__codelineno-0-289"></a> <span class="n">code</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span>
</span><span id="__span-0-290"><a id="__codelineno-0-290" name="__codelineno-0-290"></a> <span class="n">timeout_ms</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">30000</span><span class="p">,</span>
</span><span id="__span-0-291"><a id="__codelineno-0-291" name="__codelineno-0-291"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">ExecutionResult</span><span class="p">:</span>
</span><span id="__span-0-292"><a id="__codelineno-0-292" name="__codelineno-0-292"></a><span class="w"> </span><span class="sd">"""Execute Python code in FreeCAD context.</span>
</span><span id="__span-0-293"><a id="__codelineno-0-293" name="__codelineno-0-293"></a>
</span><span id="__span-0-294"><a id="__codelineno-0-294" name="__codelineno-0-294"></a><span class="sd"> The code runs with access to FreeCAD modules (FreeCAD, App, Gui).</span>
</span><span id="__span-0-295"><a id="__codelineno-0-295" name="__codelineno-0-295"></a><span class="sd"> To return a value, assign it to the `_result_` variable.</span>
</span><span id="__span-0-296"><a id="__codelineno-0-296" name="__codelineno-0-296"></a>
</span><span id="__span-0-297"><a id="__codelineno-0-297" name="__codelineno-0-297"></a><span class="sd"> Args:</span>
</span><span id="__span-0-298"><a id="__codelineno-0-298" name="__codelineno-0-298"></a><span class="sd"> code: Python code to execute.</span>
</span><span id="__span-0-299"><a id="__codelineno-0-299" name="__codelineno-0-299"></a><span class="sd"> timeout_ms: Maximum execution time in milliseconds.</span>
</span><span id="__span-0-300"><a id="__codelineno-0-300" name="__codelineno-0-300"></a>
</span><span id="__span-0-301"><a id="__codelineno-0-301" name="__codelineno-0-301"></a><span class="sd"> Returns:</span>
</span><span id="__span-0-302"><a id="__codelineno-0-302" name="__codelineno-0-302"></a><span class="sd"> ExecutionResult with success status, output, and any errors.</span>
</span><span id="__span-0-303"><a id="__codelineno-0-303" name="__codelineno-0-303"></a><span class="sd"> """</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> </div> </div> <div class="doc doc-object doc-function"> <h6 id="freecad_mcp.bridge.base.FreecadBridge.get_active_document" class="doc doc-heading"> <code class="highlight language-python"><span class="n">get_active_document</span><span class="p">()</span></code> <span class="doc doc-labels"> <small class="doc doc-label doc-label-abstractmethod"><code>abstractmethod</code></small> <small class="doc doc-label doc-label-async"><code>async</code></small> </span> <a href="#freecad_mcp.bridge.base.FreecadBridge.get_active_document" class="headerlink" title="Permanent link">¶</a></h6> <div class="doc doc-contents "> <p>Get the active document.</p> <p><span class="doc-section-title">Returns:</span></p> <table> <thead> <tr> <th>Type</th> <th>Description</th> </tr> </thead> <tbody> <tr class="doc-section-item"> <td> <code><a class="autorefs autorefs-internal" title="DocumentInfo
dataclass
(freecad_mcp.bridge.base.DocumentInfo)" href="#freecad_mcp.bridge.base.DocumentInfo">DocumentInfo</a> | None</code> </td> <td> <div class="doc-md-description"> <p>DocumentInfo for active document, or None if no document is active.</p> </div> </td> </tr> </tbody> </table> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/base.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-317">317</a></span>
<span class="normal"><a href="#__codelineno-0-318">318</a></span>
<span class="normal"><a href="#__codelineno-0-319">319</a></span>
<span class="normal"><a href="#__codelineno-0-320">320</a></span>
<span class="normal"><a href="#__codelineno-0-321">321</a></span>
<span class="normal"><a href="#__codelineno-0-322">322</a></span>
<span class="normal"><a href="#__codelineno-0-323">323</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-317"><a id="__codelineno-0-317" name="__codelineno-0-317"></a><span class="nd">@abstractmethod</span>
</span><span id="__span-0-318"><a id="__codelineno-0-318" name="__codelineno-0-318"></a><span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">get_active_document</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">DocumentInfo</span> <span class="o">|</span> <span class="kc">None</span><span class="p">:</span>
</span><span id="__span-0-319"><a id="__codelineno-0-319" name="__codelineno-0-319"></a><span class="w"> </span><span class="sd">"""Get the active document.</span>
</span><span id="__span-0-320"><a id="__codelineno-0-320" name="__codelineno-0-320"></a>
</span><span id="__span-0-321"><a id="__codelineno-0-321" name="__codelineno-0-321"></a><span class="sd"> Returns:</span>
</span><span id="__span-0-322"><a id="__codelineno-0-322" name="__codelineno-0-322"></a><span class="sd"> DocumentInfo for active document, or None if no document is active.</span>
</span><span id="__span-0-323"><a id="__codelineno-0-323" name="__codelineno-0-323"></a><span class="sd"> """</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> </div> </div> <div class="doc doc-object doc-function"> <h6 id="freecad_mcp.bridge.base.FreecadBridge.get_console_output" class="doc doc-heading"> <code class="highlight language-python"><span class="n">get_console_output</span><span class="p">(</span><span class="n">lines</span><span class="o">=</span><span class="mi">100</span><span class="p">)</span></code> <span class="doc doc-labels"> <small class="doc doc-label doc-label-abstractmethod"><code>abstractmethod</code></small> <small class="doc doc-label doc-label-async"><code>async</code></small> </span> <a href="#freecad_mcp.bridge.base.FreecadBridge.get_console_output" class="headerlink" title="Permanent link">¶</a></h6> <div class="doc doc-contents "> <p>Get recent console output.</p> <p><span class="doc-section-title">Parameters:</span></p> <table> <thead> <tr> <th>Name</th> <th>Type</th> <th>Description</th> <th>Default</th> </tr> </thead> <tbody> <tr class="doc-section-item"> <td> <code>lines</code> </td> <td> <code><span title="int">int</span></code> </td> <td> <div class="doc-md-description"> <p>Maximum number of lines to return.</p> </div> </td> <td> <code>100</code> </td> </tr> </tbody> </table> <p><span class="doc-section-title">Returns:</span></p> <table> <thead> <tr> <th>Type</th> <th>Description</th> </tr> </thead> <tbody> <tr class="doc-section-item"> <td> <code><span title="list">list</span>[<span title="str">str</span>]</code> </td> <td> <div class="doc-md-description"> <p>List of console output lines, most recent last.</p> </div> </td> </tr> </tbody> </table> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/base.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-602">602</a></span>
<span class="normal"><a href="#__codelineno-0-603">603</a></span>
<span class="normal"><a href="#__codelineno-0-604">604</a></span>
<span class="normal"><a href="#__codelineno-0-605">605</a></span>
<span class="normal"><a href="#__codelineno-0-606">606</a></span>
<span class="normal"><a href="#__codelineno-0-607">607</a></span>
<span class="normal"><a href="#__codelineno-0-608">608</a></span>
<span class="normal"><a href="#__codelineno-0-609">609</a></span>
<span class="normal"><a href="#__codelineno-0-610">610</a></span>
<span class="normal"><a href="#__codelineno-0-611">611</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-602"><a id="__codelineno-0-602" name="__codelineno-0-602"></a><span class="nd">@abstractmethod</span>
</span><span id="__span-0-603"><a id="__codelineno-0-603" name="__codelineno-0-603"></a><span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">get_console_output</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">lines</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">100</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">list</span><span class="p">[</span><span class="nb">str</span><span class="p">]:</span>
</span><span id="__span-0-604"><a id="__codelineno-0-604" name="__codelineno-0-604"></a><span class="w"> </span><span class="sd">"""Get recent console output.</span>
</span><span id="__span-0-605"><a id="__codelineno-0-605" name="__codelineno-0-605"></a>
</span><span id="__span-0-606"><a id="__codelineno-0-606" name="__codelineno-0-606"></a><span class="sd"> Args:</span>
</span><span id="__span-0-607"><a id="__codelineno-0-607" name="__codelineno-0-607"></a><span class="sd"> lines: Maximum number of lines to return.</span>
</span><span id="__span-0-608"><a id="__codelineno-0-608" name="__codelineno-0-608"></a>
</span><span id="__span-0-609"><a id="__codelineno-0-609" name="__codelineno-0-609"></a><span class="sd"> Returns:</span>
</span><span id="__span-0-610"><a id="__codelineno-0-610" name="__codelineno-0-610"></a><span class="sd"> List of console output lines, most recent last.</span>
</span><span id="__span-0-611"><a id="__codelineno-0-611" name="__codelineno-0-611"></a><span class="sd"> """</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> </div> </div> <div class="doc doc-object doc-function"> <h6 id="freecad_mcp.bridge.base.FreecadBridge.get_documents" class="doc doc-heading"> <code class="highlight language-python"><span class="n">get_documents</span><span class="p">()</span></code> <span class="doc doc-labels"> <small class="doc doc-label doc-label-abstractmethod"><code>abstractmethod</code></small> <small class="doc doc-label doc-label-async"><code>async</code></small> </span> <a href="#freecad_mcp.bridge.base.FreecadBridge.get_documents" class="headerlink" title="Permanent link">¶</a></h6> <div class="doc doc-contents "> <p>Get list of open documents.</p> <p><span class="doc-section-title">Returns:</span></p> <table> <thead> <tr> <th>Type</th> <th>Description</th> </tr> </thead> <tbody> <tr class="doc-section-item"> <td> <code><span title="list">list</span>[<a class="autorefs autorefs-internal" title="DocumentInfo
dataclass
(freecad_mcp.bridge.base.DocumentInfo)" href="#freecad_mcp.bridge.base.DocumentInfo">DocumentInfo</a>]</code> </td> <td> <div class="doc-md-description"> <p>List of DocumentInfo for each open document.</p> </div> </td> </tr> </tbody> </table> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/base.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-309">309</a></span>
<span class="normal"><a href="#__codelineno-0-310">310</a></span>
<span class="normal"><a href="#__codelineno-0-311">311</a></span>
<span class="normal"><a href="#__codelineno-0-312">312</a></span>
<span class="normal"><a href="#__codelineno-0-313">313</a></span>
<span class="normal"><a href="#__codelineno-0-314">314</a></span>
<span class="normal"><a href="#__codelineno-0-315">315</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-309"><a id="__codelineno-0-309" name="__codelineno-0-309"></a><span class="nd">@abstractmethod</span>
</span><span id="__span-0-310"><a id="__codelineno-0-310" name="__codelineno-0-310"></a><span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">get_documents</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">list</span><span class="p">[</span><span class="n">DocumentInfo</span><span class="p">]:</span>
</span><span id="__span-0-311"><a id="__codelineno-0-311" name="__codelineno-0-311"></a><span class="w"> </span><span class="sd">"""Get list of open documents.</span>
</span><span id="__span-0-312"><a id="__codelineno-0-312" name="__codelineno-0-312"></a>
</span><span id="__span-0-313"><a id="__codelineno-0-313" name="__codelineno-0-313"></a><span class="sd"> Returns:</span>
</span><span id="__span-0-314"><a id="__codelineno-0-314" name="__codelineno-0-314"></a><span class="sd"> List of DocumentInfo for each open document.</span>
</span><span id="__span-0-315"><a id="__codelineno-0-315" name="__codelineno-0-315"></a><span class="sd"> """</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> </div> </div> <div class="doc doc-object doc-function"> <h6 id="freecad_mcp.bridge.base.FreecadBridge.get_freecad_version" class="doc doc-heading"> <code class="highlight language-python"><span class="n">get_freecad_version</span><span class="p">()</span></code> <span class="doc doc-labels"> <small class="doc doc-label doc-label-abstractmethod"><code>abstractmethod</code></small> <small class="doc doc-label doc-label-async"><code>async</code></small> </span> <a href="#freecad_mcp.bridge.base.FreecadBridge.get_freecad_version" class="headerlink" title="Permanent link">¶</a></h6> <div class="doc doc-contents "> <p>Get FreeCAD version information.</p> <p><span class="doc-section-title">Returns:</span></p> <table> <thead> <tr> <th>Type</th> <th>Description</th> </tr> </thead> <tbody> <tr class="doc-section-item"> <td> <code><span title="dict">dict</span>[<span title="str">str</span>, <span title="typing.Any">Any</span>]</code> </td> <td> <div class="doc-md-description"> <p>Dictionary with version, build_date, python_version, gui_available.</p> </div> </td> </tr> </tbody> </table> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/base.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-582">582</a></span>
<span class="normal"><a href="#__codelineno-0-583">583</a></span>
<span class="normal"><a href="#__codelineno-0-584">584</a></span>
<span class="normal"><a href="#__codelineno-0-585">585</a></span>
<span class="normal"><a href="#__codelineno-0-586">586</a></span>
<span class="normal"><a href="#__codelineno-0-587">587</a></span>
<span class="normal"><a href="#__codelineno-0-588">588</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-582"><a id="__codelineno-0-582" name="__codelineno-0-582"></a><span class="nd">@abstractmethod</span>
</span><span id="__span-0-583"><a id="__codelineno-0-583" name="__codelineno-0-583"></a><span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">get_freecad_version</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Any</span><span class="p">]:</span>
</span><span id="__span-0-584"><a id="__codelineno-0-584" name="__codelineno-0-584"></a><span class="w"> </span><span class="sd">"""Get FreeCAD version information.</span>
</span><span id="__span-0-585"><a id="__codelineno-0-585" name="__codelineno-0-585"></a>
</span><span id="__span-0-586"><a id="__codelineno-0-586" name="__codelineno-0-586"></a><span class="sd"> Returns:</span>
</span><span id="__span-0-587"><a id="__codelineno-0-587" name="__codelineno-0-587"></a><span class="sd"> Dictionary with version, build_date, python_version, gui_available.</span>
</span><span id="__span-0-588"><a id="__codelineno-0-588" name="__codelineno-0-588"></a><span class="sd"> """</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> </div> </div> <div class="doc doc-object doc-function"> <h6 id="freecad_mcp.bridge.base.FreecadBridge.get_macros" class="doc doc-heading"> <code class="highlight language-python"><span class="n">get_macros</span><span class="p">()</span></code> <span class="doc doc-labels"> <small class="doc doc-label doc-label-abstractmethod"><code>abstractmethod</code></small> <small class="doc doc-label doc-label-async"><code>async</code></small> </span> <a href="#freecad_mcp.bridge.base.FreecadBridge.get_macros" class="headerlink" title="Permanent link">¶</a></h6> <div class="doc doc-contents "> <p>Get list of available macros.</p> <p><span class="doc-section-title">Returns:</span></p> <table> <thead> <tr> <th>Type</th> <th>Description</th> </tr> </thead> <tbody> <tr class="doc-section-item"> <td> <code><span title="list">list</span>[<a class="autorefs autorefs-internal" title="MacroInfo
dataclass
(freecad_mcp.bridge.base.MacroInfo)" href="#freecad_mcp.bridge.base.MacroInfo">MacroInfo</a>]</code> </td> <td> <div class="doc-md-description"> <p>List of MacroInfo for each macro.</p> </div> </td> </tr> </tbody> </table> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/base.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-513">513</a></span>
<span class="normal"><a href="#__codelineno-0-514">514</a></span>
<span class="normal"><a href="#__codelineno-0-515">515</a></span>
<span class="normal"><a href="#__codelineno-0-516">516</a></span>
<span class="normal"><a href="#__codelineno-0-517">517</a></span>
<span class="normal"><a href="#__codelineno-0-518">518</a></span>
<span class="normal"><a href="#__codelineno-0-519">519</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-513"><a id="__codelineno-0-513" name="__codelineno-0-513"></a><span class="nd">@abstractmethod</span>
</span><span id="__span-0-514"><a id="__codelineno-0-514" name="__codelineno-0-514"></a><span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">get_macros</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">list</span><span class="p">[</span><span class="n">MacroInfo</span><span class="p">]:</span>
</span><span id="__span-0-515"><a id="__codelineno-0-515" name="__codelineno-0-515"></a><span class="w"> </span><span class="sd">"""Get list of available macros.</span>
</span><span id="__span-0-516"><a id="__codelineno-0-516" name="__codelineno-0-516"></a>
</span><span id="__span-0-517"><a id="__codelineno-0-517" name="__codelineno-0-517"></a><span class="sd"> Returns:</span>
</span><span id="__span-0-518"><a id="__codelineno-0-518" name="__codelineno-0-518"></a><span class="sd"> List of MacroInfo for each macro.</span>
</span><span id="__span-0-519"><a id="__codelineno-0-519" name="__codelineno-0-519"></a><span class="sd"> """</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> </div> </div> <div class="doc doc-object doc-function"> <h6 id="freecad_mcp.bridge.base.FreecadBridge.get_object" class="doc doc-heading"> <code class="highlight language-python"><span class="n">get_object</span><span class="p">(</span><span class="n">obj_name</span><span class="p">,</span> <span class="n">doc_name</span><span class="o">=</span><span class="kc">None</span><span class="p">)</span></code> <span class="doc doc-labels"> <small class="doc doc-label doc-label-abstractmethod"><code>abstractmethod</code></small> <small class="doc doc-label doc-label-async"><code>async</code></small> </span> <a href="#freecad_mcp.bridge.base.FreecadBridge.get_object" class="headerlink" title="Permanent link">¶</a></h6> <div class="doc doc-contents "> <p>Get detailed object information.</p> <p><span class="doc-section-title">Parameters:</span></p> <table> <thead> <tr> <th>Name</th> <th>Type</th> <th>Description</th> <th>Default</th> </tr> </thead> <tbody> <tr class="doc-section-item"> <td> <code>obj_name</code> </td> <td> <code><span title="str">str</span></code> </td> <td> <div class="doc-md-description"> <p>Name of the object.</p> </div> </td> <td> <em>required</em> </td> </tr> <tr class="doc-section-item"> <td> <code>doc_name</code> </td> <td> <code><span title="str">str</span> | None</code> </td> <td> <div class="doc-md-description"> <p>Document name (uses active if None).</p> </div> </td> <td> <code>None</code> </td> </tr> </tbody> </table> <p><span class="doc-section-title">Returns:</span></p> <table> <thead> <tr> <th>Type</th> <th>Description</th> </tr> </thead> <tbody> <tr class="doc-section-item"> <td> <code><a class="autorefs autorefs-internal" title="ObjectInfo
dataclass
(freecad_mcp.bridge.base.ObjectInfo)" href="#freecad_mcp.bridge.base.ObjectInfo">ObjectInfo</a></code> </td> <td> <div class="doc-md-description"> <p>ObjectInfo with full object details.</p> </div> </td> </tr> </tbody> </table> <p><span class="doc-section-title">Raises:</span></p> <table> <thead> <tr> <th>Type</th> <th>Description</th> </tr> </thead> <tbody> <tr class="doc-section-item"> <td> <code><span title="ValueError">ValueError</span></code> </td> <td> <div class="doc-md-description"> <p>If object not found.</p> </div> </td> </tr> </tbody> </table> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/base.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-396">396</a></span>
<span class="normal"><a href="#__codelineno-0-397">397</a></span>
<span class="normal"><a href="#__codelineno-0-398">398</a></span>
<span class="normal"><a href="#__codelineno-0-399">399</a></span>
<span class="normal"><a href="#__codelineno-0-400">400</a></span>
<span class="normal"><a href="#__codelineno-0-401">401</a></span>
<span class="normal"><a href="#__codelineno-0-402">402</a></span>
<span class="normal"><a href="#__codelineno-0-403">403</a></span>
<span class="normal"><a href="#__codelineno-0-404">404</a></span>
<span class="normal"><a href="#__codelineno-0-405">405</a></span>
<span class="normal"><a href="#__codelineno-0-406">406</a></span>
<span class="normal"><a href="#__codelineno-0-407">407</a></span>
<span class="normal"><a href="#__codelineno-0-408">408</a></span>
<span class="normal"><a href="#__codelineno-0-409">409</a></span>
<span class="normal"><a href="#__codelineno-0-410">410</a></span>
<span class="normal"><a href="#__codelineno-0-411">411</a></span>
<span class="normal"><a href="#__codelineno-0-412">412</a></span>
<span class="normal"><a href="#__codelineno-0-413">413</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-396"><a id="__codelineno-0-396" name="__codelineno-0-396"></a><span class="nd">@abstractmethod</span>
</span><span id="__span-0-397"><a id="__codelineno-0-397" name="__codelineno-0-397"></a><span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">get_object</span><span class="p">(</span>
</span><span id="__span-0-398"><a id="__codelineno-0-398" name="__codelineno-0-398"></a> <span class="bp">self</span><span class="p">,</span>
</span><span id="__span-0-399"><a id="__codelineno-0-399" name="__codelineno-0-399"></a> <span class="n">obj_name</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span>
</span><span id="__span-0-400"><a id="__codelineno-0-400" name="__codelineno-0-400"></a> <span class="n">doc_name</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-401"><a id="__codelineno-0-401" name="__codelineno-0-401"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">ObjectInfo</span><span class="p">:</span>
</span><span id="__span-0-402"><a id="__codelineno-0-402" name="__codelineno-0-402"></a><span class="w"> </span><span class="sd">"""Get detailed object information.</span>
</span><span id="__span-0-403"><a id="__codelineno-0-403" name="__codelineno-0-403"></a>
</span><span id="__span-0-404"><a id="__codelineno-0-404" name="__codelineno-0-404"></a><span class="sd"> Args:</span>
</span><span id="__span-0-405"><a id="__codelineno-0-405" name="__codelineno-0-405"></a><span class="sd"> obj_name: Name of the object.</span>
</span><span id="__span-0-406"><a id="__codelineno-0-406" name="__codelineno-0-406"></a><span class="sd"> doc_name: Document name (uses active if None).</span>
</span><span id="__span-0-407"><a id="__codelineno-0-407" name="__codelineno-0-407"></a>
</span><span id="__span-0-408"><a id="__codelineno-0-408" name="__codelineno-0-408"></a><span class="sd"> Returns:</span>
</span><span id="__span-0-409"><a id="__codelineno-0-409" name="__codelineno-0-409"></a><span class="sd"> ObjectInfo with full object details.</span>
</span><span id="__span-0-410"><a id="__codelineno-0-410" name="__codelineno-0-410"></a>
</span><span id="__span-0-411"><a id="__codelineno-0-411" name="__codelineno-0-411"></a><span class="sd"> Raises:</span>
</span><span id="__span-0-412"><a id="__codelineno-0-412" name="__codelineno-0-412"></a><span class="sd"> ValueError: If object not found.</span>
</span><span id="__span-0-413"><a id="__codelineno-0-413" name="__codelineno-0-413"></a><span class="sd"> """</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> </div> </div> <div class="doc doc-object doc-function"> <h6 id="freecad_mcp.bridge.base.FreecadBridge.get_objects" class="doc doc-heading"> <code class="highlight language-python"><span class="n">get_objects</span><span class="p">(</span><span class="n">doc_name</span><span class="o">=</span><span class="kc">None</span><span class="p">)</span></code> <span class="doc doc-labels"> <small class="doc doc-label doc-label-abstractmethod"><code>abstractmethod</code></small> <small class="doc doc-label doc-label-async"><code>async</code></small> </span> <a href="#freecad_mcp.bridge.base.FreecadBridge.get_objects" class="headerlink" title="Permanent link">¶</a></h6> <div class="doc doc-contents "> <p>Get all objects in a document.</p> <p><span class="doc-section-title">Parameters:</span></p> <table> <thead> <tr> <th>Name</th> <th>Type</th> <th>Description</th> <th>Default</th> </tr> </thead> <tbody> <tr class="doc-section-item"> <td> <code>doc_name</code> </td> <td> <code><span title="str">str</span> | None</code> </td> <td> <div class="doc-md-description"> <p>Document name (uses active if None).</p> </div> </td> <td> <code>None</code> </td> </tr> </tbody> </table> <p><span class="doc-section-title">Returns:</span></p> <table> <thead> <tr> <th>Type</th> <th>Description</th> </tr> </thead> <tbody> <tr class="doc-section-item"> <td> <code><span title="list">list</span>[<a class="autorefs autorefs-internal" title="ObjectInfo
dataclass
(freecad_mcp.bridge.base.ObjectInfo)" href="#freecad_mcp.bridge.base.ObjectInfo">ObjectInfo</a>]</code> </td> <td> <div class="doc-md-description"> <p>List of ObjectInfo for each object.</p> </div> </td> </tr> </tbody> </table> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/base.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-385">385</a></span>
<span class="normal"><a href="#__codelineno-0-386">386</a></span>
<span class="normal"><a href="#__codelineno-0-387">387</a></span>
<span class="normal"><a href="#__codelineno-0-388">388</a></span>
<span class="normal"><a href="#__codelineno-0-389">389</a></span>
<span class="normal"><a href="#__codelineno-0-390">390</a></span>
<span class="normal"><a href="#__codelineno-0-391">391</a></span>
<span class="normal"><a href="#__codelineno-0-392">392</a></span>
<span class="normal"><a href="#__codelineno-0-393">393</a></span>
<span class="normal"><a href="#__codelineno-0-394">394</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-385"><a id="__codelineno-0-385" name="__codelineno-0-385"></a><span class="nd">@abstractmethod</span>
</span><span id="__span-0-386"><a id="__codelineno-0-386" name="__codelineno-0-386"></a><span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">get_objects</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">doc_name</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">list</span><span class="p">[</span><span class="n">ObjectInfo</span><span class="p">]:</span>
</span><span id="__span-0-387"><a id="__codelineno-0-387" name="__codelineno-0-387"></a><span class="w"> </span><span class="sd">"""Get all objects in a document.</span>
</span><span id="__span-0-388"><a id="__codelineno-0-388" name="__codelineno-0-388"></a>
</span><span id="__span-0-389"><a id="__codelineno-0-389" name="__codelineno-0-389"></a><span class="sd"> Args:</span>
</span><span id="__span-0-390"><a id="__codelineno-0-390" name="__codelineno-0-390"></a><span class="sd"> doc_name: Document name (uses active if None).</span>
</span><span id="__span-0-391"><a id="__codelineno-0-391" name="__codelineno-0-391"></a>
</span><span id="__span-0-392"><a id="__codelineno-0-392" name="__codelineno-0-392"></a><span class="sd"> Returns:</span>
</span><span id="__span-0-393"><a id="__codelineno-0-393" name="__codelineno-0-393"></a><span class="sd"> List of ObjectInfo for each object.</span>
</span><span id="__span-0-394"><a id="__codelineno-0-394" name="__codelineno-0-394"></a><span class="sd"> """</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> </div> </div> <div class="doc doc-object doc-function"> <h6 id="freecad_mcp.bridge.base.FreecadBridge.get_screenshot" class="doc doc-heading"> <code class="highlight language-python"><span class="n">get_screenshot</span><span class="p">(</span><span class="n">view_angle</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">width</span><span class="o">=</span><span class="mi">800</span><span class="p">,</span> <span class="n">height</span><span class="o">=</span><span class="mi">600</span><span class="p">,</span> <span class="n">doc_name</span><span class="o">=</span><span class="kc">None</span><span class="p">)</span></code> <span class="doc doc-labels"> <small class="doc doc-label doc-label-abstractmethod"><code>abstractmethod</code></small> <small class="doc doc-label doc-label-async"><code>async</code></small> </span> <a href="#freecad_mcp.bridge.base.FreecadBridge.get_screenshot" class="headerlink" title="Permanent link">¶</a></h6> <div class="doc doc-contents "> <p>Capture a screenshot of the 3D view.</p> <p><span class="doc-section-title">Parameters:</span></p> <table> <thead> <tr> <th>Name</th> <th>Type</th> <th>Description</th> <th>Default</th> </tr> </thead> <tbody> <tr class="doc-section-item"> <td> <code>view_angle</code> </td> <td> <code><a class="autorefs autorefs-internal" title="ViewAngle (freecad_mcp.bridge.base.ViewAngle)" href="#freecad_mcp.bridge.base.ViewAngle">ViewAngle</a> | None</code> </td> <td> <div class="doc-md-description"> <p>View angle to set before capture.</p> </div> </td> <td> <code>None</code> </td> </tr> <tr class="doc-section-item"> <td> <code>width</code> </td> <td> <code><span title="int">int</span></code> </td> <td> <div class="doc-md-description"> <p>Image width in pixels.</p> </div> </td> <td> <code>800</code> </td> </tr> <tr class="doc-section-item"> <td> <code>height</code> </td> <td> <code><span title="int">int</span></code> </td> <td> <div class="doc-md-description"> <p>Image height in pixels.</p> </div> </td> <td> <code>600</code> </td> </tr> <tr class="doc-section-item"> <td> <code>doc_name</code> </td> <td> <code><span title="str">str</span> | None</code> </td> <td> <div class="doc-md-description"> <p>Document name (uses active if None).</p> </div> </td> <td> <code>None</code> </td> </tr> </tbody> </table> <p><span class="doc-section-title">Returns:</span></p> <table> <thead> <tr> <th>Type</th> <th>Description</th> </tr> </thead> <tbody> <tr class="doc-section-item"> <td> <code><a class="autorefs autorefs-internal" title="ScreenshotResult
dataclass
(freecad_mcp.bridge.base.ScreenshotResult)" href="#freecad_mcp.bridge.base.ScreenshotResult">ScreenshotResult</a></code> </td> <td> <div class="doc-md-description"> <p>ScreenshotResult with image data or error.</p> </div> </td> </tr> </tbody> </table> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/base.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-476">476</a></span>
<span class="normal"><a href="#__codelineno-0-477">477</a></span>
<span class="normal"><a href="#__codelineno-0-478">478</a></span>
<span class="normal"><a href="#__codelineno-0-479">479</a></span>
<span class="normal"><a href="#__codelineno-0-480">480</a></span>
<span class="normal"><a href="#__codelineno-0-481">481</a></span>
<span class="normal"><a href="#__codelineno-0-482">482</a></span>
<span class="normal"><a href="#__codelineno-0-483">483</a></span>
<span class="normal"><a href="#__codelineno-0-484">484</a></span>
<span class="normal"><a href="#__codelineno-0-485">485</a></span>
<span class="normal"><a href="#__codelineno-0-486">486</a></span>
<span class="normal"><a href="#__codelineno-0-487">487</a></span>
<span class="normal"><a href="#__codelineno-0-488">488</a></span>
<span class="normal"><a href="#__codelineno-0-489">489</a></span>
<span class="normal"><a href="#__codelineno-0-490">490</a></span>
<span class="normal"><a href="#__codelineno-0-491">491</a></span>
<span class="normal"><a href="#__codelineno-0-492">492</a></span>
<span class="normal"><a href="#__codelineno-0-493">493</a></span>
<span class="normal"><a href="#__codelineno-0-494">494</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-476"><a id="__codelineno-0-476" name="__codelineno-0-476"></a><span class="nd">@abstractmethod</span>
</span><span id="__span-0-477"><a id="__codelineno-0-477" name="__codelineno-0-477"></a><span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">get_screenshot</span><span class="p">(</span>
</span><span id="__span-0-478"><a id="__codelineno-0-478" name="__codelineno-0-478"></a> <span class="bp">self</span><span class="p">,</span>
</span><span id="__span-0-479"><a id="__codelineno-0-479" name="__codelineno-0-479"></a> <span class="n">view_angle</span><span class="p">:</span> <span class="n">ViewAngle</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-480"><a id="__codelineno-0-480" name="__codelineno-0-480"></a> <span class="n">width</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">800</span><span class="p">,</span>
</span><span id="__span-0-481"><a id="__codelineno-0-481" name="__codelineno-0-481"></a> <span class="n">height</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">600</span><span class="p">,</span>
</span><span id="__span-0-482"><a id="__codelineno-0-482" name="__codelineno-0-482"></a> <span class="n">doc_name</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-483"><a id="__codelineno-0-483" name="__codelineno-0-483"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">ScreenshotResult</span><span class="p">:</span>
</span><span id="__span-0-484"><a id="__codelineno-0-484" name="__codelineno-0-484"></a><span class="w"> </span><span class="sd">"""Capture a screenshot of the 3D view.</span>
</span><span id="__span-0-485"><a id="__codelineno-0-485" name="__codelineno-0-485"></a>
</span><span id="__span-0-486"><a id="__codelineno-0-486" name="__codelineno-0-486"></a><span class="sd"> Args:</span>
</span><span id="__span-0-487"><a id="__codelineno-0-487" name="__codelineno-0-487"></a><span class="sd"> view_angle: View angle to set before capture.</span>
</span><span id="__span-0-488"><a id="__codelineno-0-488" name="__codelineno-0-488"></a><span class="sd"> width: Image width in pixels.</span>
</span><span id="__span-0-489"><a id="__codelineno-0-489" name="__codelineno-0-489"></a><span class="sd"> height: Image height in pixels.</span>
</span><span id="__span-0-490"><a id="__codelineno-0-490" name="__codelineno-0-490"></a><span class="sd"> doc_name: Document name (uses active if None).</span>
</span><span id="__span-0-491"><a id="__codelineno-0-491" name="__codelineno-0-491"></a>
</span><span id="__span-0-492"><a id="__codelineno-0-492" name="__codelineno-0-492"></a><span class="sd"> Returns:</span>
</span><span id="__span-0-493"><a id="__codelineno-0-493" name="__codelineno-0-493"></a><span class="sd"> ScreenshotResult with image data or error.</span>
</span><span id="__span-0-494"><a id="__codelineno-0-494" name="__codelineno-0-494"></a><span class="sd"> """</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> </div> </div> <div class="doc doc-object doc-function"> <h6 id="freecad_mcp.bridge.base.FreecadBridge.get_status" class="doc doc-heading"> <code class="highlight language-python"><span class="n">get_status</span><span class="p">()</span></code> <span class="doc doc-labels"> <small class="doc doc-label doc-label-abstractmethod"><code>abstractmethod</code></small> <small class="doc doc-label doc-label-async"><code>async</code></small> </span> <a href="#freecad_mcp.bridge.base.FreecadBridge.get_status" class="headerlink" title="Permanent link">¶</a></h6> <div class="doc doc-contents "> <p>Get detailed connection status.</p> <p><span class="doc-section-title">Returns:</span></p> <table> <thead> <tr> <th>Type</th> <th>Description</th> </tr> </thead> <tbody> <tr class="doc-section-item"> <td> <code><a class="autorefs autorefs-internal" title="ConnectionStatus
dataclass
(freecad_mcp.bridge.base.ConnectionStatus)" href="#freecad_mcp.bridge.base.ConnectionStatus">ConnectionStatus</a></code> </td> <td> <div class="doc-md-description"> <p>ConnectionStatus with full status information.</p> </div> </td> </tr> </tbody> </table> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/base.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-274">274</a></span>
<span class="normal"><a href="#__codelineno-0-275">275</a></span>
<span class="normal"><a href="#__codelineno-0-276">276</a></span>
<span class="normal"><a href="#__codelineno-0-277">277</a></span>
<span class="normal"><a href="#__codelineno-0-278">278</a></span>
<span class="normal"><a href="#__codelineno-0-279">279</a></span>
<span class="normal"><a href="#__codelineno-0-280">280</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-274"><a id="__codelineno-0-274" name="__codelineno-0-274"></a><span class="nd">@abstractmethod</span>
</span><span id="__span-0-275"><a id="__codelineno-0-275" name="__codelineno-0-275"></a><span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">get_status</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">ConnectionStatus</span><span class="p">:</span>
</span><span id="__span-0-276"><a id="__codelineno-0-276" name="__codelineno-0-276"></a><span class="w"> </span><span class="sd">"""Get detailed connection status.</span>
</span><span id="__span-0-277"><a id="__codelineno-0-277" name="__codelineno-0-277"></a>
</span><span id="__span-0-278"><a id="__codelineno-0-278" name="__codelineno-0-278"></a><span class="sd"> Returns:</span>
</span><span id="__span-0-279"><a id="__codelineno-0-279" name="__codelineno-0-279"></a><span class="sd"> ConnectionStatus with full status information.</span>
</span><span id="__span-0-280"><a id="__codelineno-0-280" name="__codelineno-0-280"></a><span class="sd"> """</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> </div> </div> <div class="doc doc-object doc-function"> <h6 id="freecad_mcp.bridge.base.FreecadBridge.get_workbenches" class="doc doc-heading"> <code class="highlight language-python"><span class="n">get_workbenches</span><span class="p">()</span></code> <span class="doc doc-labels"> <small class="doc doc-label doc-label-abstractmethod"><code>abstractmethod</code></small> <small class="doc doc-label doc-label-async"><code>async</code></small> </span> <a href="#freecad_mcp.bridge.base.FreecadBridge.get_workbenches" class="headerlink" title="Permanent link">¶</a></h6> <div class="doc doc-contents "> <p>Get list of available workbenches.</p> <p><span class="doc-section-title">Returns:</span></p> <table> <thead> <tr> <th>Type</th> <th>Description</th> </tr> </thead> <tbody> <tr class="doc-section-item"> <td> <code><span title="list">list</span>[<a class="autorefs autorefs-internal" title="WorkbenchInfo
dataclass
(freecad_mcp.bridge.base.WorkbenchInfo)" href="#freecad_mcp.bridge.base.WorkbenchInfo">WorkbenchInfo</a>]</code> </td> <td> <div class="doc-md-description"> <p>List of WorkbenchInfo for each workbench.</p> </div> </td> </tr> </tbody> </table> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/base.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-559">559</a></span>
<span class="normal"><a href="#__codelineno-0-560">560</a></span>
<span class="normal"><a href="#__codelineno-0-561">561</a></span>
<span class="normal"><a href="#__codelineno-0-562">562</a></span>
<span class="normal"><a href="#__codelineno-0-563">563</a></span>
<span class="normal"><a href="#__codelineno-0-564">564</a></span>
<span class="normal"><a href="#__codelineno-0-565">565</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-559"><a id="__codelineno-0-559" name="__codelineno-0-559"></a><span class="nd">@abstractmethod</span>
</span><span id="__span-0-560"><a id="__codelineno-0-560" name="__codelineno-0-560"></a><span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">get_workbenches</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">list</span><span class="p">[</span><span class="n">WorkbenchInfo</span><span class="p">]:</span>
</span><span id="__span-0-561"><a id="__codelineno-0-561" name="__codelineno-0-561"></a><span class="w"> </span><span class="sd">"""Get list of available workbenches.</span>
</span><span id="__span-0-562"><a id="__codelineno-0-562" name="__codelineno-0-562"></a>
</span><span id="__span-0-563"><a id="__codelineno-0-563" name="__codelineno-0-563"></a><span class="sd"> Returns:</span>
</span><span id="__span-0-564"><a id="__codelineno-0-564" name="__codelineno-0-564"></a><span class="sd"> List of WorkbenchInfo for each workbench.</span>
</span><span id="__span-0-565"><a id="__codelineno-0-565" name="__codelineno-0-565"></a><span class="sd"> """</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> </div> </div> <div class="doc doc-object doc-function"> <h6 id="freecad_mcp.bridge.base.FreecadBridge.is_connected" class="doc doc-heading"> <code class="highlight language-python"><span class="n">is_connected</span><span class="p">()</span></code> <span class="doc doc-labels"> <small class="doc doc-label doc-label-abstractmethod"><code>abstractmethod</code></small> <small class="doc doc-label doc-label-async"><code>async</code></small> </span> <a href="#freecad_mcp.bridge.base.FreecadBridge.is_connected" class="headerlink" title="Permanent link">¶</a></h6> <div class="doc doc-contents "> <p>Check if bridge is connected to FreeCAD.</p> <p><span class="doc-section-title">Returns:</span></p> <table> <thead> <tr> <th>Type</th> <th>Description</th> </tr> </thead> <tbody> <tr class="doc-section-item"> <td> <code><span title="bool">bool</span></code> </td> <td> <div class="doc-md-description"> <p>True if connected, False otherwise.</p> </div> </td> </tr> </tbody> </table> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/base.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-255">255</a></span>
<span class="normal"><a href="#__codelineno-0-256">256</a></span>
<span class="normal"><a href="#__codelineno-0-257">257</a></span>
<span class="normal"><a href="#__codelineno-0-258">258</a></span>
<span class="normal"><a href="#__codelineno-0-259">259</a></span>
<span class="normal"><a href="#__codelineno-0-260">260</a></span>
<span class="normal"><a href="#__codelineno-0-261">261</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-255"><a id="__codelineno-0-255" name="__codelineno-0-255"></a><span class="nd">@abstractmethod</span>
</span><span id="__span-0-256"><a id="__codelineno-0-256" name="__codelineno-0-256"></a><span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">is_connected</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">bool</span><span class="p">:</span>
</span><span id="__span-0-257"><a id="__codelineno-0-257" name="__codelineno-0-257"></a><span class="w"> </span><span class="sd">"""Check if bridge is connected to FreeCAD.</span>
</span><span id="__span-0-258"><a id="__codelineno-0-258" name="__codelineno-0-258"></a>
</span><span id="__span-0-259"><a id="__codelineno-0-259" name="__codelineno-0-259"></a><span class="sd"> Returns:</span>
</span><span id="__span-0-260"><a id="__codelineno-0-260" name="__codelineno-0-260"></a><span class="sd"> True if connected, False otherwise.</span>
</span><span id="__span-0-261"><a id="__codelineno-0-261" name="__codelineno-0-261"></a><span class="sd"> """</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> </div> </div> <div class="doc doc-object doc-function"> <h6 id="freecad_mcp.bridge.base.FreecadBridge.is_gui_available" class="doc doc-heading"> <code class="highlight language-python"><span class="n">is_gui_available</span><span class="p">()</span></code> <span class="doc doc-labels"> <small class="doc doc-label doc-label-abstractmethod"><code>abstractmethod</code></small> <small class="doc doc-label doc-label-async"><code>async</code></small> </span> <a href="#freecad_mcp.bridge.base.FreecadBridge.is_gui_available" class="headerlink" title="Permanent link">¶</a></h6> <div class="doc doc-contents "> <p>Check if FreeCAD GUI is available.</p> <p><span class="doc-section-title">Returns:</span></p> <table> <thead> <tr> <th>Type</th> <th>Description</th> </tr> </thead> <tbody> <tr class="doc-section-item"> <td> <code><span title="bool">bool</span></code> </td> <td> <div class="doc-md-description"> <p>True if GUI is available, False for headless mode.</p> </div> </td> </tr> </tbody> </table> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/base.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-590">590</a></span>
<span class="normal"><a href="#__codelineno-0-591">591</a></span>
<span class="normal"><a href="#__codelineno-0-592">592</a></span>
<span class="normal"><a href="#__codelineno-0-593">593</a></span>
<span class="normal"><a href="#__codelineno-0-594">594</a></span>
<span class="normal"><a href="#__codelineno-0-595">595</a></span>
<span class="normal"><a href="#__codelineno-0-596">596</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-590"><a id="__codelineno-0-590" name="__codelineno-0-590"></a><span class="nd">@abstractmethod</span>
</span><span id="__span-0-591"><a id="__codelineno-0-591" name="__codelineno-0-591"></a><span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">is_gui_available</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">bool</span><span class="p">:</span>
</span><span id="__span-0-592"><a id="__codelineno-0-592" name="__codelineno-0-592"></a><span class="w"> </span><span class="sd">"""Check if FreeCAD GUI is available.</span>
</span><span id="__span-0-593"><a id="__codelineno-0-593" name="__codelineno-0-593"></a>
</span><span id="__span-0-594"><a id="__codelineno-0-594" name="__codelineno-0-594"></a><span class="sd"> Returns:</span>
</span><span id="__span-0-595"><a id="__codelineno-0-595" name="__codelineno-0-595"></a><span class="sd"> True if GUI is available, False for headless mode.</span>
</span><span id="__span-0-596"><a id="__codelineno-0-596" name="__codelineno-0-596"></a><span class="sd"> """</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> </div> </div> <div class="doc doc-object doc-function"> <h6 id="freecad_mcp.bridge.base.FreecadBridge.open_document" class="doc doc-heading"> <code class="highlight language-python"><span class="n">open_document</span><span class="p">(</span><span class="n">path</span><span class="p">)</span></code> <span class="doc doc-labels"> <small class="doc doc-label doc-label-abstractmethod"><code>abstractmethod</code></small> <small class="doc doc-label doc-label-async"><code>async</code></small> </span> <a href="#freecad_mcp.bridge.base.FreecadBridge.open_document" class="headerlink" title="Permanent link">¶</a></h6> <div class="doc doc-contents "> <p>Open an existing document.</p> <p><span class="doc-section-title">Parameters:</span></p> <table> <thead> <tr> <th>Name</th> <th>Type</th> <th>Description</th> <th>Default</th> </tr> </thead> <tbody> <tr class="doc-section-item"> <td> <code>path</code> </td> <td> <code><span title="str">str</span></code> </td> <td> <div class="doc-md-description"> <p>Path to the .FCStd file.</p> </div> </td> <td> <em>required</em> </td> </tr> </tbody> </table> <p><span class="doc-section-title">Returns:</span></p> <table> <thead> <tr> <th>Type</th> <th>Description</th> </tr> </thead> <tbody> <tr class="doc-section-item"> <td> <code><a class="autorefs autorefs-internal" title="DocumentInfo
dataclass
(freecad_mcp.bridge.base.DocumentInfo)" href="#freecad_mcp.bridge.base.DocumentInfo">DocumentInfo</a></code> </td> <td> <div class="doc-md-description"> <p>DocumentInfo for the opened document.</p> </div> </td> </tr> </tbody> </table> <p><span class="doc-section-title">Raises:</span></p> <table> <thead> <tr> <th>Type</th> <th>Description</th> </tr> </thead> <tbody> <tr class="doc-section-item"> <td> <code><span title="FileNotFoundError">FileNotFoundError</span></code> </td> <td> <div class="doc-md-description"> <p>If file doesn't exist.</p> </div> </td> </tr> <tr class="doc-section-item"> <td> <code><span title="ValueError">ValueError</span></code> </td> <td> <div class="doc-md-description"> <p>If file is not a valid FreeCAD document.</p> </div> </td> </tr> </tbody> </table> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/base.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-339">339</a></span>
<span class="normal"><a href="#__codelineno-0-340">340</a></span>
<span class="normal"><a href="#__codelineno-0-341">341</a></span>
<span class="normal"><a href="#__codelineno-0-342">342</a></span>
<span class="normal"><a href="#__codelineno-0-343">343</a></span>
<span class="normal"><a href="#__codelineno-0-344">344</a></span>
<span class="normal"><a href="#__codelineno-0-345">345</a></span>
<span class="normal"><a href="#__codelineno-0-346">346</a></span>
<span class="normal"><a href="#__codelineno-0-347">347</a></span>
<span class="normal"><a href="#__codelineno-0-348">348</a></span>
<span class="normal"><a href="#__codelineno-0-349">349</a></span>
<span class="normal"><a href="#__codelineno-0-350">350</a></span>
<span class="normal"><a href="#__codelineno-0-351">351</a></span>
<span class="normal"><a href="#__codelineno-0-352">352</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-339"><a id="__codelineno-0-339" name="__codelineno-0-339"></a><span class="nd">@abstractmethod</span>
</span><span id="__span-0-340"><a id="__codelineno-0-340" name="__codelineno-0-340"></a><span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">open_document</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">path</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">DocumentInfo</span><span class="p">:</span>
</span><span id="__span-0-341"><a id="__codelineno-0-341" name="__codelineno-0-341"></a><span class="w"> </span><span class="sd">"""Open an existing document.</span>
</span><span id="__span-0-342"><a id="__codelineno-0-342" name="__codelineno-0-342"></a>
</span><span id="__span-0-343"><a id="__codelineno-0-343" name="__codelineno-0-343"></a><span class="sd"> Args:</span>
</span><span id="__span-0-344"><a id="__codelineno-0-344" name="__codelineno-0-344"></a><span class="sd"> path: Path to the .FCStd file.</span>
</span><span id="__span-0-345"><a id="__codelineno-0-345" name="__codelineno-0-345"></a>
</span><span id="__span-0-346"><a id="__codelineno-0-346" name="__codelineno-0-346"></a><span class="sd"> Returns:</span>
</span><span id="__span-0-347"><a id="__codelineno-0-347" name="__codelineno-0-347"></a><span class="sd"> DocumentInfo for the opened document.</span>
</span><span id="__span-0-348"><a id="__codelineno-0-348" name="__codelineno-0-348"></a>
</span><span id="__span-0-349"><a id="__codelineno-0-349" name="__codelineno-0-349"></a><span class="sd"> Raises:</span>
</span><span id="__span-0-350"><a id="__codelineno-0-350" name="__codelineno-0-350"></a><span class="sd"> FileNotFoundError: If file doesn't exist.</span>
</span><span id="__span-0-351"><a id="__codelineno-0-351" name="__codelineno-0-351"></a><span class="sd"> ValueError: If file is not a valid FreeCAD document.</span>
</span><span id="__span-0-352"><a id="__codelineno-0-352" name="__codelineno-0-352"></a><span class="sd"> """</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> </div> </div> <div class="doc doc-object doc-function"> <h6 id="freecad_mcp.bridge.base.FreecadBridge.ping" class="doc doc-heading"> <code class="highlight language-python"><span class="n">ping</span><span class="p">()</span></code> <span class="doc doc-labels"> <small class="doc doc-label doc-label-abstractmethod"><code>abstractmethod</code></small> <small class="doc doc-label doc-label-async"><code>async</code></small> </span> <a href="#freecad_mcp.bridge.base.FreecadBridge.ping" class="headerlink" title="Permanent link">¶</a></h6> <div class="doc doc-contents "> <p>Ping FreeCAD to check connection and measure latency.</p> <p><span class="doc-section-title">Returns:</span></p> <table> <thead> <tr> <th>Type</th> <th>Description</th> </tr> </thead> <tbody> <tr class="doc-section-item"> <td> <code><span title="float">float</span></code> </td> <td> <div class="doc-md-description"> <p>Round-trip time in milliseconds.</p> </div> </td> </tr> </tbody> </table> <p><span class="doc-section-title">Raises:</span></p> <table> <thead> <tr> <th>Type</th> <th>Description</th> </tr> </thead> <tbody> <tr class="doc-section-item"> <td> <code><span title="ConnectionError">ConnectionError</span></code> </td> <td> <div class="doc-md-description"> <p>If not connected.</p> </div> </td> </tr> </tbody> </table> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/base.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-263">263</a></span>
<span class="normal"><a href="#__codelineno-0-264">264</a></span>
<span class="normal"><a href="#__codelineno-0-265">265</a></span>
<span class="normal"><a href="#__codelineno-0-266">266</a></span>
<span class="normal"><a href="#__codelineno-0-267">267</a></span>
<span class="normal"><a href="#__codelineno-0-268">268</a></span>
<span class="normal"><a href="#__codelineno-0-269">269</a></span>
<span class="normal"><a href="#__codelineno-0-270">270</a></span>
<span class="normal"><a href="#__codelineno-0-271">271</a></span>
<span class="normal"><a href="#__codelineno-0-272">272</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-263"><a id="__codelineno-0-263" name="__codelineno-0-263"></a><span class="nd">@abstractmethod</span>
</span><span id="__span-0-264"><a id="__codelineno-0-264" name="__codelineno-0-264"></a><span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">ping</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">float</span><span class="p">:</span>
</span><span id="__span-0-265"><a id="__codelineno-0-265" name="__codelineno-0-265"></a><span class="w"> </span><span class="sd">"""Ping FreeCAD to check connection and measure latency.</span>
</span><span id="__span-0-266"><a id="__codelineno-0-266" name="__codelineno-0-266"></a>
</span><span id="__span-0-267"><a id="__codelineno-0-267" name="__codelineno-0-267"></a><span class="sd"> Returns:</span>
</span><span id="__span-0-268"><a id="__codelineno-0-268" name="__codelineno-0-268"></a><span class="sd"> Round-trip time in milliseconds.</span>
</span><span id="__span-0-269"><a id="__codelineno-0-269" name="__codelineno-0-269"></a>
</span><span id="__span-0-270"><a id="__codelineno-0-270" name="__codelineno-0-270"></a><span class="sd"> Raises:</span>
</span><span id="__span-0-271"><a id="__codelineno-0-271" name="__codelineno-0-271"></a><span class="sd"> ConnectionError: If not connected.</span>
</span><span id="__span-0-272"><a id="__codelineno-0-272" name="__codelineno-0-272"></a><span class="sd"> """</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> </div> </div> <div class="doc doc-object doc-function"> <h6 id="freecad_mcp.bridge.base.FreecadBridge.run_macro" class="doc doc-heading"> <code class="highlight language-python"><span class="n">run_macro</span><span class="p">(</span><span class="n">macro_name</span><span class="p">,</span> <span class="n">args</span><span class="o">=</span><span class="kc">None</span><span class="p">)</span></code> <span class="doc doc-labels"> <small class="doc doc-label doc-label-abstractmethod"><code>abstractmethod</code></small> <small class="doc doc-label doc-label-async"><code>async</code></small> </span> <a href="#freecad_mcp.bridge.base.FreecadBridge.run_macro" class="headerlink" title="Permanent link">¶</a></h6> <div class="doc doc-contents "> <p>Run a macro by name.</p> <p><span class="doc-section-title">Parameters:</span></p> <table> <thead> <tr> <th>Name</th> <th>Type</th> <th>Description</th> <th>Default</th> </tr> </thead> <tbody> <tr class="doc-section-item"> <td> <code>macro_name</code> </td> <td> <code><span title="str">str</span></code> </td> <td> <div class="doc-md-description"> <p>Macro name (without .FCMacro extension).</p> </div> </td> <td> <em>required</em> </td> </tr> <tr class="doc-section-item"> <td> <code>args</code> </td> <td> <code><span title="dict">dict</span>[<span title="str">str</span>, <span title="typing.Any">Any</span>] | None</code> </td> <td> <div class="doc-md-description"> <p>Arguments to pass to the macro.</p> </div> </td> <td> <code>None</code> </td> </tr> </tbody> </table> <p><span class="doc-section-title">Returns:</span></p> <table> <thead> <tr> <th>Type</th> <th>Description</th> </tr> </thead> <tbody> <tr class="doc-section-item"> <td> <code><a class="autorefs autorefs-internal" title="ExecutionResult
dataclass
(freecad_mcp.bridge.base.ExecutionResult)" href="#freecad_mcp.bridge.base.ExecutionResult">ExecutionResult</a></code> </td> <td> <div class="doc-md-description"> <p>ExecutionResult from macro execution.</p> </div> </td> </tr> </tbody> </table> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/base.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-521">521</a></span>
<span class="normal"><a href="#__codelineno-0-522">522</a></span>
<span class="normal"><a href="#__codelineno-0-523">523</a></span>
<span class="normal"><a href="#__codelineno-0-524">524</a></span>
<span class="normal"><a href="#__codelineno-0-525">525</a></span>
<span class="normal"><a href="#__codelineno-0-526">526</a></span>
<span class="normal"><a href="#__codelineno-0-527">527</a></span>
<span class="normal"><a href="#__codelineno-0-528">528</a></span>
<span class="normal"><a href="#__codelineno-0-529">529</a></span>
<span class="normal"><a href="#__codelineno-0-530">530</a></span>
<span class="normal"><a href="#__codelineno-0-531">531</a></span>
<span class="normal"><a href="#__codelineno-0-532">532</a></span>
<span class="normal"><a href="#__codelineno-0-533">533</a></span>
<span class="normal"><a href="#__codelineno-0-534">534</a></span>
<span class="normal"><a href="#__codelineno-0-535">535</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-521"><a id="__codelineno-0-521" name="__codelineno-0-521"></a><span class="nd">@abstractmethod</span>
</span><span id="__span-0-522"><a id="__codelineno-0-522" name="__codelineno-0-522"></a><span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">run_macro</span><span class="p">(</span>
</span><span id="__span-0-523"><a id="__codelineno-0-523" name="__codelineno-0-523"></a> <span class="bp">self</span><span class="p">,</span>
</span><span id="__span-0-524"><a id="__codelineno-0-524" name="__codelineno-0-524"></a> <span class="n">macro_name</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span>
</span><span id="__span-0-525"><a id="__codelineno-0-525" name="__codelineno-0-525"></a> <span class="n">args</span><span class="p">:</span> <span class="nb">dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Any</span><span class="p">]</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-526"><a id="__codelineno-0-526" name="__codelineno-0-526"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">ExecutionResult</span><span class="p">:</span>
</span><span id="__span-0-527"><a id="__codelineno-0-527" name="__codelineno-0-527"></a><span class="w"> </span><span class="sd">"""Run a macro by name.</span>
</span><span id="__span-0-528"><a id="__codelineno-0-528" name="__codelineno-0-528"></a>
</span><span id="__span-0-529"><a id="__codelineno-0-529" name="__codelineno-0-529"></a><span class="sd"> Args:</span>
</span><span id="__span-0-530"><a id="__codelineno-0-530" name="__codelineno-0-530"></a><span class="sd"> macro_name: Macro name (without .FCMacro extension).</span>
</span><span id="__span-0-531"><a id="__codelineno-0-531" name="__codelineno-0-531"></a><span class="sd"> args: Arguments to pass to the macro.</span>
</span><span id="__span-0-532"><a id="__codelineno-0-532" name="__codelineno-0-532"></a>
</span><span id="__span-0-533"><a id="__codelineno-0-533" name="__codelineno-0-533"></a><span class="sd"> Returns:</span>
</span><span id="__span-0-534"><a id="__codelineno-0-534" name="__codelineno-0-534"></a><span class="sd"> ExecutionResult from macro execution.</span>
</span><span id="__span-0-535"><a id="__codelineno-0-535" name="__codelineno-0-535"></a><span class="sd"> """</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> </div> </div> <div class="doc doc-object doc-function"> <h6 id="freecad_mcp.bridge.base.FreecadBridge.save_document" class="doc doc-heading"> <code class="highlight language-python"><span class="n">save_document</span><span class="p">(</span><span class="n">doc_name</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">path</span><span class="o">=</span><span class="kc">None</span><span class="p">)</span></code> <span class="doc doc-labels"> <small class="doc doc-label doc-label-abstractmethod"><code>abstractmethod</code></small> <small class="doc doc-label doc-label-async"><code>async</code></small> </span> <a href="#freecad_mcp.bridge.base.FreecadBridge.save_document" class="headerlink" title="Permanent link">¶</a></h6> <div class="doc doc-contents "> <p>Save a document.</p> <p><span class="doc-section-title">Parameters:</span></p> <table> <thead> <tr> <th>Name</th> <th>Type</th> <th>Description</th> <th>Default</th> </tr> </thead> <tbody> <tr class="doc-section-item"> <td> <code>doc_name</code> </td> <td> <code><span title="str">str</span> | None</code> </td> <td> <div class="doc-md-description"> <p>Document name (uses active if None).</p> </div> </td> <td> <code>None</code> </td> </tr> <tr class="doc-section-item"> <td> <code>path</code> </td> <td> <code><span title="str">str</span> | None</code> </td> <td> <div class="doc-md-description"> <p>Save path (uses existing path if None).</p> </div> </td> <td> <code>None</code> </td> </tr> </tbody> </table> <p><span class="doc-section-title">Returns:</span></p> <table> <thead> <tr> <th>Type</th> <th>Description</th> </tr> </thead> <tbody> <tr class="doc-section-item"> <td> <code><span title="str">str</span></code> </td> <td> <div class="doc-md-description"> <p>Path where document was saved.</p> </div> </td> </tr> </tbody> </table> <p><span class="doc-section-title">Raises:</span></p> <table> <thead> <tr> <th>Type</th> <th>Description</th> </tr> </thead> <tbody> <tr class="doc-section-item"> <td> <code><span title="ValueError">ValueError</span></code> </td> <td> <div class="doc-md-description"> <p>If document not found or no path specified for new doc.</p> </div> </td> </tr> </tbody> </table> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/base.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-354">354</a></span>
<span class="normal"><a href="#__codelineno-0-355">355</a></span>
<span class="normal"><a href="#__codelineno-0-356">356</a></span>
<span class="normal"><a href="#__codelineno-0-357">357</a></span>
<span class="normal"><a href="#__codelineno-0-358">358</a></span>
<span class="normal"><a href="#__codelineno-0-359">359</a></span>
<span class="normal"><a href="#__codelineno-0-360">360</a></span>
<span class="normal"><a href="#__codelineno-0-361">361</a></span>
<span class="normal"><a href="#__codelineno-0-362">362</a></span>
<span class="normal"><a href="#__codelineno-0-363">363</a></span>
<span class="normal"><a href="#__codelineno-0-364">364</a></span>
<span class="normal"><a href="#__codelineno-0-365">365</a></span>
<span class="normal"><a href="#__codelineno-0-366">366</a></span>
<span class="normal"><a href="#__codelineno-0-367">367</a></span>
<span class="normal"><a href="#__codelineno-0-368">368</a></span>
<span class="normal"><a href="#__codelineno-0-369">369</a></span>
<span class="normal"><a href="#__codelineno-0-370">370</a></span>
<span class="normal"><a href="#__codelineno-0-371">371</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-354"><a id="__codelineno-0-354" name="__codelineno-0-354"></a><span class="nd">@abstractmethod</span>
</span><span id="__span-0-355"><a id="__codelineno-0-355" name="__codelineno-0-355"></a><span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">save_document</span><span class="p">(</span>
</span><span id="__span-0-356"><a id="__codelineno-0-356" name="__codelineno-0-356"></a> <span class="bp">self</span><span class="p">,</span>
</span><span id="__span-0-357"><a id="__codelineno-0-357" name="__codelineno-0-357"></a> <span class="n">doc_name</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-358"><a id="__codelineno-0-358" name="__codelineno-0-358"></a> <span class="n">path</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-359"><a id="__codelineno-0-359" name="__codelineno-0-359"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">str</span><span class="p">:</span>
</span><span id="__span-0-360"><a id="__codelineno-0-360" name="__codelineno-0-360"></a><span class="w"> </span><span class="sd">"""Save a document.</span>
</span><span id="__span-0-361"><a id="__codelineno-0-361" name="__codelineno-0-361"></a>
</span><span id="__span-0-362"><a id="__codelineno-0-362" name="__codelineno-0-362"></a><span class="sd"> Args:</span>
</span><span id="__span-0-363"><a id="__codelineno-0-363" name="__codelineno-0-363"></a><span class="sd"> doc_name: Document name (uses active if None).</span>
</span><span id="__span-0-364"><a id="__codelineno-0-364" name="__codelineno-0-364"></a><span class="sd"> path: Save path (uses existing path if None).</span>
</span><span id="__span-0-365"><a id="__codelineno-0-365" name="__codelineno-0-365"></a>
</span><span id="__span-0-366"><a id="__codelineno-0-366" name="__codelineno-0-366"></a><span class="sd"> Returns:</span>
</span><span id="__span-0-367"><a id="__codelineno-0-367" name="__codelineno-0-367"></a><span class="sd"> Path where document was saved.</span>
</span><span id="__span-0-368"><a id="__codelineno-0-368" name="__codelineno-0-368"></a>
</span><span id="__span-0-369"><a id="__codelineno-0-369" name="__codelineno-0-369"></a><span class="sd"> Raises:</span>
</span><span id="__span-0-370"><a id="__codelineno-0-370" name="__codelineno-0-370"></a><span class="sd"> ValueError: If document not found or no path specified for new doc.</span>
</span><span id="__span-0-371"><a id="__codelineno-0-371" name="__codelineno-0-371"></a><span class="sd"> """</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> </div> </div> <div class="doc doc-object doc-function"> <h6 id="freecad_mcp.bridge.base.FreecadBridge.set_view" class="doc doc-heading"> <code class="highlight language-python"><span class="n">set_view</span><span class="p">(</span><span class="n">view_angle</span><span class="p">,</span> <span class="n">doc_name</span><span class="o">=</span><span class="kc">None</span><span class="p">)</span></code> <span class="doc doc-labels"> <small class="doc doc-label doc-label-abstractmethod"><code>abstractmethod</code></small> <small class="doc doc-label doc-label-async"><code>async</code></small> </span> <a href="#freecad_mcp.bridge.base.FreecadBridge.set_view" class="headerlink" title="Permanent link">¶</a></h6> <div class="doc doc-contents "> <p>Set the 3D view angle.</p> <p><span class="doc-section-title">Parameters:</span></p> <table> <thead> <tr> <th>Name</th> <th>Type</th> <th>Description</th> <th>Default</th> </tr> </thead> <tbody> <tr class="doc-section-item"> <td> <code>view_angle</code> </td> <td> <code><a class="autorefs autorefs-internal" title="ViewAngle (freecad_mcp.bridge.base.ViewAngle)" href="#freecad_mcp.bridge.base.ViewAngle">ViewAngle</a></code> </td> <td> <div class="doc-md-description"> <p>View angle to set.</p> </div> </td> <td> <em>required</em> </td> </tr> <tr class="doc-section-item"> <td> <code>doc_name</code> </td> <td> <code><span title="str">str</span> | None</code> </td> <td> <div class="doc-md-description"> <p>Document name (uses active if None).</p> </div> </td> <td> <code>None</code> </td> </tr> </tbody> </table> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/base.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-496">496</a></span>
<span class="normal"><a href="#__codelineno-0-497">497</a></span>
<span class="normal"><a href="#__codelineno-0-498">498</a></span>
<span class="normal"><a href="#__codelineno-0-499">499</a></span>
<span class="normal"><a href="#__codelineno-0-500">500</a></span>
<span class="normal"><a href="#__codelineno-0-501">501</a></span>
<span class="normal"><a href="#__codelineno-0-502">502</a></span>
<span class="normal"><a href="#__codelineno-0-503">503</a></span>
<span class="normal"><a href="#__codelineno-0-504">504</a></span>
<span class="normal"><a href="#__codelineno-0-505">505</a></span>
<span class="normal"><a href="#__codelineno-0-506">506</a></span>
<span class="normal"><a href="#__codelineno-0-507">507</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-496"><a id="__codelineno-0-496" name="__codelineno-0-496"></a><span class="nd">@abstractmethod</span>
</span><span id="__span-0-497"><a id="__codelineno-0-497" name="__codelineno-0-497"></a><span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">set_view</span><span class="p">(</span>
</span><span id="__span-0-498"><a id="__codelineno-0-498" name="__codelineno-0-498"></a> <span class="bp">self</span><span class="p">,</span>
</span><span id="__span-0-499"><a id="__codelineno-0-499" name="__codelineno-0-499"></a> <span class="n">view_angle</span><span class="p">:</span> <span class="n">ViewAngle</span><span class="p">,</span>
</span><span id="__span-0-500"><a id="__codelineno-0-500" name="__codelineno-0-500"></a> <span class="n">doc_name</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-501"><a id="__codelineno-0-501" name="__codelineno-0-501"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="kc">None</span><span class="p">:</span>
</span><span id="__span-0-502"><a id="__codelineno-0-502" name="__codelineno-0-502"></a><span class="w"> </span><span class="sd">"""Set the 3D view angle.</span>
</span><span id="__span-0-503"><a id="__codelineno-0-503" name="__codelineno-0-503"></a>
</span><span id="__span-0-504"><a id="__codelineno-0-504" name="__codelineno-0-504"></a><span class="sd"> Args:</span>
</span><span id="__span-0-505"><a id="__codelineno-0-505" name="__codelineno-0-505"></a><span class="sd"> view_angle: View angle to set.</span>
</span><span id="__span-0-506"><a id="__codelineno-0-506" name="__codelineno-0-506"></a><span class="sd"> doc_name: Document name (uses active if None).</span>
</span><span id="__span-0-507"><a id="__codelineno-0-507" name="__codelineno-0-507"></a><span class="sd"> """</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> </div> </div> </div> </div> </div> <div class="doc doc-object doc-class"> <h4 id="freecad_mcp.bridge.base.MacroInfo" class="doc doc-heading"> <code>MacroInfo</code> <span class="doc doc-labels"> <small class="doc doc-label doc-label-dataclass"><code>dataclass</code></small> </span> <a href="#freecad_mcp.bridge.base.MacroInfo" class="headerlink" title="Permanent link">¶</a></h4> <div class="doc doc-contents "> <p>Information about a FreeCAD macro.</p> <p><span class="doc-section-title">Attributes:</span></p> <table> <thead> <tr> <th>Name</th> <th>Type</th> <th>Description</th> </tr> </thead> <tbody> <tr class="doc-section-item"> <td><code><span title="freecad_mcp.bridge.base.MacroInfo.name">name</span></code></td> <td> <code><span title="str">str</span></code> </td> <td> <div class="doc-md-description"> <p>Macro name (without extension).</p> </div> </td> </tr> <tr class="doc-section-item"> <td><code><span title="freecad_mcp.bridge.base.MacroInfo.path">path</span></code></td> <td> <code><span title="str">str</span></code> </td> <td> <div class="doc-md-description"> <p>Full path to macro file.</p> </div> </td> </tr> <tr class="doc-section-item"> <td><code><span title="freecad_mcp.bridge.base.MacroInfo.description">description</span></code></td> <td> <code><span title="str">str</span></code> </td> <td> <div class="doc-md-description"> <p>Macro description from comments.</p> </div> </td> </tr> <tr class="doc-section-item"> <td><code><span title="freecad_mcp.bridge.base.MacroInfo.is_system">is_system</span></code></td> <td> <code><span title="bool">bool</span></code> </td> <td> <div class="doc-md-description"> <p>Whether it's a system macro.</p> </div> </td> </tr> </tbody> </table> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/base.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-172">172</a></span>
<span class="normal"><a href="#__codelineno-0-173">173</a></span>
<span class="normal"><a href="#__codelineno-0-174">174</a></span>
<span class="normal"><a href="#__codelineno-0-175">175</a></span>
<span class="normal"><a href="#__codelineno-0-176">176</a></span>
<span class="normal"><a href="#__codelineno-0-177">177</a></span>
<span class="normal"><a href="#__codelineno-0-178">178</a></span>
<span class="normal"><a href="#__codelineno-0-179">179</a></span>
<span class="normal"><a href="#__codelineno-0-180">180</a></span>
<span class="normal"><a href="#__codelineno-0-181">181</a></span>
<span class="normal"><a href="#__codelineno-0-182">182</a></span>
<span class="normal"><a href="#__codelineno-0-183">183</a></span>
<span class="normal"><a href="#__codelineno-0-184">184</a></span>
<span class="normal"><a href="#__codelineno-0-185">185</a></span>
<span class="normal"><a href="#__codelineno-0-186">186</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-172"><a id="__codelineno-0-172" name="__codelineno-0-172"></a><span class="nd">@dataclass</span>
</span><span id="__span-0-173"><a id="__codelineno-0-173" name="__codelineno-0-173"></a><span class="k">class</span><span class="w"> </span><span class="nc">MacroInfo</span><span class="p">:</span>
</span><span id="__span-0-174"><a id="__codelineno-0-174" name="__codelineno-0-174"></a><span class="w"> </span><span class="sd">"""Information about a FreeCAD macro.</span>
</span><span id="__span-0-175"><a id="__codelineno-0-175" name="__codelineno-0-175"></a>
</span><span id="__span-0-176"><a id="__codelineno-0-176" name="__codelineno-0-176"></a><span class="sd"> Attributes:</span>
</span><span id="__span-0-177"><a id="__codelineno-0-177" name="__codelineno-0-177"></a><span class="sd"> name: Macro name (without extension).</span>
</span><span id="__span-0-178"><a id="__codelineno-0-178" name="__codelineno-0-178"></a><span class="sd"> path: Full path to macro file.</span>
</span><span id="__span-0-179"><a id="__codelineno-0-179" name="__codelineno-0-179"></a><span class="sd"> description: Macro description from comments.</span>
</span><span id="__span-0-180"><a id="__codelineno-0-180" name="__codelineno-0-180"></a><span class="sd"> is_system: Whether it's a system macro.</span>
</span><span id="__span-0-181"><a id="__codelineno-0-181" name="__codelineno-0-181"></a><span class="sd"> """</span>
</span><span id="__span-0-182"><a id="__codelineno-0-182" name="__codelineno-0-182"></a>
</span><span id="__span-0-183"><a id="__codelineno-0-183" name="__codelineno-0-183"></a> <span class="n">name</span><span class="p">:</span> <span class="nb">str</span>
</span><span id="__span-0-184"><a id="__codelineno-0-184" name="__codelineno-0-184"></a> <span class="n">path</span><span class="p">:</span> <span class="nb">str</span>
</span><span id="__span-0-185"><a id="__codelineno-0-185" name="__codelineno-0-185"></a> <span class="n">description</span><span class="p">:</span> <span class="nb">str</span> <span class="o">=</span> <span class="s2">""</span>
</span><span id="__span-0-186"><a id="__codelineno-0-186" name="__codelineno-0-186"></a> <span class="n">is_system</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">False</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> <div class="doc doc-children"> </div> </div> </div> <div class="doc doc-object doc-class"> <h4 id="freecad_mcp.bridge.base.ObjectInfo" class="doc doc-heading"> <code>ObjectInfo</code> <span class="doc doc-labels"> <small class="doc doc-label doc-label-dataclass"><code>dataclass</code></small> </span> <a href="#freecad_mcp.bridge.base.ObjectInfo" class="headerlink" title="Permanent link">¶</a></h4> <div class="doc doc-contents "> <p>Information about a FreeCAD object.</p> <p><span class="doc-section-title">Attributes:</span></p> <table> <thead> <tr> <th>Name</th> <th>Type</th> <th>Description</th> </tr> </thead> <tbody> <tr class="doc-section-item"> <td><code><span title="freecad_mcp.bridge.base.ObjectInfo.name">name</span></code></td> <td> <code><span title="str">str</span></code> </td> <td> <div class="doc-md-description"> <p>Object name (identifier).</p> </div> </td> </tr> <tr class="doc-section-item"> <td><code><span title="freecad_mcp.bridge.base.ObjectInfo.label">label</span></code></td> <td> <code><span title="str">str</span></code> </td> <td> <div class="doc-md-description"> <p>Display label.</p> </div> </td> </tr> <tr class="doc-section-item"> <td><code><span title="freecad_mcp.bridge.base.ObjectInfo.type_id">type_id</span></code></td> <td> <code><span title="str">str</span></code> </td> <td> <div class="doc-md-description"> <p>FreeCAD TypeId string (e.g., "Part::Box").</p> </div> </td> </tr> <tr class="doc-section-item"> <td><code><span title="freecad_mcp.bridge.base.ObjectInfo.properties">properties</span></code></td> <td> <code><span title="dict">dict</span>[<span title="str">str</span>, <span title="typing.Any">Any</span>]</code> </td> <td> <div class="doc-md-description"> <p>Dictionary of property names to values.</p> </div> </td> </tr> <tr class="doc-section-item"> <td><code><span title="freecad_mcp.bridge.base.ObjectInfo.shape_info">shape_info</span></code></td> <td> <code><span title="dict">dict</span>[<span title="str">str</span>, <span title="typing.Any">Any</span>] | None</code> </td> <td> <div class="doc-md-description"> <p>Shape geometry details if applicable.</p> </div> </td> </tr> <tr class="doc-section-item"> <td><code><span title="freecad_mcp.bridge.base.ObjectInfo.children">children</span></code></td> <td> <code><span title="list">list</span>[<span title="str">str</span>]</code> </td> <td> <div class="doc-md-description"> <p>List of child object names (OutList).</p> </div> </td> </tr> <tr class="doc-section-item"> <td><code><span title="freecad_mcp.bridge.base.ObjectInfo.parents">parents</span></code></td> <td> <code><span title="list">list</span>[<span title="str">str</span>]</code> </td> <td> <div class="doc-md-description"> <p>List of parent object names (InList).</p> </div> </td> </tr> <tr class="doc-section-item"> <td><code><span title="freecad_mcp.bridge.base.ObjectInfo.visibility">visibility</span></code></td> <td> <code><span title="bool">bool</span></code> </td> <td> <div class="doc-md-description"> <p>Whether object is visible in the view.</p> </div> </td> </tr> </tbody> </table> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/base.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-93"> 93</a></span>
<span class="normal"><a href="#__codelineno-0-94"> 94</a></span>
<span class="normal"><a href="#__codelineno-0-95"> 95</a></span>
<span class="normal"><a href="#__codelineno-0-96"> 96</a></span>
<span class="normal"><a href="#__codelineno-0-97"> 97</a></span>
<span class="normal"><a href="#__codelineno-0-98"> 98</a></span>
<span class="normal"><a href="#__codelineno-0-99"> 99</a></span>
<span class="normal"><a href="#__codelineno-0-100">100</a></span>
<span class="normal"><a href="#__codelineno-0-101">101</a></span>
<span class="normal"><a href="#__codelineno-0-102">102</a></span>
<span class="normal"><a href="#__codelineno-0-103">103</a></span>
<span class="normal"><a href="#__codelineno-0-104">104</a></span>
<span class="normal"><a href="#__codelineno-0-105">105</a></span>
<span class="normal"><a href="#__codelineno-0-106">106</a></span>
<span class="normal"><a href="#__codelineno-0-107">107</a></span>
<span class="normal"><a href="#__codelineno-0-108">108</a></span>
<span class="normal"><a href="#__codelineno-0-109">109</a></span>
<span class="normal"><a href="#__codelineno-0-110">110</a></span>
<span class="normal"><a href="#__codelineno-0-111">111</a></span>
<span class="normal"><a href="#__codelineno-0-112">112</a></span>
<span class="normal"><a href="#__codelineno-0-113">113</a></span>
<span class="normal"><a href="#__codelineno-0-114">114</a></span>
<span class="normal"><a href="#__codelineno-0-115">115</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-93"><a id="__codelineno-0-93" name="__codelineno-0-93"></a><span class="nd">@dataclass</span>
</span><span id="__span-0-94"><a id="__codelineno-0-94" name="__codelineno-0-94"></a><span class="k">class</span><span class="w"> </span><span class="nc">ObjectInfo</span><span class="p">:</span>
</span><span id="__span-0-95"><a id="__codelineno-0-95" name="__codelineno-0-95"></a><span class="w"> </span><span class="sd">"""Information about a FreeCAD object.</span>
</span><span id="__span-0-96"><a id="__codelineno-0-96" name="__codelineno-0-96"></a>
</span><span id="__span-0-97"><a id="__codelineno-0-97" name="__codelineno-0-97"></a><span class="sd"> Attributes:</span>
</span><span id="__span-0-98"><a id="__codelineno-0-98" name="__codelineno-0-98"></a><span class="sd"> name: Object name (identifier).</span>
</span><span id="__span-0-99"><a id="__codelineno-0-99" name="__codelineno-0-99"></a><span class="sd"> label: Display label.</span>
</span><span id="__span-0-100"><a id="__codelineno-0-100" name="__codelineno-0-100"></a><span class="sd"> type_id: FreeCAD TypeId string (e.g., "Part::Box").</span>
</span><span id="__span-0-101"><a id="__codelineno-0-101" name="__codelineno-0-101"></a><span class="sd"> properties: Dictionary of property names to values.</span>
</span><span id="__span-0-102"><a id="__codelineno-0-102" name="__codelineno-0-102"></a><span class="sd"> shape_info: Shape geometry details if applicable.</span>
</span><span id="__span-0-103"><a id="__codelineno-0-103" name="__codelineno-0-103"></a><span class="sd"> children: List of child object names (OutList).</span>
</span><span id="__span-0-104"><a id="__codelineno-0-104" name="__codelineno-0-104"></a><span class="sd"> parents: List of parent object names (InList).</span>
</span><span id="__span-0-105"><a id="__codelineno-0-105" name="__codelineno-0-105"></a><span class="sd"> visibility: Whether object is visible in the view.</span>
</span><span id="__span-0-106"><a id="__codelineno-0-106" name="__codelineno-0-106"></a><span class="sd"> """</span>
</span><span id="__span-0-107"><a id="__codelineno-0-107" name="__codelineno-0-107"></a>
</span><span id="__span-0-108"><a id="__codelineno-0-108" name="__codelineno-0-108"></a> <span class="n">name</span><span class="p">:</span> <span class="nb">str</span>
</span><span id="__span-0-109"><a id="__codelineno-0-109" name="__codelineno-0-109"></a> <span class="n">label</span><span class="p">:</span> <span class="nb">str</span>
</span><span id="__span-0-110"><a id="__codelineno-0-110" name="__codelineno-0-110"></a> <span class="n">type_id</span><span class="p">:</span> <span class="nb">str</span>
</span><span id="__span-0-111"><a id="__codelineno-0-111" name="__codelineno-0-111"></a> <span class="n">properties</span><span class="p">:</span> <span class="nb">dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Any</span><span class="p">]</span> <span class="o">=</span> <span class="n">field</span><span class="p">(</span><span class="n">default_factory</span><span class="o">=</span><span class="nb">dict</span><span class="p">)</span>
</span><span id="__span-0-112"><a id="__codelineno-0-112" name="__codelineno-0-112"></a> <span class="n">shape_info</span><span class="p">:</span> <span class="nb">dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Any</span><span class="p">]</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span>
</span><span id="__span-0-113"><a id="__codelineno-0-113" name="__codelineno-0-113"></a> <span class="n">children</span><span class="p">:</span> <span class="nb">list</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span> <span class="o">=</span> <span class="n">field</span><span class="p">(</span><span class="n">default_factory</span><span class="o">=</span><span class="nb">list</span><span class="p">)</span>
</span><span id="__span-0-114"><a id="__codelineno-0-114" name="__codelineno-0-114"></a> <span class="n">parents</span><span class="p">:</span> <span class="nb">list</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span> <span class="o">=</span> <span class="n">field</span><span class="p">(</span><span class="n">default_factory</span><span class="o">=</span><span class="nb">list</span><span class="p">)</span>
</span><span id="__span-0-115"><a id="__codelineno-0-115" name="__codelineno-0-115"></a> <span class="n">visibility</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">True</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> <div class="doc doc-children"> </div> </div> </div> <div class="doc doc-object doc-class"> <h4 id="freecad_mcp.bridge.base.ObjectType" class="doc doc-heading"> <code>ObjectType</code> <a href="#freecad_mcp.bridge.base.ObjectType" class="headerlink" title="Permanent link">¶</a></h4> <div class="doc doc-contents "> <p class="doc doc-class-bases"> Bases: <code><span title="str">str</span></code>, <code><span title="enum.Enum">Enum</span></code></p> <p>FreeCAD object type categories.</p> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/base.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-32">32</a></span>
<span class="normal"><a href="#__codelineno-0-33">33</a></span>
<span class="normal"><a href="#__codelineno-0-34">34</a></span>
<span class="normal"><a href="#__codelineno-0-35">35</a></span>
<span class="normal"><a href="#__codelineno-0-36">36</a></span>
<span class="normal"><a href="#__codelineno-0-37">37</a></span>
<span class="normal"><a href="#__codelineno-0-38">38</a></span>
<span class="normal"><a href="#__codelineno-0-39">39</a></span>
<span class="normal"><a href="#__codelineno-0-40">40</a></span>
<span class="normal"><a href="#__codelineno-0-41">41</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-32"><a id="__codelineno-0-32" name="__codelineno-0-32"></a><span class="k">class</span><span class="w"> </span><span class="nc">ObjectType</span><span class="p">(</span><span class="nb">str</span><span class="p">,</span> <span class="n">Enum</span><span class="p">):</span>
</span><span id="__span-0-33"><a id="__codelineno-0-33" name="__codelineno-0-33"></a><span class="w"> </span><span class="sd">"""FreeCAD object type categories."""</span>
</span><span id="__span-0-34"><a id="__codelineno-0-34" name="__codelineno-0-34"></a>
</span><span id="__span-0-35"><a id="__codelineno-0-35" name="__codelineno-0-35"></a> <span class="n">PART</span> <span class="o">=</span> <span class="s2">"Part"</span>
</span><span id="__span-0-36"><a id="__codelineno-0-36" name="__codelineno-0-36"></a> <span class="n">PART_DESIGN</span> <span class="o">=</span> <span class="s2">"PartDesign"</span>
</span><span id="__span-0-37"><a id="__codelineno-0-37" name="__codelineno-0-37"></a> <span class="n">DRAFT</span> <span class="o">=</span> <span class="s2">"Draft"</span>
</span><span id="__span-0-38"><a id="__codelineno-0-38" name="__codelineno-0-38"></a> <span class="n">SKETCHER</span> <span class="o">=</span> <span class="s2">"Sketcher"</span>
</span><span id="__span-0-39"><a id="__codelineno-0-39" name="__codelineno-0-39"></a> <span class="n">FEM</span> <span class="o">=</span> <span class="s2">"Fem"</span>
</span><span id="__span-0-40"><a id="__codelineno-0-40" name="__codelineno-0-40"></a> <span class="n">MESH</span> <span class="o">=</span> <span class="s2">"Mesh"</span>
</span><span id="__span-0-41"><a id="__codelineno-0-41" name="__codelineno-0-41"></a> <span class="n">SPREADSHEET</span> <span class="o">=</span> <span class="s2">"Spreadsheet"</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> <div class="doc doc-children"> </div> </div> </div> <div class="doc doc-object doc-class"> <h4 id="freecad_mcp.bridge.base.ScreenshotResult" class="doc doc-heading"> <code>ScreenshotResult</code> <span class="doc doc-labels"> <small class="doc doc-label doc-label-dataclass"><code>dataclass</code></small> </span> <a href="#freecad_mcp.bridge.base.ScreenshotResult" class="headerlink" title="Permanent link">¶</a></h4> <div class="doc doc-contents "> <p>Result of a screenshot capture.</p> <p><span class="doc-section-title">Attributes:</span></p> <table> <thead> <tr> <th>Name</th> <th>Type</th> <th>Description</th> </tr> </thead> <tbody> <tr class="doc-section-item"> <td><code><span title="freecad_mcp.bridge.base.ScreenshotResult.success">success</span></code></td> <td> <code><span title="bool">bool</span></code> </td> <td> <div class="doc-md-description"> <p>Whether screenshot was captured successfully.</p> </div> </td> </tr> <tr class="doc-section-item"> <td><code><span title="freecad_mcp.bridge.base.ScreenshotResult.data">data</span></code></td> <td> <code><span title="str">str</span> | None</code> </td> <td> <div class="doc-md-description"> <p>Base64-encoded image data.</p> </div> </td> </tr> <tr class="doc-section-item"> <td><code><span title="freecad_mcp.bridge.base.ScreenshotResult.format">format</span></code></td> <td> <code><span title="str">str</span></code> </td> <td> <div class="doc-md-description"> <p>Image format (png, jpg).</p> </div> </td> </tr> <tr class="doc-section-item"> <td><code><span title="freecad_mcp.bridge.base.ScreenshotResult.width">width</span></code></td> <td> <code><span title="int">int</span></code> </td> <td> <div class="doc-md-description"> <p>Image width in pixels.</p> </div> </td> </tr> <tr class="doc-section-item"> <td><code><span title="freecad_mcp.bridge.base.ScreenshotResult.height">height</span></code></td> <td> <code><span title="int">int</span></code> </td> <td> <div class="doc-md-description"> <p>Image height in pixels.</p> </div> </td> </tr> <tr class="doc-section-item"> <td><code><span title="freecad_mcp.bridge.base.ScreenshotResult.view_angle">view_angle</span></code></td> <td> <code><a class="autorefs autorefs-internal" title="ViewAngle (freecad_mcp.bridge.base.ViewAngle)" href="#freecad_mcp.bridge.base.ViewAngle">ViewAngle</a> | None</code> </td> <td> <div class="doc-md-description"> <p>The view angle used.</p> </div> </td> </tr> <tr class="doc-section-item"> <td><code><span title="freecad_mcp.bridge.base.ScreenshotResult.error">error</span></code></td> <td> <code><span title="str">str</span> | None</code> </td> <td> <div class="doc-md-description"> <p>Error message if failed.</p> </div> </td> </tr> </tbody> </table> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/base.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-149">149</a></span>
<span class="normal"><a href="#__codelineno-0-150">150</a></span>
<span class="normal"><a href="#__codelineno-0-151">151</a></span>
<span class="normal"><a href="#__codelineno-0-152">152</a></span>
<span class="normal"><a href="#__codelineno-0-153">153</a></span>
<span class="normal"><a href="#__codelineno-0-154">154</a></span>
<span class="normal"><a href="#__codelineno-0-155">155</a></span>
<span class="normal"><a href="#__codelineno-0-156">156</a></span>
<span class="normal"><a href="#__codelineno-0-157">157</a></span>
<span class="normal"><a href="#__codelineno-0-158">158</a></span>
<span class="normal"><a href="#__codelineno-0-159">159</a></span>
<span class="normal"><a href="#__codelineno-0-160">160</a></span>
<span class="normal"><a href="#__codelineno-0-161">161</a></span>
<span class="normal"><a href="#__codelineno-0-162">162</a></span>
<span class="normal"><a href="#__codelineno-0-163">163</a></span>
<span class="normal"><a href="#__codelineno-0-164">164</a></span>
<span class="normal"><a href="#__codelineno-0-165">165</a></span>
<span class="normal"><a href="#__codelineno-0-166">166</a></span>
<span class="normal"><a href="#__codelineno-0-167">167</a></span>
<span class="normal"><a href="#__codelineno-0-168">168</a></span>
<span class="normal"><a href="#__codelineno-0-169">169</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-149"><a id="__codelineno-0-149" name="__codelineno-0-149"></a><span class="nd">@dataclass</span>
</span><span id="__span-0-150"><a id="__codelineno-0-150" name="__codelineno-0-150"></a><span class="k">class</span><span class="w"> </span><span class="nc">ScreenshotResult</span><span class="p">:</span>
</span><span id="__span-0-151"><a id="__codelineno-0-151" name="__codelineno-0-151"></a><span class="w"> </span><span class="sd">"""Result of a screenshot capture.</span>
</span><span id="__span-0-152"><a id="__codelineno-0-152" name="__codelineno-0-152"></a>
</span><span id="__span-0-153"><a id="__codelineno-0-153" name="__codelineno-0-153"></a><span class="sd"> Attributes:</span>
</span><span id="__span-0-154"><a id="__codelineno-0-154" name="__codelineno-0-154"></a><span class="sd"> success: Whether screenshot was captured successfully.</span>
</span><span id="__span-0-155"><a id="__codelineno-0-155" name="__codelineno-0-155"></a><span class="sd"> data: Base64-encoded image data.</span>
</span><span id="__span-0-156"><a id="__codelineno-0-156" name="__codelineno-0-156"></a><span class="sd"> format: Image format (png, jpg).</span>
</span><span id="__span-0-157"><a id="__codelineno-0-157" name="__codelineno-0-157"></a><span class="sd"> width: Image width in pixels.</span>
</span><span id="__span-0-158"><a id="__codelineno-0-158" name="__codelineno-0-158"></a><span class="sd"> height: Image height in pixels.</span>
</span><span id="__span-0-159"><a id="__codelineno-0-159" name="__codelineno-0-159"></a><span class="sd"> view_angle: The view angle used.</span>
</span><span id="__span-0-160"><a id="__codelineno-0-160" name="__codelineno-0-160"></a><span class="sd"> error: Error message if failed.</span>
</span><span id="__span-0-161"><a id="__codelineno-0-161" name="__codelineno-0-161"></a><span class="sd"> """</span>
</span><span id="__span-0-162"><a id="__codelineno-0-162" name="__codelineno-0-162"></a>
</span><span id="__span-0-163"><a id="__codelineno-0-163" name="__codelineno-0-163"></a> <span class="n">success</span><span class="p">:</span> <span class="nb">bool</span>
</span><span id="__span-0-164"><a id="__codelineno-0-164" name="__codelineno-0-164"></a> <span class="n">data</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span>
</span><span id="__span-0-165"><a id="__codelineno-0-165" name="__codelineno-0-165"></a> <span class="nb">format</span><span class="p">:</span> <span class="nb">str</span> <span class="o">=</span> <span class="s2">"png"</span>
</span><span id="__span-0-166"><a id="__codelineno-0-166" name="__codelineno-0-166"></a> <span class="n">width</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">0</span>
</span><span id="__span-0-167"><a id="__codelineno-0-167" name="__codelineno-0-167"></a> <span class="n">height</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">0</span>
</span><span id="__span-0-168"><a id="__codelineno-0-168" name="__codelineno-0-168"></a> <span class="n">view_angle</span><span class="p">:</span> <span class="n">ViewAngle</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span>
</span><span id="__span-0-169"><a id="__codelineno-0-169" name="__codelineno-0-169"></a> <span class="n">error</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> <div class="doc doc-children"> </div> </div> </div> <div class="doc doc-object doc-class"> <h4 id="freecad_mcp.bridge.base.ShapeInfo" class="doc doc-heading"> <code>ShapeInfo</code> <span class="doc doc-labels"> <small class="doc doc-label doc-label-dataclass"><code>dataclass</code></small> </span> <a href="#freecad_mcp.bridge.base.ShapeInfo" class="headerlink" title="Permanent link">¶</a></h4> <div class="doc doc-contents "> <p>Detailed shape geometry information.</p> <p><span class="doc-section-title">Attributes:</span></p> <table> <thead> <tr> <th>Name</th> <th>Type</th> <th>Description</th> </tr> </thead> <tbody> <tr class="doc-section-item"> <td><code><span title="freecad_mcp.bridge.base.ShapeInfo.shape_type">shape_type</span></code></td> <td> <code><span title="str">str</span></code> </td> <td> <div class="doc-md-description"> <p>Type of shape (Solid, Shell, Face, etc.).</p> </div> </td> </tr> <tr class="doc-section-item"> <td><code><span title="freecad_mcp.bridge.base.ShapeInfo.volume">volume</span></code></td> <td> <code><span title="float">float</span> | None</code> </td> <td> <div class="doc-md-description"> <p>Volume of the shape (for solids).</p> </div> </td> </tr> <tr class="doc-section-item"> <td><code><span title="freecad_mcp.bridge.base.ShapeInfo.area">area</span></code></td> <td> <code><span title="float">float</span> | None</code> </td> <td> <div class="doc-md-description"> <p>Surface area of the shape.</p> </div> </td> </tr> <tr class="doc-section-item"> <td><code><span title="freecad_mcp.bridge.base.ShapeInfo.center_of_mass">center_of_mass</span></code></td> <td> <code><span title="tuple">tuple</span>[<span title="float">float</span>, <span title="float">float</span>, <span title="float">float</span>] | None</code> </td> <td> <div class="doc-md-description"> <p>Center of mass coordinates.</p> </div> </td> </tr> <tr class="doc-section-item"> <td><code><span title="freecad_mcp.bridge.base.ShapeInfo.bounding_box">bounding_box</span></code></td> <td> <code><span title="tuple">tuple</span>[<span title="tuple">tuple</span>[<span title="float">float</span>, <span title="float">float</span>, <span title="float">float</span>], <span title="tuple">tuple</span>[<span title="float">float</span>, <span title="float">float</span>, <span title="float">float</span>]] | None</code> </td> <td> <div class="doc-md-description"> <p>Bounding box as (min, max) tuples.</p> </div> </td> </tr> <tr class="doc-section-item"> <td><code><span title="freecad_mcp.bridge.base.ShapeInfo.is_valid">is_valid</span></code></td> <td> <code><span title="bool">bool</span></code> </td> <td> <div class="doc-md-description"> <p>Whether the shape is geometrically valid.</p> </div> </td> </tr> <tr class="doc-section-item"> <td><code><span title="freecad_mcp.bridge.base.ShapeInfo.is_closed">is_closed</span></code></td> <td> <code><span title="bool">bool</span></code> </td> <td> <div class="doc-md-description"> <p>Whether the shape is closed.</p> </div> </td> </tr> <tr class="doc-section-item"> <td><code><span title="freecad_mcp.bridge.base.ShapeInfo.vertex_count">vertex_count</span></code></td> <td> <code><span title="int">int</span></code> </td> <td> <div class="doc-md-description"> <p>Number of vertices.</p> </div> </td> </tr> <tr class="doc-section-item"> <td><code><span title="freecad_mcp.bridge.base.ShapeInfo.edge_count">edge_count</span></code></td> <td> <code><span title="int">int</span></code> </td> <td> <div class="doc-md-description"> <p>Number of edges.</p> </div> </td> </tr> <tr class="doc-section-item"> <td><code><span title="freecad_mcp.bridge.base.ShapeInfo.face_count">face_count</span></code></td> <td> <code><span title="int">int</span></code> </td> <td> <div class="doc-md-description"> <p>Number of faces.</p> </div> </td> </tr> </tbody> </table> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/base.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-118">118</a></span>
<span class="normal"><a href="#__codelineno-0-119">119</a></span>
<span class="normal"><a href="#__codelineno-0-120">120</a></span>
<span class="normal"><a href="#__codelineno-0-121">121</a></span>
<span class="normal"><a href="#__codelineno-0-122">122</a></span>
<span class="normal"><a href="#__codelineno-0-123">123</a></span>
<span class="normal"><a href="#__codelineno-0-124">124</a></span>
<span class="normal"><a href="#__codelineno-0-125">125</a></span>
<span class="normal"><a href="#__codelineno-0-126">126</a></span>
<span class="normal"><a href="#__codelineno-0-127">127</a></span>
<span class="normal"><a href="#__codelineno-0-128">128</a></span>
<span class="normal"><a href="#__codelineno-0-129">129</a></span>
<span class="normal"><a href="#__codelineno-0-130">130</a></span>
<span class="normal"><a href="#__codelineno-0-131">131</a></span>
<span class="normal"><a href="#__codelineno-0-132">132</a></span>
<span class="normal"><a href="#__codelineno-0-133">133</a></span>
<span class="normal"><a href="#__codelineno-0-134">134</a></span>
<span class="normal"><a href="#__codelineno-0-135">135</a></span>
<span class="normal"><a href="#__codelineno-0-136">136</a></span>
<span class="normal"><a href="#__codelineno-0-137">137</a></span>
<span class="normal"><a href="#__codelineno-0-138">138</a></span>
<span class="normal"><a href="#__codelineno-0-139">139</a></span>
<span class="normal"><a href="#__codelineno-0-140">140</a></span>
<span class="normal"><a href="#__codelineno-0-141">141</a></span>
<span class="normal"><a href="#__codelineno-0-142">142</a></span>
<span class="normal"><a href="#__codelineno-0-143">143</a></span>
<span class="normal"><a href="#__codelineno-0-144">144</a></span>
<span class="normal"><a href="#__codelineno-0-145">145</a></span>
<span class="normal"><a href="#__codelineno-0-146">146</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-118"><a id="__codelineno-0-118" name="__codelineno-0-118"></a><span class="nd">@dataclass</span>
</span><span id="__span-0-119"><a id="__codelineno-0-119" name="__codelineno-0-119"></a><span class="k">class</span><span class="w"> </span><span class="nc">ShapeInfo</span><span class="p">:</span>
</span><span id="__span-0-120"><a id="__codelineno-0-120" name="__codelineno-0-120"></a><span class="w"> </span><span class="sd">"""Detailed shape geometry information.</span>
</span><span id="__span-0-121"><a id="__codelineno-0-121" name="__codelineno-0-121"></a>
</span><span id="__span-0-122"><a id="__codelineno-0-122" name="__codelineno-0-122"></a><span class="sd"> Attributes:</span>
</span><span id="__span-0-123"><a id="__codelineno-0-123" name="__codelineno-0-123"></a><span class="sd"> shape_type: Type of shape (Solid, Shell, Face, etc.).</span>
</span><span id="__span-0-124"><a id="__codelineno-0-124" name="__codelineno-0-124"></a><span class="sd"> volume: Volume of the shape (for solids).</span>
</span><span id="__span-0-125"><a id="__codelineno-0-125" name="__codelineno-0-125"></a><span class="sd"> area: Surface area of the shape.</span>
</span><span id="__span-0-126"><a id="__codelineno-0-126" name="__codelineno-0-126"></a><span class="sd"> center_of_mass: Center of mass coordinates.</span>
</span><span id="__span-0-127"><a id="__codelineno-0-127" name="__codelineno-0-127"></a><span class="sd"> bounding_box: Bounding box as (min, max) tuples.</span>
</span><span id="__span-0-128"><a id="__codelineno-0-128" name="__codelineno-0-128"></a><span class="sd"> is_valid: Whether the shape is geometrically valid.</span>
</span><span id="__span-0-129"><a id="__codelineno-0-129" name="__codelineno-0-129"></a><span class="sd"> is_closed: Whether the shape is closed.</span>
</span><span id="__span-0-130"><a id="__codelineno-0-130" name="__codelineno-0-130"></a><span class="sd"> vertex_count: Number of vertices.</span>
</span><span id="__span-0-131"><a id="__codelineno-0-131" name="__codelineno-0-131"></a><span class="sd"> edge_count: Number of edges.</span>
</span><span id="__span-0-132"><a id="__codelineno-0-132" name="__codelineno-0-132"></a><span class="sd"> face_count: Number of faces.</span>
</span><span id="__span-0-133"><a id="__codelineno-0-133" name="__codelineno-0-133"></a><span class="sd"> """</span>
</span><span id="__span-0-134"><a id="__codelineno-0-134" name="__codelineno-0-134"></a>
</span><span id="__span-0-135"><a id="__codelineno-0-135" name="__codelineno-0-135"></a> <span class="n">shape_type</span><span class="p">:</span> <span class="nb">str</span>
</span><span id="__span-0-136"><a id="__codelineno-0-136" name="__codelineno-0-136"></a> <span class="n">volume</span><span class="p">:</span> <span class="nb">float</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span>
</span><span id="__span-0-137"><a id="__codelineno-0-137" name="__codelineno-0-137"></a> <span class="n">area</span><span class="p">:</span> <span class="nb">float</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span>
</span><span id="__span-0-138"><a id="__codelineno-0-138" name="__codelineno-0-138"></a> <span class="n">center_of_mass</span><span class="p">:</span> <span class="nb">tuple</span><span class="p">[</span><span class="nb">float</span><span class="p">,</span> <span class="nb">float</span><span class="p">,</span> <span class="nb">float</span><span class="p">]</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span>
</span><span id="__span-0-139"><a id="__codelineno-0-139" name="__codelineno-0-139"></a> <span class="n">bounding_box</span><span class="p">:</span> <span class="p">(</span>
</span><span id="__span-0-140"><a id="__codelineno-0-140" name="__codelineno-0-140"></a> <span class="nb">tuple</span><span class="p">[</span><span class="nb">tuple</span><span class="p">[</span><span class="nb">float</span><span class="p">,</span> <span class="nb">float</span><span class="p">,</span> <span class="nb">float</span><span class="p">],</span> <span class="nb">tuple</span><span class="p">[</span><span class="nb">float</span><span class="p">,</span> <span class="nb">float</span><span class="p">,</span> <span class="nb">float</span><span class="p">]]</span> <span class="o">|</span> <span class="kc">None</span>
</span><span id="__span-0-141"><a id="__codelineno-0-141" name="__codelineno-0-141"></a> <span class="p">)</span> <span class="o">=</span> <span class="kc">None</span>
</span><span id="__span-0-142"><a id="__codelineno-0-142" name="__codelineno-0-142"></a> <span class="n">is_valid</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">True</span>
</span><span id="__span-0-143"><a id="__codelineno-0-143" name="__codelineno-0-143"></a> <span class="n">is_closed</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">False</span>
</span><span id="__span-0-144"><a id="__codelineno-0-144" name="__codelineno-0-144"></a> <span class="n">vertex_count</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">0</span>
</span><span id="__span-0-145"><a id="__codelineno-0-145" name="__codelineno-0-145"></a> <span class="n">edge_count</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">0</span>
</span><span id="__span-0-146"><a id="__codelineno-0-146" name="__codelineno-0-146"></a> <span class="n">face_count</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">0</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> <div class="doc doc-children"> </div> </div> </div> <div class="doc doc-object doc-class"> <h4 id="freecad_mcp.bridge.base.ViewAngle" class="doc doc-heading"> <code>ViewAngle</code> <a href="#freecad_mcp.bridge.base.ViewAngle" class="headerlink" title="Permanent link">¶</a></h4> <div class="doc doc-contents "> <p class="doc doc-class-bases"> Bases: <code><span title="str">str</span></code>, <code><span title="enum.Enum">Enum</span></code></p> <p>Standard view angles for screenshots.</p> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/base.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-19">19</a></span>
<span class="normal"><a href="#__codelineno-0-20">20</a></span>
<span class="normal"><a href="#__codelineno-0-21">21</a></span>
<span class="normal"><a href="#__codelineno-0-22">22</a></span>
<span class="normal"><a href="#__codelineno-0-23">23</a></span>
<span class="normal"><a href="#__codelineno-0-24">24</a></span>
<span class="normal"><a href="#__codelineno-0-25">25</a></span>
<span class="normal"><a href="#__codelineno-0-26">26</a></span>
<span class="normal"><a href="#__codelineno-0-27">27</a></span>
<span class="normal"><a href="#__codelineno-0-28">28</a></span>
<span class="normal"><a href="#__codelineno-0-29">29</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-19"><a id="__codelineno-0-19" name="__codelineno-0-19"></a><span class="k">class</span><span class="w"> </span><span class="nc">ViewAngle</span><span class="p">(</span><span class="nb">str</span><span class="p">,</span> <span class="n">Enum</span><span class="p">):</span>
</span><span id="__span-0-20"><a id="__codelineno-0-20" name="__codelineno-0-20"></a><span class="w"> </span><span class="sd">"""Standard view angles for screenshots."""</span>
</span><span id="__span-0-21"><a id="__codelineno-0-21" name="__codelineno-0-21"></a>
</span><span id="__span-0-22"><a id="__codelineno-0-22" name="__codelineno-0-22"></a> <span class="n">ISOMETRIC</span> <span class="o">=</span> <span class="s2">"Isometric"</span>
</span><span id="__span-0-23"><a id="__codelineno-0-23" name="__codelineno-0-23"></a> <span class="n">FRONT</span> <span class="o">=</span> <span class="s2">"Front"</span>
</span><span id="__span-0-24"><a id="__codelineno-0-24" name="__codelineno-0-24"></a> <span class="n">BACK</span> <span class="o">=</span> <span class="s2">"Back"</span>
</span><span id="__span-0-25"><a id="__codelineno-0-25" name="__codelineno-0-25"></a> <span class="n">TOP</span> <span class="o">=</span> <span class="s2">"Top"</span>
</span><span id="__span-0-26"><a id="__codelineno-0-26" name="__codelineno-0-26"></a> <span class="n">BOTTOM</span> <span class="o">=</span> <span class="s2">"Bottom"</span>
</span><span id="__span-0-27"><a id="__codelineno-0-27" name="__codelineno-0-27"></a> <span class="n">LEFT</span> <span class="o">=</span> <span class="s2">"Left"</span>
</span><span id="__span-0-28"><a id="__codelineno-0-28" name="__codelineno-0-28"></a> <span class="n">RIGHT</span> <span class="o">=</span> <span class="s2">"Right"</span>
</span><span id="__span-0-29"><a id="__codelineno-0-29" name="__codelineno-0-29"></a> <span class="n">FIT_ALL</span> <span class="o">=</span> <span class="s2">"FitAll"</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> <div class="doc doc-children"> </div> </div> </div> <div class="doc doc-object doc-class"> <h4 id="freecad_mcp.bridge.base.WorkbenchInfo" class="doc doc-heading"> <code>WorkbenchInfo</code> <span class="doc doc-labels"> <small class="doc doc-label doc-label-dataclass"><code>dataclass</code></small> </span> <a href="#freecad_mcp.bridge.base.WorkbenchInfo" class="headerlink" title="Permanent link">¶</a></h4> <div class="doc doc-contents "> <p>Information about a FreeCAD workbench.</p> <p><span class="doc-section-title">Attributes:</span></p> <table> <thead> <tr> <th>Name</th> <th>Type</th> <th>Description</th> </tr> </thead> <tbody> <tr class="doc-section-item"> <td><code><span title="freecad_mcp.bridge.base.WorkbenchInfo.name">name</span></code></td> <td> <code><span title="str">str</span></code> </td> <td> <div class="doc-md-description"> <p>Workbench internal name.</p> </div> </td> </tr> <tr class="doc-section-item"> <td><code><span title="freecad_mcp.bridge.base.WorkbenchInfo.label">label</span></code></td> <td> <code><span title="str">str</span></code> </td> <td> <div class="doc-md-description"> <p>Display label.</p> </div> </td> </tr> <tr class="doc-section-item"> <td><code><span title="freecad_mcp.bridge.base.WorkbenchInfo.icon">icon</span></code></td> <td> <code><span title="str">str</span></code> </td> <td> <div class="doc-md-description"> <p>Icon resource path.</p> </div> </td> </tr> <tr class="doc-section-item"> <td><code><span title="freecad_mcp.bridge.base.WorkbenchInfo.is_active">is_active</span></code></td> <td> <code><span title="bool">bool</span></code> </td> <td> <div class="doc-md-description"> <p>Whether workbench is currently active.</p> </div> </td> </tr> </tbody> </table> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/base.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-189">189</a></span>
<span class="normal"><a href="#__codelineno-0-190">190</a></span>
<span class="normal"><a href="#__codelineno-0-191">191</a></span>
<span class="normal"><a href="#__codelineno-0-192">192</a></span>
<span class="normal"><a href="#__codelineno-0-193">193</a></span>
<span class="normal"><a href="#__codelineno-0-194">194</a></span>
<span class="normal"><a href="#__codelineno-0-195">195</a></span>
<span class="normal"><a href="#__codelineno-0-196">196</a></span>
<span class="normal"><a href="#__codelineno-0-197">197</a></span>
<span class="normal"><a href="#__codelineno-0-198">198</a></span>
<span class="normal"><a href="#__codelineno-0-199">199</a></span>
<span class="normal"><a href="#__codelineno-0-200">200</a></span>
<span class="normal"><a href="#__codelineno-0-201">201</a></span>
<span class="normal"><a href="#__codelineno-0-202">202</a></span>
<span class="normal"><a href="#__codelineno-0-203">203</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-189"><a id="__codelineno-0-189" name="__codelineno-0-189"></a><span class="nd">@dataclass</span>
</span><span id="__span-0-190"><a id="__codelineno-0-190" name="__codelineno-0-190"></a><span class="k">class</span><span class="w"> </span><span class="nc">WorkbenchInfo</span><span class="p">:</span>
</span><span id="__span-0-191"><a id="__codelineno-0-191" name="__codelineno-0-191"></a><span class="w"> </span><span class="sd">"""Information about a FreeCAD workbench.</span>
</span><span id="__span-0-192"><a id="__codelineno-0-192" name="__codelineno-0-192"></a>
</span><span id="__span-0-193"><a id="__codelineno-0-193" name="__codelineno-0-193"></a><span class="sd"> Attributes:</span>
</span><span id="__span-0-194"><a id="__codelineno-0-194" name="__codelineno-0-194"></a><span class="sd"> name: Workbench internal name.</span>
</span><span id="__span-0-195"><a id="__codelineno-0-195" name="__codelineno-0-195"></a><span class="sd"> label: Display label.</span>
</span><span id="__span-0-196"><a id="__codelineno-0-196" name="__codelineno-0-196"></a><span class="sd"> icon: Icon resource path.</span>
</span><span id="__span-0-197"><a id="__codelineno-0-197" name="__codelineno-0-197"></a><span class="sd"> is_active: Whether workbench is currently active.</span>
</span><span id="__span-0-198"><a id="__codelineno-0-198" name="__codelineno-0-198"></a><span class="sd"> """</span>
</span><span id="__span-0-199"><a id="__codelineno-0-199" name="__codelineno-0-199"></a>
</span><span id="__span-0-200"><a id="__codelineno-0-200" name="__codelineno-0-200"></a> <span class="n">name</span><span class="p">:</span> <span class="nb">str</span>
</span><span id="__span-0-201"><a id="__codelineno-0-201" name="__codelineno-0-201"></a> <span class="n">label</span><span class="p">:</span> <span class="nb">str</span>
</span><span id="__span-0-202"><a id="__codelineno-0-202" name="__codelineno-0-202"></a> <span class="n">icon</span><span class="p">:</span> <span class="nb">str</span> <span class="o">=</span> <span class="s2">""</span>
</span><span id="__span-0-203"><a id="__codelineno-0-203" name="__codelineno-0-203"></a> <span class="n">is_active</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">False</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> <div class="doc doc-children"> </div> </div> </div> </div> </div> </div><p>options: show_root_heading: true show_source: true</p> <h2 id="xml-rpc-bridge">XML-RPC Bridge<a class="headerlink" href="#xml-rpc-bridge" title="Permanent link">¶</a></h2> <div class="doc doc-object doc-module"> <h2 id="freecad_mcp.bridge.xmlrpc" class="doc doc-heading"> <code>freecad_mcp.bridge.xmlrpc</code> <a href="#freecad_mcp.bridge.xmlrpc" class="headerlink" title="Permanent link">¶</a></h2> <div class="doc doc-contents first"> <p>XML-RPC bridge for FreeCAD GUI mode communication.</p> <p>This bridge connects to a FreeCAD instance running an XML-RPC server, allowing remote control while FreeCAD has its GUI open.</p> <p>Compatible with neka-nat/freecad-mcp XML-RPC protocol, providing interoperability with existing FreeCAD Robust MCP addons.</p> <p>Design inspired by neka-nat/freecad-mcp (MIT License): - Uses neka-nat's proven XML-RPC protocol (port 9875) - Connection health monitoring and auto-reconnect - Timeout handling for long operations</p> <details class="attribution" open> <summary>Attribution</summary> <p>The XML-RPC protocol design and port selection (9875) were inspired by neka-nat/freecad-mcp (https://github.com/neka-nat/freecad-mcp), which is licensed under the MIT License. This implementation is a complete rewrite that maintains protocol compatibility.</p> </details> <div class="doc doc-children"> <h3 id="freecad_mcp.bridge.xmlrpc-classes">Classes<a href="#freecad_mcp.bridge.xmlrpc-classes" class="headerlink" title="Permanent link">¶</a></h3> <div class="doc doc-object doc-class"> <h4 id="freecad_mcp.bridge.xmlrpc.XmlRpcBridge" class="doc doc-heading"> <code>XmlRpcBridge</code> <a href="#freecad_mcp.bridge.xmlrpc.XmlRpcBridge" class="headerlink" title="Permanent link">¶</a></h4> <div class="doc doc-contents "> <p class="doc doc-class-bases"> Bases: <code><a class="autorefs autorefs-internal" title="FreecadBridge (freecad_mcp.bridge.base.FreecadBridge)" href="#freecad_mcp.bridge.base.FreecadBridge">FreecadBridge</a></code></p> <p>Bridge that communicates with FreeCAD via XML-RPC.</p> <p>This bridge connects to a FreeCAD instance that is running the XML-RPC server addon. It provides full access to FreeCAD functionality including GUI operations like screenshots.</p> <p><span class="doc-section-title">Attributes:</span></p> <table> <thead> <tr> <th>Name</th> <th>Type</th> <th>Description</th> </tr> </thead> <tbody> <tr class="doc-section-item"> <td><code><span title="freecad_mcp.bridge.xmlrpc.XmlRpcBridge.host">host</span></code></td> <td> </td> <td> <div class="doc-md-description"> <p>XML-RPC server hostname.</p> </div> </td> </tr> <tr class="doc-section-item"> <td><code><span title="freecad_mcp.bridge.xmlrpc.XmlRpcBridge.port">port</span></code></td> <td> </td> <td> <div class="doc-md-description"> <p>XML-RPC server port.</p> </div> </td> </tr> <tr class="doc-section-item"> <td><code><span title="freecad_mcp.bridge.xmlrpc.XmlRpcBridge.timeout">timeout</span></code></td> <td> </td> <td> <div class="doc-md-description"> <p>Connection and request timeout in seconds.</p> </div> </td> </tr> </tbody> </table> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/xmlrpc.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-43"> 43</a></span>
<span class="normal"><a href="#__codelineno-0-44"> 44</a></span>
<span class="normal"><a href="#__codelineno-0-45"> 45</a></span>
<span class="normal"><a href="#__codelineno-0-46"> 46</a></span>
<span class="normal"><a href="#__codelineno-0-47"> 47</a></span>
<span class="normal"><a href="#__codelineno-0-48"> 48</a></span>
<span class="normal"><a href="#__codelineno-0-49"> 49</a></span>
<span class="normal"><a href="#__codelineno-0-50"> 50</a></span>
<span class="normal"><a href="#__codelineno-0-51"> 51</a></span>
<span class="normal"><a href="#__codelineno-0-52"> 52</a></span>
<span class="normal"><a href="#__codelineno-0-53"> 53</a></span>
<span class="normal"><a href="#__codelineno-0-54"> 54</a></span>
<span class="normal"><a href="#__codelineno-0-55"> 55</a></span>
<span class="normal"><a href="#__codelineno-0-56"> 56</a></span>
<span class="normal"><a href="#__codelineno-0-57"> 57</a></span>
<span class="normal"><a href="#__codelineno-0-58"> 58</a></span>
<span class="normal"><a href="#__codelineno-0-59"> 59</a></span>
<span class="normal"><a href="#__codelineno-0-60"> 60</a></span>
<span class="normal"><a href="#__codelineno-0-61"> 61</a></span>
<span class="normal"><a href="#__codelineno-0-62"> 62</a></span>
<span class="normal"><a href="#__codelineno-0-63"> 63</a></span>
<span class="normal"><a href="#__codelineno-0-64"> 64</a></span>
<span class="normal"><a href="#__codelineno-0-65"> 65</a></span>
<span class="normal"><a href="#__codelineno-0-66"> 66</a></span>
<span class="normal"><a href="#__codelineno-0-67"> 67</a></span>
<span class="normal"><a href="#__codelineno-0-68"> 68</a></span>
<span class="normal"><a href="#__codelineno-0-69"> 69</a></span>
<span class="normal"><a href="#__codelineno-0-70"> 70</a></span>
<span class="normal"><a href="#__codelineno-0-71"> 71</a></span>
<span class="normal"><a href="#__codelineno-0-72"> 72</a></span>
<span class="normal"><a href="#__codelineno-0-73"> 73</a></span>
<span class="normal"><a href="#__codelineno-0-74"> 74</a></span>
<span class="normal"><a href="#__codelineno-0-75"> 75</a></span>
<span class="normal"><a href="#__codelineno-0-76"> 76</a></span>
<span class="normal"><a href="#__codelineno-0-77"> 77</a></span>
<span class="normal"><a href="#__codelineno-0-78"> 78</a></span>
<span class="normal"><a href="#__codelineno-0-79"> 79</a></span>
<span class="normal"><a href="#__codelineno-0-80"> 80</a></span>
<span class="normal"><a href="#__codelineno-0-81"> 81</a></span>
<span class="normal"><a href="#__codelineno-0-82"> 82</a></span>
<span class="normal"><a href="#__codelineno-0-83"> 83</a></span>
<span class="normal"><a href="#__codelineno-0-84"> 84</a></span>
<span class="normal"><a href="#__codelineno-0-85"> 85</a></span>
<span class="normal"><a href="#__codelineno-0-86"> 86</a></span>
<span class="normal"><a href="#__codelineno-0-87"> 87</a></span>
<span class="normal"><a href="#__codelineno-0-88"> 88</a></span>
<span class="normal"><a href="#__codelineno-0-89"> 89</a></span>
<span class="normal"><a href="#__codelineno-0-90"> 90</a></span>
<span class="normal"><a href="#__codelineno-0-91"> 91</a></span>
<span class="normal"><a href="#__codelineno-0-92"> 92</a></span>
<span class="normal"><a href="#__codelineno-0-93"> 93</a></span>
<span class="normal"><a href="#__codelineno-0-94"> 94</a></span>
<span class="normal"><a href="#__codelineno-0-95"> 95</a></span>
<span class="normal"><a href="#__codelineno-0-96"> 96</a></span>
<span class="normal"><a href="#__codelineno-0-97"> 97</a></span>
<span class="normal"><a href="#__codelineno-0-98"> 98</a></span>
<span class="normal"><a href="#__codelineno-0-99"> 99</a></span>
<span class="normal"><a href="#__codelineno-0-100"> 100</a></span>
<span class="normal"><a href="#__codelineno-0-101"> 101</a></span>
<span class="normal"><a href="#__codelineno-0-102"> 102</a></span>
<span class="normal"><a href="#__codelineno-0-103"> 103</a></span>
<span class="normal"><a href="#__codelineno-0-104"> 104</a></span>
<span class="normal"><a href="#__codelineno-0-105"> 105</a></span>
<span class="normal"><a href="#__codelineno-0-106"> 106</a></span>
<span class="normal"><a href="#__codelineno-0-107"> 107</a></span>
<span class="normal"><a href="#__codelineno-0-108"> 108</a></span>
<span class="normal"><a href="#__codelineno-0-109"> 109</a></span>
<span class="normal"><a href="#__codelineno-0-110"> 110</a></span>
<span class="normal"><a href="#__codelineno-0-111"> 111</a></span>
<span class="normal"><a href="#__codelineno-0-112"> 112</a></span>
<span class="normal"><a href="#__codelineno-0-113"> 113</a></span>
<span class="normal"><a href="#__codelineno-0-114"> 114</a></span>
<span class="normal"><a href="#__codelineno-0-115"> 115</a></span>
<span class="normal"><a href="#__codelineno-0-116"> 116</a></span>
<span class="normal"><a href="#__codelineno-0-117"> 117</a></span>
<span class="normal"><a href="#__codelineno-0-118"> 118</a></span>
<span class="normal"><a href="#__codelineno-0-119"> 119</a></span>
<span class="normal"><a href="#__codelineno-0-120"> 120</a></span>
<span class="normal"><a href="#__codelineno-0-121"> 121</a></span>
<span class="normal"><a href="#__codelineno-0-122"> 122</a></span>
<span class="normal"><a href="#__codelineno-0-123"> 123</a></span>
<span class="normal"><a href="#__codelineno-0-124"> 124</a></span>
<span class="normal"><a href="#__codelineno-0-125"> 125</a></span>
<span class="normal"><a href="#__codelineno-0-126"> 126</a></span>
<span class="normal"><a href="#__codelineno-0-127"> 127</a></span>
<span class="normal"><a href="#__codelineno-0-128"> 128</a></span>
<span class="normal"><a href="#__codelineno-0-129"> 129</a></span>
<span class="normal"><a href="#__codelineno-0-130"> 130</a></span>
<span class="normal"><a href="#__codelineno-0-131"> 131</a></span>
<span class="normal"><a href="#__codelineno-0-132"> 132</a></span>
<span class="normal"><a href="#__codelineno-0-133"> 133</a></span>
<span class="normal"><a href="#__codelineno-0-134"> 134</a></span>
<span class="normal"><a href="#__codelineno-0-135"> 135</a></span>
<span class="normal"><a href="#__codelineno-0-136"> 136</a></span>
<span class="normal"><a href="#__codelineno-0-137"> 137</a></span>
<span class="normal"><a href="#__codelineno-0-138"> 138</a></span>
<span class="normal"><a href="#__codelineno-0-139"> 139</a></span>
<span class="normal"><a href="#__codelineno-0-140"> 140</a></span>
<span class="normal"><a href="#__codelineno-0-141"> 141</a></span>
<span class="normal"><a href="#__codelineno-0-142"> 142</a></span>
<span class="normal"><a href="#__codelineno-0-143"> 143</a></span>
<span class="normal"><a href="#__codelineno-0-144"> 144</a></span>
<span class="normal"><a href="#__codelineno-0-145"> 145</a></span>
<span class="normal"><a href="#__codelineno-0-146"> 146</a></span>
<span class="normal"><a href="#__codelineno-0-147"> 147</a></span>
<span class="normal"><a href="#__codelineno-0-148"> 148</a></span>
<span class="normal"><a href="#__codelineno-0-149"> 149</a></span>
<span class="normal"><a href="#__codelineno-0-150"> 150</a></span>
<span class="normal"><a href="#__codelineno-0-151"> 151</a></span>
<span class="normal"><a href="#__codelineno-0-152"> 152</a></span>
<span class="normal"><a href="#__codelineno-0-153"> 153</a></span>
<span class="normal"><a href="#__codelineno-0-154"> 154</a></span>
<span class="normal"><a href="#__codelineno-0-155"> 155</a></span>
<span class="normal"><a href="#__codelineno-0-156"> 156</a></span>
<span class="normal"><a href="#__codelineno-0-157"> 157</a></span>
<span class="normal"><a href="#__codelineno-0-158"> 158</a></span>
<span class="normal"><a href="#__codelineno-0-159"> 159</a></span>
<span class="normal"><a href="#__codelineno-0-160"> 160</a></span>
<span class="normal"><a href="#__codelineno-0-161"> 161</a></span>
<span class="normal"><a href="#__codelineno-0-162"> 162</a></span>
<span class="normal"><a href="#__codelineno-0-163"> 163</a></span>
<span class="normal"><a href="#__codelineno-0-164"> 164</a></span>
<span class="normal"><a href="#__codelineno-0-165"> 165</a></span>
<span class="normal"><a href="#__codelineno-0-166"> 166</a></span>
<span class="normal"><a href="#__codelineno-0-167"> 167</a></span>
<span class="normal"><a href="#__codelineno-0-168"> 168</a></span>
<span class="normal"><a href="#__codelineno-0-169"> 169</a></span>
<span class="normal"><a href="#__codelineno-0-170"> 170</a></span>
<span class="normal"><a href="#__codelineno-0-171"> 171</a></span>
<span class="normal"><a href="#__codelineno-0-172"> 172</a></span>
<span class="normal"><a href="#__codelineno-0-173"> 173</a></span>
<span class="normal"><a href="#__codelineno-0-174"> 174</a></span>
<span class="normal"><a href="#__codelineno-0-175"> 175</a></span>
<span class="normal"><a href="#__codelineno-0-176"> 176</a></span>
<span class="normal"><a href="#__codelineno-0-177"> 177</a></span>
<span class="normal"><a href="#__codelineno-0-178"> 178</a></span>
<span class="normal"><a href="#__codelineno-0-179"> 179</a></span>
<span class="normal"><a href="#__codelineno-0-180"> 180</a></span>
<span class="normal"><a href="#__codelineno-0-181"> 181</a></span>
<span class="normal"><a href="#__codelineno-0-182"> 182</a></span>
<span class="normal"><a href="#__codelineno-0-183"> 183</a></span>
<span class="normal"><a href="#__codelineno-0-184"> 184</a></span>
<span class="normal"><a href="#__codelineno-0-185"> 185</a></span>
<span class="normal"><a href="#__codelineno-0-186"> 186</a></span>
<span class="normal"><a href="#__codelineno-0-187"> 187</a></span>
<span class="normal"><a href="#__codelineno-0-188"> 188</a></span>
<span class="normal"><a href="#__codelineno-0-189"> 189</a></span>
<span class="normal"><a href="#__codelineno-0-190"> 190</a></span>
<span class="normal"><a href="#__codelineno-0-191"> 191</a></span>
<span class="normal"><a href="#__codelineno-0-192"> 192</a></span>
<span class="normal"><a href="#__codelineno-0-193"> 193</a></span>
<span class="normal"><a href="#__codelineno-0-194"> 194</a></span>
<span class="normal"><a href="#__codelineno-0-195"> 195</a></span>
<span class="normal"><a href="#__codelineno-0-196"> 196</a></span>
<span class="normal"><a href="#__codelineno-0-197"> 197</a></span>
<span class="normal"><a href="#__codelineno-0-198"> 198</a></span>
<span class="normal"><a href="#__codelineno-0-199"> 199</a></span>
<span class="normal"><a href="#__codelineno-0-200"> 200</a></span>
<span class="normal"><a href="#__codelineno-0-201"> 201</a></span>
<span class="normal"><a href="#__codelineno-0-202"> 202</a></span>
<span class="normal"><a href="#__codelineno-0-203"> 203</a></span>
<span class="normal"><a href="#__codelineno-0-204"> 204</a></span>
<span class="normal"><a href="#__codelineno-0-205"> 205</a></span>
<span class="normal"><a href="#__codelineno-0-206"> 206</a></span>
<span class="normal"><a href="#__codelineno-0-207"> 207</a></span>
<span class="normal"><a href="#__codelineno-0-208"> 208</a></span>
<span class="normal"><a href="#__codelineno-0-209"> 209</a></span>
<span class="normal"><a href="#__codelineno-0-210"> 210</a></span>
<span class="normal"><a href="#__codelineno-0-211"> 211</a></span>
<span class="normal"><a href="#__codelineno-0-212"> 212</a></span>
<span class="normal"><a href="#__codelineno-0-213"> 213</a></span>
<span class="normal"><a href="#__codelineno-0-214"> 214</a></span>
<span class="normal"><a href="#__codelineno-0-215"> 215</a></span>
<span class="normal"><a href="#__codelineno-0-216"> 216</a></span>
<span class="normal"><a href="#__codelineno-0-217"> 217</a></span>
<span class="normal"><a href="#__codelineno-0-218"> 218</a></span>
<span class="normal"><a href="#__codelineno-0-219"> 219</a></span>
<span class="normal"><a href="#__codelineno-0-220"> 220</a></span>
<span class="normal"><a href="#__codelineno-0-221"> 221</a></span>
<span class="normal"><a href="#__codelineno-0-222"> 222</a></span>
<span class="normal"><a href="#__codelineno-0-223"> 223</a></span>
<span class="normal"><a href="#__codelineno-0-224"> 224</a></span>
<span class="normal"><a href="#__codelineno-0-225"> 225</a></span>
<span class="normal"><a href="#__codelineno-0-226"> 226</a></span>
<span class="normal"><a href="#__codelineno-0-227"> 227</a></span>
<span class="normal"><a href="#__codelineno-0-228"> 228</a></span>
<span class="normal"><a href="#__codelineno-0-229"> 229</a></span>
<span class="normal"><a href="#__codelineno-0-230"> 230</a></span>
<span class="normal"><a href="#__codelineno-0-231"> 231</a></span>
<span class="normal"><a href="#__codelineno-0-232"> 232</a></span>
<span class="normal"><a href="#__codelineno-0-233"> 233</a></span>
<span class="normal"><a href="#__codelineno-0-234"> 234</a></span>
<span class="normal"><a href="#__codelineno-0-235"> 235</a></span>
<span class="normal"><a href="#__codelineno-0-236"> 236</a></span>
<span class="normal"><a href="#__codelineno-0-237"> 237</a></span>
<span class="normal"><a href="#__codelineno-0-238"> 238</a></span>
<span class="normal"><a href="#__codelineno-0-239"> 239</a></span>
<span class="normal"><a href="#__codelineno-0-240"> 240</a></span>
<span class="normal"><a href="#__codelineno-0-241"> 241</a></span>
<span class="normal"><a href="#__codelineno-0-242"> 242</a></span>
<span class="normal"><a href="#__codelineno-0-243"> 243</a></span>
<span class="normal"><a href="#__codelineno-0-244"> 244</a></span>
<span class="normal"><a href="#__codelineno-0-245"> 245</a></span>
<span class="normal"><a href="#__codelineno-0-246"> 246</a></span>
<span class="normal"><a href="#__codelineno-0-247"> 247</a></span>
<span class="normal"><a href="#__codelineno-0-248"> 248</a></span>
<span class="normal"><a href="#__codelineno-0-249"> 249</a></span>
<span class="normal"><a href="#__codelineno-0-250"> 250</a></span>
<span class="normal"><a href="#__codelineno-0-251"> 251</a></span>
<span class="normal"><a href="#__codelineno-0-252"> 252</a></span>
<span class="normal"><a href="#__codelineno-0-253"> 253</a></span>
<span class="normal"><a href="#__codelineno-0-254"> 254</a></span>
<span class="normal"><a href="#__codelineno-0-255"> 255</a></span>
<span class="normal"><a href="#__codelineno-0-256"> 256</a></span>
<span class="normal"><a href="#__codelineno-0-257"> 257</a></span>
<span class="normal"><a href="#__codelineno-0-258"> 258</a></span>
<span class="normal"><a href="#__codelineno-0-259"> 259</a></span>
<span class="normal"><a href="#__codelineno-0-260"> 260</a></span>
<span class="normal"><a href="#__codelineno-0-261"> 261</a></span>
<span class="normal"><a href="#__codelineno-0-262"> 262</a></span>
<span class="normal"><a href="#__codelineno-0-263"> 263</a></span>
<span class="normal"><a href="#__codelineno-0-264"> 264</a></span>
<span class="normal"><a href="#__codelineno-0-265"> 265</a></span>
<span class="normal"><a href="#__codelineno-0-266"> 266</a></span>
<span class="normal"><a href="#__codelineno-0-267"> 267</a></span>
<span class="normal"><a href="#__codelineno-0-268"> 268</a></span>
<span class="normal"><a href="#__codelineno-0-269"> 269</a></span>
<span class="normal"><a href="#__codelineno-0-270"> 270</a></span>
<span class="normal"><a href="#__codelineno-0-271"> 271</a></span>
<span class="normal"><a href="#__codelineno-0-272"> 272</a></span>
<span class="normal"><a href="#__codelineno-0-273"> 273</a></span>
<span class="normal"><a href="#__codelineno-0-274"> 274</a></span>
<span class="normal"><a href="#__codelineno-0-275"> 275</a></span>
<span class="normal"><a href="#__codelineno-0-276"> 276</a></span>
<span class="normal"><a href="#__codelineno-0-277"> 277</a></span>
<span class="normal"><a href="#__codelineno-0-278"> 278</a></span>
<span class="normal"><a href="#__codelineno-0-279"> 279</a></span>
<span class="normal"><a href="#__codelineno-0-280"> 280</a></span>
<span class="normal"><a href="#__codelineno-0-281"> 281</a></span>
<span class="normal"><a href="#__codelineno-0-282"> 282</a></span>
<span class="normal"><a href="#__codelineno-0-283"> 283</a></span>
<span class="normal"><a href="#__codelineno-0-284"> 284</a></span>
<span class="normal"><a href="#__codelineno-0-285"> 285</a></span>
<span class="normal"><a href="#__codelineno-0-286"> 286</a></span>
<span class="normal"><a href="#__codelineno-0-287"> 287</a></span>
<span class="normal"><a href="#__codelineno-0-288"> 288</a></span>
<span class="normal"><a href="#__codelineno-0-289"> 289</a></span>
<span class="normal"><a href="#__codelineno-0-290"> 290</a></span>
<span class="normal"><a href="#__codelineno-0-291"> 291</a></span>
<span class="normal"><a href="#__codelineno-0-292"> 292</a></span>
<span class="normal"><a href="#__codelineno-0-293"> 293</a></span>
<span class="normal"><a href="#__codelineno-0-294"> 294</a></span>
<span class="normal"><a href="#__codelineno-0-295"> 295</a></span>
<span class="normal"><a href="#__codelineno-0-296"> 296</a></span>
<span class="normal"><a href="#__codelineno-0-297"> 297</a></span>
<span class="normal"><a href="#__codelineno-0-298"> 298</a></span>
<span class="normal"><a href="#__codelineno-0-299"> 299</a></span>
<span class="normal"><a href="#__codelineno-0-300"> 300</a></span>
<span class="normal"><a href="#__codelineno-0-301"> 301</a></span>
<span class="normal"><a href="#__codelineno-0-302"> 302</a></span>
<span class="normal"><a href="#__codelineno-0-303"> 303</a></span>
<span class="normal"><a href="#__codelineno-0-304"> 304</a></span>
<span class="normal"><a href="#__codelineno-0-305"> 305</a></span>
<span class="normal"><a href="#__codelineno-0-306"> 306</a></span>
<span class="normal"><a href="#__codelineno-0-307"> 307</a></span>
<span class="normal"><a href="#__codelineno-0-308"> 308</a></span>
<span class="normal"><a href="#__codelineno-0-309"> 309</a></span>
<span class="normal"><a href="#__codelineno-0-310"> 310</a></span>
<span class="normal"><a href="#__codelineno-0-311"> 311</a></span>
<span class="normal"><a href="#__codelineno-0-312"> 312</a></span>
<span class="normal"><a href="#__codelineno-0-313"> 313</a></span>
<span class="normal"><a href="#__codelineno-0-314"> 314</a></span>
<span class="normal"><a href="#__codelineno-0-315"> 315</a></span>
<span class="normal"><a href="#__codelineno-0-316"> 316</a></span>
<span class="normal"><a href="#__codelineno-0-317"> 317</a></span>
<span class="normal"><a href="#__codelineno-0-318"> 318</a></span>
<span class="normal"><a href="#__codelineno-0-319"> 319</a></span>
<span class="normal"><a href="#__codelineno-0-320"> 320</a></span>
<span class="normal"><a href="#__codelineno-0-321"> 321</a></span>
<span class="normal"><a href="#__codelineno-0-322"> 322</a></span>
<span class="normal"><a href="#__codelineno-0-323"> 323</a></span>
<span class="normal"><a href="#__codelineno-0-324"> 324</a></span>
<span class="normal"><a href="#__codelineno-0-325"> 325</a></span>
<span class="normal"><a href="#__codelineno-0-326"> 326</a></span>
<span class="normal"><a href="#__codelineno-0-327"> 327</a></span>
<span class="normal"><a href="#__codelineno-0-328"> 328</a></span>
<span class="normal"><a href="#__codelineno-0-329"> 329</a></span>
<span class="normal"><a href="#__codelineno-0-330"> 330</a></span>
<span class="normal"><a href="#__codelineno-0-331"> 331</a></span>
<span class="normal"><a href="#__codelineno-0-332"> 332</a></span>
<span class="normal"><a href="#__codelineno-0-333"> 333</a></span>
<span class="normal"><a href="#__codelineno-0-334"> 334</a></span>
<span class="normal"><a href="#__codelineno-0-335"> 335</a></span>
<span class="normal"><a href="#__codelineno-0-336"> 336</a></span>
<span class="normal"><a href="#__codelineno-0-337"> 337</a></span>
<span class="normal"><a href="#__codelineno-0-338"> 338</a></span>
<span class="normal"><a href="#__codelineno-0-339"> 339</a></span>
<span class="normal"><a href="#__codelineno-0-340"> 340</a></span>
<span class="normal"><a href="#__codelineno-0-341"> 341</a></span>
<span class="normal"><a href="#__codelineno-0-342"> 342</a></span>
<span class="normal"><a href="#__codelineno-0-343"> 343</a></span>
<span class="normal"><a href="#__codelineno-0-344"> 344</a></span>
<span class="normal"><a href="#__codelineno-0-345"> 345</a></span>
<span class="normal"><a href="#__codelineno-0-346"> 346</a></span>
<span class="normal"><a href="#__codelineno-0-347"> 347</a></span>
<span class="normal"><a href="#__codelineno-0-348"> 348</a></span>
<span class="normal"><a href="#__codelineno-0-349"> 349</a></span>
<span class="normal"><a href="#__codelineno-0-350"> 350</a></span>
<span class="normal"><a href="#__codelineno-0-351"> 351</a></span>
<span class="normal"><a href="#__codelineno-0-352"> 352</a></span>
<span class="normal"><a href="#__codelineno-0-353"> 353</a></span>
<span class="normal"><a href="#__codelineno-0-354"> 354</a></span>
<span class="normal"><a href="#__codelineno-0-355"> 355</a></span>
<span class="normal"><a href="#__codelineno-0-356"> 356</a></span>
<span class="normal"><a href="#__codelineno-0-357"> 357</a></span>
<span class="normal"><a href="#__codelineno-0-358"> 358</a></span>
<span class="normal"><a href="#__codelineno-0-359"> 359</a></span>
<span class="normal"><a href="#__codelineno-0-360"> 360</a></span>
<span class="normal"><a href="#__codelineno-0-361"> 361</a></span>
<span class="normal"><a href="#__codelineno-0-362"> 362</a></span>
<span class="normal"><a href="#__codelineno-0-363"> 363</a></span>
<span class="normal"><a href="#__codelineno-0-364"> 364</a></span>
<span class="normal"><a href="#__codelineno-0-365"> 365</a></span>
<span class="normal"><a href="#__codelineno-0-366"> 366</a></span>
<span class="normal"><a href="#__codelineno-0-367"> 367</a></span>
<span class="normal"><a href="#__codelineno-0-368"> 368</a></span>
<span class="normal"><a href="#__codelineno-0-369"> 369</a></span>
<span class="normal"><a href="#__codelineno-0-370"> 370</a></span>
<span class="normal"><a href="#__codelineno-0-371"> 371</a></span>
<span class="normal"><a href="#__codelineno-0-372"> 372</a></span>
<span class="normal"><a href="#__codelineno-0-373"> 373</a></span>
<span class="normal"><a href="#__codelineno-0-374"> 374</a></span>
<span class="normal"><a href="#__codelineno-0-375"> 375</a></span>
<span class="normal"><a href="#__codelineno-0-376"> 376</a></span>
<span class="normal"><a href="#__codelineno-0-377"> 377</a></span>
<span class="normal"><a href="#__codelineno-0-378"> 378</a></span>
<span class="normal"><a href="#__codelineno-0-379"> 379</a></span>
<span class="normal"><a href="#__codelineno-0-380"> 380</a></span>
<span class="normal"><a href="#__codelineno-0-381"> 381</a></span>
<span class="normal"><a href="#__codelineno-0-382"> 382</a></span>
<span class="normal"><a href="#__codelineno-0-383"> 383</a></span>
<span class="normal"><a href="#__codelineno-0-384"> 384</a></span>
<span class="normal"><a href="#__codelineno-0-385"> 385</a></span>
<span class="normal"><a href="#__codelineno-0-386"> 386</a></span>
<span class="normal"><a href="#__codelineno-0-387"> 387</a></span>
<span class="normal"><a href="#__codelineno-0-388"> 388</a></span>
<span class="normal"><a href="#__codelineno-0-389"> 389</a></span>
<span class="normal"><a href="#__codelineno-0-390"> 390</a></span>
<span class="normal"><a href="#__codelineno-0-391"> 391</a></span>
<span class="normal"><a href="#__codelineno-0-392"> 392</a></span>
<span class="normal"><a href="#__codelineno-0-393"> 393</a></span>
<span class="normal"><a href="#__codelineno-0-394"> 394</a></span>
<span class="normal"><a href="#__codelineno-0-395"> 395</a></span>
<span class="normal"><a href="#__codelineno-0-396"> 396</a></span>
<span class="normal"><a href="#__codelineno-0-397"> 397</a></span>
<span class="normal"><a href="#__codelineno-0-398"> 398</a></span>
<span class="normal"><a href="#__codelineno-0-399"> 399</a></span>
<span class="normal"><a href="#__codelineno-0-400"> 400</a></span>
<span class="normal"><a href="#__codelineno-0-401"> 401</a></span>
<span class="normal"><a href="#__codelineno-0-402"> 402</a></span>
<span class="normal"><a href="#__codelineno-0-403"> 403</a></span>
<span class="normal"><a href="#__codelineno-0-404"> 404</a></span>
<span class="normal"><a href="#__codelineno-0-405"> 405</a></span>
<span class="normal"><a href="#__codelineno-0-406"> 406</a></span>
<span class="normal"><a href="#__codelineno-0-407"> 407</a></span>
<span class="normal"><a href="#__codelineno-0-408"> 408</a></span>
<span class="normal"><a href="#__codelineno-0-409"> 409</a></span>
<span class="normal"><a href="#__codelineno-0-410"> 410</a></span>
<span class="normal"><a href="#__codelineno-0-411"> 411</a></span>
<span class="normal"><a href="#__codelineno-0-412"> 412</a></span>
<span class="normal"><a href="#__codelineno-0-413"> 413</a></span>
<span class="normal"><a href="#__codelineno-0-414"> 414</a></span>
<span class="normal"><a href="#__codelineno-0-415"> 415</a></span>
<span class="normal"><a href="#__codelineno-0-416"> 416</a></span>
<span class="normal"><a href="#__codelineno-0-417"> 417</a></span>
<span class="normal"><a href="#__codelineno-0-418"> 418</a></span>
<span class="normal"><a href="#__codelineno-0-419"> 419</a></span>
<span class="normal"><a href="#__codelineno-0-420"> 420</a></span>
<span class="normal"><a href="#__codelineno-0-421"> 421</a></span>
<span class="normal"><a href="#__codelineno-0-422"> 422</a></span>
<span class="normal"><a href="#__codelineno-0-423"> 423</a></span>
<span class="normal"><a href="#__codelineno-0-424"> 424</a></span>
<span class="normal"><a href="#__codelineno-0-425"> 425</a></span>
<span class="normal"><a href="#__codelineno-0-426"> 426</a></span>
<span class="normal"><a href="#__codelineno-0-427"> 427</a></span>
<span class="normal"><a href="#__codelineno-0-428"> 428</a></span>
<span class="normal"><a href="#__codelineno-0-429"> 429</a></span>
<span class="normal"><a href="#__codelineno-0-430"> 430</a></span>
<span class="normal"><a href="#__codelineno-0-431"> 431</a></span>
<span class="normal"><a href="#__codelineno-0-432"> 432</a></span>
<span class="normal"><a href="#__codelineno-0-433"> 433</a></span>
<span class="normal"><a href="#__codelineno-0-434"> 434</a></span>
<span class="normal"><a href="#__codelineno-0-435"> 435</a></span>
<span class="normal"><a href="#__codelineno-0-436"> 436</a></span>
<span class="normal"><a href="#__codelineno-0-437"> 437</a></span>
<span class="normal"><a href="#__codelineno-0-438"> 438</a></span>
<span class="normal"><a href="#__codelineno-0-439"> 439</a></span>
<span class="normal"><a href="#__codelineno-0-440"> 440</a></span>
<span class="normal"><a href="#__codelineno-0-441"> 441</a></span>
<span class="normal"><a href="#__codelineno-0-442"> 442</a></span>
<span class="normal"><a href="#__codelineno-0-443"> 443</a></span>
<span class="normal"><a href="#__codelineno-0-444"> 444</a></span>
<span class="normal"><a href="#__codelineno-0-445"> 445</a></span>
<span class="normal"><a href="#__codelineno-0-446"> 446</a></span>
<span class="normal"><a href="#__codelineno-0-447"> 447</a></span>
<span class="normal"><a href="#__codelineno-0-448"> 448</a></span>
<span class="normal"><a href="#__codelineno-0-449"> 449</a></span>
<span class="normal"><a href="#__codelineno-0-450"> 450</a></span>
<span class="normal"><a href="#__codelineno-0-451"> 451</a></span>
<span class="normal"><a href="#__codelineno-0-452"> 452</a></span>
<span class="normal"><a href="#__codelineno-0-453"> 453</a></span>
<span class="normal"><a href="#__codelineno-0-454"> 454</a></span>
<span class="normal"><a href="#__codelineno-0-455"> 455</a></span>
<span class="normal"><a href="#__codelineno-0-456"> 456</a></span>
<span class="normal"><a href="#__codelineno-0-457"> 457</a></span>
<span class="normal"><a href="#__codelineno-0-458"> 458</a></span>
<span class="normal"><a href="#__codelineno-0-459"> 459</a></span>
<span class="normal"><a href="#__codelineno-0-460"> 460</a></span>
<span class="normal"><a href="#__codelineno-0-461"> 461</a></span>
<span class="normal"><a href="#__codelineno-0-462"> 462</a></span>
<span class="normal"><a href="#__codelineno-0-463"> 463</a></span>
<span class="normal"><a href="#__codelineno-0-464"> 464</a></span>
<span class="normal"><a href="#__codelineno-0-465"> 465</a></span>
<span class="normal"><a href="#__codelineno-0-466"> 466</a></span>
<span class="normal"><a href="#__codelineno-0-467"> 467</a></span>
<span class="normal"><a href="#__codelineno-0-468"> 468</a></span>
<span class="normal"><a href="#__codelineno-0-469"> 469</a></span>
<span class="normal"><a href="#__codelineno-0-470"> 470</a></span>
<span class="normal"><a href="#__codelineno-0-471"> 471</a></span>
<span class="normal"><a href="#__codelineno-0-472"> 472</a></span>
<span class="normal"><a href="#__codelineno-0-473"> 473</a></span>
<span class="normal"><a href="#__codelineno-0-474"> 474</a></span>
<span class="normal"><a href="#__codelineno-0-475"> 475</a></span>
<span class="normal"><a href="#__codelineno-0-476"> 476</a></span>
<span class="normal"><a href="#__codelineno-0-477"> 477</a></span>
<span class="normal"><a href="#__codelineno-0-478"> 478</a></span>
<span class="normal"><a href="#__codelineno-0-479"> 479</a></span>
<span class="normal"><a href="#__codelineno-0-480"> 480</a></span>
<span class="normal"><a href="#__codelineno-0-481"> 481</a></span>
<span class="normal"><a href="#__codelineno-0-482"> 482</a></span>
<span class="normal"><a href="#__codelineno-0-483"> 483</a></span>
<span class="normal"><a href="#__codelineno-0-484"> 484</a></span>
<span class="normal"><a href="#__codelineno-0-485"> 485</a></span>
<span class="normal"><a href="#__codelineno-0-486"> 486</a></span>
<span class="normal"><a href="#__codelineno-0-487"> 487</a></span>
<span class="normal"><a href="#__codelineno-0-488"> 488</a></span>
<span class="normal"><a href="#__codelineno-0-489"> 489</a></span>
<span class="normal"><a href="#__codelineno-0-490"> 490</a></span>
<span class="normal"><a href="#__codelineno-0-491"> 491</a></span>
<span class="normal"><a href="#__codelineno-0-492"> 492</a></span>
<span class="normal"><a href="#__codelineno-0-493"> 493</a></span>
<span class="normal"><a href="#__codelineno-0-494"> 494</a></span>
<span class="normal"><a href="#__codelineno-0-495"> 495</a></span>
<span class="normal"><a href="#__codelineno-0-496"> 496</a></span>
<span class="normal"><a href="#__codelineno-0-497"> 497</a></span>
<span class="normal"><a href="#__codelineno-0-498"> 498</a></span>
<span class="normal"><a href="#__codelineno-0-499"> 499</a></span>
<span class="normal"><a href="#__codelineno-0-500"> 500</a></span>
<span class="normal"><a href="#__codelineno-0-501"> 501</a></span>
<span class="normal"><a href="#__codelineno-0-502"> 502</a></span>
<span class="normal"><a href="#__codelineno-0-503"> 503</a></span>
<span class="normal"><a href="#__codelineno-0-504"> 504</a></span>
<span class="normal"><a href="#__codelineno-0-505"> 505</a></span>
<span class="normal"><a href="#__codelineno-0-506"> 506</a></span>
<span class="normal"><a href="#__codelineno-0-507"> 507</a></span>
<span class="normal"><a href="#__codelineno-0-508"> 508</a></span>
<span class="normal"><a href="#__codelineno-0-509"> 509</a></span>
<span class="normal"><a href="#__codelineno-0-510"> 510</a></span>
<span class="normal"><a href="#__codelineno-0-511"> 511</a></span>
<span class="normal"><a href="#__codelineno-0-512"> 512</a></span>
<span class="normal"><a href="#__codelineno-0-513"> 513</a></span>
<span class="normal"><a href="#__codelineno-0-514"> 514</a></span>
<span class="normal"><a href="#__codelineno-0-515"> 515</a></span>
<span class="normal"><a href="#__codelineno-0-516"> 516</a></span>
<span class="normal"><a href="#__codelineno-0-517"> 517</a></span>
<span class="normal"><a href="#__codelineno-0-518"> 518</a></span>
<span class="normal"><a href="#__codelineno-0-519"> 519</a></span>
<span class="normal"><a href="#__codelineno-0-520"> 520</a></span>
<span class="normal"><a href="#__codelineno-0-521"> 521</a></span>
<span class="normal"><a href="#__codelineno-0-522"> 522</a></span>
<span class="normal"><a href="#__codelineno-0-523"> 523</a></span>
<span class="normal"><a href="#__codelineno-0-524"> 524</a></span>
<span class="normal"><a href="#__codelineno-0-525"> 525</a></span>
<span class="normal"><a href="#__codelineno-0-526"> 526</a></span>
<span class="normal"><a href="#__codelineno-0-527"> 527</a></span>
<span class="normal"><a href="#__codelineno-0-528"> 528</a></span>
<span class="normal"><a href="#__codelineno-0-529"> 529</a></span>
<span class="normal"><a href="#__codelineno-0-530"> 530</a></span>
<span class="normal"><a href="#__codelineno-0-531"> 531</a></span>
<span class="normal"><a href="#__codelineno-0-532"> 532</a></span>
<span class="normal"><a href="#__codelineno-0-533"> 533</a></span>
<span class="normal"><a href="#__codelineno-0-534"> 534</a></span>
<span class="normal"><a href="#__codelineno-0-535"> 535</a></span>
<span class="normal"><a href="#__codelineno-0-536"> 536</a></span>
<span class="normal"><a href="#__codelineno-0-537"> 537</a></span>
<span class="normal"><a href="#__codelineno-0-538"> 538</a></span>
<span class="normal"><a href="#__codelineno-0-539"> 539</a></span>
<span class="normal"><a href="#__codelineno-0-540"> 540</a></span>
<span class="normal"><a href="#__codelineno-0-541"> 541</a></span>
<span class="normal"><a href="#__codelineno-0-542"> 542</a></span>
<span class="normal"><a href="#__codelineno-0-543"> 543</a></span>
<span class="normal"><a href="#__codelineno-0-544"> 544</a></span>
<span class="normal"><a href="#__codelineno-0-545"> 545</a></span>
<span class="normal"><a href="#__codelineno-0-546"> 546</a></span>
<span class="normal"><a href="#__codelineno-0-547"> 547</a></span>
<span class="normal"><a href="#__codelineno-0-548"> 548</a></span>
<span class="normal"><a href="#__codelineno-0-549"> 549</a></span>
<span class="normal"><a href="#__codelineno-0-550"> 550</a></span>
<span class="normal"><a href="#__codelineno-0-551"> 551</a></span>
<span class="normal"><a href="#__codelineno-0-552"> 552</a></span>
<span class="normal"><a href="#__codelineno-0-553"> 553</a></span>
<span class="normal"><a href="#__codelineno-0-554"> 554</a></span>
<span class="normal"><a href="#__codelineno-0-555"> 555</a></span>
<span class="normal"><a href="#__codelineno-0-556"> 556</a></span>
<span class="normal"><a href="#__codelineno-0-557"> 557</a></span>
<span class="normal"><a href="#__codelineno-0-558"> 558</a></span>
<span class="normal"><a href="#__codelineno-0-559"> 559</a></span>
<span class="normal"><a href="#__codelineno-0-560"> 560</a></span>
<span class="normal"><a href="#__codelineno-0-561"> 561</a></span>
<span class="normal"><a href="#__codelineno-0-562"> 562</a></span>
<span class="normal"><a href="#__codelineno-0-563"> 563</a></span>
<span class="normal"><a href="#__codelineno-0-564"> 564</a></span>
<span class="normal"><a href="#__codelineno-0-565"> 565</a></span>
<span class="normal"><a href="#__codelineno-0-566"> 566</a></span>
<span class="normal"><a href="#__codelineno-0-567"> 567</a></span>
<span class="normal"><a href="#__codelineno-0-568"> 568</a></span>
<span class="normal"><a href="#__codelineno-0-569"> 569</a></span>
<span class="normal"><a href="#__codelineno-0-570"> 570</a></span>
<span class="normal"><a href="#__codelineno-0-571"> 571</a></span>
<span class="normal"><a href="#__codelineno-0-572"> 572</a></span>
<span class="normal"><a href="#__codelineno-0-573"> 573</a></span>
<span class="normal"><a href="#__codelineno-0-574"> 574</a></span>
<span class="normal"><a href="#__codelineno-0-575"> 575</a></span>
<span class="normal"><a href="#__codelineno-0-576"> 576</a></span>
<span class="normal"><a href="#__codelineno-0-577"> 577</a></span>
<span class="normal"><a href="#__codelineno-0-578"> 578</a></span>
<span class="normal"><a href="#__codelineno-0-579"> 579</a></span>
<span class="normal"><a href="#__codelineno-0-580"> 580</a></span>
<span class="normal"><a href="#__codelineno-0-581"> 581</a></span>
<span class="normal"><a href="#__codelineno-0-582"> 582</a></span>
<span class="normal"><a href="#__codelineno-0-583"> 583</a></span>
<span class="normal"><a href="#__codelineno-0-584"> 584</a></span>
<span class="normal"><a href="#__codelineno-0-585"> 585</a></span>
<span class="normal"><a href="#__codelineno-0-586"> 586</a></span>
<span class="normal"><a href="#__codelineno-0-587"> 587</a></span>
<span class="normal"><a href="#__codelineno-0-588"> 588</a></span>
<span class="normal"><a href="#__codelineno-0-589"> 589</a></span>
<span class="normal"><a href="#__codelineno-0-590"> 590</a></span>
<span class="normal"><a href="#__codelineno-0-591"> 591</a></span>
<span class="normal"><a href="#__codelineno-0-592"> 592</a></span>
<span class="normal"><a href="#__codelineno-0-593"> 593</a></span>
<span class="normal"><a href="#__codelineno-0-594"> 594</a></span>
<span class="normal"><a href="#__codelineno-0-595"> 595</a></span>
<span class="normal"><a href="#__codelineno-0-596"> 596</a></span>
<span class="normal"><a href="#__codelineno-0-597"> 597</a></span>
<span class="normal"><a href="#__codelineno-0-598"> 598</a></span>
<span class="normal"><a href="#__codelineno-0-599"> 599</a></span>
<span class="normal"><a href="#__codelineno-0-600"> 600</a></span>
<span class="normal"><a href="#__codelineno-0-601"> 601</a></span>
<span class="normal"><a href="#__codelineno-0-602"> 602</a></span>
<span class="normal"><a href="#__codelineno-0-603"> 603</a></span>
<span class="normal"><a href="#__codelineno-0-604"> 604</a></span>
<span class="normal"><a href="#__codelineno-0-605"> 605</a></span>
<span class="normal"><a href="#__codelineno-0-606"> 606</a></span>
<span class="normal"><a href="#__codelineno-0-607"> 607</a></span>
<span class="normal"><a href="#__codelineno-0-608"> 608</a></span>
<span class="normal"><a href="#__codelineno-0-609"> 609</a></span>
<span class="normal"><a href="#__codelineno-0-610"> 610</a></span>
<span class="normal"><a href="#__codelineno-0-611"> 611</a></span>
<span class="normal"><a href="#__codelineno-0-612"> 612</a></span>
<span class="normal"><a href="#__codelineno-0-613"> 613</a></span>
<span class="normal"><a href="#__codelineno-0-614"> 614</a></span>
<span class="normal"><a href="#__codelineno-0-615"> 615</a></span>
<span class="normal"><a href="#__codelineno-0-616"> 616</a></span>
<span class="normal"><a href="#__codelineno-0-617"> 617</a></span>
<span class="normal"><a href="#__codelineno-0-618"> 618</a></span>
<span class="normal"><a href="#__codelineno-0-619"> 619</a></span>
<span class="normal"><a href="#__codelineno-0-620"> 620</a></span>
<span class="normal"><a href="#__codelineno-0-621"> 621</a></span>
<span class="normal"><a href="#__codelineno-0-622"> 622</a></span>
<span class="normal"><a href="#__codelineno-0-623"> 623</a></span>
<span class="normal"><a href="#__codelineno-0-624"> 624</a></span>
<span class="normal"><a href="#__codelineno-0-625"> 625</a></span>
<span class="normal"><a href="#__codelineno-0-626"> 626</a></span>
<span class="normal"><a href="#__codelineno-0-627"> 627</a></span>
<span class="normal"><a href="#__codelineno-0-628"> 628</a></span>
<span class="normal"><a href="#__codelineno-0-629"> 629</a></span>
<span class="normal"><a href="#__codelineno-0-630"> 630</a></span>
<span class="normal"><a href="#__codelineno-0-631"> 631</a></span>
<span class="normal"><a href="#__codelineno-0-632"> 632</a></span>
<span class="normal"><a href="#__codelineno-0-633"> 633</a></span>
<span class="normal"><a href="#__codelineno-0-634"> 634</a></span>
<span class="normal"><a href="#__codelineno-0-635"> 635</a></span>
<span class="normal"><a href="#__codelineno-0-636"> 636</a></span>
<span class="normal"><a href="#__codelineno-0-637"> 637</a></span>
<span class="normal"><a href="#__codelineno-0-638"> 638</a></span>
<span class="normal"><a href="#__codelineno-0-639"> 639</a></span>
<span class="normal"><a href="#__codelineno-0-640"> 640</a></span>
<span class="normal"><a href="#__codelineno-0-641"> 641</a></span>
<span class="normal"><a href="#__codelineno-0-642"> 642</a></span>
<span class="normal"><a href="#__codelineno-0-643"> 643</a></span>
<span class="normal"><a href="#__codelineno-0-644"> 644</a></span>
<span class="normal"><a href="#__codelineno-0-645"> 645</a></span>
<span class="normal"><a href="#__codelineno-0-646"> 646</a></span>
<span class="normal"><a href="#__codelineno-0-647"> 647</a></span>
<span class="normal"><a href="#__codelineno-0-648"> 648</a></span>
<span class="normal"><a href="#__codelineno-0-649"> 649</a></span>
<span class="normal"><a href="#__codelineno-0-650"> 650</a></span>
<span class="normal"><a href="#__codelineno-0-651"> 651</a></span>
<span class="normal"><a href="#__codelineno-0-652"> 652</a></span>
<span class="normal"><a href="#__codelineno-0-653"> 653</a></span>
<span class="normal"><a href="#__codelineno-0-654"> 654</a></span>
<span class="normal"><a href="#__codelineno-0-655"> 655</a></span>
<span class="normal"><a href="#__codelineno-0-656"> 656</a></span>
<span class="normal"><a href="#__codelineno-0-657"> 657</a></span>
<span class="normal"><a href="#__codelineno-0-658"> 658</a></span>
<span class="normal"><a href="#__codelineno-0-659"> 659</a></span>
<span class="normal"><a href="#__codelineno-0-660"> 660</a></span>
<span class="normal"><a href="#__codelineno-0-661"> 661</a></span>
<span class="normal"><a href="#__codelineno-0-662"> 662</a></span>
<span class="normal"><a href="#__codelineno-0-663"> 663</a></span>
<span class="normal"><a href="#__codelineno-0-664"> 664</a></span>
<span class="normal"><a href="#__codelineno-0-665"> 665</a></span>
<span class="normal"><a href="#__codelineno-0-666"> 666</a></span>
<span class="normal"><a href="#__codelineno-0-667"> 667</a></span>
<span class="normal"><a href="#__codelineno-0-668"> 668</a></span>
<span class="normal"><a href="#__codelineno-0-669"> 669</a></span>
<span class="normal"><a href="#__codelineno-0-670"> 670</a></span>
<span class="normal"><a href="#__codelineno-0-671"> 671</a></span>
<span class="normal"><a href="#__codelineno-0-672"> 672</a></span>
<span class="normal"><a href="#__codelineno-0-673"> 673</a></span>
<span class="normal"><a href="#__codelineno-0-674"> 674</a></span>
<span class="normal"><a href="#__codelineno-0-675"> 675</a></span>
<span class="normal"><a href="#__codelineno-0-676"> 676</a></span>
<span class="normal"><a href="#__codelineno-0-677"> 677</a></span>
<span class="normal"><a href="#__codelineno-0-678"> 678</a></span>
<span class="normal"><a href="#__codelineno-0-679"> 679</a></span>
<span class="normal"><a href="#__codelineno-0-680"> 680</a></span>
<span class="normal"><a href="#__codelineno-0-681"> 681</a></span>
<span class="normal"><a href="#__codelineno-0-682"> 682</a></span>
<span class="normal"><a href="#__codelineno-0-683"> 683</a></span>
<span class="normal"><a href="#__codelineno-0-684"> 684</a></span>
<span class="normal"><a href="#__codelineno-0-685"> 685</a></span>
<span class="normal"><a href="#__codelineno-0-686"> 686</a></span>
<span class="normal"><a href="#__codelineno-0-687"> 687</a></span>
<span class="normal"><a href="#__codelineno-0-688"> 688</a></span>
<span class="normal"><a href="#__codelineno-0-689"> 689</a></span>
<span class="normal"><a href="#__codelineno-0-690"> 690</a></span>
<span class="normal"><a href="#__codelineno-0-691"> 691</a></span>
<span class="normal"><a href="#__codelineno-0-692"> 692</a></span>
<span class="normal"><a href="#__codelineno-0-693"> 693</a></span>
<span class="normal"><a href="#__codelineno-0-694"> 694</a></span>
<span class="normal"><a href="#__codelineno-0-695"> 695</a></span>
<span class="normal"><a href="#__codelineno-0-696"> 696</a></span>
<span class="normal"><a href="#__codelineno-0-697"> 697</a></span>
<span class="normal"><a href="#__codelineno-0-698"> 698</a></span>
<span class="normal"><a href="#__codelineno-0-699"> 699</a></span>
<span class="normal"><a href="#__codelineno-0-700"> 700</a></span>
<span class="normal"><a href="#__codelineno-0-701"> 701</a></span>
<span class="normal"><a href="#__codelineno-0-702"> 702</a></span>
<span class="normal"><a href="#__codelineno-0-703"> 703</a></span>
<span class="normal"><a href="#__codelineno-0-704"> 704</a></span>
<span class="normal"><a href="#__codelineno-0-705"> 705</a></span>
<span class="normal"><a href="#__codelineno-0-706"> 706</a></span>
<span class="normal"><a href="#__codelineno-0-707"> 707</a></span>
<span class="normal"><a href="#__codelineno-0-708"> 708</a></span>
<span class="normal"><a href="#__codelineno-0-709"> 709</a></span>
<span class="normal"><a href="#__codelineno-0-710"> 710</a></span>
<span class="normal"><a href="#__codelineno-0-711"> 711</a></span>
<span class="normal"><a href="#__codelineno-0-712"> 712</a></span>
<span class="normal"><a href="#__codelineno-0-713"> 713</a></span>
<span class="normal"><a href="#__codelineno-0-714"> 714</a></span>
<span class="normal"><a href="#__codelineno-0-715"> 715</a></span>
<span class="normal"><a href="#__codelineno-0-716"> 716</a></span>
<span class="normal"><a href="#__codelineno-0-717"> 717</a></span>
<span class="normal"><a href="#__codelineno-0-718"> 718</a></span>
<span class="normal"><a href="#__codelineno-0-719"> 719</a></span>
<span class="normal"><a href="#__codelineno-0-720"> 720</a></span>
<span class="normal"><a href="#__codelineno-0-721"> 721</a></span>
<span class="normal"><a href="#__codelineno-0-722"> 722</a></span>
<span class="normal"><a href="#__codelineno-0-723"> 723</a></span>
<span class="normal"><a href="#__codelineno-0-724"> 724</a></span>
<span class="normal"><a href="#__codelineno-0-725"> 725</a></span>
<span class="normal"><a href="#__codelineno-0-726"> 726</a></span>
<span class="normal"><a href="#__codelineno-0-727"> 727</a></span>
<span class="normal"><a href="#__codelineno-0-728"> 728</a></span>
<span class="normal"><a href="#__codelineno-0-729"> 729</a></span>
<span class="normal"><a href="#__codelineno-0-730"> 730</a></span>
<span class="normal"><a href="#__codelineno-0-731"> 731</a></span>
<span class="normal"><a href="#__codelineno-0-732"> 732</a></span>
<span class="normal"><a href="#__codelineno-0-733"> 733</a></span>
<span class="normal"><a href="#__codelineno-0-734"> 734</a></span>
<span class="normal"><a href="#__codelineno-0-735"> 735</a></span>
<span class="normal"><a href="#__codelineno-0-736"> 736</a></span>
<span class="normal"><a href="#__codelineno-0-737"> 737</a></span>
<span class="normal"><a href="#__codelineno-0-738"> 738</a></span>
<span class="normal"><a href="#__codelineno-0-739"> 739</a></span>
<span class="normal"><a href="#__codelineno-0-740"> 740</a></span>
<span class="normal"><a href="#__codelineno-0-741"> 741</a></span>
<span class="normal"><a href="#__codelineno-0-742"> 742</a></span>
<span class="normal"><a href="#__codelineno-0-743"> 743</a></span>
<span class="normal"><a href="#__codelineno-0-744"> 744</a></span>
<span class="normal"><a href="#__codelineno-0-745"> 745</a></span>
<span class="normal"><a href="#__codelineno-0-746"> 746</a></span>
<span class="normal"><a href="#__codelineno-0-747"> 747</a></span>
<span class="normal"><a href="#__codelineno-0-748"> 748</a></span>
<span class="normal"><a href="#__codelineno-0-749"> 749</a></span>
<span class="normal"><a href="#__codelineno-0-750"> 750</a></span>
<span class="normal"><a href="#__codelineno-0-751"> 751</a></span>
<span class="normal"><a href="#__codelineno-0-752"> 752</a></span>
<span class="normal"><a href="#__codelineno-0-753"> 753</a></span>
<span class="normal"><a href="#__codelineno-0-754"> 754</a></span>
<span class="normal"><a href="#__codelineno-0-755"> 755</a></span>
<span class="normal"><a href="#__codelineno-0-756"> 756</a></span>
<span class="normal"><a href="#__codelineno-0-757"> 757</a></span>
<span class="normal"><a href="#__codelineno-0-758"> 758</a></span>
<span class="normal"><a href="#__codelineno-0-759"> 759</a></span>
<span class="normal"><a href="#__codelineno-0-760"> 760</a></span>
<span class="normal"><a href="#__codelineno-0-761"> 761</a></span>
<span class="normal"><a href="#__codelineno-0-762"> 762</a></span>
<span class="normal"><a href="#__codelineno-0-763"> 763</a></span>
<span class="normal"><a href="#__codelineno-0-764"> 764</a></span>
<span class="normal"><a href="#__codelineno-0-765"> 765</a></span>
<span class="normal"><a href="#__codelineno-0-766"> 766</a></span>
<span class="normal"><a href="#__codelineno-0-767"> 767</a></span>
<span class="normal"><a href="#__codelineno-0-768"> 768</a></span>
<span class="normal"><a href="#__codelineno-0-769"> 769</a></span>
<span class="normal"><a href="#__codelineno-0-770"> 770</a></span>
<span class="normal"><a href="#__codelineno-0-771"> 771</a></span>
<span class="normal"><a href="#__codelineno-0-772"> 772</a></span>
<span class="normal"><a href="#__codelineno-0-773"> 773</a></span>
<span class="normal"><a href="#__codelineno-0-774"> 774</a></span>
<span class="normal"><a href="#__codelineno-0-775"> 775</a></span>
<span class="normal"><a href="#__codelineno-0-776"> 776</a></span>
<span class="normal"><a href="#__codelineno-0-777"> 777</a></span>
<span class="normal"><a href="#__codelineno-0-778"> 778</a></span>
<span class="normal"><a href="#__codelineno-0-779"> 779</a></span>
<span class="normal"><a href="#__codelineno-0-780"> 780</a></span>
<span class="normal"><a href="#__codelineno-0-781"> 781</a></span>
<span class="normal"><a href="#__codelineno-0-782"> 782</a></span>
<span class="normal"><a href="#__codelineno-0-783"> 783</a></span>
<span class="normal"><a href="#__codelineno-0-784"> 784</a></span>
<span class="normal"><a href="#__codelineno-0-785"> 785</a></span>
<span class="normal"><a href="#__codelineno-0-786"> 786</a></span>
<span class="normal"><a href="#__codelineno-0-787"> 787</a></span>
<span class="normal"><a href="#__codelineno-0-788"> 788</a></span>
<span class="normal"><a href="#__codelineno-0-789"> 789</a></span>
<span class="normal"><a href="#__codelineno-0-790"> 790</a></span>
<span class="normal"><a href="#__codelineno-0-791"> 791</a></span>
<span class="normal"><a href="#__codelineno-0-792"> 792</a></span>
<span class="normal"><a href="#__codelineno-0-793"> 793</a></span>
<span class="normal"><a href="#__codelineno-0-794"> 794</a></span>
<span class="normal"><a href="#__codelineno-0-795"> 795</a></span>
<span class="normal"><a href="#__codelineno-0-796"> 796</a></span>
<span class="normal"><a href="#__codelineno-0-797"> 797</a></span>
<span class="normal"><a href="#__codelineno-0-798"> 798</a></span>
<span class="normal"><a href="#__codelineno-0-799"> 799</a></span>
<span class="normal"><a href="#__codelineno-0-800"> 800</a></span>
<span class="normal"><a href="#__codelineno-0-801"> 801</a></span>
<span class="normal"><a href="#__codelineno-0-802"> 802</a></span>
<span class="normal"><a href="#__codelineno-0-803"> 803</a></span>
<span class="normal"><a href="#__codelineno-0-804"> 804</a></span>
<span class="normal"><a href="#__codelineno-0-805"> 805</a></span>
<span class="normal"><a href="#__codelineno-0-806"> 806</a></span>
<span class="normal"><a href="#__codelineno-0-807"> 807</a></span>
<span class="normal"><a href="#__codelineno-0-808"> 808</a></span>
<span class="normal"><a href="#__codelineno-0-809"> 809</a></span>
<span class="normal"><a href="#__codelineno-0-810"> 810</a></span>
<span class="normal"><a href="#__codelineno-0-811"> 811</a></span>
<span class="normal"><a href="#__codelineno-0-812"> 812</a></span>
<span class="normal"><a href="#__codelineno-0-813"> 813</a></span>
<span class="normal"><a href="#__codelineno-0-814"> 814</a></span>
<span class="normal"><a href="#__codelineno-0-815"> 815</a></span>
<span class="normal"><a href="#__codelineno-0-816"> 816</a></span>
<span class="normal"><a href="#__codelineno-0-817"> 817</a></span>
<span class="normal"><a href="#__codelineno-0-818"> 818</a></span>
<span class="normal"><a href="#__codelineno-0-819"> 819</a></span>
<span class="normal"><a href="#__codelineno-0-820"> 820</a></span>
<span class="normal"><a href="#__codelineno-0-821"> 821</a></span>
<span class="normal"><a href="#__codelineno-0-822"> 822</a></span>
<span class="normal"><a href="#__codelineno-0-823"> 823</a></span>
<span class="normal"><a href="#__codelineno-0-824"> 824</a></span>
<span class="normal"><a href="#__codelineno-0-825"> 825</a></span>
<span class="normal"><a href="#__codelineno-0-826"> 826</a></span>
<span class="normal"><a href="#__codelineno-0-827"> 827</a></span>
<span class="normal"><a href="#__codelineno-0-828"> 828</a></span>
<span class="normal"><a href="#__codelineno-0-829"> 829</a></span>
<span class="normal"><a href="#__codelineno-0-830"> 830</a></span>
<span class="normal"><a href="#__codelineno-0-831"> 831</a></span>
<span class="normal"><a href="#__codelineno-0-832"> 832</a></span>
<span class="normal"><a href="#__codelineno-0-833"> 833</a></span>
<span class="normal"><a href="#__codelineno-0-834"> 834</a></span>
<span class="normal"><a href="#__codelineno-0-835"> 835</a></span>
<span class="normal"><a href="#__codelineno-0-836"> 836</a></span>
<span class="normal"><a href="#__codelineno-0-837"> 837</a></span>
<span class="normal"><a href="#__codelineno-0-838"> 838</a></span>
<span class="normal"><a href="#__codelineno-0-839"> 839</a></span>
<span class="normal"><a href="#__codelineno-0-840"> 840</a></span>
<span class="normal"><a href="#__codelineno-0-841"> 841</a></span>
<span class="normal"><a href="#__codelineno-0-842"> 842</a></span>
<span class="normal"><a href="#__codelineno-0-843"> 843</a></span>
<span class="normal"><a href="#__codelineno-0-844"> 844</a></span>
<span class="normal"><a href="#__codelineno-0-845"> 845</a></span>
<span class="normal"><a href="#__codelineno-0-846"> 846</a></span>
<span class="normal"><a href="#__codelineno-0-847"> 847</a></span>
<span class="normal"><a href="#__codelineno-0-848"> 848</a></span>
<span class="normal"><a href="#__codelineno-0-849"> 849</a></span>
<span class="normal"><a href="#__codelineno-0-850"> 850</a></span>
<span class="normal"><a href="#__codelineno-0-851"> 851</a></span>
<span class="normal"><a href="#__codelineno-0-852"> 852</a></span>
<span class="normal"><a href="#__codelineno-0-853"> 853</a></span>
<span class="normal"><a href="#__codelineno-0-854"> 854</a></span>
<span class="normal"><a href="#__codelineno-0-855"> 855</a></span>
<span class="normal"><a href="#__codelineno-0-856"> 856</a></span>
<span class="normal"><a href="#__codelineno-0-857"> 857</a></span>
<span class="normal"><a href="#__codelineno-0-858"> 858</a></span>
<span class="normal"><a href="#__codelineno-0-859"> 859</a></span>
<span class="normal"><a href="#__codelineno-0-860"> 860</a></span>
<span class="normal"><a href="#__codelineno-0-861"> 861</a></span>
<span class="normal"><a href="#__codelineno-0-862"> 862</a></span>
<span class="normal"><a href="#__codelineno-0-863"> 863</a></span>
<span class="normal"><a href="#__codelineno-0-864"> 864</a></span>
<span class="normal"><a href="#__codelineno-0-865"> 865</a></span>
<span class="normal"><a href="#__codelineno-0-866"> 866</a></span>
<span class="normal"><a href="#__codelineno-0-867"> 867</a></span>
<span class="normal"><a href="#__codelineno-0-868"> 868</a></span>
<span class="normal"><a href="#__codelineno-0-869"> 869</a></span>
<span class="normal"><a href="#__codelineno-0-870"> 870</a></span>
<span class="normal"><a href="#__codelineno-0-871"> 871</a></span>
<span class="normal"><a href="#__codelineno-0-872"> 872</a></span>
<span class="normal"><a href="#__codelineno-0-873"> 873</a></span>
<span class="normal"><a href="#__codelineno-0-874"> 874</a></span>
<span class="normal"><a href="#__codelineno-0-875"> 875</a></span>
<span class="normal"><a href="#__codelineno-0-876"> 876</a></span>
<span class="normal"><a href="#__codelineno-0-877"> 877</a></span>
<span class="normal"><a href="#__codelineno-0-878"> 878</a></span>
<span class="normal"><a href="#__codelineno-0-879"> 879</a></span>
<span class="normal"><a href="#__codelineno-0-880"> 880</a></span>
<span class="normal"><a href="#__codelineno-0-881"> 881</a></span>
<span class="normal"><a href="#__codelineno-0-882"> 882</a></span>
<span class="normal"><a href="#__codelineno-0-883"> 883</a></span>
<span class="normal"><a href="#__codelineno-0-884"> 884</a></span>
<span class="normal"><a href="#__codelineno-0-885"> 885</a></span>
<span class="normal"><a href="#__codelineno-0-886"> 886</a></span>
<span class="normal"><a href="#__codelineno-0-887"> 887</a></span>
<span class="normal"><a href="#__codelineno-0-888"> 888</a></span>
<span class="normal"><a href="#__codelineno-0-889"> 889</a></span>
<span class="normal"><a href="#__codelineno-0-890"> 890</a></span>
<span class="normal"><a href="#__codelineno-0-891"> 891</a></span>
<span class="normal"><a href="#__codelineno-0-892"> 892</a></span>
<span class="normal"><a href="#__codelineno-0-893"> 893</a></span>
<span class="normal"><a href="#__codelineno-0-894"> 894</a></span>
<span class="normal"><a href="#__codelineno-0-895"> 895</a></span>
<span class="normal"><a href="#__codelineno-0-896"> 896</a></span>
<span class="normal"><a href="#__codelineno-0-897"> 897</a></span>
<span class="normal"><a href="#__codelineno-0-898"> 898</a></span>
<span class="normal"><a href="#__codelineno-0-899"> 899</a></span>
<span class="normal"><a href="#__codelineno-0-900"> 900</a></span>
<span class="normal"><a href="#__codelineno-0-901"> 901</a></span>
<span class="normal"><a href="#__codelineno-0-902"> 902</a></span>
<span class="normal"><a href="#__codelineno-0-903"> 903</a></span>
<span class="normal"><a href="#__codelineno-0-904"> 904</a></span>
<span class="normal"><a href="#__codelineno-0-905"> 905</a></span>
<span class="normal"><a href="#__codelineno-0-906"> 906</a></span>
<span class="normal"><a href="#__codelineno-0-907"> 907</a></span>
<span class="normal"><a href="#__codelineno-0-908"> 908</a></span>
<span class="normal"><a href="#__codelineno-0-909"> 909</a></span>
<span class="normal"><a href="#__codelineno-0-910"> 910</a></span>
<span class="normal"><a href="#__codelineno-0-911"> 911</a></span>
<span class="normal"><a href="#__codelineno-0-912"> 912</a></span>
<span class="normal"><a href="#__codelineno-0-913"> 913</a></span>
<span class="normal"><a href="#__codelineno-0-914"> 914</a></span>
<span class="normal"><a href="#__codelineno-0-915"> 915</a></span>
<span class="normal"><a href="#__codelineno-0-916"> 916</a></span>
<span class="normal"><a href="#__codelineno-0-917"> 917</a></span>
<span class="normal"><a href="#__codelineno-0-918"> 918</a></span>
<span class="normal"><a href="#__codelineno-0-919"> 919</a></span>
<span class="normal"><a href="#__codelineno-0-920"> 920</a></span>
<span class="normal"><a href="#__codelineno-0-921"> 921</a></span>
<span class="normal"><a href="#__codelineno-0-922"> 922</a></span>
<span class="normal"><a href="#__codelineno-0-923"> 923</a></span>
<span class="normal"><a href="#__codelineno-0-924"> 924</a></span>
<span class="normal"><a href="#__codelineno-0-925"> 925</a></span>
<span class="normal"><a href="#__codelineno-0-926"> 926</a></span>
<span class="normal"><a href="#__codelineno-0-927"> 927</a></span>
<span class="normal"><a href="#__codelineno-0-928"> 928</a></span>
<span class="normal"><a href="#__codelineno-0-929"> 929</a></span>
<span class="normal"><a href="#__codelineno-0-930"> 930</a></span>
<span class="normal"><a href="#__codelineno-0-931"> 931</a></span>
<span class="normal"><a href="#__codelineno-0-932"> 932</a></span>
<span class="normal"><a href="#__codelineno-0-933"> 933</a></span>
<span class="normal"><a href="#__codelineno-0-934"> 934</a></span>
<span class="normal"><a href="#__codelineno-0-935"> 935</a></span>
<span class="normal"><a href="#__codelineno-0-936"> 936</a></span>
<span class="normal"><a href="#__codelineno-0-937"> 937</a></span>
<span class="normal"><a href="#__codelineno-0-938"> 938</a></span>
<span class="normal"><a href="#__codelineno-0-939"> 939</a></span>
<span class="normal"><a href="#__codelineno-0-940"> 940</a></span>
<span class="normal"><a href="#__codelineno-0-941"> 941</a></span>
<span class="normal"><a href="#__codelineno-0-942"> 942</a></span>
<span class="normal"><a href="#__codelineno-0-943"> 943</a></span>
<span class="normal"><a href="#__codelineno-0-944"> 944</a></span>
<span class="normal"><a href="#__codelineno-0-945"> 945</a></span>
<span class="normal"><a href="#__codelineno-0-946"> 946</a></span>
<span class="normal"><a href="#__codelineno-0-947"> 947</a></span>
<span class="normal"><a href="#__codelineno-0-948"> 948</a></span>
<span class="normal"><a href="#__codelineno-0-949"> 949</a></span>
<span class="normal"><a href="#__codelineno-0-950"> 950</a></span>
<span class="normal"><a href="#__codelineno-0-951"> 951</a></span>
<span class="normal"><a href="#__codelineno-0-952"> 952</a></span>
<span class="normal"><a href="#__codelineno-0-953"> 953</a></span>
<span class="normal"><a href="#__codelineno-0-954"> 954</a></span>
<span class="normal"><a href="#__codelineno-0-955"> 955</a></span>
<span class="normal"><a href="#__codelineno-0-956"> 956</a></span>
<span class="normal"><a href="#__codelineno-0-957"> 957</a></span>
<span class="normal"><a href="#__codelineno-0-958"> 958</a></span>
<span class="normal"><a href="#__codelineno-0-959"> 959</a></span>
<span class="normal"><a href="#__codelineno-0-960"> 960</a></span>
<span class="normal"><a href="#__codelineno-0-961"> 961</a></span>
<span class="normal"><a href="#__codelineno-0-962"> 962</a></span>
<span class="normal"><a href="#__codelineno-0-963"> 963</a></span>
<span class="normal"><a href="#__codelineno-0-964"> 964</a></span>
<span class="normal"><a href="#__codelineno-0-965"> 965</a></span>
<span class="normal"><a href="#__codelineno-0-966"> 966</a></span>
<span class="normal"><a href="#__codelineno-0-967"> 967</a></span>
<span class="normal"><a href="#__codelineno-0-968"> 968</a></span>
<span class="normal"><a href="#__codelineno-0-969"> 969</a></span>
<span class="normal"><a href="#__codelineno-0-970"> 970</a></span>
<span class="normal"><a href="#__codelineno-0-971"> 971</a></span>
<span class="normal"><a href="#__codelineno-0-972"> 972</a></span>
<span class="normal"><a href="#__codelineno-0-973"> 973</a></span>
<span class="normal"><a href="#__codelineno-0-974"> 974</a></span>
<span class="normal"><a href="#__codelineno-0-975"> 975</a></span>
<span class="normal"><a href="#__codelineno-0-976"> 976</a></span>
<span class="normal"><a href="#__codelineno-0-977"> 977</a></span>
<span class="normal"><a href="#__codelineno-0-978"> 978</a></span>
<span class="normal"><a href="#__codelineno-0-979"> 979</a></span>
<span class="normal"><a href="#__codelineno-0-980"> 980</a></span>
<span class="normal"><a href="#__codelineno-0-981"> 981</a></span>
<span class="normal"><a href="#__codelineno-0-982"> 982</a></span>
<span class="normal"><a href="#__codelineno-0-983"> 983</a></span>
<span class="normal"><a href="#__codelineno-0-984"> 984</a></span>
<span class="normal"><a href="#__codelineno-0-985"> 985</a></span>
<span class="normal"><a href="#__codelineno-0-986"> 986</a></span>
<span class="normal"><a href="#__codelineno-0-987"> 987</a></span>
<span class="normal"><a href="#__codelineno-0-988"> 988</a></span>
<span class="normal"><a href="#__codelineno-0-989"> 989</a></span>
<span class="normal"><a href="#__codelineno-0-990"> 990</a></span>
<span class="normal"><a href="#__codelineno-0-991"> 991</a></span>
<span class="normal"><a href="#__codelineno-0-992"> 992</a></span>
<span class="normal"><a href="#__codelineno-0-993"> 993</a></span>
<span class="normal"><a href="#__codelineno-0-994"> 994</a></span>
<span class="normal"><a href="#__codelineno-0-995"> 995</a></span>
<span class="normal"><a href="#__codelineno-0-996"> 996</a></span>
<span class="normal"><a href="#__codelineno-0-997"> 997</a></span>
<span class="normal"><a href="#__codelineno-0-998"> 998</a></span>
<span class="normal"><a href="#__codelineno-0-999"> 999</a></span>
<span class="normal"><a href="#__codelineno-0-1000">1000</a></span>
<span class="normal"><a href="#__codelineno-0-1001">1001</a></span>
<span class="normal"><a href="#__codelineno-0-1002">1002</a></span>
<span class="normal"><a href="#__codelineno-0-1003">1003</a></span>
<span class="normal"><a href="#__codelineno-0-1004">1004</a></span>
<span class="normal"><a href="#__codelineno-0-1005">1005</a></span>
<span class="normal"><a href="#__codelineno-0-1006">1006</a></span>
<span class="normal"><a href="#__codelineno-0-1007">1007</a></span>
<span class="normal"><a href="#__codelineno-0-1008">1008</a></span>
<span class="normal"><a href="#__codelineno-0-1009">1009</a></span>
<span class="normal"><a href="#__codelineno-0-1010">1010</a></span>
<span class="normal"><a href="#__codelineno-0-1011">1011</a></span>
<span class="normal"><a href="#__codelineno-0-1012">1012</a></span>
<span class="normal"><a href="#__codelineno-0-1013">1013</a></span>
<span class="normal"><a href="#__codelineno-0-1014">1014</a></span>
<span class="normal"><a href="#__codelineno-0-1015">1015</a></span>
<span class="normal"><a href="#__codelineno-0-1016">1016</a></span>
<span class="normal"><a href="#__codelineno-0-1017">1017</a></span>
<span class="normal"><a href="#__codelineno-0-1018">1018</a></span>
<span class="normal"><a href="#__codelineno-0-1019">1019</a></span>
<span class="normal"><a href="#__codelineno-0-1020">1020</a></span>
<span class="normal"><a href="#__codelineno-0-1021">1021</a></span>
<span class="normal"><a href="#__codelineno-0-1022">1022</a></span>
<span class="normal"><a href="#__codelineno-0-1023">1023</a></span>
<span class="normal"><a href="#__codelineno-0-1024">1024</a></span>
<span class="normal"><a href="#__codelineno-0-1025">1025</a></span>
<span class="normal"><a href="#__codelineno-0-1026">1026</a></span>
<span class="normal"><a href="#__codelineno-0-1027">1027</a></span>
<span class="normal"><a href="#__codelineno-0-1028">1028</a></span>
<span class="normal"><a href="#__codelineno-0-1029">1029</a></span>
<span class="normal"><a href="#__codelineno-0-1030">1030</a></span>
<span class="normal"><a href="#__codelineno-0-1031">1031</a></span>
<span class="normal"><a href="#__codelineno-0-1032">1032</a></span>
<span class="normal"><a href="#__codelineno-0-1033">1033</a></span>
<span class="normal"><a href="#__codelineno-0-1034">1034</a></span>
<span class="normal"><a href="#__codelineno-0-1035">1035</a></span>
<span class="normal"><a href="#__codelineno-0-1036">1036</a></span>
<span class="normal"><a href="#__codelineno-0-1037">1037</a></span>
<span class="normal"><a href="#__codelineno-0-1038">1038</a></span>
<span class="normal"><a href="#__codelineno-0-1039">1039</a></span>
<span class="normal"><a href="#__codelineno-0-1040">1040</a></span>
<span class="normal"><a href="#__codelineno-0-1041">1041</a></span>
<span class="normal"><a href="#__codelineno-0-1042">1042</a></span>
<span class="normal"><a href="#__codelineno-0-1043">1043</a></span>
<span class="normal"><a href="#__codelineno-0-1044">1044</a></span>
<span class="normal"><a href="#__codelineno-0-1045">1045</a></span>
<span class="normal"><a href="#__codelineno-0-1046">1046</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-43"><a id="__codelineno-0-43" name="__codelineno-0-43"></a><span class="k">class</span><span class="w"> </span><span class="nc">XmlRpcBridge</span><span class="p">(</span><span class="n">FreecadBridge</span><span class="p">):</span>
</span><span id="__span-0-44"><a id="__codelineno-0-44" name="__codelineno-0-44"></a><span class="w"> </span><span class="sd">"""Bridge that communicates with FreeCAD via XML-RPC.</span>
</span><span id="__span-0-45"><a id="__codelineno-0-45" name="__codelineno-0-45"></a>
</span><span id="__span-0-46"><a id="__codelineno-0-46" name="__codelineno-0-46"></a><span class="sd"> This bridge connects to a FreeCAD instance that is running the</span>
</span><span id="__span-0-47"><a id="__codelineno-0-47" name="__codelineno-0-47"></a><span class="sd"> XML-RPC server addon. It provides full access to FreeCAD functionality</span>
</span><span id="__span-0-48"><a id="__codelineno-0-48" name="__codelineno-0-48"></a><span class="sd"> including GUI operations like screenshots.</span>
</span><span id="__span-0-49"><a id="__codelineno-0-49" name="__codelineno-0-49"></a>
</span><span id="__span-0-50"><a id="__codelineno-0-50" name="__codelineno-0-50"></a><span class="sd"> Attributes:</span>
</span><span id="__span-0-51"><a id="__codelineno-0-51" name="__codelineno-0-51"></a><span class="sd"> host: XML-RPC server hostname.</span>
</span><span id="__span-0-52"><a id="__codelineno-0-52" name="__codelineno-0-52"></a><span class="sd"> port: XML-RPC server port.</span>
</span><span id="__span-0-53"><a id="__codelineno-0-53" name="__codelineno-0-53"></a><span class="sd"> timeout: Connection and request timeout in seconds.</span>
</span><span id="__span-0-54"><a id="__codelineno-0-54" name="__codelineno-0-54"></a><span class="sd"> """</span>
</span><span id="__span-0-55"><a id="__codelineno-0-55" name="__codelineno-0-55"></a>
</span><span id="__span-0-56"><a id="__codelineno-0-56" name="__codelineno-0-56"></a> <span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span>
</span><span id="__span-0-57"><a id="__codelineno-0-57" name="__codelineno-0-57"></a> <span class="bp">self</span><span class="p">,</span>
</span><span id="__span-0-58"><a id="__codelineno-0-58" name="__codelineno-0-58"></a> <span class="n">host</span><span class="p">:</span> <span class="nb">str</span> <span class="o">=</span> <span class="n">DEFAULT_XMLRPC_HOST</span><span class="p">,</span>
</span><span id="__span-0-59"><a id="__codelineno-0-59" name="__codelineno-0-59"></a> <span class="n">port</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="n">DEFAULT_XMLRPC_PORT</span><span class="p">,</span>
</span><span id="__span-0-60"><a id="__codelineno-0-60" name="__codelineno-0-60"></a> <span class="n">timeout</span><span class="p">:</span> <span class="nb">float</span> <span class="o">=</span> <span class="n">DEFAULT_TIMEOUT</span><span class="p">,</span>
</span><span id="__span-0-61"><a id="__codelineno-0-61" name="__codelineno-0-61"></a> <span class="p">)</span> <span class="o">-&gt;</span> <span class="kc">None</span><span class="p">:</span>
</span><span id="__span-0-62"><a id="__codelineno-0-62" name="__codelineno-0-62"></a><span class="w"> </span><span class="sd">"""Initialize the XML-RPC bridge.</span>
</span><span id="__span-0-63"><a id="__codelineno-0-63" name="__codelineno-0-63"></a>
</span><span id="__span-0-64"><a id="__codelineno-0-64" name="__codelineno-0-64"></a><span class="sd"> Args:</span>
</span><span id="__span-0-65"><a id="__codelineno-0-65" name="__codelineno-0-65"></a><span class="sd"> host: XML-RPC server hostname.</span>
</span><span id="__span-0-66"><a id="__codelineno-0-66" name="__codelineno-0-66"></a><span class="sd"> port: XML-RPC server port.</span>
</span><span id="__span-0-67"><a id="__codelineno-0-67" name="__codelineno-0-67"></a><span class="sd"> timeout: Connection and request timeout in seconds.</span>
</span><span id="__span-0-68"><a id="__codelineno-0-68" name="__codelineno-0-68"></a><span class="sd"> """</span>
</span><span id="__span-0-69"><a id="__codelineno-0-69" name="__codelineno-0-69"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_host</span> <span class="o">=</span> <span class="n">host</span>
</span><span id="__span-0-70"><a id="__codelineno-0-70" name="__codelineno-0-70"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_port</span> <span class="o">=</span> <span class="n">port</span>
</span><span id="__span-0-71"><a id="__codelineno-0-71" name="__codelineno-0-71"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_timeout</span> <span class="o">=</span> <span class="n">timeout</span>
</span><span id="__span-0-72"><a id="__codelineno-0-72" name="__codelineno-0-72"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_proxy</span><span class="p">:</span> <span class="n">xmlrpc</span><span class="o">.</span><span class="n">client</span><span class="o">.</span><span class="n">ServerProxy</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span>
</span><span id="__span-0-73"><a id="__codelineno-0-73" name="__codelineno-0-73"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_connected</span> <span class="o">=</span> <span class="kc">False</span>
</span><span id="__span-0-74"><a id="__codelineno-0-74" name="__codelineno-0-74"></a>
</span><span id="__span-0-75"><a id="__codelineno-0-75" name="__codelineno-0-75"></a> <span class="nd">@property</span>
</span><span id="__span-0-76"><a id="__codelineno-0-76" name="__codelineno-0-76"></a> <span class="k">def</span><span class="w"> </span><span class="nf">_server_url</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">str</span><span class="p">:</span>
</span><span id="__span-0-77"><a id="__codelineno-0-77" name="__codelineno-0-77"></a><span class="w"> </span><span class="sd">"""Get the XML-RPC server URL."""</span>
</span><span id="__span-0-78"><a id="__codelineno-0-78" name="__codelineno-0-78"></a> <span class="k">return</span> <span class="sa">f</span><span class="s2">"http://</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">_host</span><span class="si">}</span><span class="s2">:</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">_port</span><span class="si">}</span><span class="s2">"</span>
</span><span id="__span-0-79"><a id="__codelineno-0-79" name="__codelineno-0-79"></a>
</span><span id="__span-0-80"><a id="__codelineno-0-80" name="__codelineno-0-80"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">connect</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kc">None</span><span class="p">:</span>
</span><span id="__span-0-81"><a id="__codelineno-0-81" name="__codelineno-0-81"></a><span class="w"> </span><span class="sd">"""Establish connection to FreeCAD XML-RPC server.</span>
</span><span id="__span-0-82"><a id="__codelineno-0-82" name="__codelineno-0-82"></a>
</span><span id="__span-0-83"><a id="__codelineno-0-83" name="__codelineno-0-83"></a><span class="sd"> Raises:</span>
</span><span id="__span-0-84"><a id="__codelineno-0-84" name="__codelineno-0-84"></a><span class="sd"> ConnectionError: If connection cannot be established.</span>
</span><span id="__span-0-85"><a id="__codelineno-0-85" name="__codelineno-0-85"></a><span class="sd"> """</span>
</span><span id="__span-0-86"><a id="__codelineno-0-86" name="__codelineno-0-86"></a> <span class="n">loop</span> <span class="o">=</span> <span class="n">asyncio</span><span class="o">.</span><span class="n">get_event_loop</span><span class="p">()</span>
</span><span id="__span-0-87"><a id="__codelineno-0-87" name="__codelineno-0-87"></a> <span class="k">try</span><span class="p">:</span>
</span><span id="__span-0-88"><a id="__codelineno-0-88" name="__codelineno-0-88"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_proxy</span> <span class="o">=</span> <span class="k">await</span> <span class="n">loop</span><span class="o">.</span><span class="n">run_in_executor</span><span class="p">(</span>
</span><span id="__span-0-89"><a id="__codelineno-0-89" name="__codelineno-0-89"></a> <span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-90"><a id="__codelineno-0-90" name="__codelineno-0-90"></a> <span class="k">lambda</span><span class="p">:</span> <span class="n">xmlrpc</span><span class="o">.</span><span class="n">client</span><span class="o">.</span><span class="n">ServerProxy</span><span class="p">(</span>
</span><span id="__span-0-91"><a id="__codelineno-0-91" name="__codelineno-0-91"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_server_url</span><span class="p">,</span>
</span><span id="__span-0-92"><a id="__codelineno-0-92" name="__codelineno-0-92"></a> <span class="n">allow_none</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span>
</span><span id="__span-0-93"><a id="__codelineno-0-93" name="__codelineno-0-93"></a> <span class="p">),</span>
</span><span id="__span-0-94"><a id="__codelineno-0-94" name="__codelineno-0-94"></a> <span class="p">)</span>
</span><span id="__span-0-95"><a id="__codelineno-0-95" name="__codelineno-0-95"></a> <span class="c1"># Test connection with a ping</span>
</span><span id="__span-0-96"><a id="__codelineno-0-96" name="__codelineno-0-96"></a> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">ping</span><span class="p">()</span>
</span><span id="__span-0-97"><a id="__codelineno-0-97" name="__codelineno-0-97"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_connected</span> <span class="o">=</span> <span class="kc">True</span>
</span><span id="__span-0-98"><a id="__codelineno-0-98" name="__codelineno-0-98"></a> <span class="k">except</span> <span class="ne">ConnectionRefusedError</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
</span><span id="__span-0-99"><a id="__codelineno-0-99" name="__codelineno-0-99"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_connected</span> <span class="o">=</span> <span class="kc">False</span>
</span><span id="__span-0-100"><a id="__codelineno-0-100" name="__codelineno-0-100"></a> <span class="n">msg</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_connection_refused_message</span><span class="p">()</span>
</span><span id="__span-0-101"><a id="__codelineno-0-101" name="__codelineno-0-101"></a> <span class="k">raise</span> <span class="ne">ConnectionError</span><span class="p">(</span><span class="n">msg</span><span class="p">)</span> <span class="kn">from</span><span class="w"> </span><span class="nn">e</span>
</span><span id="__span-0-102"><a id="__codelineno-0-102" name="__codelineno-0-102"></a> <span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
</span><span id="__span-0-103"><a id="__codelineno-0-103" name="__codelineno-0-103"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_connected</span> <span class="o">=</span> <span class="kc">False</span>
</span><span id="__span-0-104"><a id="__codelineno-0-104" name="__codelineno-0-104"></a> <span class="n">error_str</span> <span class="o">=</span> <span class="nb">str</span><span class="p">(</span><span class="n">e</span><span class="p">)</span>
</span><span id="__span-0-105"><a id="__codelineno-0-105" name="__codelineno-0-105"></a> <span class="k">if</span> <span class="s2">"Connection refused"</span> <span class="ow">in</span> <span class="n">error_str</span> <span class="ow">or</span> <span class="s2">"Errno 61"</span> <span class="ow">in</span> <span class="n">error_str</span><span class="p">:</span>
</span><span id="__span-0-106"><a id="__codelineno-0-106" name="__codelineno-0-106"></a> <span class="n">msg</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_connection_refused_message</span><span class="p">()</span>
</span><span id="__span-0-107"><a id="__codelineno-0-107" name="__codelineno-0-107"></a> <span class="k">else</span><span class="p">:</span>
</span><span id="__span-0-108"><a id="__codelineno-0-108" name="__codelineno-0-108"></a> <span class="n">msg</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">"Failed to connect to XML-RPC server at </span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">_server_url</span><span class="si">}</span><span class="s2">: </span><span class="si">{</span><span class="n">e</span><span class="si">}</span><span class="s2">"</span>
</span><span id="__span-0-109"><a id="__codelineno-0-109" name="__codelineno-0-109"></a> <span class="k">raise</span> <span class="ne">ConnectionError</span><span class="p">(</span><span class="n">msg</span><span class="p">)</span> <span class="kn">from</span><span class="w"> </span><span class="nn">e</span>
</span><span id="__span-0-110"><a id="__codelineno-0-110" name="__codelineno-0-110"></a>
</span><span id="__span-0-111"><a id="__codelineno-0-111" name="__codelineno-0-111"></a> <span class="k">def</span><span class="w"> </span><span class="nf">_get_connection_refused_message</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">str</span><span class="p">:</span>
</span><span id="__span-0-112"><a id="__codelineno-0-112" name="__codelineno-0-112"></a><span class="w"> </span><span class="sd">"""Get a helpful error message when connection is refused."""</span>
</span><span id="__span-0-113"><a id="__codelineno-0-113" name="__codelineno-0-113"></a> <span class="k">return</span> <span class="sa">f</span><span class="s2">"""</span>
</span><span id="__span-0-114"><a id="__codelineno-0-114" name="__codelineno-0-114"></a><span class="s2">================================================================================</span>
</span><span id="__span-0-115"><a id="__codelineno-0-115" name="__codelineno-0-115"></a><span class="s2">CONNECTION REFUSED: Cannot connect to FreeCAD at </span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">_server_url</span><span class="si">}</span>
</span><span id="__span-0-116"><a id="__codelineno-0-116" name="__codelineno-0-116"></a>
</span><span id="__span-0-117"><a id="__codelineno-0-117" name="__codelineno-0-117"></a><span class="s2">The FreeCAD Robust MCP Bridge server is not running. To fix this:</span>
</span><span id="__span-0-118"><a id="__codelineno-0-118" name="__codelineno-0-118"></a>
</span><span id="__span-0-119"><a id="__codelineno-0-119" name="__codelineno-0-119"></a><span class="s2">1. Start FreeCAD (the GUI application)</span>
</span><span id="__span-0-120"><a id="__codelineno-0-120" name="__codelineno-0-120"></a>
</span><span id="__span-0-121"><a id="__codelineno-0-121" name="__codelineno-0-121"></a><span class="s2">2. Start the MCP bridge using one of these methods:</span>
</span><span id="__span-0-122"><a id="__codelineno-0-122" name="__codelineno-0-122"></a>
</span><span id="__span-0-123"><a id="__codelineno-0-123" name="__codelineno-0-123"></a><span class="s2"> Option A: Using the Robust MCP Bridge Workbench (recommended)</span>
</span><span id="__span-0-124"><a id="__codelineno-0-124" name="__codelineno-0-124"></a><span class="s2"> - Install via FreeCAD Addon Manager: Tools → Addon Manager</span>
</span><span id="__span-0-125"><a id="__codelineno-0-125" name="__codelineno-0-125"></a><span class="s2"> - Search for "Robust MCP Bridge" and install</span>
</span><span id="__span-0-126"><a id="__codelineno-0-126" name="__codelineno-0-126"></a><span class="s2"> - Switch to the Robust MCP Bridge workbench</span>
</span><span id="__span-0-127"><a id="__codelineno-0-127" name="__codelineno-0-127"></a><span class="s2"> - Click "Start MCP Bridge" in the toolbar</span>
</span><span id="__span-0-128"><a id="__codelineno-0-128" name="__codelineno-0-128"></a>
</span><span id="__span-0-129"><a id="__codelineno-0-129" name="__codelineno-0-129"></a><span class="s2"> Option B: From source (for developers)</span>
</span><span id="__span-0-130"><a id="__codelineno-0-130" name="__codelineno-0-130"></a><span class="s2"> - Run: just freecad::run-gui</span>
</span><span id="__span-0-131"><a id="__codelineno-0-131" name="__codelineno-0-131"></a>
</span><span id="__span-0-132"><a id="__codelineno-0-132" name="__codelineno-0-132"></a><span class="s2">3. You should see: "MCP Bridge started!"</span>
</span><span id="__span-0-133"><a id="__codelineno-0-133" name="__codelineno-0-133"></a><span class="s2"> - XML-RPC: localhost:</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">_port</span><span class="si">}</span>
</span><span id="__span-0-134"><a id="__codelineno-0-134" name="__codelineno-0-134"></a><span class="s2"> - Socket: localhost:9876</span>
</span><span id="__span-0-135"><a id="__codelineno-0-135" name="__codelineno-0-135"></a>
</span><span id="__span-0-136"><a id="__codelineno-0-136" name="__codelineno-0-136"></a><span class="s2">4. Then restart your MCP client (e.g., restart Claude Code)</span>
</span><span id="__span-0-137"><a id="__codelineno-0-137" name="__codelineno-0-137"></a><span class="s2">================================================================================</span>
</span><span id="__span-0-138"><a id="__codelineno-0-138" name="__codelineno-0-138"></a><span class="s2">"""</span>
</span><span id="__span-0-139"><a id="__codelineno-0-139" name="__codelineno-0-139"></a>
</span><span id="__span-0-140"><a id="__codelineno-0-140" name="__codelineno-0-140"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">disconnect</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kc">None</span><span class="p">:</span>
</span><span id="__span-0-141"><a id="__codelineno-0-141" name="__codelineno-0-141"></a><span class="w"> </span><span class="sd">"""Close connection to FreeCAD XML-RPC server."""</span>
</span><span id="__span-0-142"><a id="__codelineno-0-142" name="__codelineno-0-142"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_proxy</span> <span class="o">=</span> <span class="kc">None</span>
</span><span id="__span-0-143"><a id="__codelineno-0-143" name="__codelineno-0-143"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_connected</span> <span class="o">=</span> <span class="kc">False</span>
</span><span id="__span-0-144"><a id="__codelineno-0-144" name="__codelineno-0-144"></a>
</span><span id="__span-0-145"><a id="__codelineno-0-145" name="__codelineno-0-145"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">is_connected</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">bool</span><span class="p">:</span>
</span><span id="__span-0-146"><a id="__codelineno-0-146" name="__codelineno-0-146"></a><span class="w"> </span><span class="sd">"""Check if bridge is connected to FreeCAD."""</span>
</span><span id="__span-0-147"><a id="__codelineno-0-147" name="__codelineno-0-147"></a> <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">_connected</span> <span class="ow">or</span> <span class="bp">self</span><span class="o">.</span><span class="n">_proxy</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
</span><span id="__span-0-148"><a id="__codelineno-0-148" name="__codelineno-0-148"></a> <span class="k">return</span> <span class="kc">False</span>
</span><span id="__span-0-149"><a id="__codelineno-0-149" name="__codelineno-0-149"></a>
</span><span id="__span-0-150"><a id="__codelineno-0-150" name="__codelineno-0-150"></a> <span class="k">try</span><span class="p">:</span>
</span><span id="__span-0-151"><a id="__codelineno-0-151" name="__codelineno-0-151"></a> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">ping</span><span class="p">()</span>
</span><span id="__span-0-152"><a id="__codelineno-0-152" name="__codelineno-0-152"></a> <span class="k">return</span> <span class="kc">True</span>
</span><span id="__span-0-153"><a id="__codelineno-0-153" name="__codelineno-0-153"></a> <span class="k">except</span> <span class="ne">Exception</span><span class="p">:</span>
</span><span id="__span-0-154"><a id="__codelineno-0-154" name="__codelineno-0-154"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_connected</span> <span class="o">=</span> <span class="kc">False</span>
</span><span id="__span-0-155"><a id="__codelineno-0-155" name="__codelineno-0-155"></a> <span class="k">return</span> <span class="kc">False</span>
</span><span id="__span-0-156"><a id="__codelineno-0-156" name="__codelineno-0-156"></a>
</span><span id="__span-0-157"><a id="__codelineno-0-157" name="__codelineno-0-157"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">ping</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">float</span><span class="p">:</span>
</span><span id="__span-0-158"><a id="__codelineno-0-158" name="__codelineno-0-158"></a><span class="w"> </span><span class="sd">"""Ping FreeCAD to check connection and measure latency.</span>
</span><span id="__span-0-159"><a id="__codelineno-0-159" name="__codelineno-0-159"></a>
</span><span id="__span-0-160"><a id="__codelineno-0-160" name="__codelineno-0-160"></a><span class="sd"> Returns:</span>
</span><span id="__span-0-161"><a id="__codelineno-0-161" name="__codelineno-0-161"></a><span class="sd"> Round-trip time in milliseconds.</span>
</span><span id="__span-0-162"><a id="__codelineno-0-162" name="__codelineno-0-162"></a>
</span><span id="__span-0-163"><a id="__codelineno-0-163" name="__codelineno-0-163"></a><span class="sd"> Raises:</span>
</span><span id="__span-0-164"><a id="__codelineno-0-164" name="__codelineno-0-164"></a><span class="sd"> ConnectionError: If not connected.</span>
</span><span id="__span-0-165"><a id="__codelineno-0-165" name="__codelineno-0-165"></a><span class="sd"> """</span>
</span><span id="__span-0-166"><a id="__codelineno-0-166" name="__codelineno-0-166"></a> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_proxy</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
</span><span id="__span-0-167"><a id="__codelineno-0-167" name="__codelineno-0-167"></a> <span class="n">msg</span> <span class="o">=</span> <span class="s2">"Not connected to XML-RPC server"</span>
</span><span id="__span-0-168"><a id="__codelineno-0-168" name="__codelineno-0-168"></a> <span class="k">raise</span> <span class="ne">ConnectionError</span><span class="p">(</span><span class="n">msg</span><span class="p">)</span>
</span><span id="__span-0-169"><a id="__codelineno-0-169" name="__codelineno-0-169"></a>
</span><span id="__span-0-170"><a id="__codelineno-0-170" name="__codelineno-0-170"></a> <span class="n">loop</span> <span class="o">=</span> <span class="n">asyncio</span><span class="o">.</span><span class="n">get_event_loop</span><span class="p">()</span>
</span><span id="__span-0-171"><a id="__codelineno-0-171" name="__codelineno-0-171"></a> <span class="n">start</span> <span class="o">=</span> <span class="n">time</span><span class="o">.</span><span class="n">perf_counter</span><span class="p">()</span>
</span><span id="__span-0-172"><a id="__codelineno-0-172" name="__codelineno-0-172"></a>
</span><span id="__span-0-173"><a id="__codelineno-0-173" name="__codelineno-0-173"></a> <span class="k">try</span><span class="p">:</span>
</span><span id="__span-0-174"><a id="__codelineno-0-174" name="__codelineno-0-174"></a> <span class="c1"># Try standard system.listMethods or a simple execute</span>
</span><span id="__span-0-175"><a id="__codelineno-0-175" name="__codelineno-0-175"></a> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_proxy</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
</span><span id="__span-0-176"><a id="__codelineno-0-176" name="__codelineno-0-176"></a> <span class="n">msg</span> <span class="o">=</span> <span class="s2">"Not connected"</span>
</span><span id="__span-0-177"><a id="__codelineno-0-177" name="__codelineno-0-177"></a> <span class="k">raise</span> <span class="ne">ConnectionError</span><span class="p">(</span><span class="n">msg</span><span class="p">)</span>
</span><span id="__span-0-178"><a id="__codelineno-0-178" name="__codelineno-0-178"></a> <span class="n">proxy</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_proxy</span> <span class="c1"># Local reference for lambda</span>
</span><span id="__span-0-179"><a id="__codelineno-0-179" name="__codelineno-0-179"></a> <span class="k">await</span> <span class="n">asyncio</span><span class="o">.</span><span class="n">wait_for</span><span class="p">(</span>
</span><span id="__span-0-180"><a id="__codelineno-0-180" name="__codelineno-0-180"></a> <span class="n">loop</span><span class="o">.</span><span class="n">run_in_executor</span><span class="p">(</span>
</span><span id="__span-0-181"><a id="__codelineno-0-181" name="__codelineno-0-181"></a> <span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-182"><a id="__codelineno-0-182" name="__codelineno-0-182"></a> <span class="k">lambda</span><span class="p">:</span> <span class="n">proxy</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s2">"_result_ = True"</span><span class="p">),</span>
</span><span id="__span-0-183"><a id="__codelineno-0-183" name="__codelineno-0-183"></a> <span class="p">),</span>
</span><span id="__span-0-184"><a id="__codelineno-0-184" name="__codelineno-0-184"></a> <span class="n">timeout</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">_timeout</span><span class="p">,</span>
</span><span id="__span-0-185"><a id="__codelineno-0-185" name="__codelineno-0-185"></a> <span class="p">)</span>
</span><span id="__span-0-186"><a id="__codelineno-0-186" name="__codelineno-0-186"></a> <span class="k">except</span> <span class="ne">TimeoutError</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
</span><span id="__span-0-187"><a id="__codelineno-0-187" name="__codelineno-0-187"></a> <span class="n">msg</span> <span class="o">=</span> <span class="s2">"Ping timed out"</span>
</span><span id="__span-0-188"><a id="__codelineno-0-188" name="__codelineno-0-188"></a> <span class="k">raise</span> <span class="ne">ConnectionError</span><span class="p">(</span><span class="n">msg</span><span class="p">)</span> <span class="kn">from</span><span class="w"> </span><span class="nn">e</span>
</span><span id="__span-0-189"><a id="__codelineno-0-189" name="__codelineno-0-189"></a> <span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
</span><span id="__span-0-190"><a id="__codelineno-0-190" name="__codelineno-0-190"></a> <span class="n">msg</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">"Ping failed: </span><span class="si">{</span><span class="n">e</span><span class="si">}</span><span class="s2">"</span>
</span><span id="__span-0-191"><a id="__codelineno-0-191" name="__codelineno-0-191"></a> <span class="k">raise</span> <span class="ne">ConnectionError</span><span class="p">(</span><span class="n">msg</span><span class="p">)</span> <span class="kn">from</span><span class="w"> </span><span class="nn">e</span>
</span><span id="__span-0-192"><a id="__codelineno-0-192" name="__codelineno-0-192"></a>
</span><span id="__span-0-193"><a id="__codelineno-0-193" name="__codelineno-0-193"></a> <span class="k">return</span> <span class="p">(</span><span class="n">time</span><span class="o">.</span><span class="n">perf_counter</span><span class="p">()</span> <span class="o">-</span> <span class="n">start</span><span class="p">)</span> <span class="o">*</span> <span class="mi">1000</span>
</span><span id="__span-0-194"><a id="__codelineno-0-194" name="__codelineno-0-194"></a>
</span><span id="__span-0-195"><a id="__codelineno-0-195" name="__codelineno-0-195"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">get_status</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">ConnectionStatus</span><span class="p">:</span>
</span><span id="__span-0-196"><a id="__codelineno-0-196" name="__codelineno-0-196"></a><span class="w"> </span><span class="sd">"""Get detailed connection status.</span>
</span><span id="__span-0-197"><a id="__codelineno-0-197" name="__codelineno-0-197"></a>
</span><span id="__span-0-198"><a id="__codelineno-0-198" name="__codelineno-0-198"></a><span class="sd"> Returns:</span>
</span><span id="__span-0-199"><a id="__codelineno-0-199" name="__codelineno-0-199"></a><span class="sd"> ConnectionStatus with full status information.</span>
</span><span id="__span-0-200"><a id="__codelineno-0-200" name="__codelineno-0-200"></a><span class="sd"> """</span>
</span><span id="__span-0-201"><a id="__codelineno-0-201" name="__codelineno-0-201"></a> <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">_connected</span> <span class="ow">or</span> <span class="bp">self</span><span class="o">.</span><span class="n">_proxy</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
</span><span id="__span-0-202"><a id="__codelineno-0-202" name="__codelineno-0-202"></a> <span class="k">return</span> <span class="n">ConnectionStatus</span><span class="p">(</span>
</span><span id="__span-0-203"><a id="__codelineno-0-203" name="__codelineno-0-203"></a> <span class="n">connected</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
</span><span id="__span-0-204"><a id="__codelineno-0-204" name="__codelineno-0-204"></a> <span class="n">mode</span><span class="o">=</span><span class="s2">"xmlrpc"</span><span class="p">,</span>
</span><span id="__span-0-205"><a id="__codelineno-0-205" name="__codelineno-0-205"></a> <span class="n">error</span><span class="o">=</span><span class="s2">"Not connected"</span><span class="p">,</span>
</span><span id="__span-0-206"><a id="__codelineno-0-206" name="__codelineno-0-206"></a> <span class="p">)</span>
</span><span id="__span-0-207"><a id="__codelineno-0-207" name="__codelineno-0-207"></a>
</span><span id="__span-0-208"><a id="__codelineno-0-208" name="__codelineno-0-208"></a> <span class="k">try</span><span class="p">:</span>
</span><span id="__span-0-209"><a id="__codelineno-0-209" name="__codelineno-0-209"></a> <span class="n">ping_ms</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">ping</span><span class="p">()</span>
</span><span id="__span-0-210"><a id="__codelineno-0-210" name="__codelineno-0-210"></a> <span class="n">version_info</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_freecad_version</span><span class="p">()</span>
</span><span id="__span-0-211"><a id="__codelineno-0-211" name="__codelineno-0-211"></a> <span class="n">gui_available</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">is_gui_available</span><span class="p">()</span>
</span><span id="__span-0-212"><a id="__codelineno-0-212" name="__codelineno-0-212"></a>
</span><span id="__span-0-213"><a id="__codelineno-0-213" name="__codelineno-0-213"></a> <span class="k">return</span> <span class="n">ConnectionStatus</span><span class="p">(</span>
</span><span id="__span-0-214"><a id="__codelineno-0-214" name="__codelineno-0-214"></a> <span class="n">connected</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span>
</span><span id="__span-0-215"><a id="__codelineno-0-215" name="__codelineno-0-215"></a> <span class="n">mode</span><span class="o">=</span><span class="s2">"xmlrpc"</span><span class="p">,</span>
</span><span id="__span-0-216"><a id="__codelineno-0-216" name="__codelineno-0-216"></a> <span class="n">freecad_version</span><span class="o">=</span><span class="n">version_info</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"version"</span><span class="p">,</span> <span class="s2">"unknown"</span><span class="p">),</span>
</span><span id="__span-0-217"><a id="__codelineno-0-217" name="__codelineno-0-217"></a> <span class="n">gui_available</span><span class="o">=</span><span class="n">gui_available</span><span class="p">,</span>
</span><span id="__span-0-218"><a id="__codelineno-0-218" name="__codelineno-0-218"></a> <span class="n">last_ping_ms</span><span class="o">=</span><span class="n">ping_ms</span><span class="p">,</span>
</span><span id="__span-0-219"><a id="__codelineno-0-219" name="__codelineno-0-219"></a> <span class="p">)</span>
</span><span id="__span-0-220"><a id="__codelineno-0-220" name="__codelineno-0-220"></a> <span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
</span><span id="__span-0-221"><a id="__codelineno-0-221" name="__codelineno-0-221"></a> <span class="k">return</span> <span class="n">ConnectionStatus</span><span class="p">(</span>
</span><span id="__span-0-222"><a id="__codelineno-0-222" name="__codelineno-0-222"></a> <span class="n">connected</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
</span><span id="__span-0-223"><a id="__codelineno-0-223" name="__codelineno-0-223"></a> <span class="n">mode</span><span class="o">=</span><span class="s2">"xmlrpc"</span><span class="p">,</span>
</span><span id="__span-0-224"><a id="__codelineno-0-224" name="__codelineno-0-224"></a> <span class="n">error</span><span class="o">=</span><span class="nb">str</span><span class="p">(</span><span class="n">e</span><span class="p">),</span>
</span><span id="__span-0-225"><a id="__codelineno-0-225" name="__codelineno-0-225"></a> <span class="p">)</span>
</span><span id="__span-0-226"><a id="__codelineno-0-226" name="__codelineno-0-226"></a>
</span><span id="__span-0-227"><a id="__codelineno-0-227" name="__codelineno-0-227"></a> <span class="c1"># =========================================================================</span>
</span><span id="__span-0-228"><a id="__codelineno-0-228" name="__codelineno-0-228"></a> <span class="c1"># Code Execution</span>
</span><span id="__span-0-229"><a id="__codelineno-0-229" name="__codelineno-0-229"></a> <span class="c1"># =========================================================================</span>
</span><span id="__span-0-230"><a id="__codelineno-0-230" name="__codelineno-0-230"></a>
</span><span id="__span-0-231"><a id="__codelineno-0-231" name="__codelineno-0-231"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">execute_python</span><span class="p">(</span>
</span><span id="__span-0-232"><a id="__codelineno-0-232" name="__codelineno-0-232"></a> <span class="bp">self</span><span class="p">,</span>
</span><span id="__span-0-233"><a id="__codelineno-0-233" name="__codelineno-0-233"></a> <span class="n">code</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span>
</span><span id="__span-0-234"><a id="__codelineno-0-234" name="__codelineno-0-234"></a> <span class="n">timeout_ms</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">30000</span><span class="p">,</span>
</span><span id="__span-0-235"><a id="__codelineno-0-235" name="__codelineno-0-235"></a> <span class="p">)</span> <span class="o">-&gt;</span> <span class="n">ExecutionResult</span><span class="p">:</span>
</span><span id="__span-0-236"><a id="__codelineno-0-236" name="__codelineno-0-236"></a><span class="w"> </span><span class="sd">"""Execute Python code in FreeCAD context via XML-RPC.</span>
</span><span id="__span-0-237"><a id="__codelineno-0-237" name="__codelineno-0-237"></a>
</span><span id="__span-0-238"><a id="__codelineno-0-238" name="__codelineno-0-238"></a><span class="sd"> Args:</span>
</span><span id="__span-0-239"><a id="__codelineno-0-239" name="__codelineno-0-239"></a><span class="sd"> code: Python code to execute.</span>
</span><span id="__span-0-240"><a id="__codelineno-0-240" name="__codelineno-0-240"></a><span class="sd"> timeout_ms: Maximum execution time in milliseconds.</span>
</span><span id="__span-0-241"><a id="__codelineno-0-241" name="__codelineno-0-241"></a>
</span><span id="__span-0-242"><a id="__codelineno-0-242" name="__codelineno-0-242"></a><span class="sd"> Returns:</span>
</span><span id="__span-0-243"><a id="__codelineno-0-243" name="__codelineno-0-243"></a><span class="sd"> ExecutionResult with execution outcome.</span>
</span><span id="__span-0-244"><a id="__codelineno-0-244" name="__codelineno-0-244"></a><span class="sd"> """</span>
</span><span id="__span-0-245"><a id="__codelineno-0-245" name="__codelineno-0-245"></a> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_proxy</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
</span><span id="__span-0-246"><a id="__codelineno-0-246" name="__codelineno-0-246"></a> <span class="k">return</span> <span class="n">ExecutionResult</span><span class="p">(</span>
</span><span id="__span-0-247"><a id="__codelineno-0-247" name="__codelineno-0-247"></a> <span class="n">success</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
</span><span id="__span-0-248"><a id="__codelineno-0-248" name="__codelineno-0-248"></a> <span class="n">result</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-249"><a id="__codelineno-0-249" name="__codelineno-0-249"></a> <span class="n">stdout</span><span class="o">=</span><span class="s2">""</span><span class="p">,</span>
</span><span id="__span-0-250"><a id="__codelineno-0-250" name="__codelineno-0-250"></a> <span class="n">stderr</span><span class="o">=</span><span class="s2">"Not connected to XML-RPC server"</span><span class="p">,</span>
</span><span id="__span-0-251"><a id="__codelineno-0-251" name="__codelineno-0-251"></a> <span class="n">execution_time_ms</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span>
</span><span id="__span-0-252"><a id="__codelineno-0-252" name="__codelineno-0-252"></a> <span class="n">error_type</span><span class="o">=</span><span class="s2">"ConnectionError"</span><span class="p">,</span>
</span><span id="__span-0-253"><a id="__codelineno-0-253" name="__codelineno-0-253"></a> <span class="p">)</span>
</span><span id="__span-0-254"><a id="__codelineno-0-254" name="__codelineno-0-254"></a>
</span><span id="__span-0-255"><a id="__codelineno-0-255" name="__codelineno-0-255"></a> <span class="n">loop</span> <span class="o">=</span> <span class="n">asyncio</span><span class="o">.</span><span class="n">get_event_loop</span><span class="p">()</span>
</span><span id="__span-0-256"><a id="__codelineno-0-256" name="__codelineno-0-256"></a> <span class="n">start</span> <span class="o">=</span> <span class="n">time</span><span class="o">.</span><span class="n">perf_counter</span><span class="p">()</span>
</span><span id="__span-0-257"><a id="__codelineno-0-257" name="__codelineno-0-257"></a> <span class="n">proxy</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_proxy</span> <span class="c1"># Local reference for lambda</span>
</span><span id="__span-0-258"><a id="__codelineno-0-258" name="__codelineno-0-258"></a>
</span><span id="__span-0-259"><a id="__codelineno-0-259" name="__codelineno-0-259"></a> <span class="k">try</span><span class="p">:</span>
</span><span id="__span-0-260"><a id="__codelineno-0-260" name="__codelineno-0-260"></a> <span class="n">result</span> <span class="o">=</span> <span class="k">await</span> <span class="n">asyncio</span><span class="o">.</span><span class="n">wait_for</span><span class="p">(</span>
</span><span id="__span-0-261"><a id="__codelineno-0-261" name="__codelineno-0-261"></a> <span class="n">loop</span><span class="o">.</span><span class="n">run_in_executor</span><span class="p">(</span>
</span><span id="__span-0-262"><a id="__codelineno-0-262" name="__codelineno-0-262"></a> <span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-263"><a id="__codelineno-0-263" name="__codelineno-0-263"></a> <span class="k">lambda</span><span class="p">:</span> <span class="n">proxy</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="n">code</span><span class="p">),</span>
</span><span id="__span-0-264"><a id="__codelineno-0-264" name="__codelineno-0-264"></a> <span class="p">),</span>
</span><span id="__span-0-265"><a id="__codelineno-0-265" name="__codelineno-0-265"></a> <span class="n">timeout</span><span class="o">=</span><span class="n">timeout_ms</span> <span class="o">/</span> <span class="mi">1000</span><span class="p">,</span>
</span><span id="__span-0-266"><a id="__codelineno-0-266" name="__codelineno-0-266"></a> <span class="p">)</span>
</span><span id="__span-0-267"><a id="__codelineno-0-267" name="__codelineno-0-267"></a> <span class="n">elapsed</span> <span class="o">=</span> <span class="p">(</span><span class="n">time</span><span class="o">.</span><span class="n">perf_counter</span><span class="p">()</span> <span class="o">-</span> <span class="n">start</span><span class="p">)</span> <span class="o">*</span> <span class="mi">1000</span>
</span><span id="__span-0-268"><a id="__codelineno-0-268" name="__codelineno-0-268"></a>
</span><span id="__span-0-269"><a id="__codelineno-0-269" name="__codelineno-0-269"></a> <span class="c1"># Parse result from XML-RPC server</span>
</span><span id="__span-0-270"><a id="__codelineno-0-270" name="__codelineno-0-270"></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">result</span><span class="p">,</span> <span class="nb">dict</span><span class="p">):</span>
</span><span id="__span-0-271"><a id="__codelineno-0-271" name="__codelineno-0-271"></a> <span class="k">return</span> <span class="n">ExecutionResult</span><span class="p">(</span>
</span><span id="__span-0-272"><a id="__codelineno-0-272" name="__codelineno-0-272"></a> <span class="n">success</span><span class="o">=</span><span class="n">result</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"success"</span><span class="p">,</span> <span class="kc">False</span><span class="p">),</span>
</span><span id="__span-0-273"><a id="__codelineno-0-273" name="__codelineno-0-273"></a> <span class="n">result</span><span class="o">=</span><span class="n">result</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"result"</span><span class="p">),</span>
</span><span id="__span-0-274"><a id="__codelineno-0-274" name="__codelineno-0-274"></a> <span class="n">stdout</span><span class="o">=</span><span class="n">result</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"stdout"</span><span class="p">,</span> <span class="s2">""</span><span class="p">),</span>
</span><span id="__span-0-275"><a id="__codelineno-0-275" name="__codelineno-0-275"></a> <span class="n">stderr</span><span class="o">=</span><span class="n">result</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"stderr"</span><span class="p">,</span> <span class="s2">""</span><span class="p">),</span>
</span><span id="__span-0-276"><a id="__codelineno-0-276" name="__codelineno-0-276"></a> <span class="n">execution_time_ms</span><span class="o">=</span><span class="n">elapsed</span><span class="p">,</span>
</span><span id="__span-0-277"><a id="__codelineno-0-277" name="__codelineno-0-277"></a> <span class="n">error_type</span><span class="o">=</span><span class="n">result</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"error_type"</span><span class="p">),</span>
</span><span id="__span-0-278"><a id="__codelineno-0-278" name="__codelineno-0-278"></a> <span class="n">error_traceback</span><span class="o">=</span><span class="n">result</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"error_traceback"</span><span class="p">),</span>
</span><span id="__span-0-279"><a id="__codelineno-0-279" name="__codelineno-0-279"></a> <span class="p">)</span>
</span><span id="__span-0-280"><a id="__codelineno-0-280" name="__codelineno-0-280"></a> <span class="k">else</span><span class="p">:</span>
</span><span id="__span-0-281"><a id="__codelineno-0-281" name="__codelineno-0-281"></a> <span class="c1"># Simple result format</span>
</span><span id="__span-0-282"><a id="__codelineno-0-282" name="__codelineno-0-282"></a> <span class="k">return</span> <span class="n">ExecutionResult</span><span class="p">(</span>
</span><span id="__span-0-283"><a id="__codelineno-0-283" name="__codelineno-0-283"></a> <span class="n">success</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span>
</span><span id="__span-0-284"><a id="__codelineno-0-284" name="__codelineno-0-284"></a> <span class="n">result</span><span class="o">=</span><span class="n">result</span><span class="p">,</span>
</span><span id="__span-0-285"><a id="__codelineno-0-285" name="__codelineno-0-285"></a> <span class="n">stdout</span><span class="o">=</span><span class="s2">""</span><span class="p">,</span>
</span><span id="__span-0-286"><a id="__codelineno-0-286" name="__codelineno-0-286"></a> <span class="n">stderr</span><span class="o">=</span><span class="s2">""</span><span class="p">,</span>
</span><span id="__span-0-287"><a id="__codelineno-0-287" name="__codelineno-0-287"></a> <span class="n">execution_time_ms</span><span class="o">=</span><span class="n">elapsed</span><span class="p">,</span>
</span><span id="__span-0-288"><a id="__codelineno-0-288" name="__codelineno-0-288"></a> <span class="p">)</span>
</span><span id="__span-0-289"><a id="__codelineno-0-289" name="__codelineno-0-289"></a>
</span><span id="__span-0-290"><a id="__codelineno-0-290" name="__codelineno-0-290"></a> <span class="k">except</span> <span class="ne">TimeoutError</span><span class="p">:</span>
</span><span id="__span-0-291"><a id="__codelineno-0-291" name="__codelineno-0-291"></a> <span class="k">return</span> <span class="n">ExecutionResult</span><span class="p">(</span>
</span><span id="__span-0-292"><a id="__codelineno-0-292" name="__codelineno-0-292"></a> <span class="n">success</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
</span><span id="__span-0-293"><a id="__codelineno-0-293" name="__codelineno-0-293"></a> <span class="n">result</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-294"><a id="__codelineno-0-294" name="__codelineno-0-294"></a> <span class="n">stdout</span><span class="o">=</span><span class="s2">""</span><span class="p">,</span>
</span><span id="__span-0-295"><a id="__codelineno-0-295" name="__codelineno-0-295"></a> <span class="n">stderr</span><span class="o">=</span><span class="sa">f</span><span class="s2">"Execution timed out after </span><span class="si">{</span><span class="n">timeout_ms</span><span class="si">}</span><span class="s2">ms"</span><span class="p">,</span>
</span><span id="__span-0-296"><a id="__codelineno-0-296" name="__codelineno-0-296"></a> <span class="n">execution_time_ms</span><span class="o">=</span><span class="nb">float</span><span class="p">(</span><span class="n">timeout_ms</span><span class="p">),</span>
</span><span id="__span-0-297"><a id="__codelineno-0-297" name="__codelineno-0-297"></a> <span class="n">error_type</span><span class="o">=</span><span class="s2">"TimeoutError"</span><span class="p">,</span>
</span><span id="__span-0-298"><a id="__codelineno-0-298" name="__codelineno-0-298"></a> <span class="p">)</span>
</span><span id="__span-0-299"><a id="__codelineno-0-299" name="__codelineno-0-299"></a> <span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
</span><span id="__span-0-300"><a id="__codelineno-0-300" name="__codelineno-0-300"></a> <span class="n">elapsed</span> <span class="o">=</span> <span class="p">(</span><span class="n">time</span><span class="o">.</span><span class="n">perf_counter</span><span class="p">()</span> <span class="o">-</span> <span class="n">start</span><span class="p">)</span> <span class="o">*</span> <span class="mi">1000</span>
</span><span id="__span-0-301"><a id="__codelineno-0-301" name="__codelineno-0-301"></a> <span class="k">return</span> <span class="n">ExecutionResult</span><span class="p">(</span>
</span><span id="__span-0-302"><a id="__codelineno-0-302" name="__codelineno-0-302"></a> <span class="n">success</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
</span><span id="__span-0-303"><a id="__codelineno-0-303" name="__codelineno-0-303"></a> <span class="n">result</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-304"><a id="__codelineno-0-304" name="__codelineno-0-304"></a> <span class="n">stdout</span><span class="o">=</span><span class="s2">""</span><span class="p">,</span>
</span><span id="__span-0-305"><a id="__codelineno-0-305" name="__codelineno-0-305"></a> <span class="n">stderr</span><span class="o">=</span><span class="nb">str</span><span class="p">(</span><span class="n">e</span><span class="p">),</span>
</span><span id="__span-0-306"><a id="__codelineno-0-306" name="__codelineno-0-306"></a> <span class="n">execution_time_ms</span><span class="o">=</span><span class="n">elapsed</span><span class="p">,</span>
</span><span id="__span-0-307"><a id="__codelineno-0-307" name="__codelineno-0-307"></a> <span class="n">error_type</span><span class="o">=</span><span class="nb">type</span><span class="p">(</span><span class="n">e</span><span class="p">)</span><span class="o">.</span><span class="vm">__name__</span><span class="p">,</span>
</span><span id="__span-0-308"><a id="__codelineno-0-308" name="__codelineno-0-308"></a> <span class="p">)</span>
</span><span id="__span-0-309"><a id="__codelineno-0-309" name="__codelineno-0-309"></a>
</span><span id="__span-0-310"><a id="__codelineno-0-310" name="__codelineno-0-310"></a> <span class="c1"># =========================================================================</span>
</span><span id="__span-0-311"><a id="__codelineno-0-311" name="__codelineno-0-311"></a> <span class="c1"># Document Management</span>
</span><span id="__span-0-312"><a id="__codelineno-0-312" name="__codelineno-0-312"></a> <span class="c1"># =========================================================================</span>
</span><span id="__span-0-313"><a id="__codelineno-0-313" name="__codelineno-0-313"></a>
</span><span id="__span-0-314"><a id="__codelineno-0-314" name="__codelineno-0-314"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">get_documents</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">list</span><span class="p">[</span><span class="n">DocumentInfo</span><span class="p">]:</span>
</span><span id="__span-0-315"><a id="__codelineno-0-315" name="__codelineno-0-315"></a><span class="w"> </span><span class="sd">"""Get list of open documents."""</span>
</span><span id="__span-0-316"><a id="__codelineno-0-316" name="__codelineno-0-316"></a> <span class="n">result</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">execute_python</span><span class="p">(</span>
</span><span id="__span-0-317"><a id="__codelineno-0-317" name="__codelineno-0-317"></a><span class="w"> </span><span class="sd">"""</span>
</span><span id="__span-0-318"><a id="__codelineno-0-318" name="__codelineno-0-318"></a><span class="sd">_result_ = []</span>
</span><span id="__span-0-319"><a id="__codelineno-0-319" name="__codelineno-0-319"></a><span class="sd">for doc in FreeCAD.listDocuments().values():</span>
</span><span id="__span-0-320"><a id="__codelineno-0-320" name="__codelineno-0-320"></a><span class="sd"> _result_.append({</span>
</span><span id="__span-0-321"><a id="__codelineno-0-321" name="__codelineno-0-321"></a><span class="sd"> "name": doc.Name,</span>
</span><span id="__span-0-322"><a id="__codelineno-0-322" name="__codelineno-0-322"></a><span class="sd"> "label": doc.Label,</span>
</span><span id="__span-0-323"><a id="__codelineno-0-323" name="__codelineno-0-323"></a><span class="sd"> "path": doc.FileName or None,</span>
</span><span id="__span-0-324"><a id="__codelineno-0-324" name="__codelineno-0-324"></a><span class="sd"> "objects": [obj.Name for obj in doc.Objects],</span>
</span><span id="__span-0-325"><a id="__codelineno-0-325" name="__codelineno-0-325"></a><span class="sd"> "is_modified": doc.Modified if hasattr(doc, "Modified") else False,</span>
</span><span id="__span-0-326"><a id="__codelineno-0-326" name="__codelineno-0-326"></a><span class="sd"> "active_object": doc.ActiveObject.Name if doc.ActiveObject else None,</span>
</span><span id="__span-0-327"><a id="__codelineno-0-327" name="__codelineno-0-327"></a><span class="sd"> })</span>
</span><span id="__span-0-328"><a id="__codelineno-0-328" name="__codelineno-0-328"></a><span class="sd">"""</span>
</span><span id="__span-0-329"><a id="__codelineno-0-329" name="__codelineno-0-329"></a> <span class="p">)</span>
</span><span id="__span-0-330"><a id="__codelineno-0-330" name="__codelineno-0-330"></a>
</span><span id="__span-0-331"><a id="__codelineno-0-331" name="__codelineno-0-331"></a> <span class="k">if</span> <span class="n">result</span><span class="o">.</span><span class="n">success</span> <span class="ow">and</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">:</span>
</span><span id="__span-0-332"><a id="__codelineno-0-332" name="__codelineno-0-332"></a> <span class="k">return</span> <span class="p">[</span><span class="n">DocumentInfo</span><span class="p">(</span><span class="o">**</span><span class="n">doc</span><span class="p">)</span> <span class="k">for</span> <span class="n">doc</span> <span class="ow">in</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">]</span>
</span><span id="__span-0-333"><a id="__codelineno-0-333" name="__codelineno-0-333"></a> <span class="k">return</span> <span class="p">[]</span>
</span><span id="__span-0-334"><a id="__codelineno-0-334" name="__codelineno-0-334"></a>
</span><span id="__span-0-335"><a id="__codelineno-0-335" name="__codelineno-0-335"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">get_active_document</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">DocumentInfo</span> <span class="o">|</span> <span class="kc">None</span><span class="p">:</span>
</span><span id="__span-0-336"><a id="__codelineno-0-336" name="__codelineno-0-336"></a><span class="w"> </span><span class="sd">"""Get the active document."""</span>
</span><span id="__span-0-337"><a id="__codelineno-0-337" name="__codelineno-0-337"></a> <span class="n">result</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">execute_python</span><span class="p">(</span>
</span><span id="__span-0-338"><a id="__codelineno-0-338" name="__codelineno-0-338"></a><span class="w"> </span><span class="sd">"""</span>
</span><span id="__span-0-339"><a id="__codelineno-0-339" name="__codelineno-0-339"></a><span class="sd">doc = FreeCAD.ActiveDocument</span>
</span><span id="__span-0-340"><a id="__codelineno-0-340" name="__codelineno-0-340"></a><span class="sd">if doc:</span>
</span><span id="__span-0-341"><a id="__codelineno-0-341" name="__codelineno-0-341"></a><span class="sd"> _result_ = {</span>
</span><span id="__span-0-342"><a id="__codelineno-0-342" name="__codelineno-0-342"></a><span class="sd"> "name": doc.Name,</span>
</span><span id="__span-0-343"><a id="__codelineno-0-343" name="__codelineno-0-343"></a><span class="sd"> "label": doc.Label,</span>
</span><span id="__span-0-344"><a id="__codelineno-0-344" name="__codelineno-0-344"></a><span class="sd"> "path": doc.FileName or None,</span>
</span><span id="__span-0-345"><a id="__codelineno-0-345" name="__codelineno-0-345"></a><span class="sd"> "objects": [obj.Name for obj in doc.Objects],</span>
</span><span id="__span-0-346"><a id="__codelineno-0-346" name="__codelineno-0-346"></a><span class="sd"> "is_modified": doc.Modified if hasattr(doc, "Modified") else False,</span>
</span><span id="__span-0-347"><a id="__codelineno-0-347" name="__codelineno-0-347"></a><span class="sd"> "active_object": doc.ActiveObject.Name if doc.ActiveObject else None,</span>
</span><span id="__span-0-348"><a id="__codelineno-0-348" name="__codelineno-0-348"></a><span class="sd"> }</span>
</span><span id="__span-0-349"><a id="__codelineno-0-349" name="__codelineno-0-349"></a><span class="sd">else:</span>
</span><span id="__span-0-350"><a id="__codelineno-0-350" name="__codelineno-0-350"></a><span class="sd"> _result_ = None</span>
</span><span id="__span-0-351"><a id="__codelineno-0-351" name="__codelineno-0-351"></a><span class="sd">"""</span>
</span><span id="__span-0-352"><a id="__codelineno-0-352" name="__codelineno-0-352"></a> <span class="p">)</span>
</span><span id="__span-0-353"><a id="__codelineno-0-353" name="__codelineno-0-353"></a>
</span><span id="__span-0-354"><a id="__codelineno-0-354" name="__codelineno-0-354"></a> <span class="k">if</span> <span class="n">result</span><span class="o">.</span><span class="n">success</span> <span class="ow">and</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">:</span>
</span><span id="__span-0-355"><a id="__codelineno-0-355" name="__codelineno-0-355"></a> <span class="k">return</span> <span class="n">DocumentInfo</span><span class="p">(</span><span class="o">**</span><span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">)</span>
</span><span id="__span-0-356"><a id="__codelineno-0-356" name="__codelineno-0-356"></a> <span class="k">return</span> <span class="kc">None</span>
</span><span id="__span-0-357"><a id="__codelineno-0-357" name="__codelineno-0-357"></a>
</span><span id="__span-0-358"><a id="__codelineno-0-358" name="__codelineno-0-358"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">create_document</span><span class="p">(</span>
</span><span id="__span-0-359"><a id="__codelineno-0-359" name="__codelineno-0-359"></a> <span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">label</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span>
</span><span id="__span-0-360"><a id="__codelineno-0-360" name="__codelineno-0-360"></a> <span class="p">)</span> <span class="o">-&gt;</span> <span class="n">DocumentInfo</span><span class="p">:</span>
</span><span id="__span-0-361"><a id="__codelineno-0-361" name="__codelineno-0-361"></a><span class="w"> </span><span class="sd">"""Create a new document."""</span>
</span><span id="__span-0-362"><a id="__codelineno-0-362" name="__codelineno-0-362"></a> <span class="n">label</span> <span class="o">=</span> <span class="n">label</span> <span class="ow">or</span> <span class="n">name</span>
</span><span id="__span-0-363"><a id="__codelineno-0-363" name="__codelineno-0-363"></a> <span class="n">result</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">execute_python</span><span class="p">(</span>
</span><span id="__span-0-364"><a id="__codelineno-0-364" name="__codelineno-0-364"></a> <span class="sa">f</span><span class="s2">"""</span>
</span><span id="__span-0-365"><a id="__codelineno-0-365" name="__codelineno-0-365"></a><span class="s2">doc = FreeCAD.newDocument(</span><span class="si">{</span><span class="n">name</span><span class="si">!r}</span><span class="s2">)</span>
</span><span id="__span-0-366"><a id="__codelineno-0-366" name="__codelineno-0-366"></a><span class="s2">doc.Label = </span><span class="si">{</span><span class="n">label</span><span class="si">!r}</span>
</span><span id="__span-0-367"><a id="__codelineno-0-367" name="__codelineno-0-367"></a><span class="s2">_result_ = </span><span class="se">{{</span>
</span><span id="__span-0-368"><a id="__codelineno-0-368" name="__codelineno-0-368"></a><span class="s2"> "name": doc.Name,</span>
</span><span id="__span-0-369"><a id="__codelineno-0-369" name="__codelineno-0-369"></a><span class="s2"> "label": doc.Label,</span>
</span><span id="__span-0-370"><a id="__codelineno-0-370" name="__codelineno-0-370"></a><span class="s2"> "path": doc.FileName or None,</span>
</span><span id="__span-0-371"><a id="__codelineno-0-371" name="__codelineno-0-371"></a><span class="s2"> "objects": [],</span>
</span><span id="__span-0-372"><a id="__codelineno-0-372" name="__codelineno-0-372"></a><span class="s2"> "is_modified": False,</span>
</span><span id="__span-0-373"><a id="__codelineno-0-373" name="__codelineno-0-373"></a><span class="se">}}</span>
</span><span id="__span-0-374"><a id="__codelineno-0-374" name="__codelineno-0-374"></a><span class="s2">"""</span>
</span><span id="__span-0-375"><a id="__codelineno-0-375" name="__codelineno-0-375"></a> <span class="p">)</span>
</span><span id="__span-0-376"><a id="__codelineno-0-376" name="__codelineno-0-376"></a>
</span><span id="__span-0-377"><a id="__codelineno-0-377" name="__codelineno-0-377"></a> <span class="k">if</span> <span class="n">result</span><span class="o">.</span><span class="n">success</span> <span class="ow">and</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">:</span>
</span><span id="__span-0-378"><a id="__codelineno-0-378" name="__codelineno-0-378"></a> <span class="k">return</span> <span class="n">DocumentInfo</span><span class="p">(</span><span class="o">**</span><span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">)</span>
</span><span id="__span-0-379"><a id="__codelineno-0-379" name="__codelineno-0-379"></a>
</span><span id="__span-0-380"><a id="__codelineno-0-380" name="__codelineno-0-380"></a> <span class="n">error_msg</span> <span class="o">=</span> <span class="n">result</span><span class="o">.</span><span class="n">error_traceback</span> <span class="ow">or</span> <span class="s2">"Failed to create document"</span>
</span><span id="__span-0-381"><a id="__codelineno-0-381" name="__codelineno-0-381"></a> <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="n">error_msg</span><span class="p">)</span>
</span><span id="__span-0-382"><a id="__codelineno-0-382" name="__codelineno-0-382"></a>
</span><span id="__span-0-383"><a id="__codelineno-0-383" name="__codelineno-0-383"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">open_document</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">path</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">DocumentInfo</span><span class="p">:</span>
</span><span id="__span-0-384"><a id="__codelineno-0-384" name="__codelineno-0-384"></a><span class="w"> </span><span class="sd">"""Open an existing document."""</span>
</span><span id="__span-0-385"><a id="__codelineno-0-385" name="__codelineno-0-385"></a> <span class="n">result</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">execute_python</span><span class="p">(</span>
</span><span id="__span-0-386"><a id="__codelineno-0-386" name="__codelineno-0-386"></a> <span class="sa">f</span><span class="s2">"""</span>
</span><span id="__span-0-387"><a id="__codelineno-0-387" name="__codelineno-0-387"></a><span class="s2">import os</span>
</span><span id="__span-0-388"><a id="__codelineno-0-388" name="__codelineno-0-388"></a><span class="s2">if not os.path.exists(</span><span class="si">{</span><span class="n">path</span><span class="si">!r}</span><span class="s2">):</span>
</span><span id="__span-0-389"><a id="__codelineno-0-389" name="__codelineno-0-389"></a><span class="s2"> raise FileNotFoundError(f"File not found: </span><span class="si">{</span><span class="n">path</span><span class="si">!r}</span><span class="s2">")</span>
</span><span id="__span-0-390"><a id="__codelineno-0-390" name="__codelineno-0-390"></a>
</span><span id="__span-0-391"><a id="__codelineno-0-391" name="__codelineno-0-391"></a><span class="s2">doc = FreeCAD.openDocument(</span><span class="si">{</span><span class="n">path</span><span class="si">!r}</span><span class="s2">)</span>
</span><span id="__span-0-392"><a id="__codelineno-0-392" name="__codelineno-0-392"></a><span class="s2">_result_ = </span><span class="se">{{</span>
</span><span id="__span-0-393"><a id="__codelineno-0-393" name="__codelineno-0-393"></a><span class="s2"> "name": doc.Name,</span>
</span><span id="__span-0-394"><a id="__codelineno-0-394" name="__codelineno-0-394"></a><span class="s2"> "label": doc.Label,</span>
</span><span id="__span-0-395"><a id="__codelineno-0-395" name="__codelineno-0-395"></a><span class="s2"> "path": doc.FileName or None,</span>
</span><span id="__span-0-396"><a id="__codelineno-0-396" name="__codelineno-0-396"></a><span class="s2"> "objects": [obj.Name for obj in doc.Objects],</span>
</span><span id="__span-0-397"><a id="__codelineno-0-397" name="__codelineno-0-397"></a><span class="s2"> "is_modified": doc.Modified if hasattr(doc, "Modified") else False,</span>
</span><span id="__span-0-398"><a id="__codelineno-0-398" name="__codelineno-0-398"></a><span class="se">}}</span>
</span><span id="__span-0-399"><a id="__codelineno-0-399" name="__codelineno-0-399"></a><span class="s2">"""</span>
</span><span id="__span-0-400"><a id="__codelineno-0-400" name="__codelineno-0-400"></a> <span class="p">)</span>
</span><span id="__span-0-401"><a id="__codelineno-0-401" name="__codelineno-0-401"></a>
</span><span id="__span-0-402"><a id="__codelineno-0-402" name="__codelineno-0-402"></a> <span class="k">if</span> <span class="n">result</span><span class="o">.</span><span class="n">success</span> <span class="ow">and</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">:</span>
</span><span id="__span-0-403"><a id="__codelineno-0-403" name="__codelineno-0-403"></a> <span class="k">return</span> <span class="n">DocumentInfo</span><span class="p">(</span><span class="o">**</span><span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">)</span>
</span><span id="__span-0-404"><a id="__codelineno-0-404" name="__codelineno-0-404"></a>
</span><span id="__span-0-405"><a id="__codelineno-0-405" name="__codelineno-0-405"></a> <span class="k">if</span> <span class="s2">"FileNotFoundError"</span> <span class="ow">in</span> <span class="p">(</span><span class="n">result</span><span class="o">.</span><span class="n">error_type</span> <span class="ow">or</span> <span class="s2">""</span><span class="p">):</span>
</span><span id="__span-0-406"><a id="__codelineno-0-406" name="__codelineno-0-406"></a> <span class="k">raise</span> <span class="ne">FileNotFoundError</span><span class="p">(</span><span class="n">result</span><span class="o">.</span><span class="n">stderr</span><span class="p">)</span>
</span><span id="__span-0-407"><a id="__codelineno-0-407" name="__codelineno-0-407"></a>
</span><span id="__span-0-408"><a id="__codelineno-0-408" name="__codelineno-0-408"></a> <span class="n">error_msg</span> <span class="o">=</span> <span class="n">result</span><span class="o">.</span><span class="n">error_traceback</span> <span class="ow">or</span> <span class="s2">"Failed to open document"</span>
</span><span id="__span-0-409"><a id="__codelineno-0-409" name="__codelineno-0-409"></a> <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="n">error_msg</span><span class="p">)</span>
</span><span id="__span-0-410"><a id="__codelineno-0-410" name="__codelineno-0-410"></a>
</span><span id="__span-0-411"><a id="__codelineno-0-411" name="__codelineno-0-411"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">save_document</span><span class="p">(</span>
</span><span id="__span-0-412"><a id="__codelineno-0-412" name="__codelineno-0-412"></a> <span class="bp">self</span><span class="p">,</span>
</span><span id="__span-0-413"><a id="__codelineno-0-413" name="__codelineno-0-413"></a> <span class="n">doc_name</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-414"><a id="__codelineno-0-414" name="__codelineno-0-414"></a> <span class="n">path</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-415"><a id="__codelineno-0-415" name="__codelineno-0-415"></a> <span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">str</span><span class="p">:</span>
</span><span id="__span-0-416"><a id="__codelineno-0-416" name="__codelineno-0-416"></a><span class="w"> </span><span class="sd">"""Save a document."""</span>
</span><span id="__span-0-417"><a id="__codelineno-0-417" name="__codelineno-0-417"></a> <span class="n">code</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">"""</span>
</span><span id="__span-0-418"><a id="__codelineno-0-418" name="__codelineno-0-418"></a><span class="s2">doc = FreeCAD.ActiveDocument if </span><span class="si">{</span><span class="n">doc_name</span><span class="si">!r}</span><span class="s2"> is None else FreeCAD.getDocument(</span><span class="si">{</span><span class="n">doc_name</span><span class="si">!r}</span><span class="s2">)</span>
</span><span id="__span-0-419"><a id="__codelineno-0-419" name="__codelineno-0-419"></a><span class="s2">if doc is None:</span>
</span><span id="__span-0-420"><a id="__codelineno-0-420" name="__codelineno-0-420"></a><span class="s2"> raise ValueError("No active document" if </span><span class="si">{</span><span class="n">doc_name</span><span class="si">!r}</span><span class="s2"> is None else f"Document not found: </span><span class="si">{</span><span class="n">doc_name</span><span class="si">!r}</span><span class="s2">")</span>
</span><span id="__span-0-421"><a id="__codelineno-0-421" name="__codelineno-0-421"></a>
</span><span id="__span-0-422"><a id="__codelineno-0-422" name="__codelineno-0-422"></a><span class="s2">save_path = </span><span class="si">{</span><span class="n">path</span><span class="si">!r}</span><span class="s2"> or doc.FileName</span>
</span><span id="__span-0-423"><a id="__codelineno-0-423" name="__codelineno-0-423"></a><span class="s2">if not save_path:</span>
</span><span id="__span-0-424"><a id="__codelineno-0-424" name="__codelineno-0-424"></a><span class="s2"> raise ValueError("No path specified for new document")</span>
</span><span id="__span-0-425"><a id="__codelineno-0-425" name="__codelineno-0-425"></a>
</span><span id="__span-0-426"><a id="__codelineno-0-426" name="__codelineno-0-426"></a><span class="s2">doc.saveAs(save_path)</span>
</span><span id="__span-0-427"><a id="__codelineno-0-427" name="__codelineno-0-427"></a><span class="s2">_result_ = save_path</span>
</span><span id="__span-0-428"><a id="__codelineno-0-428" name="__codelineno-0-428"></a><span class="s2">"""</span>
</span><span id="__span-0-429"><a id="__codelineno-0-429" name="__codelineno-0-429"></a> <span class="n">result</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">execute_python</span><span class="p">(</span><span class="n">code</span><span class="p">)</span>
</span><span id="__span-0-430"><a id="__codelineno-0-430" name="__codelineno-0-430"></a>
</span><span id="__span-0-431"><a id="__codelineno-0-431" name="__codelineno-0-431"></a> <span class="k">if</span> <span class="n">result</span><span class="o">.</span><span class="n">success</span> <span class="ow">and</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">:</span>
</span><span id="__span-0-432"><a id="__codelineno-0-432" name="__codelineno-0-432"></a> <span class="k">return</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span>
</span><span id="__span-0-433"><a id="__codelineno-0-433" name="__codelineno-0-433"></a>
</span><span id="__span-0-434"><a id="__codelineno-0-434" name="__codelineno-0-434"></a> <span class="n">error_msg</span> <span class="o">=</span> <span class="n">result</span><span class="o">.</span><span class="n">error_traceback</span> <span class="ow">or</span> <span class="s2">"Failed to save document"</span>
</span><span id="__span-0-435"><a id="__codelineno-0-435" name="__codelineno-0-435"></a> <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="n">error_msg</span><span class="p">)</span>
</span><span id="__span-0-436"><a id="__codelineno-0-436" name="__codelineno-0-436"></a>
</span><span id="__span-0-437"><a id="__codelineno-0-437" name="__codelineno-0-437"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">close_document</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">doc_name</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kc">None</span><span class="p">:</span>
</span><span id="__span-0-438"><a id="__codelineno-0-438" name="__codelineno-0-438"></a><span class="w"> </span><span class="sd">"""Close a document."""</span>
</span><span id="__span-0-439"><a id="__codelineno-0-439" name="__codelineno-0-439"></a> <span class="n">code</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">"""</span>
</span><span id="__span-0-440"><a id="__codelineno-0-440" name="__codelineno-0-440"></a><span class="s2">doc_name = </span><span class="si">{</span><span class="n">doc_name</span><span class="si">!r}</span>
</span><span id="__span-0-441"><a id="__codelineno-0-441" name="__codelineno-0-441"></a><span class="s2">if doc_name is None:</span>
</span><span id="__span-0-442"><a id="__codelineno-0-442" name="__codelineno-0-442"></a><span class="s2"> doc = FreeCAD.ActiveDocument</span>
</span><span id="__span-0-443"><a id="__codelineno-0-443" name="__codelineno-0-443"></a><span class="s2"> if doc:</span>
</span><span id="__span-0-444"><a id="__codelineno-0-444" name="__codelineno-0-444"></a><span class="s2"> doc_name = doc.Name</span>
</span><span id="__span-0-445"><a id="__codelineno-0-445" name="__codelineno-0-445"></a><span class="s2"> else:</span>
</span><span id="__span-0-446"><a id="__codelineno-0-446" name="__codelineno-0-446"></a><span class="s2"> raise ValueError("No active document")</span>
</span><span id="__span-0-447"><a id="__codelineno-0-447" name="__codelineno-0-447"></a>
</span><span id="__span-0-448"><a id="__codelineno-0-448" name="__codelineno-0-448"></a><span class="s2">FreeCAD.closeDocument(doc_name)</span>
</span><span id="__span-0-449"><a id="__codelineno-0-449" name="__codelineno-0-449"></a><span class="s2">_result_ = True</span>
</span><span id="__span-0-450"><a id="__codelineno-0-450" name="__codelineno-0-450"></a><span class="s2">"""</span>
</span><span id="__span-0-451"><a id="__codelineno-0-451" name="__codelineno-0-451"></a> <span class="n">result</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">execute_python</span><span class="p">(</span><span class="n">code</span><span class="p">)</span>
</span><span id="__span-0-452"><a id="__codelineno-0-452" name="__codelineno-0-452"></a>
</span><span id="__span-0-453"><a id="__codelineno-0-453" name="__codelineno-0-453"></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">result</span><span class="o">.</span><span class="n">success</span><span class="p">:</span>
</span><span id="__span-0-454"><a id="__codelineno-0-454" name="__codelineno-0-454"></a> <span class="n">error_msg</span> <span class="o">=</span> <span class="n">result</span><span class="o">.</span><span class="n">error_traceback</span> <span class="ow">or</span> <span class="s2">"Failed to close document"</span>
</span><span id="__span-0-455"><a id="__codelineno-0-455" name="__codelineno-0-455"></a> <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="n">error_msg</span><span class="p">)</span>
</span><span id="__span-0-456"><a id="__codelineno-0-456" name="__codelineno-0-456"></a>
</span><span id="__span-0-457"><a id="__codelineno-0-457" name="__codelineno-0-457"></a> <span class="c1"># =========================================================================</span>
</span><span id="__span-0-458"><a id="__codelineno-0-458" name="__codelineno-0-458"></a> <span class="c1"># Object Management</span>
</span><span id="__span-0-459"><a id="__codelineno-0-459" name="__codelineno-0-459"></a> <span class="c1"># =========================================================================</span>
</span><span id="__span-0-460"><a id="__codelineno-0-460" name="__codelineno-0-460"></a>
</span><span id="__span-0-461"><a id="__codelineno-0-461" name="__codelineno-0-461"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">get_objects</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">doc_name</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">list</span><span class="p">[</span><span class="n">ObjectInfo</span><span class="p">]:</span>
</span><span id="__span-0-462"><a id="__codelineno-0-462" name="__codelineno-0-462"></a><span class="w"> </span><span class="sd">"""Get all objects in a document."""</span>
</span><span id="__span-0-463"><a id="__codelineno-0-463" name="__codelineno-0-463"></a> <span class="n">code</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">"""</span>
</span><span id="__span-0-464"><a id="__codelineno-0-464" name="__codelineno-0-464"></a><span class="s2">doc = FreeCAD.ActiveDocument if </span><span class="si">{</span><span class="n">doc_name</span><span class="si">!r}</span><span class="s2"> is None else FreeCAD.getDocument(</span><span class="si">{</span><span class="n">doc_name</span><span class="si">!r}</span><span class="s2">)</span>
</span><span id="__span-0-465"><a id="__codelineno-0-465" name="__codelineno-0-465"></a><span class="s2">if doc is None:</span>
</span><span id="__span-0-466"><a id="__codelineno-0-466" name="__codelineno-0-466"></a><span class="s2"> raise ValueError("No document found")</span>
</span><span id="__span-0-467"><a id="__codelineno-0-467" name="__codelineno-0-467"></a>
</span><span id="__span-0-468"><a id="__codelineno-0-468" name="__codelineno-0-468"></a><span class="s2">objects = []</span>
</span><span id="__span-0-469"><a id="__codelineno-0-469" name="__codelineno-0-469"></a><span class="s2">for obj in doc.Objects:</span>
</span><span id="__span-0-470"><a id="__codelineno-0-470" name="__codelineno-0-470"></a><span class="s2"> obj_info = </span><span class="se">{{</span>
</span><span id="__span-0-471"><a id="__codelineno-0-471" name="__codelineno-0-471"></a><span class="s2"> "name": obj.Name,</span>
</span><span id="__span-0-472"><a id="__codelineno-0-472" name="__codelineno-0-472"></a><span class="s2"> "label": obj.Label,</span>
</span><span id="__span-0-473"><a id="__codelineno-0-473" name="__codelineno-0-473"></a><span class="s2"> "type_id": obj.TypeId,</span>
</span><span id="__span-0-474"><a id="__codelineno-0-474" name="__codelineno-0-474"></a><span class="s2"> "visibility": obj.ViewObject.Visibility if hasattr(obj, "ViewObject") and obj.ViewObject else True,</span>
</span><span id="__span-0-475"><a id="__codelineno-0-475" name="__codelineno-0-475"></a><span class="s2"> "children": [c.Name for c in obj.OutList] if hasattr(obj, "OutList") else [],</span>
</span><span id="__span-0-476"><a id="__codelineno-0-476" name="__codelineno-0-476"></a><span class="s2"> "parents": [p.Name for p in obj.InList] if hasattr(obj, "InList") else [],</span>
</span><span id="__span-0-477"><a id="__codelineno-0-477" name="__codelineno-0-477"></a><span class="s2"> </span><span class="se">}}</span>
</span><span id="__span-0-478"><a id="__codelineno-0-478" name="__codelineno-0-478"></a><span class="s2"> objects.append(obj_info)</span>
</span><span id="__span-0-479"><a id="__codelineno-0-479" name="__codelineno-0-479"></a>
</span><span id="__span-0-480"><a id="__codelineno-0-480" name="__codelineno-0-480"></a><span class="s2">_result_ = objects</span>
</span><span id="__span-0-481"><a id="__codelineno-0-481" name="__codelineno-0-481"></a><span class="s2">"""</span>
</span><span id="__span-0-482"><a id="__codelineno-0-482" name="__codelineno-0-482"></a> <span class="n">result</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">execute_python</span><span class="p">(</span><span class="n">code</span><span class="p">)</span>
</span><span id="__span-0-483"><a id="__codelineno-0-483" name="__codelineno-0-483"></a>
</span><span id="__span-0-484"><a id="__codelineno-0-484" name="__codelineno-0-484"></a> <span class="k">if</span> <span class="n">result</span><span class="o">.</span><span class="n">success</span> <span class="ow">and</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">:</span>
</span><span id="__span-0-485"><a id="__codelineno-0-485" name="__codelineno-0-485"></a> <span class="k">return</span> <span class="p">[</span><span class="n">ObjectInfo</span><span class="p">(</span><span class="o">**</span><span class="n">obj</span><span class="p">)</span> <span class="k">for</span> <span class="n">obj</span> <span class="ow">in</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">]</span>
</span><span id="__span-0-486"><a id="__codelineno-0-486" name="__codelineno-0-486"></a> <span class="k">return</span> <span class="p">[]</span>
</span><span id="__span-0-487"><a id="__codelineno-0-487" name="__codelineno-0-487"></a>
</span><span id="__span-0-488"><a id="__codelineno-0-488" name="__codelineno-0-488"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">get_object</span><span class="p">(</span>
</span><span id="__span-0-489"><a id="__codelineno-0-489" name="__codelineno-0-489"></a> <span class="bp">self</span><span class="p">,</span>
</span><span id="__span-0-490"><a id="__codelineno-0-490" name="__codelineno-0-490"></a> <span class="n">obj_name</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span>
</span><span id="__span-0-491"><a id="__codelineno-0-491" name="__codelineno-0-491"></a> <span class="n">doc_name</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-492"><a id="__codelineno-0-492" name="__codelineno-0-492"></a> <span class="p">)</span> <span class="o">-&gt;</span> <span class="n">ObjectInfo</span><span class="p">:</span>
</span><span id="__span-0-493"><a id="__codelineno-0-493" name="__codelineno-0-493"></a><span class="w"> </span><span class="sd">"""Get detailed object information."""</span>
</span><span id="__span-0-494"><a id="__codelineno-0-494" name="__codelineno-0-494"></a> <span class="n">code</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">"""</span>
</span><span id="__span-0-495"><a id="__codelineno-0-495" name="__codelineno-0-495"></a><span class="s2">doc = FreeCAD.ActiveDocument if </span><span class="si">{</span><span class="n">doc_name</span><span class="si">!r}</span><span class="s2"> is None else FreeCAD.getDocument(</span><span class="si">{</span><span class="n">doc_name</span><span class="si">!r}</span><span class="s2">)</span>
</span><span id="__span-0-496"><a id="__codelineno-0-496" name="__codelineno-0-496"></a><span class="s2">if doc is None:</span>
</span><span id="__span-0-497"><a id="__codelineno-0-497" name="__codelineno-0-497"></a><span class="s2"> raise ValueError("No document found")</span>
</span><span id="__span-0-498"><a id="__codelineno-0-498" name="__codelineno-0-498"></a>
</span><span id="__span-0-499"><a id="__codelineno-0-499" name="__codelineno-0-499"></a><span class="s2">obj = doc.getObject(</span><span class="si">{</span><span class="n">obj_name</span><span class="si">!r}</span><span class="s2">)</span>
</span><span id="__span-0-500"><a id="__codelineno-0-500" name="__codelineno-0-500"></a><span class="s2">if obj is None:</span>
</span><span id="__span-0-501"><a id="__codelineno-0-501" name="__codelineno-0-501"></a><span class="s2"> raise ValueError(f"Object not found: </span><span class="si">{</span><span class="n">obj_name</span><span class="si">!r}</span><span class="s2">")</span>
</span><span id="__span-0-502"><a id="__codelineno-0-502" name="__codelineno-0-502"></a>
</span><span id="__span-0-503"><a id="__codelineno-0-503" name="__codelineno-0-503"></a><span class="s2">props = </span><span class="se">{{}}</span>
</span><span id="__span-0-504"><a id="__codelineno-0-504" name="__codelineno-0-504"></a><span class="s2">for prop in obj.PropertiesList:</span>
</span><span id="__span-0-505"><a id="__codelineno-0-505" name="__codelineno-0-505"></a><span class="s2"> try:</span>
</span><span id="__span-0-506"><a id="__codelineno-0-506" name="__codelineno-0-506"></a><span class="s2"> val = getattr(obj, prop)</span>
</span><span id="__span-0-507"><a id="__codelineno-0-507" name="__codelineno-0-507"></a><span class="s2"> if hasattr(val, '__class__') and val.__class__.__module__ != 'builtins':</span>
</span><span id="__span-0-508"><a id="__codelineno-0-508" name="__codelineno-0-508"></a><span class="s2"> val = str(val)</span>
</span><span id="__span-0-509"><a id="__codelineno-0-509" name="__codelineno-0-509"></a><span class="s2"> props[prop] = val</span>
</span><span id="__span-0-510"><a id="__codelineno-0-510" name="__codelineno-0-510"></a><span class="s2"> except Exception:</span>
</span><span id="__span-0-511"><a id="__codelineno-0-511" name="__codelineno-0-511"></a><span class="s2"> props[prop] = "&lt;unreadable&gt;"</span>
</span><span id="__span-0-512"><a id="__codelineno-0-512" name="__codelineno-0-512"></a>
</span><span id="__span-0-513"><a id="__codelineno-0-513" name="__codelineno-0-513"></a><span class="s2">shape_info = None</span>
</span><span id="__span-0-514"><a id="__codelineno-0-514" name="__codelineno-0-514"></a><span class="s2">if hasattr(obj, "Shape"):</span>
</span><span id="__span-0-515"><a id="__codelineno-0-515" name="__codelineno-0-515"></a><span class="s2"> shape = obj.Shape</span>
</span><span id="__span-0-516"><a id="__codelineno-0-516" name="__codelineno-0-516"></a><span class="s2"> shape_info = </span><span class="se">{{</span>
</span><span id="__span-0-517"><a id="__codelineno-0-517" name="__codelineno-0-517"></a><span class="s2"> "shape_type": shape.ShapeType,</span>
</span><span id="__span-0-518"><a id="__codelineno-0-518" name="__codelineno-0-518"></a><span class="s2"> "volume": shape.Volume if hasattr(shape, "Volume") else None,</span>
</span><span id="__span-0-519"><a id="__codelineno-0-519" name="__codelineno-0-519"></a><span class="s2"> "area": shape.Area if hasattr(shape, "Area") else None,</span>
</span><span id="__span-0-520"><a id="__codelineno-0-520" name="__codelineno-0-520"></a><span class="s2"> "is_valid": shape.isValid(),</span>
</span><span id="__span-0-521"><a id="__codelineno-0-521" name="__codelineno-0-521"></a><span class="s2"> "is_closed": shape.isClosed() if hasattr(shape, "isClosed") else False,</span>
</span><span id="__span-0-522"><a id="__codelineno-0-522" name="__codelineno-0-522"></a><span class="s2"> "vertex_count": len(shape.Vertexes) if hasattr(shape, "Vertexes") else 0,</span>
</span><span id="__span-0-523"><a id="__codelineno-0-523" name="__codelineno-0-523"></a><span class="s2"> "edge_count": len(shape.Edges) if hasattr(shape, "Edges") else 0,</span>
</span><span id="__span-0-524"><a id="__codelineno-0-524" name="__codelineno-0-524"></a><span class="s2"> "face_count": len(shape.Faces) if hasattr(shape, "Faces") else 0,</span>
</span><span id="__span-0-525"><a id="__codelineno-0-525" name="__codelineno-0-525"></a><span class="s2"> </span><span class="se">}}</span>
</span><span id="__span-0-526"><a id="__codelineno-0-526" name="__codelineno-0-526"></a>
</span><span id="__span-0-527"><a id="__codelineno-0-527" name="__codelineno-0-527"></a><span class="s2">_result_ = </span><span class="se">{{</span>
</span><span id="__span-0-528"><a id="__codelineno-0-528" name="__codelineno-0-528"></a><span class="s2"> "name": obj.Name,</span>
</span><span id="__span-0-529"><a id="__codelineno-0-529" name="__codelineno-0-529"></a><span class="s2"> "label": obj.Label,</span>
</span><span id="__span-0-530"><a id="__codelineno-0-530" name="__codelineno-0-530"></a><span class="s2"> "type_id": obj.TypeId,</span>
</span><span id="__span-0-531"><a id="__codelineno-0-531" name="__codelineno-0-531"></a><span class="s2"> "properties": props,</span>
</span><span id="__span-0-532"><a id="__codelineno-0-532" name="__codelineno-0-532"></a><span class="s2"> "shape_info": shape_info,</span>
</span><span id="__span-0-533"><a id="__codelineno-0-533" name="__codelineno-0-533"></a><span class="s2"> "children": [c.Name for c in obj.OutList] if hasattr(obj, "OutList") else [],</span>
</span><span id="__span-0-534"><a id="__codelineno-0-534" name="__codelineno-0-534"></a><span class="s2"> "parents": [p.Name for p in obj.InList] if hasattr(obj, "InList") else [],</span>
</span><span id="__span-0-535"><a id="__codelineno-0-535" name="__codelineno-0-535"></a><span class="s2"> "visibility": obj.ViewObject.Visibility if hasattr(obj, "ViewObject") and obj.ViewObject else True,</span>
</span><span id="__span-0-536"><a id="__codelineno-0-536" name="__codelineno-0-536"></a><span class="se">}}</span>
</span><span id="__span-0-537"><a id="__codelineno-0-537" name="__codelineno-0-537"></a><span class="s2">"""</span>
</span><span id="__span-0-538"><a id="__codelineno-0-538" name="__codelineno-0-538"></a> <span class="n">result</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">execute_python</span><span class="p">(</span><span class="n">code</span><span class="p">)</span>
</span><span id="__span-0-539"><a id="__codelineno-0-539" name="__codelineno-0-539"></a>
</span><span id="__span-0-540"><a id="__codelineno-0-540" name="__codelineno-0-540"></a> <span class="k">if</span> <span class="n">result</span><span class="o">.</span><span class="n">success</span> <span class="ow">and</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">:</span>
</span><span id="__span-0-541"><a id="__codelineno-0-541" name="__codelineno-0-541"></a> <span class="k">return</span> <span class="n">ObjectInfo</span><span class="p">(</span><span class="o">**</span><span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">)</span>
</span><span id="__span-0-542"><a id="__codelineno-0-542" name="__codelineno-0-542"></a>
</span><span id="__span-0-543"><a id="__codelineno-0-543" name="__codelineno-0-543"></a> <span class="n">error_msg</span> <span class="o">=</span> <span class="n">result</span><span class="o">.</span><span class="n">error_traceback</span> <span class="ow">or</span> <span class="s2">"Failed to get object"</span>
</span><span id="__span-0-544"><a id="__codelineno-0-544" name="__codelineno-0-544"></a> <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="n">error_msg</span><span class="p">)</span>
</span><span id="__span-0-545"><a id="__codelineno-0-545" name="__codelineno-0-545"></a>
</span><span id="__span-0-546"><a id="__codelineno-0-546" name="__codelineno-0-546"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">create_object</span><span class="p">(</span>
</span><span id="__span-0-547"><a id="__codelineno-0-547" name="__codelineno-0-547"></a> <span class="bp">self</span><span class="p">,</span>
</span><span id="__span-0-548"><a id="__codelineno-0-548" name="__codelineno-0-548"></a> <span class="n">type_id</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span>
</span><span id="__span-0-549"><a id="__codelineno-0-549" name="__codelineno-0-549"></a> <span class="n">name</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-550"><a id="__codelineno-0-550" name="__codelineno-0-550"></a> <span class="n">properties</span><span class="p">:</span> <span class="nb">dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Any</span><span class="p">]</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-551"><a id="__codelineno-0-551" name="__codelineno-0-551"></a> <span class="n">doc_name</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-552"><a id="__codelineno-0-552" name="__codelineno-0-552"></a> <span class="p">)</span> <span class="o">-&gt;</span> <span class="n">ObjectInfo</span><span class="p">:</span>
</span><span id="__span-0-553"><a id="__codelineno-0-553" name="__codelineno-0-553"></a><span class="w"> </span><span class="sd">"""Create a new object."""</span>
</span><span id="__span-0-554"><a id="__codelineno-0-554" name="__codelineno-0-554"></a> <span class="n">properties</span> <span class="o">=</span> <span class="n">properties</span> <span class="ow">or</span> <span class="p">{}</span>
</span><span id="__span-0-555"><a id="__codelineno-0-555" name="__codelineno-0-555"></a> <span class="n">code</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">"""</span>
</span><span id="__span-0-556"><a id="__codelineno-0-556" name="__codelineno-0-556"></a><span class="s2">doc = FreeCAD.ActiveDocument if </span><span class="si">{</span><span class="n">doc_name</span><span class="si">!r}</span><span class="s2"> is None else FreeCAD.getDocument(</span><span class="si">{</span><span class="n">doc_name</span><span class="si">!r}</span><span class="s2">)</span>
</span><span id="__span-0-557"><a id="__codelineno-0-557" name="__codelineno-0-557"></a><span class="s2">if doc is None:</span>
</span><span id="__span-0-558"><a id="__codelineno-0-558" name="__codelineno-0-558"></a><span class="s2"> raise ValueError("No document found")</span>
</span><span id="__span-0-559"><a id="__codelineno-0-559" name="__codelineno-0-559"></a>
</span><span id="__span-0-560"><a id="__codelineno-0-560" name="__codelineno-0-560"></a><span class="s2">obj = doc.addObject(</span><span class="si">{</span><span class="n">type_id</span><span class="si">!r}</span><span class="s2">, </span><span class="si">{</span><span class="n">name</span><span class="si">!r}</span><span class="s2"> or "")</span>
</span><span id="__span-0-561"><a id="__codelineno-0-561" name="__codelineno-0-561"></a>
</span><span id="__span-0-562"><a id="__codelineno-0-562" name="__codelineno-0-562"></a><span class="s2"># Set properties</span>
</span><span id="__span-0-563"><a id="__codelineno-0-563" name="__codelineno-0-563"></a><span class="s2">for prop_name, prop_val in </span><span class="si">{</span><span class="n">properties</span><span class="si">!r}</span><span class="s2">.items():</span>
</span><span id="__span-0-564"><a id="__codelineno-0-564" name="__codelineno-0-564"></a><span class="s2"> if hasattr(obj, prop_name):</span>
</span><span id="__span-0-565"><a id="__codelineno-0-565" name="__codelineno-0-565"></a><span class="s2"> setattr(obj, prop_name, prop_val)</span>
</span><span id="__span-0-566"><a id="__codelineno-0-566" name="__codelineno-0-566"></a>
</span><span id="__span-0-567"><a id="__codelineno-0-567" name="__codelineno-0-567"></a><span class="s2">doc.recompute()</span>
</span><span id="__span-0-568"><a id="__codelineno-0-568" name="__codelineno-0-568"></a>
</span><span id="__span-0-569"><a id="__codelineno-0-569" name="__codelineno-0-569"></a><span class="s2">_result_ = </span><span class="se">{{</span>
</span><span id="__span-0-570"><a id="__codelineno-0-570" name="__codelineno-0-570"></a><span class="s2"> "name": obj.Name,</span>
</span><span id="__span-0-571"><a id="__codelineno-0-571" name="__codelineno-0-571"></a><span class="s2"> "label": obj.Label,</span>
</span><span id="__span-0-572"><a id="__codelineno-0-572" name="__codelineno-0-572"></a><span class="s2"> "type_id": obj.TypeId,</span>
</span><span id="__span-0-573"><a id="__codelineno-0-573" name="__codelineno-0-573"></a><span class="s2"> "visibility": True,</span>
</span><span id="__span-0-574"><a id="__codelineno-0-574" name="__codelineno-0-574"></a><span class="s2"> "children": [c.Name for c in obj.OutList] if hasattr(obj, "OutList") else [],</span>
</span><span id="__span-0-575"><a id="__codelineno-0-575" name="__codelineno-0-575"></a><span class="s2"> "parents": [p.Name for p in obj.InList] if hasattr(obj, "InList") else [],</span>
</span><span id="__span-0-576"><a id="__codelineno-0-576" name="__codelineno-0-576"></a><span class="se">}}</span>
</span><span id="__span-0-577"><a id="__codelineno-0-577" name="__codelineno-0-577"></a><span class="s2">"""</span>
</span><span id="__span-0-578"><a id="__codelineno-0-578" name="__codelineno-0-578"></a> <span class="n">result</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">execute_python</span><span class="p">(</span><span class="n">code</span><span class="p">)</span>
</span><span id="__span-0-579"><a id="__codelineno-0-579" name="__codelineno-0-579"></a>
</span><span id="__span-0-580"><a id="__codelineno-0-580" name="__codelineno-0-580"></a> <span class="k">if</span> <span class="n">result</span><span class="o">.</span><span class="n">success</span> <span class="ow">and</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">:</span>
</span><span id="__span-0-581"><a id="__codelineno-0-581" name="__codelineno-0-581"></a> <span class="k">return</span> <span class="n">ObjectInfo</span><span class="p">(</span><span class="o">**</span><span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">)</span>
</span><span id="__span-0-582"><a id="__codelineno-0-582" name="__codelineno-0-582"></a>
</span><span id="__span-0-583"><a id="__codelineno-0-583" name="__codelineno-0-583"></a> <span class="n">error_msg</span> <span class="o">=</span> <span class="n">result</span><span class="o">.</span><span class="n">error_traceback</span> <span class="ow">or</span> <span class="s2">"Failed to create object"</span>
</span><span id="__span-0-584"><a id="__codelineno-0-584" name="__codelineno-0-584"></a> <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="n">error_msg</span><span class="p">)</span>
</span><span id="__span-0-585"><a id="__codelineno-0-585" name="__codelineno-0-585"></a>
</span><span id="__span-0-586"><a id="__codelineno-0-586" name="__codelineno-0-586"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">edit_object</span><span class="p">(</span>
</span><span id="__span-0-587"><a id="__codelineno-0-587" name="__codelineno-0-587"></a> <span class="bp">self</span><span class="p">,</span>
</span><span id="__span-0-588"><a id="__codelineno-0-588" name="__codelineno-0-588"></a> <span class="n">obj_name</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span>
</span><span id="__span-0-589"><a id="__codelineno-0-589" name="__codelineno-0-589"></a> <span class="n">properties</span><span class="p">:</span> <span class="nb">dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Any</span><span class="p">],</span>
</span><span id="__span-0-590"><a id="__codelineno-0-590" name="__codelineno-0-590"></a> <span class="n">doc_name</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-591"><a id="__codelineno-0-591" name="__codelineno-0-591"></a> <span class="p">)</span> <span class="o">-&gt;</span> <span class="n">ObjectInfo</span><span class="p">:</span>
</span><span id="__span-0-592"><a id="__codelineno-0-592" name="__codelineno-0-592"></a><span class="w"> </span><span class="sd">"""Edit object properties."""</span>
</span><span id="__span-0-593"><a id="__codelineno-0-593" name="__codelineno-0-593"></a> <span class="n">code</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">"""</span>
</span><span id="__span-0-594"><a id="__codelineno-0-594" name="__codelineno-0-594"></a><span class="s2">doc = FreeCAD.ActiveDocument if </span><span class="si">{</span><span class="n">doc_name</span><span class="si">!r}</span><span class="s2"> is None else FreeCAD.getDocument(</span><span class="si">{</span><span class="n">doc_name</span><span class="si">!r}</span><span class="s2">)</span>
</span><span id="__span-0-595"><a id="__codelineno-0-595" name="__codelineno-0-595"></a><span class="s2">if doc is None:</span>
</span><span id="__span-0-596"><a id="__codelineno-0-596" name="__codelineno-0-596"></a><span class="s2"> raise ValueError("No document found")</span>
</span><span id="__span-0-597"><a id="__codelineno-0-597" name="__codelineno-0-597"></a>
</span><span id="__span-0-598"><a id="__codelineno-0-598" name="__codelineno-0-598"></a><span class="s2">obj = doc.getObject(</span><span class="si">{</span><span class="n">obj_name</span><span class="si">!r}</span><span class="s2">)</span>
</span><span id="__span-0-599"><a id="__codelineno-0-599" name="__codelineno-0-599"></a><span class="s2">if obj is None:</span>
</span><span id="__span-0-600"><a id="__codelineno-0-600" name="__codelineno-0-600"></a><span class="s2"> raise ValueError(f"Object not found: </span><span class="si">{</span><span class="n">obj_name</span><span class="si">!r}</span><span class="s2">")</span>
</span><span id="__span-0-601"><a id="__codelineno-0-601" name="__codelineno-0-601"></a>
</span><span id="__span-0-602"><a id="__codelineno-0-602" name="__codelineno-0-602"></a><span class="s2"># Set properties</span>
</span><span id="__span-0-603"><a id="__codelineno-0-603" name="__codelineno-0-603"></a><span class="s2">for prop_name, prop_val in </span><span class="si">{</span><span class="n">properties</span><span class="si">!r}</span><span class="s2">.items():</span>
</span><span id="__span-0-604"><a id="__codelineno-0-604" name="__codelineno-0-604"></a><span class="s2"> if hasattr(obj, prop_name):</span>
</span><span id="__span-0-605"><a id="__codelineno-0-605" name="__codelineno-0-605"></a><span class="s2"> setattr(obj, prop_name, prop_val)</span>
</span><span id="__span-0-606"><a id="__codelineno-0-606" name="__codelineno-0-606"></a>
</span><span id="__span-0-607"><a id="__codelineno-0-607" name="__codelineno-0-607"></a><span class="s2">doc.recompute()</span>
</span><span id="__span-0-608"><a id="__codelineno-0-608" name="__codelineno-0-608"></a>
</span><span id="__span-0-609"><a id="__codelineno-0-609" name="__codelineno-0-609"></a><span class="s2">_result_ = </span><span class="se">{{</span>
</span><span id="__span-0-610"><a id="__codelineno-0-610" name="__codelineno-0-610"></a><span class="s2"> "name": obj.Name,</span>
</span><span id="__span-0-611"><a id="__codelineno-0-611" name="__codelineno-0-611"></a><span class="s2"> "label": obj.Label,</span>
</span><span id="__span-0-612"><a id="__codelineno-0-612" name="__codelineno-0-612"></a><span class="s2"> "type_id": obj.TypeId,</span>
</span><span id="__span-0-613"><a id="__codelineno-0-613" name="__codelineno-0-613"></a><span class="s2"> "visibility": obj.ViewObject.Visibility if hasattr(obj, "ViewObject") and obj.ViewObject else True,</span>
</span><span id="__span-0-614"><a id="__codelineno-0-614" name="__codelineno-0-614"></a><span class="s2"> "children": [c.Name for c in obj.OutList] if hasattr(obj, "OutList") else [],</span>
</span><span id="__span-0-615"><a id="__codelineno-0-615" name="__codelineno-0-615"></a><span class="s2"> "parents": [p.Name for p in obj.InList] if hasattr(obj, "InList") else [],</span>
</span><span id="__span-0-616"><a id="__codelineno-0-616" name="__codelineno-0-616"></a><span class="se">}}</span>
</span><span id="__span-0-617"><a id="__codelineno-0-617" name="__codelineno-0-617"></a><span class="s2">"""</span>
</span><span id="__span-0-618"><a id="__codelineno-0-618" name="__codelineno-0-618"></a> <span class="n">result</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">execute_python</span><span class="p">(</span><span class="n">code</span><span class="p">)</span>
</span><span id="__span-0-619"><a id="__codelineno-0-619" name="__codelineno-0-619"></a>
</span><span id="__span-0-620"><a id="__codelineno-0-620" name="__codelineno-0-620"></a> <span class="k">if</span> <span class="n">result</span><span class="o">.</span><span class="n">success</span> <span class="ow">and</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">:</span>
</span><span id="__span-0-621"><a id="__codelineno-0-621" name="__codelineno-0-621"></a> <span class="k">return</span> <span class="n">ObjectInfo</span><span class="p">(</span><span class="o">**</span><span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">)</span>
</span><span id="__span-0-622"><a id="__codelineno-0-622" name="__codelineno-0-622"></a>
</span><span id="__span-0-623"><a id="__codelineno-0-623" name="__codelineno-0-623"></a> <span class="n">error_msg</span> <span class="o">=</span> <span class="n">result</span><span class="o">.</span><span class="n">error_traceback</span> <span class="ow">or</span> <span class="s2">"Failed to edit object"</span>
</span><span id="__span-0-624"><a id="__codelineno-0-624" name="__codelineno-0-624"></a> <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="n">error_msg</span><span class="p">)</span>
</span><span id="__span-0-625"><a id="__codelineno-0-625" name="__codelineno-0-625"></a>
</span><span id="__span-0-626"><a id="__codelineno-0-626" name="__codelineno-0-626"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">delete_object</span><span class="p">(</span>
</span><span id="__span-0-627"><a id="__codelineno-0-627" name="__codelineno-0-627"></a> <span class="bp">self</span><span class="p">,</span>
</span><span id="__span-0-628"><a id="__codelineno-0-628" name="__codelineno-0-628"></a> <span class="n">obj_name</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span>
</span><span id="__span-0-629"><a id="__codelineno-0-629" name="__codelineno-0-629"></a> <span class="n">doc_name</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-630"><a id="__codelineno-0-630" name="__codelineno-0-630"></a> <span class="p">)</span> <span class="o">-&gt;</span> <span class="kc">None</span><span class="p">:</span>
</span><span id="__span-0-631"><a id="__codelineno-0-631" name="__codelineno-0-631"></a><span class="w"> </span><span class="sd">"""Delete an object."""</span>
</span><span id="__span-0-632"><a id="__codelineno-0-632" name="__codelineno-0-632"></a> <span class="n">code</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">"""</span>
</span><span id="__span-0-633"><a id="__codelineno-0-633" name="__codelineno-0-633"></a><span class="s2">doc = FreeCAD.ActiveDocument if </span><span class="si">{</span><span class="n">doc_name</span><span class="si">!r}</span><span class="s2"> is None else FreeCAD.getDocument(</span><span class="si">{</span><span class="n">doc_name</span><span class="si">!r}</span><span class="s2">)</span>
</span><span id="__span-0-634"><a id="__codelineno-0-634" name="__codelineno-0-634"></a><span class="s2">if doc is None:</span>
</span><span id="__span-0-635"><a id="__codelineno-0-635" name="__codelineno-0-635"></a><span class="s2"> raise ValueError("No document found")</span>
</span><span id="__span-0-636"><a id="__codelineno-0-636" name="__codelineno-0-636"></a>
</span><span id="__span-0-637"><a id="__codelineno-0-637" name="__codelineno-0-637"></a><span class="s2">obj = doc.getObject(</span><span class="si">{</span><span class="n">obj_name</span><span class="si">!r}</span><span class="s2">)</span>
</span><span id="__span-0-638"><a id="__codelineno-0-638" name="__codelineno-0-638"></a><span class="s2">if obj is None:</span>
</span><span id="__span-0-639"><a id="__codelineno-0-639" name="__codelineno-0-639"></a><span class="s2"> raise ValueError(f"Object not found: </span><span class="si">{</span><span class="n">obj_name</span><span class="si">!r}</span><span class="s2">")</span>
</span><span id="__span-0-640"><a id="__codelineno-0-640" name="__codelineno-0-640"></a>
</span><span id="__span-0-641"><a id="__codelineno-0-641" name="__codelineno-0-641"></a><span class="s2">doc.removeObject(</span><span class="si">{</span><span class="n">obj_name</span><span class="si">!r}</span><span class="s2">)</span>
</span><span id="__span-0-642"><a id="__codelineno-0-642" name="__codelineno-0-642"></a><span class="s2">_result_ = True</span>
</span><span id="__span-0-643"><a id="__codelineno-0-643" name="__codelineno-0-643"></a><span class="s2">"""</span>
</span><span id="__span-0-644"><a id="__codelineno-0-644" name="__codelineno-0-644"></a> <span class="n">result</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">execute_python</span><span class="p">(</span><span class="n">code</span><span class="p">)</span>
</span><span id="__span-0-645"><a id="__codelineno-0-645" name="__codelineno-0-645"></a>
</span><span id="__span-0-646"><a id="__codelineno-0-646" name="__codelineno-0-646"></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">result</span><span class="o">.</span><span class="n">success</span><span class="p">:</span>
</span><span id="__span-0-647"><a id="__codelineno-0-647" name="__codelineno-0-647"></a> <span class="n">error_msg</span> <span class="o">=</span> <span class="n">result</span><span class="o">.</span><span class="n">error_traceback</span> <span class="ow">or</span> <span class="s2">"Failed to delete object"</span>
</span><span id="__span-0-648"><a id="__codelineno-0-648" name="__codelineno-0-648"></a> <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="n">error_msg</span><span class="p">)</span>
</span><span id="__span-0-649"><a id="__codelineno-0-649" name="__codelineno-0-649"></a>
</span><span id="__span-0-650"><a id="__codelineno-0-650" name="__codelineno-0-650"></a> <span class="c1"># =========================================================================</span>
</span><span id="__span-0-651"><a id="__codelineno-0-651" name="__codelineno-0-651"></a> <span class="c1"># View and Screenshot</span>
</span><span id="__span-0-652"><a id="__codelineno-0-652" name="__codelineno-0-652"></a> <span class="c1"># =========================================================================</span>
</span><span id="__span-0-653"><a id="__codelineno-0-653" name="__codelineno-0-653"></a>
</span><span id="__span-0-654"><a id="__codelineno-0-654" name="__codelineno-0-654"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">get_screenshot</span><span class="p">(</span>
</span><span id="__span-0-655"><a id="__codelineno-0-655" name="__codelineno-0-655"></a> <span class="bp">self</span><span class="p">,</span>
</span><span id="__span-0-656"><a id="__codelineno-0-656" name="__codelineno-0-656"></a> <span class="n">view_angle</span><span class="p">:</span> <span class="n">ViewAngle</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-657"><a id="__codelineno-0-657" name="__codelineno-0-657"></a> <span class="n">width</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">800</span><span class="p">,</span>
</span><span id="__span-0-658"><a id="__codelineno-0-658" name="__codelineno-0-658"></a> <span class="n">height</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">600</span><span class="p">,</span>
</span><span id="__span-0-659"><a id="__codelineno-0-659" name="__codelineno-0-659"></a> <span class="n">doc_name</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-660"><a id="__codelineno-0-660" name="__codelineno-0-660"></a> <span class="p">)</span> <span class="o">-&gt;</span> <span class="n">ScreenshotResult</span><span class="p">:</span>
</span><span id="__span-0-661"><a id="__codelineno-0-661" name="__codelineno-0-661"></a><span class="w"> </span><span class="sd">"""Capture a screenshot of the 3D view via XML-RPC."""</span>
</span><span id="__span-0-662"><a id="__codelineno-0-662" name="__codelineno-0-662"></a> <span class="n">view_angle_str</span> <span class="o">=</span> <span class="n">view_angle</span><span class="o">.</span><span class="n">value</span> <span class="k">if</span> <span class="n">view_angle</span> <span class="k">else</span> <span class="s2">"Isometric"</span>
</span><span id="__span-0-663"><a id="__codelineno-0-663" name="__codelineno-0-663"></a> <span class="n">code</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">"""</span>
</span><span id="__span-0-664"><a id="__codelineno-0-664" name="__codelineno-0-664"></a><span class="s2">import base64</span>
</span><span id="__span-0-665"><a id="__codelineno-0-665" name="__codelineno-0-665"></a><span class="s2">import tempfile</span>
</span><span id="__span-0-666"><a id="__codelineno-0-666" name="__codelineno-0-666"></a><span class="s2">import os</span>
</span><span id="__span-0-667"><a id="__codelineno-0-667" name="__codelineno-0-667"></a>
</span><span id="__span-0-668"><a id="__codelineno-0-668" name="__codelineno-0-668"></a><span class="s2">doc = FreeCAD.ActiveDocument if </span><span class="si">{</span><span class="n">doc_name</span><span class="si">!r}</span><span class="s2"> is None else FreeCAD.getDocument(</span><span class="si">{</span><span class="n">doc_name</span><span class="si">!r}</span><span class="s2">)</span>
</span><span id="__span-0-669"><a id="__codelineno-0-669" name="__codelineno-0-669"></a><span class="s2">if doc is None:</span>
</span><span id="__span-0-670"><a id="__codelineno-0-670" name="__codelineno-0-670"></a><span class="s2"> raise ValueError("No document found")</span>
</span><span id="__span-0-671"><a id="__codelineno-0-671" name="__codelineno-0-671"></a>
</span><span id="__span-0-672"><a id="__codelineno-0-672" name="__codelineno-0-672"></a><span class="s2"># Check if GUI is available</span>
</span><span id="__span-0-673"><a id="__codelineno-0-673" name="__codelineno-0-673"></a><span class="s2">if not FreeCAD.GuiUp:</span>
</span><span id="__span-0-674"><a id="__codelineno-0-674" name="__codelineno-0-674"></a><span class="s2"> raise RuntimeError("GUI not available")</span>
</span><span id="__span-0-675"><a id="__codelineno-0-675" name="__codelineno-0-675"></a>
</span><span id="__span-0-676"><a id="__codelineno-0-676" name="__codelineno-0-676"></a><span class="s2">view = FreeCADGui.ActiveDocument.ActiveView</span>
</span><span id="__span-0-677"><a id="__codelineno-0-677" name="__codelineno-0-677"></a><span class="s2">if view is None:</span>
</span><span id="__span-0-678"><a id="__codelineno-0-678" name="__codelineno-0-678"></a><span class="s2"> raise ValueError("No active view")</span>
</span><span id="__span-0-679"><a id="__codelineno-0-679" name="__codelineno-0-679"></a>
</span><span id="__span-0-680"><a id="__codelineno-0-680" name="__codelineno-0-680"></a><span class="s2"># Check if this is a 3D view (not TechDraw, Spreadsheet, etc.)</span>
</span><span id="__span-0-681"><a id="__codelineno-0-681" name="__codelineno-0-681"></a><span class="s2">view_type = view.__class__.__name__</span>
</span><span id="__span-0-682"><a id="__codelineno-0-682" name="__codelineno-0-682"></a><span class="s2">if view_type not in ["View3DInventor", "View3DInventorPy"]:</span>
</span><span id="__span-0-683"><a id="__codelineno-0-683" name="__codelineno-0-683"></a><span class="s2"> raise ValueError(f"Cannot capture screenshot from </span><span class="se">{{</span><span class="s2">view_type</span><span class="se">}}</span><span class="s2"> view")</span>
</span><span id="__span-0-684"><a id="__codelineno-0-684" name="__codelineno-0-684"></a>
</span><span id="__span-0-685"><a id="__codelineno-0-685" name="__codelineno-0-685"></a><span class="s2"># Set view angle</span>
</span><span id="__span-0-686"><a id="__codelineno-0-686" name="__codelineno-0-686"></a><span class="s2">view_type_str = </span><span class="si">{</span><span class="n">view_angle_str</span><span class="si">!r}</span>
</span><span id="__span-0-687"><a id="__codelineno-0-687" name="__codelineno-0-687"></a><span class="s2">if view_type_str == "FitAll":</span>
</span><span id="__span-0-688"><a id="__codelineno-0-688" name="__codelineno-0-688"></a><span class="s2"> view.fitAll()</span>
</span><span id="__span-0-689"><a id="__codelineno-0-689" name="__codelineno-0-689"></a><span class="s2">elif view_type_str == "Isometric":</span>
</span><span id="__span-0-690"><a id="__codelineno-0-690" name="__codelineno-0-690"></a><span class="s2"> view.viewIsometric()</span>
</span><span id="__span-0-691"><a id="__codelineno-0-691" name="__codelineno-0-691"></a><span class="s2">elif view_type_str == "Front":</span>
</span><span id="__span-0-692"><a id="__codelineno-0-692" name="__codelineno-0-692"></a><span class="s2"> view.viewFront()</span>
</span><span id="__span-0-693"><a id="__codelineno-0-693" name="__codelineno-0-693"></a><span class="s2">elif view_type_str == "Back":</span>
</span><span id="__span-0-694"><a id="__codelineno-0-694" name="__codelineno-0-694"></a><span class="s2"> view.viewRear()</span>
</span><span id="__span-0-695"><a id="__codelineno-0-695" name="__codelineno-0-695"></a><span class="s2">elif view_type_str == "Top":</span>
</span><span id="__span-0-696"><a id="__codelineno-0-696" name="__codelineno-0-696"></a><span class="s2"> view.viewTop()</span>
</span><span id="__span-0-697"><a id="__codelineno-0-697" name="__codelineno-0-697"></a><span class="s2">elif view_type_str == "Bottom":</span>
</span><span id="__span-0-698"><a id="__codelineno-0-698" name="__codelineno-0-698"></a><span class="s2"> view.viewBottom()</span>
</span><span id="__span-0-699"><a id="__codelineno-0-699" name="__codelineno-0-699"></a><span class="s2">elif view_type_str == "Left":</span>
</span><span id="__span-0-700"><a id="__codelineno-0-700" name="__codelineno-0-700"></a><span class="s2"> view.viewLeft()</span>
</span><span id="__span-0-701"><a id="__codelineno-0-701" name="__codelineno-0-701"></a><span class="s2">elif view_type_str == "Right":</span>
</span><span id="__span-0-702"><a id="__codelineno-0-702" name="__codelineno-0-702"></a><span class="s2"> view.viewRight()</span>
</span><span id="__span-0-703"><a id="__codelineno-0-703" name="__codelineno-0-703"></a>
</span><span id="__span-0-704"><a id="__codelineno-0-704" name="__codelineno-0-704"></a><span class="s2"># Save to temp file and read</span>
</span><span id="__span-0-705"><a id="__codelineno-0-705" name="__codelineno-0-705"></a><span class="s2">with tempfile.NamedTemporaryFile(suffix=".png", delete=False) as f:</span>
</span><span id="__span-0-706"><a id="__codelineno-0-706" name="__codelineno-0-706"></a><span class="s2"> temp_path = f.name</span>
</span><span id="__span-0-707"><a id="__codelineno-0-707" name="__codelineno-0-707"></a>
</span><span id="__span-0-708"><a id="__codelineno-0-708" name="__codelineno-0-708"></a><span class="s2">view.saveImage(temp_path, </span><span class="si">{</span><span class="n">width</span><span class="si">}</span><span class="s2">, </span><span class="si">{</span><span class="n">height</span><span class="si">}</span><span class="s2">, "Current")</span>
</span><span id="__span-0-709"><a id="__codelineno-0-709" name="__codelineno-0-709"></a>
</span><span id="__span-0-710"><a id="__codelineno-0-710" name="__codelineno-0-710"></a><span class="s2">with open(temp_path, "rb") as f:</span>
</span><span id="__span-0-711"><a id="__codelineno-0-711" name="__codelineno-0-711"></a><span class="s2"> image_data = base64.b64encode(f.read()).decode("utf-8")</span>
</span><span id="__span-0-712"><a id="__codelineno-0-712" name="__codelineno-0-712"></a>
</span><span id="__span-0-713"><a id="__codelineno-0-713" name="__codelineno-0-713"></a><span class="s2">os.unlink(temp_path)</span>
</span><span id="__span-0-714"><a id="__codelineno-0-714" name="__codelineno-0-714"></a>
</span><span id="__span-0-715"><a id="__codelineno-0-715" name="__codelineno-0-715"></a><span class="s2">_result_ = </span><span class="se">{{</span>
</span><span id="__span-0-716"><a id="__codelineno-0-716" name="__codelineno-0-716"></a><span class="s2"> "success": True,</span>
</span><span id="__span-0-717"><a id="__codelineno-0-717" name="__codelineno-0-717"></a><span class="s2"> "data": image_data,</span>
</span><span id="__span-0-718"><a id="__codelineno-0-718" name="__codelineno-0-718"></a><span class="s2"> "format": "png",</span>
</span><span id="__span-0-719"><a id="__codelineno-0-719" name="__codelineno-0-719"></a><span class="s2"> "width": </span><span class="si">{</span><span class="n">width</span><span class="si">}</span><span class="s2">,</span>
</span><span id="__span-0-720"><a id="__codelineno-0-720" name="__codelineno-0-720"></a><span class="s2"> "height": </span><span class="si">{</span><span class="n">height</span><span class="si">}</span><span class="s2">,</span>
</span><span id="__span-0-721"><a id="__codelineno-0-721" name="__codelineno-0-721"></a><span class="se">}}</span>
</span><span id="__span-0-722"><a id="__codelineno-0-722" name="__codelineno-0-722"></a><span class="s2">"""</span>
</span><span id="__span-0-723"><a id="__codelineno-0-723" name="__codelineno-0-723"></a> <span class="n">result</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">execute_python</span><span class="p">(</span><span class="n">code</span><span class="p">)</span>
</span><span id="__span-0-724"><a id="__codelineno-0-724" name="__codelineno-0-724"></a>
</span><span id="__span-0-725"><a id="__codelineno-0-725" name="__codelineno-0-725"></a> <span class="k">if</span> <span class="n">result</span><span class="o">.</span><span class="n">success</span> <span class="ow">and</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">:</span>
</span><span id="__span-0-726"><a id="__codelineno-0-726" name="__codelineno-0-726"></a> <span class="k">return</span> <span class="n">ScreenshotResult</span><span class="p">(</span>
</span><span id="__span-0-727"><a id="__codelineno-0-727" name="__codelineno-0-727"></a> <span class="n">success</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span>
</span><span id="__span-0-728"><a id="__codelineno-0-728" name="__codelineno-0-728"></a> <span class="n">data</span><span class="o">=</span><span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">[</span><span class="s2">"data"</span><span class="p">],</span>
</span><span id="__span-0-729"><a id="__codelineno-0-729" name="__codelineno-0-729"></a> <span class="nb">format</span><span class="o">=</span><span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">[</span><span class="s2">"format"</span><span class="p">],</span>
</span><span id="__span-0-730"><a id="__codelineno-0-730" name="__codelineno-0-730"></a> <span class="n">width</span><span class="o">=</span><span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">[</span><span class="s2">"width"</span><span class="p">],</span>
</span><span id="__span-0-731"><a id="__codelineno-0-731" name="__codelineno-0-731"></a> <span class="n">height</span><span class="o">=</span><span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">[</span><span class="s2">"height"</span><span class="p">],</span>
</span><span id="__span-0-732"><a id="__codelineno-0-732" name="__codelineno-0-732"></a> <span class="n">view_angle</span><span class="o">=</span><span class="n">view_angle</span><span class="p">,</span>
</span><span id="__span-0-733"><a id="__codelineno-0-733" name="__codelineno-0-733"></a> <span class="p">)</span>
</span><span id="__span-0-734"><a id="__codelineno-0-734" name="__codelineno-0-734"></a>
</span><span id="__span-0-735"><a id="__codelineno-0-735" name="__codelineno-0-735"></a> <span class="k">return</span> <span class="n">ScreenshotResult</span><span class="p">(</span>
</span><span id="__span-0-736"><a id="__codelineno-0-736" name="__codelineno-0-736"></a> <span class="n">success</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
</span><span id="__span-0-737"><a id="__codelineno-0-737" name="__codelineno-0-737"></a> <span class="n">error</span><span class="o">=</span><span class="n">result</span><span class="o">.</span><span class="n">error_traceback</span>
</span><span id="__span-0-738"><a id="__codelineno-0-738" name="__codelineno-0-738"></a> <span class="ow">or</span> <span class="n">result</span><span class="o">.</span><span class="n">stderr</span>
</span><span id="__span-0-739"><a id="__codelineno-0-739" name="__codelineno-0-739"></a> <span class="ow">or</span> <span class="s2">"Failed to capture screenshot"</span><span class="p">,</span>
</span><span id="__span-0-740"><a id="__codelineno-0-740" name="__codelineno-0-740"></a> <span class="n">width</span><span class="o">=</span><span class="n">width</span><span class="p">,</span>
</span><span id="__span-0-741"><a id="__codelineno-0-741" name="__codelineno-0-741"></a> <span class="n">height</span><span class="o">=</span><span class="n">height</span><span class="p">,</span>
</span><span id="__span-0-742"><a id="__codelineno-0-742" name="__codelineno-0-742"></a> <span class="n">view_angle</span><span class="o">=</span><span class="n">view_angle</span><span class="p">,</span>
</span><span id="__span-0-743"><a id="__codelineno-0-743" name="__codelineno-0-743"></a> <span class="p">)</span>
</span><span id="__span-0-744"><a id="__codelineno-0-744" name="__codelineno-0-744"></a>
</span><span id="__span-0-745"><a id="__codelineno-0-745" name="__codelineno-0-745"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">set_view</span><span class="p">(</span>
</span><span id="__span-0-746"><a id="__codelineno-0-746" name="__codelineno-0-746"></a> <span class="bp">self</span><span class="p">,</span>
</span><span id="__span-0-747"><a id="__codelineno-0-747" name="__codelineno-0-747"></a> <span class="n">view_angle</span><span class="p">:</span> <span class="n">ViewAngle</span><span class="p">,</span>
</span><span id="__span-0-748"><a id="__codelineno-0-748" name="__codelineno-0-748"></a> <span class="n">doc_name</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-749"><a id="__codelineno-0-749" name="__codelineno-0-749"></a> <span class="p">)</span> <span class="o">-&gt;</span> <span class="kc">None</span><span class="p">:</span>
</span><span id="__span-0-750"><a id="__codelineno-0-750" name="__codelineno-0-750"></a><span class="w"> </span><span class="sd">"""Set the 3D view angle."""</span>
</span><span id="__span-0-751"><a id="__codelineno-0-751" name="__codelineno-0-751"></a> <span class="n">view_angle_str</span> <span class="o">=</span> <span class="n">view_angle</span><span class="o">.</span><span class="n">value</span>
</span><span id="__span-0-752"><a id="__codelineno-0-752" name="__codelineno-0-752"></a> <span class="n">code</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">"""</span>
</span><span id="__span-0-753"><a id="__codelineno-0-753" name="__codelineno-0-753"></a><span class="s2">doc = FreeCAD.ActiveDocument if </span><span class="si">{</span><span class="n">doc_name</span><span class="si">!r}</span><span class="s2"> is None else FreeCAD.getDocument(</span><span class="si">{</span><span class="n">doc_name</span><span class="si">!r}</span><span class="s2">)</span>
</span><span id="__span-0-754"><a id="__codelineno-0-754" name="__codelineno-0-754"></a><span class="s2">if doc is None:</span>
</span><span id="__span-0-755"><a id="__codelineno-0-755" name="__codelineno-0-755"></a><span class="s2"> raise ValueError("No document found")</span>
</span><span id="__span-0-756"><a id="__codelineno-0-756" name="__codelineno-0-756"></a>
</span><span id="__span-0-757"><a id="__codelineno-0-757" name="__codelineno-0-757"></a><span class="s2">if not FreeCAD.GuiUp:</span>
</span><span id="__span-0-758"><a id="__codelineno-0-758" name="__codelineno-0-758"></a><span class="s2"> _result_ = True # Silently succeed in headless mode</span>
</span><span id="__span-0-759"><a id="__codelineno-0-759" name="__codelineno-0-759"></a><span class="s2">else:</span>
</span><span id="__span-0-760"><a id="__codelineno-0-760" name="__codelineno-0-760"></a><span class="s2"> view = FreeCADGui.ActiveDocument.ActiveView</span>
</span><span id="__span-0-761"><a id="__codelineno-0-761" name="__codelineno-0-761"></a><span class="s2"> if view is None:</span>
</span><span id="__span-0-762"><a id="__codelineno-0-762" name="__codelineno-0-762"></a><span class="s2"> raise ValueError("No active view")</span>
</span><span id="__span-0-763"><a id="__codelineno-0-763" name="__codelineno-0-763"></a>
</span><span id="__span-0-764"><a id="__codelineno-0-764" name="__codelineno-0-764"></a><span class="s2"> view_type = </span><span class="si">{</span><span class="n">view_angle_str</span><span class="si">!r}</span>
</span><span id="__span-0-765"><a id="__codelineno-0-765" name="__codelineno-0-765"></a><span class="s2"> if view_type == "FitAll":</span>
</span><span id="__span-0-766"><a id="__codelineno-0-766" name="__codelineno-0-766"></a><span class="s2"> view.fitAll()</span>
</span><span id="__span-0-767"><a id="__codelineno-0-767" name="__codelineno-0-767"></a><span class="s2"> elif view_type == "Isometric":</span>
</span><span id="__span-0-768"><a id="__codelineno-0-768" name="__codelineno-0-768"></a><span class="s2"> view.viewIsometric()</span>
</span><span id="__span-0-769"><a id="__codelineno-0-769" name="__codelineno-0-769"></a><span class="s2"> elif view_type == "Front":</span>
</span><span id="__span-0-770"><a id="__codelineno-0-770" name="__codelineno-0-770"></a><span class="s2"> view.viewFront()</span>
</span><span id="__span-0-771"><a id="__codelineno-0-771" name="__codelineno-0-771"></a><span class="s2"> elif view_type == "Back":</span>
</span><span id="__span-0-772"><a id="__codelineno-0-772" name="__codelineno-0-772"></a><span class="s2"> view.viewRear()</span>
</span><span id="__span-0-773"><a id="__codelineno-0-773" name="__codelineno-0-773"></a><span class="s2"> elif view_type == "Top":</span>
</span><span id="__span-0-774"><a id="__codelineno-0-774" name="__codelineno-0-774"></a><span class="s2"> view.viewTop()</span>
</span><span id="__span-0-775"><a id="__codelineno-0-775" name="__codelineno-0-775"></a><span class="s2"> elif view_type == "Bottom":</span>
</span><span id="__span-0-776"><a id="__codelineno-0-776" name="__codelineno-0-776"></a><span class="s2"> view.viewBottom()</span>
</span><span id="__span-0-777"><a id="__codelineno-0-777" name="__codelineno-0-777"></a><span class="s2"> elif view_type == "Left":</span>
</span><span id="__span-0-778"><a id="__codelineno-0-778" name="__codelineno-0-778"></a><span class="s2"> view.viewLeft()</span>
</span><span id="__span-0-779"><a id="__codelineno-0-779" name="__codelineno-0-779"></a><span class="s2"> elif view_type == "Right":</span>
</span><span id="__span-0-780"><a id="__codelineno-0-780" name="__codelineno-0-780"></a><span class="s2"> view.viewRight()</span>
</span><span id="__span-0-781"><a id="__codelineno-0-781" name="__codelineno-0-781"></a>
</span><span id="__span-0-782"><a id="__codelineno-0-782" name="__codelineno-0-782"></a><span class="s2"> _result_ = True</span>
</span><span id="__span-0-783"><a id="__codelineno-0-783" name="__codelineno-0-783"></a><span class="s2">"""</span>
</span><span id="__span-0-784"><a id="__codelineno-0-784" name="__codelineno-0-784"></a> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">execute_python</span><span class="p">(</span><span class="n">code</span><span class="p">)</span>
</span><span id="__span-0-785"><a id="__codelineno-0-785" name="__codelineno-0-785"></a>
</span><span id="__span-0-786"><a id="__codelineno-0-786" name="__codelineno-0-786"></a> <span class="c1"># =========================================================================</span>
</span><span id="__span-0-787"><a id="__codelineno-0-787" name="__codelineno-0-787"></a> <span class="c1"># Macros</span>
</span><span id="__span-0-788"><a id="__codelineno-0-788" name="__codelineno-0-788"></a> <span class="c1"># =========================================================================</span>
</span><span id="__span-0-789"><a id="__codelineno-0-789" name="__codelineno-0-789"></a>
</span><span id="__span-0-790"><a id="__codelineno-0-790" name="__codelineno-0-790"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">get_macros</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">list</span><span class="p">[</span><span class="n">MacroInfo</span><span class="p">]:</span>
</span><span id="__span-0-791"><a id="__codelineno-0-791" name="__codelineno-0-791"></a><span class="w"> </span><span class="sd">"""Get list of available macros."""</span>
</span><span id="__span-0-792"><a id="__codelineno-0-792" name="__codelineno-0-792"></a> <span class="n">code</span> <span class="o">=</span> <span class="s2">"""</span>
</span><span id="__span-0-793"><a id="__codelineno-0-793" name="__codelineno-0-793"></a><span class="s2">import os</span>
</span><span id="__span-0-794"><a id="__codelineno-0-794" name="__codelineno-0-794"></a>
</span><span id="__span-0-795"><a id="__codelineno-0-795" name="__codelineno-0-795"></a><span class="s2"># Get macro paths</span>
</span><span id="__span-0-796"><a id="__codelineno-0-796" name="__codelineno-0-796"></a><span class="s2">macro_paths = []</span>
</span><span id="__span-0-797"><a id="__codelineno-0-797" name="__codelineno-0-797"></a>
</span><span id="__span-0-798"><a id="__codelineno-0-798" name="__codelineno-0-798"></a><span class="s2"># User macro path</span>
</span><span id="__span-0-799"><a id="__codelineno-0-799" name="__codelineno-0-799"></a><span class="s2">user_path = FreeCAD.getUserMacroDir(True)</span>
</span><span id="__span-0-800"><a id="__codelineno-0-800" name="__codelineno-0-800"></a><span class="s2">if os.path.exists(user_path):</span>
</span><span id="__span-0-801"><a id="__codelineno-0-801" name="__codelineno-0-801"></a><span class="s2"> macro_paths.append(("user", user_path))</span>
</span><span id="__span-0-802"><a id="__codelineno-0-802" name="__codelineno-0-802"></a>
</span><span id="__span-0-803"><a id="__codelineno-0-803" name="__codelineno-0-803"></a><span class="s2"># System macro path</span>
</span><span id="__span-0-804"><a id="__codelineno-0-804" name="__codelineno-0-804"></a><span class="s2">system_path = FreeCAD.getResourceDir() + "Macro"</span>
</span><span id="__span-0-805"><a id="__codelineno-0-805" name="__codelineno-0-805"></a><span class="s2">if os.path.exists(system_path):</span>
</span><span id="__span-0-806"><a id="__codelineno-0-806" name="__codelineno-0-806"></a><span class="s2"> macro_paths.append(("system", system_path))</span>
</span><span id="__span-0-807"><a id="__codelineno-0-807" name="__codelineno-0-807"></a>
</span><span id="__span-0-808"><a id="__codelineno-0-808" name="__codelineno-0-808"></a><span class="s2">macros = []</span>
</span><span id="__span-0-809"><a id="__codelineno-0-809" name="__codelineno-0-809"></a><span class="s2">for source, path in macro_paths:</span>
</span><span id="__span-0-810"><a id="__codelineno-0-810" name="__codelineno-0-810"></a><span class="s2"> for filename in os.listdir(path):</span>
</span><span id="__span-0-811"><a id="__codelineno-0-811" name="__codelineno-0-811"></a><span class="s2"> if filename.endswith(".FCMacro"):</span>
</span><span id="__span-0-812"><a id="__codelineno-0-812" name="__codelineno-0-812"></a><span class="s2"> macro_file = os.path.join(path, filename)</span>
</span><span id="__span-0-813"><a id="__codelineno-0-813" name="__codelineno-0-813"></a><span class="s2"> description = ""</span>
</span><span id="__span-0-814"><a id="__codelineno-0-814" name="__codelineno-0-814"></a><span class="s2"> try:</span>
</span><span id="__span-0-815"><a id="__codelineno-0-815" name="__codelineno-0-815"></a><span class="s2"> with open(macro_file, "r") as f:</span>
</span><span id="__span-0-816"><a id="__codelineno-0-816" name="__codelineno-0-816"></a><span class="s2"> for line in f:</span>
</span><span id="__span-0-817"><a id="__codelineno-0-817" name="__codelineno-0-817"></a><span class="s2"> if line.startswith("#"):</span>
</span><span id="__span-0-818"><a id="__codelineno-0-818" name="__codelineno-0-818"></a><span class="s2"> desc = line.lstrip("#").strip()</span>
</span><span id="__span-0-819"><a id="__codelineno-0-819" name="__codelineno-0-819"></a><span class="s2"> if desc and not desc.startswith("!") and not desc.startswith("-*-"):</span>
</span><span id="__span-0-820"><a id="__codelineno-0-820" name="__codelineno-0-820"></a><span class="s2"> description = desc</span>
</span><span id="__span-0-821"><a id="__codelineno-0-821" name="__codelineno-0-821"></a><span class="s2"> break</span>
</span><span id="__span-0-822"><a id="__codelineno-0-822" name="__codelineno-0-822"></a><span class="s2"> except Exception:</span>
</span><span id="__span-0-823"><a id="__codelineno-0-823" name="__codelineno-0-823"></a><span class="s2"> pass</span>
</span><span id="__span-0-824"><a id="__codelineno-0-824" name="__codelineno-0-824"></a>
</span><span id="__span-0-825"><a id="__codelineno-0-825" name="__codelineno-0-825"></a><span class="s2"> macros.append({</span>
</span><span id="__span-0-826"><a id="__codelineno-0-826" name="__codelineno-0-826"></a><span class="s2"> "name": filename[:-8], # Remove .FCMacro</span>
</span><span id="__span-0-827"><a id="__codelineno-0-827" name="__codelineno-0-827"></a><span class="s2"> "path": macro_file,</span>
</span><span id="__span-0-828"><a id="__codelineno-0-828" name="__codelineno-0-828"></a><span class="s2"> "description": description,</span>
</span><span id="__span-0-829"><a id="__codelineno-0-829" name="__codelineno-0-829"></a><span class="s2"> "is_system": source == "system",</span>
</span><span id="__span-0-830"><a id="__codelineno-0-830" name="__codelineno-0-830"></a><span class="s2"> })</span>
</span><span id="__span-0-831"><a id="__codelineno-0-831" name="__codelineno-0-831"></a>
</span><span id="__span-0-832"><a id="__codelineno-0-832" name="__codelineno-0-832"></a><span class="s2">_result_ = macros</span>
</span><span id="__span-0-833"><a id="__codelineno-0-833" name="__codelineno-0-833"></a><span class="s2">"""</span>
</span><span id="__span-0-834"><a id="__codelineno-0-834" name="__codelineno-0-834"></a> <span class="n">result</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">execute_python</span><span class="p">(</span><span class="n">code</span><span class="p">)</span>
</span><span id="__span-0-835"><a id="__codelineno-0-835" name="__codelineno-0-835"></a>
</span><span id="__span-0-836"><a id="__codelineno-0-836" name="__codelineno-0-836"></a> <span class="k">if</span> <span class="n">result</span><span class="o">.</span><span class="n">success</span> <span class="ow">and</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">:</span>
</span><span id="__span-0-837"><a id="__codelineno-0-837" name="__codelineno-0-837"></a> <span class="k">return</span> <span class="p">[</span><span class="n">MacroInfo</span><span class="p">(</span><span class="o">**</span><span class="n">m</span><span class="p">)</span> <span class="k">for</span> <span class="n">m</span> <span class="ow">in</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">]</span>
</span><span id="__span-0-838"><a id="__codelineno-0-838" name="__codelineno-0-838"></a> <span class="k">return</span> <span class="p">[]</span>
</span><span id="__span-0-839"><a id="__codelineno-0-839" name="__codelineno-0-839"></a>
</span><span id="__span-0-840"><a id="__codelineno-0-840" name="__codelineno-0-840"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">run_macro</span><span class="p">(</span>
</span><span id="__span-0-841"><a id="__codelineno-0-841" name="__codelineno-0-841"></a> <span class="bp">self</span><span class="p">,</span>
</span><span id="__span-0-842"><a id="__codelineno-0-842" name="__codelineno-0-842"></a> <span class="n">macro_name</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span>
</span><span id="__span-0-843"><a id="__codelineno-0-843" name="__codelineno-0-843"></a> <span class="n">args</span><span class="p">:</span> <span class="nb">dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Any</span><span class="p">]</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-844"><a id="__codelineno-0-844" name="__codelineno-0-844"></a> <span class="p">)</span> <span class="o">-&gt;</span> <span class="n">ExecutionResult</span><span class="p">:</span>
</span><span id="__span-0-845"><a id="__codelineno-0-845" name="__codelineno-0-845"></a><span class="w"> </span><span class="sd">"""Run a macro by name."""</span>
</span><span id="__span-0-846"><a id="__codelineno-0-846" name="__codelineno-0-846"></a> <span class="n">args</span> <span class="o">=</span> <span class="n">args</span> <span class="ow">or</span> <span class="p">{}</span>
</span><span id="__span-0-847"><a id="__codelineno-0-847" name="__codelineno-0-847"></a> <span class="n">code</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">"""</span>
</span><span id="__span-0-848"><a id="__codelineno-0-848" name="__codelineno-0-848"></a><span class="s2">import os</span>
</span><span id="__span-0-849"><a id="__codelineno-0-849" name="__codelineno-0-849"></a>
</span><span id="__span-0-850"><a id="__codelineno-0-850" name="__codelineno-0-850"></a><span class="s2"># Find macro file</span>
</span><span id="__span-0-851"><a id="__codelineno-0-851" name="__codelineno-0-851"></a><span class="s2">macro_name = </span><span class="si">{</span><span class="n">macro_name</span><span class="si">!r}</span>
</span><span id="__span-0-852"><a id="__codelineno-0-852" name="__codelineno-0-852"></a><span class="s2">macro_file = None</span>
</span><span id="__span-0-853"><a id="__codelineno-0-853" name="__codelineno-0-853"></a>
</span><span id="__span-0-854"><a id="__codelineno-0-854" name="__codelineno-0-854"></a><span class="s2"># Check user macros first</span>
</span><span id="__span-0-855"><a id="__codelineno-0-855" name="__codelineno-0-855"></a><span class="s2">user_path = FreeCAD.getUserMacroDir(True)</span>
</span><span id="__span-0-856"><a id="__codelineno-0-856" name="__codelineno-0-856"></a><span class="s2">user_macro = os.path.join(user_path, macro_name + ".FCMacro")</span>
</span><span id="__span-0-857"><a id="__codelineno-0-857" name="__codelineno-0-857"></a><span class="s2">if os.path.exists(user_macro):</span>
</span><span id="__span-0-858"><a id="__codelineno-0-858" name="__codelineno-0-858"></a><span class="s2"> macro_file = user_macro</span>
</span><span id="__span-0-859"><a id="__codelineno-0-859" name="__codelineno-0-859"></a>
</span><span id="__span-0-860"><a id="__codelineno-0-860" name="__codelineno-0-860"></a><span class="s2"># Check system macros</span>
</span><span id="__span-0-861"><a id="__codelineno-0-861" name="__codelineno-0-861"></a><span class="s2">if not macro_file:</span>
</span><span id="__span-0-862"><a id="__codelineno-0-862" name="__codelineno-0-862"></a><span class="s2"> system_path = FreeCAD.getResourceDir() + "Macro"</span>
</span><span id="__span-0-863"><a id="__codelineno-0-863" name="__codelineno-0-863"></a><span class="s2"> system_macro = os.path.join(system_path, macro_name + ".FCMacro")</span>
</span><span id="__span-0-864"><a id="__codelineno-0-864" name="__codelineno-0-864"></a><span class="s2"> if os.path.exists(system_macro):</span>
</span><span id="__span-0-865"><a id="__codelineno-0-865" name="__codelineno-0-865"></a><span class="s2"> macro_file = system_macro</span>
</span><span id="__span-0-866"><a id="__codelineno-0-866" name="__codelineno-0-866"></a>
</span><span id="__span-0-867"><a id="__codelineno-0-867" name="__codelineno-0-867"></a><span class="s2">if not macro_file:</span>
</span><span id="__span-0-868"><a id="__codelineno-0-868" name="__codelineno-0-868"></a><span class="s2"> raise FileNotFoundError(f"Macro not found: </span><span class="se">{{</span><span class="s2">macro_name</span><span class="se">}}</span><span class="s2">")</span>
</span><span id="__span-0-869"><a id="__codelineno-0-869" name="__codelineno-0-869"></a>
</span><span id="__span-0-870"><a id="__codelineno-0-870" name="__codelineno-0-870"></a><span class="s2"># Set up arguments</span>
</span><span id="__span-0-871"><a id="__codelineno-0-871" name="__codelineno-0-871"></a><span class="s2">args = </span><span class="si">{</span><span class="n">args</span><span class="si">!r}</span>
</span><span id="__span-0-872"><a id="__codelineno-0-872" name="__codelineno-0-872"></a><span class="s2">for k, v in args.items():</span>
</span><span id="__span-0-873"><a id="__codelineno-0-873" name="__codelineno-0-873"></a><span class="s2"> exec(f"</span><span class="se">{{</span><span class="s2">k</span><span class="se">}}</span><span class="s2"> = </span><span class="se">{{</span><span class="s2">v!r</span><span class="se">}}</span><span class="s2">")</span>
</span><span id="__span-0-874"><a id="__codelineno-0-874" name="__codelineno-0-874"></a>
</span><span id="__span-0-875"><a id="__codelineno-0-875" name="__codelineno-0-875"></a><span class="s2"># Execute macro</span>
</span><span id="__span-0-876"><a id="__codelineno-0-876" name="__codelineno-0-876"></a><span class="s2">with open(macro_file, "r") as f:</span>
</span><span id="__span-0-877"><a id="__codelineno-0-877" name="__codelineno-0-877"></a><span class="s2"> macro_code = f.read()</span>
</span><span id="__span-0-878"><a id="__codelineno-0-878" name="__codelineno-0-878"></a>
</span><span id="__span-0-879"><a id="__codelineno-0-879" name="__codelineno-0-879"></a><span class="s2">exec(macro_code)</span>
</span><span id="__span-0-880"><a id="__codelineno-0-880" name="__codelineno-0-880"></a><span class="s2">_result_ = True</span>
</span><span id="__span-0-881"><a id="__codelineno-0-881" name="__codelineno-0-881"></a><span class="s2">"""</span>
</span><span id="__span-0-882"><a id="__codelineno-0-882" name="__codelineno-0-882"></a> <span class="k">return</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">execute_python</span><span class="p">(</span><span class="n">code</span><span class="p">)</span>
</span><span id="__span-0-883"><a id="__codelineno-0-883" name="__codelineno-0-883"></a>
</span><span id="__span-0-884"><a id="__codelineno-0-884" name="__codelineno-0-884"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">create_macro</span><span class="p">(</span>
</span><span id="__span-0-885"><a id="__codelineno-0-885" name="__codelineno-0-885"></a> <span class="bp">self</span><span class="p">,</span>
</span><span id="__span-0-886"><a id="__codelineno-0-886" name="__codelineno-0-886"></a> <span class="n">name</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span>
</span><span id="__span-0-887"><a id="__codelineno-0-887" name="__codelineno-0-887"></a> <span class="n">code</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span>
</span><span id="__span-0-888"><a id="__codelineno-0-888" name="__codelineno-0-888"></a> <span class="n">description</span><span class="p">:</span> <span class="nb">str</span> <span class="o">=</span> <span class="s2">""</span><span class="p">,</span>
</span><span id="__span-0-889"><a id="__codelineno-0-889" name="__codelineno-0-889"></a> <span class="p">)</span> <span class="o">-&gt;</span> <span class="n">MacroInfo</span><span class="p">:</span>
</span><span id="__span-0-890"><a id="__codelineno-0-890" name="__codelineno-0-890"></a><span class="w"> </span><span class="sd">"""Create a new macro."""</span>
</span><span id="__span-0-891"><a id="__codelineno-0-891" name="__codelineno-0-891"></a> <span class="n">create_code</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">"""</span>
</span><span id="__span-0-892"><a id="__codelineno-0-892" name="__codelineno-0-892"></a><span class="s2">import os</span>
</span><span id="__span-0-893"><a id="__codelineno-0-893" name="__codelineno-0-893"></a>
</span><span id="__span-0-894"><a id="__codelineno-0-894" name="__codelineno-0-894"></a><span class="s2">macro_path = FreeCAD.getUserMacroDir(True)</span>
</span><span id="__span-0-895"><a id="__codelineno-0-895" name="__codelineno-0-895"></a><span class="s2">os.makedirs(macro_path, exist_ok=True)</span>
</span><span id="__span-0-896"><a id="__codelineno-0-896" name="__codelineno-0-896"></a>
</span><span id="__span-0-897"><a id="__codelineno-0-897" name="__codelineno-0-897"></a><span class="s2">macro_file = os.path.join(macro_path, </span><span class="si">{</span><span class="n">name</span><span class="si">!r}</span><span class="s2"> + ".FCMacro")</span>
</span><span id="__span-0-898"><a id="__codelineno-0-898" name="__codelineno-0-898"></a>
</span><span id="__span-0-899"><a id="__codelineno-0-899" name="__codelineno-0-899"></a><span class="s2">header = ""</span>
</span><span id="__span-0-900"><a id="__codelineno-0-900" name="__codelineno-0-900"></a><span class="s2">if </span><span class="si">{</span><span class="n">description</span><span class="si">!r}</span><span class="s2">:</span>
</span><span id="__span-0-901"><a id="__codelineno-0-901" name="__codelineno-0-901"></a><span class="s2"> header = f"# </span><span class="si">{</span><span class="n">description</span><span class="si">!r}</span><span class="se">\\</span><span class="s2">n</span><span class="se">\\</span><span class="s2">n"</span>
</span><span id="__span-0-902"><a id="__codelineno-0-902" name="__codelineno-0-902"></a>
</span><span id="__span-0-903"><a id="__codelineno-0-903" name="__codelineno-0-903"></a><span class="s2">full_code = header + '''# -*- coding: utf-8 -*-</span>
</span><span id="__span-0-904"><a id="__codelineno-0-904" name="__codelineno-0-904"></a><span class="s2"># FreeCAD Macro: </span><span class="si">{</span><span class="n">name</span><span class="si">}</span>
</span><span id="__span-0-905"><a id="__codelineno-0-905" name="__codelineno-0-905"></a><span class="s2"># Created via MCP Bridge</span>
</span><span id="__span-0-906"><a id="__codelineno-0-906" name="__codelineno-0-906"></a>
</span><span id="__span-0-907"><a id="__codelineno-0-907" name="__codelineno-0-907"></a><span class="s2">import FreeCAD</span>
</span><span id="__span-0-908"><a id="__codelineno-0-908" name="__codelineno-0-908"></a><span class="s2">import FreeCADGui</span>
</span><span id="__span-0-909"><a id="__codelineno-0-909" name="__codelineno-0-909"></a>
</span><span id="__span-0-910"><a id="__codelineno-0-910" name="__codelineno-0-910"></a><span class="s2">''' + </span><span class="si">{</span><span class="n">code</span><span class="si">!r}</span>
</span><span id="__span-0-911"><a id="__codelineno-0-911" name="__codelineno-0-911"></a>
</span><span id="__span-0-912"><a id="__codelineno-0-912" name="__codelineno-0-912"></a><span class="s2">with open(macro_file, "w") as f:</span>
</span><span id="__span-0-913"><a id="__codelineno-0-913" name="__codelineno-0-913"></a><span class="s2"> f.write(full_code)</span>
</span><span id="__span-0-914"><a id="__codelineno-0-914" name="__codelineno-0-914"></a>
</span><span id="__span-0-915"><a id="__codelineno-0-915" name="__codelineno-0-915"></a><span class="s2">_result_ = </span><span class="se">{{</span>
</span><span id="__span-0-916"><a id="__codelineno-0-916" name="__codelineno-0-916"></a><span class="s2"> "name": </span><span class="si">{</span><span class="n">name</span><span class="si">!r}</span><span class="s2">,</span>
</span><span id="__span-0-917"><a id="__codelineno-0-917" name="__codelineno-0-917"></a><span class="s2"> "path": macro_file,</span>
</span><span id="__span-0-918"><a id="__codelineno-0-918" name="__codelineno-0-918"></a><span class="s2"> "description": </span><span class="si">{</span><span class="n">description</span><span class="si">!r}</span><span class="s2">,</span>
</span><span id="__span-0-919"><a id="__codelineno-0-919" name="__codelineno-0-919"></a><span class="s2"> "is_system": False,</span>
</span><span id="__span-0-920"><a id="__codelineno-0-920" name="__codelineno-0-920"></a><span class="se">}}</span>
</span><span id="__span-0-921"><a id="__codelineno-0-921" name="__codelineno-0-921"></a><span class="s2">"""</span>
</span><span id="__span-0-922"><a id="__codelineno-0-922" name="__codelineno-0-922"></a> <span class="n">result</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">execute_python</span><span class="p">(</span><span class="n">create_code</span><span class="p">)</span>
</span><span id="__span-0-923"><a id="__codelineno-0-923" name="__codelineno-0-923"></a>
</span><span id="__span-0-924"><a id="__codelineno-0-924" name="__codelineno-0-924"></a> <span class="k">if</span> <span class="n">result</span><span class="o">.</span><span class="n">success</span> <span class="ow">and</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">:</span>
</span><span id="__span-0-925"><a id="__codelineno-0-925" name="__codelineno-0-925"></a> <span class="k">return</span> <span class="n">MacroInfo</span><span class="p">(</span><span class="o">**</span><span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">)</span>
</span><span id="__span-0-926"><a id="__codelineno-0-926" name="__codelineno-0-926"></a>
</span><span id="__span-0-927"><a id="__codelineno-0-927" name="__codelineno-0-927"></a> <span class="n">error_msg</span> <span class="o">=</span> <span class="n">result</span><span class="o">.</span><span class="n">error_traceback</span> <span class="ow">or</span> <span class="s2">"Failed to create macro"</span>
</span><span id="__span-0-928"><a id="__codelineno-0-928" name="__codelineno-0-928"></a> <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="n">error_msg</span><span class="p">)</span>
</span><span id="__span-0-929"><a id="__codelineno-0-929" name="__codelineno-0-929"></a>
</span><span id="__span-0-930"><a id="__codelineno-0-930" name="__codelineno-0-930"></a> <span class="c1"># =========================================================================</span>
</span><span id="__span-0-931"><a id="__codelineno-0-931" name="__codelineno-0-931"></a> <span class="c1"># Workbenches</span>
</span><span id="__span-0-932"><a id="__codelineno-0-932" name="__codelineno-0-932"></a> <span class="c1"># =========================================================================</span>
</span><span id="__span-0-933"><a id="__codelineno-0-933" name="__codelineno-0-933"></a>
</span><span id="__span-0-934"><a id="__codelineno-0-934" name="__codelineno-0-934"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">get_workbenches</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">list</span><span class="p">[</span><span class="n">WorkbenchInfo</span><span class="p">]:</span>
</span><span id="__span-0-935"><a id="__codelineno-0-935" name="__codelineno-0-935"></a><span class="w"> </span><span class="sd">"""Get list of available workbenches."""</span>
</span><span id="__span-0-936"><a id="__codelineno-0-936" name="__codelineno-0-936"></a> <span class="n">code</span> <span class="o">=</span> <span class="s2">"""</span>
</span><span id="__span-0-937"><a id="__codelineno-0-937" name="__codelineno-0-937"></a><span class="s2">workbenches = []</span>
</span><span id="__span-0-938"><a id="__codelineno-0-938" name="__codelineno-0-938"></a><span class="s2">active_wb = FreeCADGui.activeWorkbench() if FreeCAD.GuiUp else None</span>
</span><span id="__span-0-939"><a id="__codelineno-0-939" name="__codelineno-0-939"></a><span class="s2">active_name = active_wb.__class__.__name__ if active_wb else None</span>
</span><span id="__span-0-940"><a id="__codelineno-0-940" name="__codelineno-0-940"></a>
</span><span id="__span-0-941"><a id="__codelineno-0-941" name="__codelineno-0-941"></a><span class="s2">if FreeCAD.GuiUp:</span>
</span><span id="__span-0-942"><a id="__codelineno-0-942" name="__codelineno-0-942"></a><span class="s2"> for name in FreeCADGui.listWorkbenches():</span>
</span><span id="__span-0-943"><a id="__codelineno-0-943" name="__codelineno-0-943"></a><span class="s2"> wb = FreeCADGui.getWorkbench(name)</span>
</span><span id="__span-0-944"><a id="__codelineno-0-944" name="__codelineno-0-944"></a><span class="s2"> workbenches.append({</span>
</span><span id="__span-0-945"><a id="__codelineno-0-945" name="__codelineno-0-945"></a><span class="s2"> "name": name,</span>
</span><span id="__span-0-946"><a id="__codelineno-0-946" name="__codelineno-0-946"></a><span class="s2"> "label": wb.MenuText if hasattr(wb, "MenuText") else name,</span>
</span><span id="__span-0-947"><a id="__codelineno-0-947" name="__codelineno-0-947"></a><span class="s2"> "icon": wb.Icon if hasattr(wb, "Icon") else "",</span>
</span><span id="__span-0-948"><a id="__codelineno-0-948" name="__codelineno-0-948"></a><span class="s2"> "is_active": name == active_name,</span>
</span><span id="__span-0-949"><a id="__codelineno-0-949" name="__codelineno-0-949"></a><span class="s2"> })</span>
</span><span id="__span-0-950"><a id="__codelineno-0-950" name="__codelineno-0-950"></a><span class="s2">else:</span>
</span><span id="__span-0-951"><a id="__codelineno-0-951" name="__codelineno-0-951"></a><span class="s2"> # Return common workbenches for headless mode</span>
</span><span id="__span-0-952"><a id="__codelineno-0-952" name="__codelineno-0-952"></a><span class="s2"> common = ["StartWorkbench", "PartWorkbench", "PartDesignWorkbench",</span>
</span><span id="__span-0-953"><a id="__codelineno-0-953" name="__codelineno-0-953"></a><span class="s2"> "DraftWorkbench", "SketcherWorkbench", "MeshWorkbench"]</span>
</span><span id="__span-0-954"><a id="__codelineno-0-954" name="__codelineno-0-954"></a><span class="s2"> for name in common:</span>
</span><span id="__span-0-955"><a id="__codelineno-0-955" name="__codelineno-0-955"></a><span class="s2"> workbenches.append({</span>
</span><span id="__span-0-956"><a id="__codelineno-0-956" name="__codelineno-0-956"></a><span class="s2"> "name": name,</span>
</span><span id="__span-0-957"><a id="__codelineno-0-957" name="__codelineno-0-957"></a><span class="s2"> "label": name.replace("Workbench", ""),</span>
</span><span id="__span-0-958"><a id="__codelineno-0-958" name="__codelineno-0-958"></a><span class="s2"> "icon": "",</span>
</span><span id="__span-0-959"><a id="__codelineno-0-959" name="__codelineno-0-959"></a><span class="s2"> "is_active": False,</span>
</span><span id="__span-0-960"><a id="__codelineno-0-960" name="__codelineno-0-960"></a><span class="s2"> })</span>
</span><span id="__span-0-961"><a id="__codelineno-0-961" name="__codelineno-0-961"></a>
</span><span id="__span-0-962"><a id="__codelineno-0-962" name="__codelineno-0-962"></a><span class="s2">_result_ = workbenches</span>
</span><span id="__span-0-963"><a id="__codelineno-0-963" name="__codelineno-0-963"></a><span class="s2">"""</span>
</span><span id="__span-0-964"><a id="__codelineno-0-964" name="__codelineno-0-964"></a> <span class="n">result</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">execute_python</span><span class="p">(</span><span class="n">code</span><span class="p">)</span>
</span><span id="__span-0-965"><a id="__codelineno-0-965" name="__codelineno-0-965"></a>
</span><span id="__span-0-966"><a id="__codelineno-0-966" name="__codelineno-0-966"></a> <span class="k">if</span> <span class="n">result</span><span class="o">.</span><span class="n">success</span> <span class="ow">and</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">:</span>
</span><span id="__span-0-967"><a id="__codelineno-0-967" name="__codelineno-0-967"></a> <span class="k">return</span> <span class="p">[</span><span class="n">WorkbenchInfo</span><span class="p">(</span><span class="o">**</span><span class="n">wb</span><span class="p">)</span> <span class="k">for</span> <span class="n">wb</span> <span class="ow">in</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">]</span>
</span><span id="__span-0-968"><a id="__codelineno-0-968" name="__codelineno-0-968"></a> <span class="k">return</span> <span class="p">[]</span>
</span><span id="__span-0-969"><a id="__codelineno-0-969" name="__codelineno-0-969"></a>
</span><span id="__span-0-970"><a id="__codelineno-0-970" name="__codelineno-0-970"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">activate_workbench</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">workbench_name</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kc">None</span><span class="p">:</span>
</span><span id="__span-0-971"><a id="__codelineno-0-971" name="__codelineno-0-971"></a><span class="w"> </span><span class="sd">"""Activate a workbench."""</span>
</span><span id="__span-0-972"><a id="__codelineno-0-972" name="__codelineno-0-972"></a> <span class="n">code</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">"""</span>
</span><span id="__span-0-973"><a id="__codelineno-0-973" name="__codelineno-0-973"></a><span class="s2">if FreeCAD.GuiUp:</span>
</span><span id="__span-0-974"><a id="__codelineno-0-974" name="__codelineno-0-974"></a><span class="s2"> try:</span>
</span><span id="__span-0-975"><a id="__codelineno-0-975" name="__codelineno-0-975"></a><span class="s2"> FreeCADGui.activateWorkbench(</span><span class="si">{</span><span class="n">workbench_name</span><span class="si">!r}</span><span class="s2">)</span>
</span><span id="__span-0-976"><a id="__codelineno-0-976" name="__codelineno-0-976"></a><span class="s2"> _result_ = True</span>
</span><span id="__span-0-977"><a id="__codelineno-0-977" name="__codelineno-0-977"></a><span class="s2"> except Exception as e:</span>
</span><span id="__span-0-978"><a id="__codelineno-0-978" name="__codelineno-0-978"></a><span class="s2"> raise ValueError(f"Failed to activate workbench: </span><span class="se">{{</span><span class="s2">e</span><span class="se">}}</span><span class="s2">")</span>
</span><span id="__span-0-979"><a id="__codelineno-0-979" name="__codelineno-0-979"></a><span class="s2">else:</span>
</span><span id="__span-0-980"><a id="__codelineno-0-980" name="__codelineno-0-980"></a><span class="s2"> _result_ = True # Silently succeed in headless mode</span>
</span><span id="__span-0-981"><a id="__codelineno-0-981" name="__codelineno-0-981"></a><span class="s2">"""</span>
</span><span id="__span-0-982"><a id="__codelineno-0-982" name="__codelineno-0-982"></a> <span class="n">result</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">execute_python</span><span class="p">(</span><span class="n">code</span><span class="p">)</span>
</span><span id="__span-0-983"><a id="__codelineno-0-983" name="__codelineno-0-983"></a>
</span><span id="__span-0-984"><a id="__codelineno-0-984" name="__codelineno-0-984"></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">result</span><span class="o">.</span><span class="n">success</span><span class="p">:</span>
</span><span id="__span-0-985"><a id="__codelineno-0-985" name="__codelineno-0-985"></a> <span class="n">error_msg</span> <span class="o">=</span> <span class="n">result</span><span class="o">.</span><span class="n">error_traceback</span> <span class="ow">or</span> <span class="s2">"Failed to activate workbench"</span>
</span><span id="__span-0-986"><a id="__codelineno-0-986" name="__codelineno-0-986"></a> <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="n">error_msg</span><span class="p">)</span>
</span><span id="__span-0-987"><a id="__codelineno-0-987" name="__codelineno-0-987"></a>
</span><span id="__span-0-988"><a id="__codelineno-0-988" name="__codelineno-0-988"></a> <span class="c1"># =========================================================================</span>
</span><span id="__span-0-989"><a id="__codelineno-0-989" name="__codelineno-0-989"></a> <span class="c1"># Version and Environment</span>
</span><span id="__span-0-990"><a id="__codelineno-0-990" name="__codelineno-0-990"></a> <span class="c1"># =========================================================================</span>
</span><span id="__span-0-991"><a id="__codelineno-0-991" name="__codelineno-0-991"></a>
</span><span id="__span-0-992"><a id="__codelineno-0-992" name="__codelineno-0-992"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">get_freecad_version</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Any</span><span class="p">]:</span>
</span><span id="__span-0-993"><a id="__codelineno-0-993" name="__codelineno-0-993"></a><span class="w"> </span><span class="sd">"""Get FreeCAD version information."""</span>
</span><span id="__span-0-994"><a id="__codelineno-0-994" name="__codelineno-0-994"></a> <span class="n">code</span> <span class="o">=</span> <span class="s2">"""</span>
</span><span id="__span-0-995"><a id="__codelineno-0-995" name="__codelineno-0-995"></a><span class="s2">import sys</span>
</span><span id="__span-0-996"><a id="__codelineno-0-996" name="__codelineno-0-996"></a><span class="s2">_result_ = {</span>
</span><span id="__span-0-997"><a id="__codelineno-0-997" name="__codelineno-0-997"></a><span class="s2"> "version": ".".join(str(x) for x in FreeCAD.Version()[:3]),</span>
</span><span id="__span-0-998"><a id="__codelineno-0-998" name="__codelineno-0-998"></a><span class="s2"> "version_tuple": FreeCAD.Version()[:3],</span>
</span><span id="__span-0-999"><a id="__codelineno-0-999" name="__codelineno-0-999"></a><span class="s2"> "build_date": FreeCAD.Version()[3] if len(FreeCAD.Version()) &gt; 3 else "unknown",</span>
</span><span id="__span-0-1000"><a id="__codelineno-0-1000" name="__codelineno-0-1000"></a><span class="s2"> "python_version": sys.version,</span>
</span><span id="__span-0-1001"><a id="__codelineno-0-1001" name="__codelineno-0-1001"></a><span class="s2"> "gui_available": FreeCAD.GuiUp,</span>
</span><span id="__span-0-1002"><a id="__codelineno-0-1002" name="__codelineno-0-1002"></a><span class="s2">}</span>
</span><span id="__span-0-1003"><a id="__codelineno-0-1003" name="__codelineno-0-1003"></a><span class="s2">"""</span>
</span><span id="__span-0-1004"><a id="__codelineno-0-1004" name="__codelineno-0-1004"></a> <span class="n">result</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">execute_python</span><span class="p">(</span><span class="n">code</span><span class="p">)</span>
</span><span id="__span-0-1005"><a id="__codelineno-0-1005" name="__codelineno-0-1005"></a>
</span><span id="__span-0-1006"><a id="__codelineno-0-1006" name="__codelineno-0-1006"></a> <span class="k">if</span> <span class="n">result</span><span class="o">.</span><span class="n">success</span> <span class="ow">and</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">:</span>
</span><span id="__span-0-1007"><a id="__codelineno-0-1007" name="__codelineno-0-1007"></a> <span class="k">return</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span>
</span><span id="__span-0-1008"><a id="__codelineno-0-1008" name="__codelineno-0-1008"></a>
</span><span id="__span-0-1009"><a id="__codelineno-0-1009" name="__codelineno-0-1009"></a> <span class="k">return</span> <span class="p">{</span>
</span><span id="__span-0-1010"><a id="__codelineno-0-1010" name="__codelineno-0-1010"></a> <span class="s2">"version"</span><span class="p">:</span> <span class="s2">"unknown"</span><span class="p">,</span>
</span><span id="__span-0-1011"><a id="__codelineno-0-1011" name="__codelineno-0-1011"></a> <span class="s2">"version_tuple"</span><span class="p">:</span> <span class="p">[],</span>
</span><span id="__span-0-1012"><a id="__codelineno-0-1012" name="__codelineno-0-1012"></a> <span class="s2">"build_date"</span><span class="p">:</span> <span class="s2">"unknown"</span><span class="p">,</span>
</span><span id="__span-0-1013"><a id="__codelineno-0-1013" name="__codelineno-0-1013"></a> <span class="s2">"python_version"</span><span class="p">:</span> <span class="s2">""</span><span class="p">,</span>
</span><span id="__span-0-1014"><a id="__codelineno-0-1014" name="__codelineno-0-1014"></a> <span class="s2">"gui_available"</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span>
</span><span id="__span-0-1015"><a id="__codelineno-0-1015" name="__codelineno-0-1015"></a> <span class="p">}</span>
</span><span id="__span-0-1016"><a id="__codelineno-0-1016" name="__codelineno-0-1016"></a>
</span><span id="__span-0-1017"><a id="__codelineno-0-1017" name="__codelineno-0-1017"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">is_gui_available</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">bool</span><span class="p">:</span>
</span><span id="__span-0-1018"><a id="__codelineno-0-1018" name="__codelineno-0-1018"></a><span class="w"> </span><span class="sd">"""Check if FreeCAD GUI is available."""</span>
</span><span id="__span-0-1019"><a id="__codelineno-0-1019" name="__codelineno-0-1019"></a> <span class="n">result</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">execute_python</span><span class="p">(</span><span class="s2">"_result_ = FreeCAD.GuiUp"</span><span class="p">)</span>
</span><span id="__span-0-1020"><a id="__codelineno-0-1020" name="__codelineno-0-1020"></a> <span class="k">return</span> <span class="nb">bool</span><span class="p">(</span><span class="n">result</span><span class="o">.</span><span class="n">success</span> <span class="ow">and</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">)</span>
</span><span id="__span-0-1021"><a id="__codelineno-0-1021" name="__codelineno-0-1021"></a>
</span><span id="__span-0-1022"><a id="__codelineno-0-1022" name="__codelineno-0-1022"></a> <span class="c1"># =========================================================================</span>
</span><span id="__span-0-1023"><a id="__codelineno-0-1023" name="__codelineno-0-1023"></a> <span class="c1"># Console</span>
</span><span id="__span-0-1024"><a id="__codelineno-0-1024" name="__codelineno-0-1024"></a> <span class="c1"># =========================================================================</span>
</span><span id="__span-0-1025"><a id="__codelineno-0-1025" name="__codelineno-0-1025"></a>
</span><span id="__span-0-1026"><a id="__codelineno-0-1026" name="__codelineno-0-1026"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">get_console_output</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">lines</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">100</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">list</span><span class="p">[</span><span class="nb">str</span><span class="p">]:</span>
</span><span id="__span-0-1027"><a id="__codelineno-0-1027" name="__codelineno-0-1027"></a><span class="w"> </span><span class="sd">"""Get recent console output."""</span>
</span><span id="__span-0-1028"><a id="__codelineno-0-1028" name="__codelineno-0-1028"></a> <span class="n">code</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">"""</span>
</span><span id="__span-0-1029"><a id="__codelineno-0-1029" name="__codelineno-0-1029"></a><span class="s2"># Try to get console output from FreeCAD</span>
</span><span id="__span-0-1030"><a id="__codelineno-0-1030" name="__codelineno-0-1030"></a><span class="s2">output_lines = []</span>
</span><span id="__span-0-1031"><a id="__codelineno-0-1031" name="__codelineno-0-1031"></a>
</span><span id="__span-0-1032"><a id="__codelineno-0-1032" name="__codelineno-0-1032"></a><span class="s2"># Try FreeCAD.Console if available</span>
</span><span id="__span-0-1033"><a id="__codelineno-0-1033" name="__codelineno-0-1033"></a><span class="s2">if hasattr(FreeCAD, 'Console'):</span>
</span><span id="__span-0-1034"><a id="__codelineno-0-1034" name="__codelineno-0-1034"></a><span class="s2"> console = FreeCAD.Console</span>
</span><span id="__span-0-1035"><a id="__codelineno-0-1035" name="__codelineno-0-1035"></a><span class="s2"> if hasattr(console, 'GetLog'):</span>
</span><span id="__span-0-1036"><a id="__codelineno-0-1036" name="__codelineno-0-1036"></a><span class="s2"> log = console.GetLog()</span>
</span><span id="__span-0-1037"><a id="__codelineno-0-1037" name="__codelineno-0-1037"></a><span class="s2"> if log:</span>
</span><span id="__span-0-1038"><a id="__codelineno-0-1038" name="__codelineno-0-1038"></a><span class="s2"> output_lines = log.split('</span><span class="se">\\</span><span class="s2">n')[-</span><span class="si">{</span><span class="n">lines</span><span class="si">}</span><span class="s2">:]</span>
</span><span id="__span-0-1039"><a id="__codelineno-0-1039" name="__codelineno-0-1039"></a>
</span><span id="__span-0-1040"><a id="__codelineno-0-1040" name="__codelineno-0-1040"></a><span class="s2">_result_ = output_lines</span>
</span><span id="__span-0-1041"><a id="__codelineno-0-1041" name="__codelineno-0-1041"></a><span class="s2">"""</span>
</span><span id="__span-0-1042"><a id="__codelineno-0-1042" name="__codelineno-0-1042"></a> <span class="n">result</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">execute_python</span><span class="p">(</span><span class="n">code</span><span class="p">)</span>
</span><span id="__span-0-1043"><a id="__codelineno-0-1043" name="__codelineno-0-1043"></a>
</span><span id="__span-0-1044"><a id="__codelineno-0-1044" name="__codelineno-0-1044"></a> <span class="k">if</span> <span class="n">result</span><span class="o">.</span><span class="n">success</span> <span class="ow">and</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">:</span>
</span><span id="__span-0-1045"><a id="__codelineno-0-1045" name="__codelineno-0-1045"></a> <span class="k">return</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span>
</span><span id="__span-0-1046"><a id="__codelineno-0-1046" name="__codelineno-0-1046"></a> <span class="k">return</span> <span class="p">[]</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> <div class="doc doc-children"> <h5 id="freecad_mcp.bridge.xmlrpc.XmlRpcBridge-functions">Functions<a href="#freecad_mcp.bridge.xmlrpc.XmlRpcBridge-functions" class="headerlink" title="Permanent link">¶</a></h5> <div class="doc doc-object doc-function"> <h6 id="freecad_mcp.bridge.xmlrpc.XmlRpcBridge.__init__" class="doc doc-heading"> <code class="highlight language-python"><span class="fm">__init__</span><span class="p">(</span><span class="n">host</span><span class="o">=</span><span class="n">DEFAULT_XMLRPC_HOST</span><span class="p">,</span> <span class="n">port</span><span class="o">=</span><span class="n">DEFAULT_XMLRPC_PORT</span><span class="p">,</span> <span class="n">timeout</span><span class="o">=</span><span class="n">DEFAULT_TIMEOUT</span><span class="p">)</span></code> <a href="#freecad_mcp.bridge.xmlrpc.XmlRpcBridge.__init__" class="headerlink" title="Permanent link">¶</a></h6> <div class="doc doc-contents "> <p>Initialize the XML-RPC bridge.</p> <p><span class="doc-section-title">Parameters:</span></p> <table> <thead> <tr> <th>Name</th> <th>Type</th> <th>Description</th> <th>Default</th> </tr> </thead> <tbody> <tr class="doc-section-item"> <td> <code>host</code> </td> <td> <code><span title="str">str</span></code> </td> <td> <div class="doc-md-description"> <p>XML-RPC server hostname.</p> </div> </td> <td> <code><span title="freecad_mcp.bridge.xmlrpc.DEFAULT_XMLRPC_HOST">DEFAULT_XMLRPC_HOST</span></code> </td> </tr> <tr class="doc-section-item"> <td> <code>port</code> </td> <td> <code><span title="int">int</span></code> </td> <td> <div class="doc-md-description"> <p>XML-RPC server port.</p> </div> </td> <td> <code><span title="freecad_mcp.bridge.xmlrpc.DEFAULT_XMLRPC_PORT">DEFAULT_XMLRPC_PORT</span></code> </td> </tr> <tr class="doc-section-item"> <td> <code>timeout</code> </td> <td> <code><span title="float">float</span></code> </td> <td> <div class="doc-md-description"> <p>Connection and request timeout in seconds.</p> </div> </td> <td> <code><span title="freecad_mcp.bridge.xmlrpc.DEFAULT_TIMEOUT">DEFAULT_TIMEOUT</span></code> </td> </tr> </tbody> </table> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/xmlrpc.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-56">56</a></span>
<span class="normal"><a href="#__codelineno-0-57">57</a></span>
<span class="normal"><a href="#__codelineno-0-58">58</a></span>
<span class="normal"><a href="#__codelineno-0-59">59</a></span>
<span class="normal"><a href="#__codelineno-0-60">60</a></span>
<span class="normal"><a href="#__codelineno-0-61">61</a></span>
<span class="normal"><a href="#__codelineno-0-62">62</a></span>
<span class="normal"><a href="#__codelineno-0-63">63</a></span>
<span class="normal"><a href="#__codelineno-0-64">64</a></span>
<span class="normal"><a href="#__codelineno-0-65">65</a></span>
<span class="normal"><a href="#__codelineno-0-66">66</a></span>
<span class="normal"><a href="#__codelineno-0-67">67</a></span>
<span class="normal"><a href="#__codelineno-0-68">68</a></span>
<span class="normal"><a href="#__codelineno-0-69">69</a></span>
<span class="normal"><a href="#__codelineno-0-70">70</a></span>
<span class="normal"><a href="#__codelineno-0-71">71</a></span>
<span class="normal"><a href="#__codelineno-0-72">72</a></span>
<span class="normal"><a href="#__codelineno-0-73">73</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-56"><a id="__codelineno-0-56" name="__codelineno-0-56"></a><span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span>
</span><span id="__span-0-57"><a id="__codelineno-0-57" name="__codelineno-0-57"></a> <span class="bp">self</span><span class="p">,</span>
</span><span id="__span-0-58"><a id="__codelineno-0-58" name="__codelineno-0-58"></a> <span class="n">host</span><span class="p">:</span> <span class="nb">str</span> <span class="o">=</span> <span class="n">DEFAULT_XMLRPC_HOST</span><span class="p">,</span>
</span><span id="__span-0-59"><a id="__codelineno-0-59" name="__codelineno-0-59"></a> <span class="n">port</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="n">DEFAULT_XMLRPC_PORT</span><span class="p">,</span>
</span><span id="__span-0-60"><a id="__codelineno-0-60" name="__codelineno-0-60"></a> <span class="n">timeout</span><span class="p">:</span> <span class="nb">float</span> <span class="o">=</span> <span class="n">DEFAULT_TIMEOUT</span><span class="p">,</span>
</span><span id="__span-0-61"><a id="__codelineno-0-61" name="__codelineno-0-61"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="kc">None</span><span class="p">:</span>
</span><span id="__span-0-62"><a id="__codelineno-0-62" name="__codelineno-0-62"></a><span class="w"> </span><span class="sd">"""Initialize the XML-RPC bridge.</span>
</span><span id="__span-0-63"><a id="__codelineno-0-63" name="__codelineno-0-63"></a>
</span><span id="__span-0-64"><a id="__codelineno-0-64" name="__codelineno-0-64"></a><span class="sd"> Args:</span>
</span><span id="__span-0-65"><a id="__codelineno-0-65" name="__codelineno-0-65"></a><span class="sd"> host: XML-RPC server hostname.</span>
</span><span id="__span-0-66"><a id="__codelineno-0-66" name="__codelineno-0-66"></a><span class="sd"> port: XML-RPC server port.</span>
</span><span id="__span-0-67"><a id="__codelineno-0-67" name="__codelineno-0-67"></a><span class="sd"> timeout: Connection and request timeout in seconds.</span>
</span><span id="__span-0-68"><a id="__codelineno-0-68" name="__codelineno-0-68"></a><span class="sd"> """</span>
</span><span id="__span-0-69"><a id="__codelineno-0-69" name="__codelineno-0-69"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_host</span> <span class="o">=</span> <span class="n">host</span>
</span><span id="__span-0-70"><a id="__codelineno-0-70" name="__codelineno-0-70"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_port</span> <span class="o">=</span> <span class="n">port</span>
</span><span id="__span-0-71"><a id="__codelineno-0-71" name="__codelineno-0-71"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_timeout</span> <span class="o">=</span> <span class="n">timeout</span>
</span><span id="__span-0-72"><a id="__codelineno-0-72" name="__codelineno-0-72"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_proxy</span><span class="p">:</span> <span class="n">xmlrpc</span><span class="o">.</span><span class="n">client</span><span class="o">.</span><span class="n">ServerProxy</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span>
</span><span id="__span-0-73"><a id="__codelineno-0-73" name="__codelineno-0-73"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_connected</span> <span class="o">=</span> <span class="kc">False</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> </div> </div> <div class="doc doc-object doc-function"> <h6 id="freecad_mcp.bridge.xmlrpc.XmlRpcBridge.activate_workbench" class="doc doc-heading"> <code class="highlight language-python"><span class="n">activate_workbench</span><span class="p">(</span><span class="n">workbench_name</span><span class="p">)</span></code> <span class="doc doc-labels"> <small class="doc doc-label doc-label-async"><code>async</code></small> </span> <a href="#freecad_mcp.bridge.xmlrpc.XmlRpcBridge.activate_workbench" class="headerlink" title="Permanent link">¶</a></h6> <div class="doc doc-contents "> <p>Activate a workbench.</p> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/xmlrpc.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-970">970</a></span>
<span class="normal"><a href="#__codelineno-0-971">971</a></span>
<span class="normal"><a href="#__codelineno-0-972">972</a></span>
<span class="normal"><a href="#__codelineno-0-973">973</a></span>
<span class="normal"><a href="#__codelineno-0-974">974</a></span>
<span class="normal"><a href="#__codelineno-0-975">975</a></span>
<span class="normal"><a href="#__codelineno-0-976">976</a></span>
<span class="normal"><a href="#__codelineno-0-977">977</a></span>
<span class="normal"><a href="#__codelineno-0-978">978</a></span>
<span class="normal"><a href="#__codelineno-0-979">979</a></span>
<span class="normal"><a href="#__codelineno-0-980">980</a></span>
<span class="normal"><a href="#__codelineno-0-981">981</a></span>
<span class="normal"><a href="#__codelineno-0-982">982</a></span>
<span class="normal"><a href="#__codelineno-0-983">983</a></span>
<span class="normal"><a href="#__codelineno-0-984">984</a></span>
<span class="normal"><a href="#__codelineno-0-985">985</a></span>
<span class="normal"><a href="#__codelineno-0-986">986</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-970"><a id="__codelineno-0-970" name="__codelineno-0-970"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">activate_workbench</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">workbench_name</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kc">None</span><span class="p">:</span>
</span><span id="__span-0-971"><a id="__codelineno-0-971" name="__codelineno-0-971"></a><span class="w"> </span><span class="sd">"""Activate a workbench."""</span>
</span><span id="__span-0-972"><a id="__codelineno-0-972" name="__codelineno-0-972"></a> <span class="n">code</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">"""</span>
</span><span id="__span-0-973"><a id="__codelineno-0-973" name="__codelineno-0-973"></a><span class="s2">if FreeCAD.GuiUp:</span>
</span><span id="__span-0-974"><a id="__codelineno-0-974" name="__codelineno-0-974"></a><span class="s2"> try:</span>
</span><span id="__span-0-975"><a id="__codelineno-0-975" name="__codelineno-0-975"></a><span class="s2"> FreeCADGui.activateWorkbench(</span><span class="si">{</span><span class="n">workbench_name</span><span class="si">!r}</span><span class="s2">)</span>
</span><span id="__span-0-976"><a id="__codelineno-0-976" name="__codelineno-0-976"></a><span class="s2"> _result_ = True</span>
</span><span id="__span-0-977"><a id="__codelineno-0-977" name="__codelineno-0-977"></a><span class="s2"> except Exception as e:</span>
</span><span id="__span-0-978"><a id="__codelineno-0-978" name="__codelineno-0-978"></a><span class="s2"> raise ValueError(f"Failed to activate workbench: </span><span class="se">{{</span><span class="s2">e</span><span class="se">}}</span><span class="s2">")</span>
</span><span id="__span-0-979"><a id="__codelineno-0-979" name="__codelineno-0-979"></a><span class="s2">else:</span>
</span><span id="__span-0-980"><a id="__codelineno-0-980" name="__codelineno-0-980"></a><span class="s2"> _result_ = True # Silently succeed in headless mode</span>
</span><span id="__span-0-981"><a id="__codelineno-0-981" name="__codelineno-0-981"></a><span class="s2">"""</span>
</span><span id="__span-0-982"><a id="__codelineno-0-982" name="__codelineno-0-982"></a> <span class="n">result</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">execute_python</span><span class="p">(</span><span class="n">code</span><span class="p">)</span>
</span><span id="__span-0-983"><a id="__codelineno-0-983" name="__codelineno-0-983"></a>
</span><span id="__span-0-984"><a id="__codelineno-0-984" name="__codelineno-0-984"></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">result</span><span class="o">.</span><span class="n">success</span><span class="p">:</span>
</span><span id="__span-0-985"><a id="__codelineno-0-985" name="__codelineno-0-985"></a> <span class="n">error_msg</span> <span class="o">=</span> <span class="n">result</span><span class="o">.</span><span class="n">error_traceback</span> <span class="ow">or</span> <span class="s2">"Failed to activate workbench"</span>
</span><span id="__span-0-986"><a id="__codelineno-0-986" name="__codelineno-0-986"></a> <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="n">error_msg</span><span class="p">)</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> </div> </div> <div class="doc doc-object doc-function"> <h6 id="freecad_mcp.bridge.xmlrpc.XmlRpcBridge.close_document" class="doc doc-heading"> <code class="highlight language-python"><span class="n">close_document</span><span class="p">(</span><span class="n">doc_name</span><span class="o">=</span><span class="kc">None</span><span class="p">)</span></code> <span class="doc doc-labels"> <small class="doc doc-label doc-label-async"><code>async</code></small> </span> <a href="#freecad_mcp.bridge.xmlrpc.XmlRpcBridge.close_document" class="headerlink" title="Permanent link">¶</a></h6> <div class="doc doc-contents "> <p>Close a document.</p> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/xmlrpc.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-437">437</a></span>
<span class="normal"><a href="#__codelineno-0-438">438</a></span>
<span class="normal"><a href="#__codelineno-0-439">439</a></span>
<span class="normal"><a href="#__codelineno-0-440">440</a></span>
<span class="normal"><a href="#__codelineno-0-441">441</a></span>
<span class="normal"><a href="#__codelineno-0-442">442</a></span>
<span class="normal"><a href="#__codelineno-0-443">443</a></span>
<span class="normal"><a href="#__codelineno-0-444">444</a></span>
<span class="normal"><a href="#__codelineno-0-445">445</a></span>
<span class="normal"><a href="#__codelineno-0-446">446</a></span>
<span class="normal"><a href="#__codelineno-0-447">447</a></span>
<span class="normal"><a href="#__codelineno-0-448">448</a></span>
<span class="normal"><a href="#__codelineno-0-449">449</a></span>
<span class="normal"><a href="#__codelineno-0-450">450</a></span>
<span class="normal"><a href="#__codelineno-0-451">451</a></span>
<span class="normal"><a href="#__codelineno-0-452">452</a></span>
<span class="normal"><a href="#__codelineno-0-453">453</a></span>
<span class="normal"><a href="#__codelineno-0-454">454</a></span>
<span class="normal"><a href="#__codelineno-0-455">455</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-437"><a id="__codelineno-0-437" name="__codelineno-0-437"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">close_document</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">doc_name</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kc">None</span><span class="p">:</span>
</span><span id="__span-0-438"><a id="__codelineno-0-438" name="__codelineno-0-438"></a><span class="w"> </span><span class="sd">"""Close a document."""</span>
</span><span id="__span-0-439"><a id="__codelineno-0-439" name="__codelineno-0-439"></a> <span class="n">code</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">"""</span>
</span><span id="__span-0-440"><a id="__codelineno-0-440" name="__codelineno-0-440"></a><span class="s2">doc_name = </span><span class="si">{</span><span class="n">doc_name</span><span class="si">!r}</span>
</span><span id="__span-0-441"><a id="__codelineno-0-441" name="__codelineno-0-441"></a><span class="s2">if doc_name is None:</span>
</span><span id="__span-0-442"><a id="__codelineno-0-442" name="__codelineno-0-442"></a><span class="s2"> doc = FreeCAD.ActiveDocument</span>
</span><span id="__span-0-443"><a id="__codelineno-0-443" name="__codelineno-0-443"></a><span class="s2"> if doc:</span>
</span><span id="__span-0-444"><a id="__codelineno-0-444" name="__codelineno-0-444"></a><span class="s2"> doc_name = doc.Name</span>
</span><span id="__span-0-445"><a id="__codelineno-0-445" name="__codelineno-0-445"></a><span class="s2"> else:</span>
</span><span id="__span-0-446"><a id="__codelineno-0-446" name="__codelineno-0-446"></a><span class="s2"> raise ValueError("No active document")</span>
</span><span id="__span-0-447"><a id="__codelineno-0-447" name="__codelineno-0-447"></a>
</span><span id="__span-0-448"><a id="__codelineno-0-448" name="__codelineno-0-448"></a><span class="s2">FreeCAD.closeDocument(doc_name)</span>
</span><span id="__span-0-449"><a id="__codelineno-0-449" name="__codelineno-0-449"></a><span class="s2">_result_ = True</span>
</span><span id="__span-0-450"><a id="__codelineno-0-450" name="__codelineno-0-450"></a><span class="s2">"""</span>
</span><span id="__span-0-451"><a id="__codelineno-0-451" name="__codelineno-0-451"></a> <span class="n">result</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">execute_python</span><span class="p">(</span><span class="n">code</span><span class="p">)</span>
</span><span id="__span-0-452"><a id="__codelineno-0-452" name="__codelineno-0-452"></a>
</span><span id="__span-0-453"><a id="__codelineno-0-453" name="__codelineno-0-453"></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">result</span><span class="o">.</span><span class="n">success</span><span class="p">:</span>
</span><span id="__span-0-454"><a id="__codelineno-0-454" name="__codelineno-0-454"></a> <span class="n">error_msg</span> <span class="o">=</span> <span class="n">result</span><span class="o">.</span><span class="n">error_traceback</span> <span class="ow">or</span> <span class="s2">"Failed to close document"</span>
</span><span id="__span-0-455"><a id="__codelineno-0-455" name="__codelineno-0-455"></a> <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="n">error_msg</span><span class="p">)</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> </div> </div> <div class="doc doc-object doc-function"> <h6 id="freecad_mcp.bridge.xmlrpc.XmlRpcBridge.connect" class="doc doc-heading"> <code class="highlight language-python"><span class="n">connect</span><span class="p">()</span></code> <span class="doc doc-labels"> <small class="doc doc-label doc-label-async"><code>async</code></small> </span> <a href="#freecad_mcp.bridge.xmlrpc.XmlRpcBridge.connect" class="headerlink" title="Permanent link">¶</a></h6> <div class="doc doc-contents "> <p>Establish connection to FreeCAD XML-RPC server.</p> <p><span class="doc-section-title">Raises:</span></p> <table> <thead> <tr> <th>Type</th> <th>Description</th> </tr> </thead> <tbody> <tr class="doc-section-item"> <td> <code><span title="ConnectionError">ConnectionError</span></code> </td> <td> <div class="doc-md-description"> <p>If connection cannot be established.</p> </div> </td> </tr> </tbody> </table> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/xmlrpc.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-80"> 80</a></span>
<span class="normal"><a href="#__codelineno-0-81"> 81</a></span>
<span class="normal"><a href="#__codelineno-0-82"> 82</a></span>
<span class="normal"><a href="#__codelineno-0-83"> 83</a></span>
<span class="normal"><a href="#__codelineno-0-84"> 84</a></span>
<span class="normal"><a href="#__codelineno-0-85"> 85</a></span>
<span class="normal"><a href="#__codelineno-0-86"> 86</a></span>
<span class="normal"><a href="#__codelineno-0-87"> 87</a></span>
<span class="normal"><a href="#__codelineno-0-88"> 88</a></span>
<span class="normal"><a href="#__codelineno-0-89"> 89</a></span>
<span class="normal"><a href="#__codelineno-0-90"> 90</a></span>
<span class="normal"><a href="#__codelineno-0-91"> 91</a></span>
<span class="normal"><a href="#__codelineno-0-92"> 92</a></span>
<span class="normal"><a href="#__codelineno-0-93"> 93</a></span>
<span class="normal"><a href="#__codelineno-0-94"> 94</a></span>
<span class="normal"><a href="#__codelineno-0-95"> 95</a></span>
<span class="normal"><a href="#__codelineno-0-96"> 96</a></span>
<span class="normal"><a href="#__codelineno-0-97"> 97</a></span>
<span class="normal"><a href="#__codelineno-0-98"> 98</a></span>
<span class="normal"><a href="#__codelineno-0-99"> 99</a></span>
<span class="normal"><a href="#__codelineno-0-100">100</a></span>
<span class="normal"><a href="#__codelineno-0-101">101</a></span>
<span class="normal"><a href="#__codelineno-0-102">102</a></span>
<span class="normal"><a href="#__codelineno-0-103">103</a></span>
<span class="normal"><a href="#__codelineno-0-104">104</a></span>
<span class="normal"><a href="#__codelineno-0-105">105</a></span>
<span class="normal"><a href="#__codelineno-0-106">106</a></span>
<span class="normal"><a href="#__codelineno-0-107">107</a></span>
<span class="normal"><a href="#__codelineno-0-108">108</a></span>
<span class="normal"><a href="#__codelineno-0-109">109</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-80"><a id="__codelineno-0-80" name="__codelineno-0-80"></a><span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">connect</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kc">None</span><span class="p">:</span>
</span><span id="__span-0-81"><a id="__codelineno-0-81" name="__codelineno-0-81"></a><span class="w"> </span><span class="sd">"""Establish connection to FreeCAD XML-RPC server.</span>
</span><span id="__span-0-82"><a id="__codelineno-0-82" name="__codelineno-0-82"></a>
</span><span id="__span-0-83"><a id="__codelineno-0-83" name="__codelineno-0-83"></a><span class="sd"> Raises:</span>
</span><span id="__span-0-84"><a id="__codelineno-0-84" name="__codelineno-0-84"></a><span class="sd"> ConnectionError: If connection cannot be established.</span>
</span><span id="__span-0-85"><a id="__codelineno-0-85" name="__codelineno-0-85"></a><span class="sd"> """</span>
</span><span id="__span-0-86"><a id="__codelineno-0-86" name="__codelineno-0-86"></a> <span class="n">loop</span> <span class="o">=</span> <span class="n">asyncio</span><span class="o">.</span><span class="n">get_event_loop</span><span class="p">()</span>
</span><span id="__span-0-87"><a id="__codelineno-0-87" name="__codelineno-0-87"></a> <span class="k">try</span><span class="p">:</span>
</span><span id="__span-0-88"><a id="__codelineno-0-88" name="__codelineno-0-88"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_proxy</span> <span class="o">=</span> <span class="k">await</span> <span class="n">loop</span><span class="o">.</span><span class="n">run_in_executor</span><span class="p">(</span>
</span><span id="__span-0-89"><a id="__codelineno-0-89" name="__codelineno-0-89"></a> <span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-90"><a id="__codelineno-0-90" name="__codelineno-0-90"></a> <span class="k">lambda</span><span class="p">:</span> <span class="n">xmlrpc</span><span class="o">.</span><span class="n">client</span><span class="o">.</span><span class="n">ServerProxy</span><span class="p">(</span>
</span><span id="__span-0-91"><a id="__codelineno-0-91" name="__codelineno-0-91"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_server_url</span><span class="p">,</span>
</span><span id="__span-0-92"><a id="__codelineno-0-92" name="__codelineno-0-92"></a> <span class="n">allow_none</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span>
</span><span id="__span-0-93"><a id="__codelineno-0-93" name="__codelineno-0-93"></a> <span class="p">),</span>
</span><span id="__span-0-94"><a id="__codelineno-0-94" name="__codelineno-0-94"></a> <span class="p">)</span>
</span><span id="__span-0-95"><a id="__codelineno-0-95" name="__codelineno-0-95"></a> <span class="c1"># Test connection with a ping</span>
</span><span id="__span-0-96"><a id="__codelineno-0-96" name="__codelineno-0-96"></a> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">ping</span><span class="p">()</span>
</span><span id="__span-0-97"><a id="__codelineno-0-97" name="__codelineno-0-97"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_connected</span> <span class="o">=</span> <span class="kc">True</span>
</span><span id="__span-0-98"><a id="__codelineno-0-98" name="__codelineno-0-98"></a> <span class="k">except</span> <span class="ne">ConnectionRefusedError</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
</span><span id="__span-0-99"><a id="__codelineno-0-99" name="__codelineno-0-99"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_connected</span> <span class="o">=</span> <span class="kc">False</span>
</span><span id="__span-0-100"><a id="__codelineno-0-100" name="__codelineno-0-100"></a> <span class="n">msg</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_connection_refused_message</span><span class="p">()</span>
</span><span id="__span-0-101"><a id="__codelineno-0-101" name="__codelineno-0-101"></a> <span class="k">raise</span> <span class="ne">ConnectionError</span><span class="p">(</span><span class="n">msg</span><span class="p">)</span> <span class="kn">from</span><span class="w"> </span><span class="nn">e</span>
</span><span id="__span-0-102"><a id="__codelineno-0-102" name="__codelineno-0-102"></a> <span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
</span><span id="__span-0-103"><a id="__codelineno-0-103" name="__codelineno-0-103"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_connected</span> <span class="o">=</span> <span class="kc">False</span>
</span><span id="__span-0-104"><a id="__codelineno-0-104" name="__codelineno-0-104"></a> <span class="n">error_str</span> <span class="o">=</span> <span class="nb">str</span><span class="p">(</span><span class="n">e</span><span class="p">)</span>
</span><span id="__span-0-105"><a id="__codelineno-0-105" name="__codelineno-0-105"></a> <span class="k">if</span> <span class="s2">"Connection refused"</span> <span class="ow">in</span> <span class="n">error_str</span> <span class="ow">or</span> <span class="s2">"Errno 61"</span> <span class="ow">in</span> <span class="n">error_str</span><span class="p">:</span>
</span><span id="__span-0-106"><a id="__codelineno-0-106" name="__codelineno-0-106"></a> <span class="n">msg</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_connection_refused_message</span><span class="p">()</span>
</span><span id="__span-0-107"><a id="__codelineno-0-107" name="__codelineno-0-107"></a> <span class="k">else</span><span class="p">:</span>
</span><span id="__span-0-108"><a id="__codelineno-0-108" name="__codelineno-0-108"></a> <span class="n">msg</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">"Failed to connect to XML-RPC server at </span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">_server_url</span><span class="si">}</span><span class="s2">: </span><span class="si">{</span><span class="n">e</span><span class="si">}</span><span class="s2">"</span>
</span><span id="__span-0-109"><a id="__codelineno-0-109" name="__codelineno-0-109"></a> <span class="k">raise</span> <span class="ne">ConnectionError</span><span class="p">(</span><span class="n">msg</span><span class="p">)</span> <span class="kn">from</span><span class="w"> </span><span class="nn">e</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> </div> </div> <div class="doc doc-object doc-function"> <h6 id="freecad_mcp.bridge.xmlrpc.XmlRpcBridge.create_document" class="doc doc-heading"> <code class="highlight language-python"><span class="n">create_document</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">label</span><span class="o">=</span><span class="kc">None</span><span class="p">)</span></code> <span class="doc doc-labels"> <small class="doc doc-label doc-label-async"><code>async</code></small> </span> <a href="#freecad_mcp.bridge.xmlrpc.XmlRpcBridge.create_document" class="headerlink" title="Permanent link">¶</a></h6> <div class="doc doc-contents "> <p>Create a new document.</p> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/xmlrpc.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-358">358</a></span>
<span class="normal"><a href="#__codelineno-0-359">359</a></span>
<span class="normal"><a href="#__codelineno-0-360">360</a></span>
<span class="normal"><a href="#__codelineno-0-361">361</a></span>
<span class="normal"><a href="#__codelineno-0-362">362</a></span>
<span class="normal"><a href="#__codelineno-0-363">363</a></span>
<span class="normal"><a href="#__codelineno-0-364">364</a></span>
<span class="normal"><a href="#__codelineno-0-365">365</a></span>
<span class="normal"><a href="#__codelineno-0-366">366</a></span>
<span class="normal"><a href="#__codelineno-0-367">367</a></span>
<span class="normal"><a href="#__codelineno-0-368">368</a></span>
<span class="normal"><a href="#__codelineno-0-369">369</a></span>
<span class="normal"><a href="#__codelineno-0-370">370</a></span>
<span class="normal"><a href="#__codelineno-0-371">371</a></span>
<span class="normal"><a href="#__codelineno-0-372">372</a></span>
<span class="normal"><a href="#__codelineno-0-373">373</a></span>
<span class="normal"><a href="#__codelineno-0-374">374</a></span>
<span class="normal"><a href="#__codelineno-0-375">375</a></span>
<span class="normal"><a href="#__codelineno-0-376">376</a></span>
<span class="normal"><a href="#__codelineno-0-377">377</a></span>
<span class="normal"><a href="#__codelineno-0-378">378</a></span>
<span class="normal"><a href="#__codelineno-0-379">379</a></span>
<span class="normal"><a href="#__codelineno-0-380">380</a></span>
<span class="normal"><a href="#__codelineno-0-381">381</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-358"><a id="__codelineno-0-358" name="__codelineno-0-358"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">create_document</span><span class="p">(</span>
</span><span id="__span-0-359"><a id="__codelineno-0-359" name="__codelineno-0-359"></a> <span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">label</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span>
</span><span id="__span-0-360"><a id="__codelineno-0-360" name="__codelineno-0-360"></a> <span class="p">)</span> <span class="o">-&gt;</span> <span class="n">DocumentInfo</span><span class="p">:</span>
</span><span id="__span-0-361"><a id="__codelineno-0-361" name="__codelineno-0-361"></a><span class="w"> </span><span class="sd">"""Create a new document."""</span>
</span><span id="__span-0-362"><a id="__codelineno-0-362" name="__codelineno-0-362"></a> <span class="n">label</span> <span class="o">=</span> <span class="n">label</span> <span class="ow">or</span> <span class="n">name</span>
</span><span id="__span-0-363"><a id="__codelineno-0-363" name="__codelineno-0-363"></a> <span class="n">result</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">execute_python</span><span class="p">(</span>
</span><span id="__span-0-364"><a id="__codelineno-0-364" name="__codelineno-0-364"></a> <span class="sa">f</span><span class="s2">"""</span>
</span><span id="__span-0-365"><a id="__codelineno-0-365" name="__codelineno-0-365"></a><span class="s2">doc = FreeCAD.newDocument(</span><span class="si">{</span><span class="n">name</span><span class="si">!r}</span><span class="s2">)</span>
</span><span id="__span-0-366"><a id="__codelineno-0-366" name="__codelineno-0-366"></a><span class="s2">doc.Label = </span><span class="si">{</span><span class="n">label</span><span class="si">!r}</span>
</span><span id="__span-0-367"><a id="__codelineno-0-367" name="__codelineno-0-367"></a><span class="s2">_result_ = </span><span class="se">{{</span>
</span><span id="__span-0-368"><a id="__codelineno-0-368" name="__codelineno-0-368"></a><span class="s2"> "name": doc.Name,</span>
</span><span id="__span-0-369"><a id="__codelineno-0-369" name="__codelineno-0-369"></a><span class="s2"> "label": doc.Label,</span>
</span><span id="__span-0-370"><a id="__codelineno-0-370" name="__codelineno-0-370"></a><span class="s2"> "path": doc.FileName or None,</span>
</span><span id="__span-0-371"><a id="__codelineno-0-371" name="__codelineno-0-371"></a><span class="s2"> "objects": [],</span>
</span><span id="__span-0-372"><a id="__codelineno-0-372" name="__codelineno-0-372"></a><span class="s2"> "is_modified": False,</span>
</span><span id="__span-0-373"><a id="__codelineno-0-373" name="__codelineno-0-373"></a><span class="se">}}</span>
</span><span id="__span-0-374"><a id="__codelineno-0-374" name="__codelineno-0-374"></a><span class="s2">"""</span>
</span><span id="__span-0-375"><a id="__codelineno-0-375" name="__codelineno-0-375"></a> <span class="p">)</span>
</span><span id="__span-0-376"><a id="__codelineno-0-376" name="__codelineno-0-376"></a>
</span><span id="__span-0-377"><a id="__codelineno-0-377" name="__codelineno-0-377"></a> <span class="k">if</span> <span class="n">result</span><span class="o">.</span><span class="n">success</span> <span class="ow">and</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">:</span>
</span><span id="__span-0-378"><a id="__codelineno-0-378" name="__codelineno-0-378"></a> <span class="k">return</span> <span class="n">DocumentInfo</span><span class="p">(</span><span class="o">**</span><span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">)</span>
</span><span id="__span-0-379"><a id="__codelineno-0-379" name="__codelineno-0-379"></a>
</span><span id="__span-0-380"><a id="__codelineno-0-380" name="__codelineno-0-380"></a> <span class="n">error_msg</span> <span class="o">=</span> <span class="n">result</span><span class="o">.</span><span class="n">error_traceback</span> <span class="ow">or</span> <span class="s2">"Failed to create document"</span>
</span><span id="__span-0-381"><a id="__codelineno-0-381" name="__codelineno-0-381"></a> <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="n">error_msg</span><span class="p">)</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> </div> </div> <div class="doc doc-object doc-function"> <h6 id="freecad_mcp.bridge.xmlrpc.XmlRpcBridge.create_macro" class="doc doc-heading"> <code class="highlight language-python"><span class="n">create_macro</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">code</span><span class="p">,</span> <span class="n">description</span><span class="o">=</span><span class="s1">''</span><span class="p">)</span></code> <span class="doc doc-labels"> <small class="doc doc-label doc-label-async"><code>async</code></small> </span> <a href="#freecad_mcp.bridge.xmlrpc.XmlRpcBridge.create_macro" class="headerlink" title="Permanent link">¶</a></h6> <div class="doc doc-contents "> <p>Create a new macro.</p> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/xmlrpc.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-884">884</a></span>
<span class="normal"><a href="#__codelineno-0-885">885</a></span>
<span class="normal"><a href="#__codelineno-0-886">886</a></span>
<span class="normal"><a href="#__codelineno-0-887">887</a></span>
<span class="normal"><a href="#__codelineno-0-888">888</a></span>
<span class="normal"><a href="#__codelineno-0-889">889</a></span>
<span class="normal"><a href="#__codelineno-0-890">890</a></span>
<span class="normal"><a href="#__codelineno-0-891">891</a></span>
<span class="normal"><a href="#__codelineno-0-892">892</a></span>
<span class="normal"><a href="#__codelineno-0-893">893</a></span>
<span class="normal"><a href="#__codelineno-0-894">894</a></span>
<span class="normal"><a href="#__codelineno-0-895">895</a></span>
<span class="normal"><a href="#__codelineno-0-896">896</a></span>
<span class="normal"><a href="#__codelineno-0-897">897</a></span>
<span class="normal"><a href="#__codelineno-0-898">898</a></span>
<span class="normal"><a href="#__codelineno-0-899">899</a></span>
<span class="normal"><a href="#__codelineno-0-900">900</a></span>
<span class="normal"><a href="#__codelineno-0-901">901</a></span>
<span class="normal"><a href="#__codelineno-0-902">902</a></span>
<span class="normal"><a href="#__codelineno-0-903">903</a></span>
<span class="normal"><a href="#__codelineno-0-904">904</a></span>
<span class="normal"><a href="#__codelineno-0-905">905</a></span>
<span class="normal"><a href="#__codelineno-0-906">906</a></span>
<span class="normal"><a href="#__codelineno-0-907">907</a></span>
<span class="normal"><a href="#__codelineno-0-908">908</a></span>
<span class="normal"><a href="#__codelineno-0-909">909</a></span>
<span class="normal"><a href="#__codelineno-0-910">910</a></span>
<span class="normal"><a href="#__codelineno-0-911">911</a></span>
<span class="normal"><a href="#__codelineno-0-912">912</a></span>
<span class="normal"><a href="#__codelineno-0-913">913</a></span>
<span class="normal"><a href="#__codelineno-0-914">914</a></span>
<span class="normal"><a href="#__codelineno-0-915">915</a></span>
<span class="normal"><a href="#__codelineno-0-916">916</a></span>
<span class="normal"><a href="#__codelineno-0-917">917</a></span>
<span class="normal"><a href="#__codelineno-0-918">918</a></span>
<span class="normal"><a href="#__codelineno-0-919">919</a></span>
<span class="normal"><a href="#__codelineno-0-920">920</a></span>
<span class="normal"><a href="#__codelineno-0-921">921</a></span>
<span class="normal"><a href="#__codelineno-0-922">922</a></span>
<span class="normal"><a href="#__codelineno-0-923">923</a></span>
<span class="normal"><a href="#__codelineno-0-924">924</a></span>
<span class="normal"><a href="#__codelineno-0-925">925</a></span>
<span class="normal"><a href="#__codelineno-0-926">926</a></span>
<span class="normal"><a href="#__codelineno-0-927">927</a></span>
<span class="normal"><a href="#__codelineno-0-928">928</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-884"><a id="__codelineno-0-884" name="__codelineno-0-884"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">create_macro</span><span class="p">(</span>
</span><span id="__span-0-885"><a id="__codelineno-0-885" name="__codelineno-0-885"></a> <span class="bp">self</span><span class="p">,</span>
</span><span id="__span-0-886"><a id="__codelineno-0-886" name="__codelineno-0-886"></a> <span class="n">name</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span>
</span><span id="__span-0-887"><a id="__codelineno-0-887" name="__codelineno-0-887"></a> <span class="n">code</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span>
</span><span id="__span-0-888"><a id="__codelineno-0-888" name="__codelineno-0-888"></a> <span class="n">description</span><span class="p">:</span> <span class="nb">str</span> <span class="o">=</span> <span class="s2">""</span><span class="p">,</span>
</span><span id="__span-0-889"><a id="__codelineno-0-889" name="__codelineno-0-889"></a> <span class="p">)</span> <span class="o">-&gt;</span> <span class="n">MacroInfo</span><span class="p">:</span>
</span><span id="__span-0-890"><a id="__codelineno-0-890" name="__codelineno-0-890"></a><span class="w"> </span><span class="sd">"""Create a new macro."""</span>
</span><span id="__span-0-891"><a id="__codelineno-0-891" name="__codelineno-0-891"></a> <span class="n">create_code</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">"""</span>
</span><span id="__span-0-892"><a id="__codelineno-0-892" name="__codelineno-0-892"></a><span class="s2">import os</span>
</span><span id="__span-0-893"><a id="__codelineno-0-893" name="__codelineno-0-893"></a>
</span><span id="__span-0-894"><a id="__codelineno-0-894" name="__codelineno-0-894"></a><span class="s2">macro_path = FreeCAD.getUserMacroDir(True)</span>
</span><span id="__span-0-895"><a id="__codelineno-0-895" name="__codelineno-0-895"></a><span class="s2">os.makedirs(macro_path, exist_ok=True)</span>
</span><span id="__span-0-896"><a id="__codelineno-0-896" name="__codelineno-0-896"></a>
</span><span id="__span-0-897"><a id="__codelineno-0-897" name="__codelineno-0-897"></a><span class="s2">macro_file = os.path.join(macro_path, </span><span class="si">{</span><span class="n">name</span><span class="si">!r}</span><span class="s2"> + ".FCMacro")</span>
</span><span id="__span-0-898"><a id="__codelineno-0-898" name="__codelineno-0-898"></a>
</span><span id="__span-0-899"><a id="__codelineno-0-899" name="__codelineno-0-899"></a><span class="s2">header = ""</span>
</span><span id="__span-0-900"><a id="__codelineno-0-900" name="__codelineno-0-900"></a><span class="s2">if </span><span class="si">{</span><span class="n">description</span><span class="si">!r}</span><span class="s2">:</span>
</span><span id="__span-0-901"><a id="__codelineno-0-901" name="__codelineno-0-901"></a><span class="s2"> header = f"# </span><span class="si">{</span><span class="n">description</span><span class="si">!r}</span><span class="se">\\</span><span class="s2">n</span><span class="se">\\</span><span class="s2">n"</span>
</span><span id="__span-0-902"><a id="__codelineno-0-902" name="__codelineno-0-902"></a>
</span><span id="__span-0-903"><a id="__codelineno-0-903" name="__codelineno-0-903"></a><span class="s2">full_code = header + '''# -*- coding: utf-8 -*-</span>
</span><span id="__span-0-904"><a id="__codelineno-0-904" name="__codelineno-0-904"></a><span class="s2"># FreeCAD Macro: </span><span class="si">{</span><span class="n">name</span><span class="si">}</span>
</span><span id="__span-0-905"><a id="__codelineno-0-905" name="__codelineno-0-905"></a><span class="s2"># Created via MCP Bridge</span>
</span><span id="__span-0-906"><a id="__codelineno-0-906" name="__codelineno-0-906"></a>
</span><span id="__span-0-907"><a id="__codelineno-0-907" name="__codelineno-0-907"></a><span class="s2">import FreeCAD</span>
</span><span id="__span-0-908"><a id="__codelineno-0-908" name="__codelineno-0-908"></a><span class="s2">import FreeCADGui</span>
</span><span id="__span-0-909"><a id="__codelineno-0-909" name="__codelineno-0-909"></a>
</span><span id="__span-0-910"><a id="__codelineno-0-910" name="__codelineno-0-910"></a><span class="s2">''' + </span><span class="si">{</span><span class="n">code</span><span class="si">!r}</span>
</span><span id="__span-0-911"><a id="__codelineno-0-911" name="__codelineno-0-911"></a>
</span><span id="__span-0-912"><a id="__codelineno-0-912" name="__codelineno-0-912"></a><span class="s2">with open(macro_file, "w") as f:</span>
</span><span id="__span-0-913"><a id="__codelineno-0-913" name="__codelineno-0-913"></a><span class="s2"> f.write(full_code)</span>
</span><span id="__span-0-914"><a id="__codelineno-0-914" name="__codelineno-0-914"></a>
</span><span id="__span-0-915"><a id="__codelineno-0-915" name="__codelineno-0-915"></a><span class="s2">_result_ = </span><span class="se">{{</span>
</span><span id="__span-0-916"><a id="__codelineno-0-916" name="__codelineno-0-916"></a><span class="s2"> "name": </span><span class="si">{</span><span class="n">name</span><span class="si">!r}</span><span class="s2">,</span>
</span><span id="__span-0-917"><a id="__codelineno-0-917" name="__codelineno-0-917"></a><span class="s2"> "path": macro_file,</span>
</span><span id="__span-0-918"><a id="__codelineno-0-918" name="__codelineno-0-918"></a><span class="s2"> "description": </span><span class="si">{</span><span class="n">description</span><span class="si">!r}</span><span class="s2">,</span>
</span><span id="__span-0-919"><a id="__codelineno-0-919" name="__codelineno-0-919"></a><span class="s2"> "is_system": False,</span>
</span><span id="__span-0-920"><a id="__codelineno-0-920" name="__codelineno-0-920"></a><span class="se">}}</span>
</span><span id="__span-0-921"><a id="__codelineno-0-921" name="__codelineno-0-921"></a><span class="s2">"""</span>
</span><span id="__span-0-922"><a id="__codelineno-0-922" name="__codelineno-0-922"></a> <span class="n">result</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">execute_python</span><span class="p">(</span><span class="n">create_code</span><span class="p">)</span>
</span><span id="__span-0-923"><a id="__codelineno-0-923" name="__codelineno-0-923"></a>
</span><span id="__span-0-924"><a id="__codelineno-0-924" name="__codelineno-0-924"></a> <span class="k">if</span> <span class="n">result</span><span class="o">.</span><span class="n">success</span> <span class="ow">and</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">:</span>
</span><span id="__span-0-925"><a id="__codelineno-0-925" name="__codelineno-0-925"></a> <span class="k">return</span> <span class="n">MacroInfo</span><span class="p">(</span><span class="o">**</span><span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">)</span>
</span><span id="__span-0-926"><a id="__codelineno-0-926" name="__codelineno-0-926"></a>
</span><span id="__span-0-927"><a id="__codelineno-0-927" name="__codelineno-0-927"></a> <span class="n">error_msg</span> <span class="o">=</span> <span class="n">result</span><span class="o">.</span><span class="n">error_traceback</span> <span class="ow">or</span> <span class="s2">"Failed to create macro"</span>
</span><span id="__span-0-928"><a id="__codelineno-0-928" name="__codelineno-0-928"></a> <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="n">error_msg</span><span class="p">)</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> </div> </div> <div class="doc doc-object doc-function"> <h6 id="freecad_mcp.bridge.xmlrpc.XmlRpcBridge.create_object" class="doc doc-heading"> <code class="highlight language-python"><span class="n">create_object</span><span class="p">(</span><span class="n">type_id</span><span class="p">,</span> <span class="n">name</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">properties</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">doc_name</span><span class="o">=</span><span class="kc">None</span><span class="p">)</span></code> <span class="doc doc-labels"> <small class="doc doc-label doc-label-async"><code>async</code></small> </span> <a href="#freecad_mcp.bridge.xmlrpc.XmlRpcBridge.create_object" class="headerlink" title="Permanent link">¶</a></h6> <div class="doc doc-contents "> <p>Create a new object.</p> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/xmlrpc.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-546">546</a></span>
<span class="normal"><a href="#__codelineno-0-547">547</a></span>
<span class="normal"><a href="#__codelineno-0-548">548</a></span>
<span class="normal"><a href="#__codelineno-0-549">549</a></span>
<span class="normal"><a href="#__codelineno-0-550">550</a></span>
<span class="normal"><a href="#__codelineno-0-551">551</a></span>
<span class="normal"><a href="#__codelineno-0-552">552</a></span>
<span class="normal"><a href="#__codelineno-0-553">553</a></span>
<span class="normal"><a href="#__codelineno-0-554">554</a></span>
<span class="normal"><a href="#__codelineno-0-555">555</a></span>
<span class="normal"><a href="#__codelineno-0-556">556</a></span>
<span class="normal"><a href="#__codelineno-0-557">557</a></span>
<span class="normal"><a href="#__codelineno-0-558">558</a></span>
<span class="normal"><a href="#__codelineno-0-559">559</a></span>
<span class="normal"><a href="#__codelineno-0-560">560</a></span>
<span class="normal"><a href="#__codelineno-0-561">561</a></span>
<span class="normal"><a href="#__codelineno-0-562">562</a></span>
<span class="normal"><a href="#__codelineno-0-563">563</a></span>
<span class="normal"><a href="#__codelineno-0-564">564</a></span>
<span class="normal"><a href="#__codelineno-0-565">565</a></span>
<span class="normal"><a href="#__codelineno-0-566">566</a></span>
<span class="normal"><a href="#__codelineno-0-567">567</a></span>
<span class="normal"><a href="#__codelineno-0-568">568</a></span>
<span class="normal"><a href="#__codelineno-0-569">569</a></span>
<span class="normal"><a href="#__codelineno-0-570">570</a></span>
<span class="normal"><a href="#__codelineno-0-571">571</a></span>
<span class="normal"><a href="#__codelineno-0-572">572</a></span>
<span class="normal"><a href="#__codelineno-0-573">573</a></span>
<span class="normal"><a href="#__codelineno-0-574">574</a></span>
<span class="normal"><a href="#__codelineno-0-575">575</a></span>
<span class="normal"><a href="#__codelineno-0-576">576</a></span>
<span class="normal"><a href="#__codelineno-0-577">577</a></span>
<span class="normal"><a href="#__codelineno-0-578">578</a></span>
<span class="normal"><a href="#__codelineno-0-579">579</a></span>
<span class="normal"><a href="#__codelineno-0-580">580</a></span>
<span class="normal"><a href="#__codelineno-0-581">581</a></span>
<span class="normal"><a href="#__codelineno-0-582">582</a></span>
<span class="normal"><a href="#__codelineno-0-583">583</a></span>
<span class="normal"><a href="#__codelineno-0-584">584</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-546"><a id="__codelineno-0-546" name="__codelineno-0-546"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">create_object</span><span class="p">(</span>
</span><span id="__span-0-547"><a id="__codelineno-0-547" name="__codelineno-0-547"></a> <span class="bp">self</span><span class="p">,</span>
</span><span id="__span-0-548"><a id="__codelineno-0-548" name="__codelineno-0-548"></a> <span class="n">type_id</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span>
</span><span id="__span-0-549"><a id="__codelineno-0-549" name="__codelineno-0-549"></a> <span class="n">name</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-550"><a id="__codelineno-0-550" name="__codelineno-0-550"></a> <span class="n">properties</span><span class="p">:</span> <span class="nb">dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Any</span><span class="p">]</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-551"><a id="__codelineno-0-551" name="__codelineno-0-551"></a> <span class="n">doc_name</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-552"><a id="__codelineno-0-552" name="__codelineno-0-552"></a> <span class="p">)</span> <span class="o">-&gt;</span> <span class="n">ObjectInfo</span><span class="p">:</span>
</span><span id="__span-0-553"><a id="__codelineno-0-553" name="__codelineno-0-553"></a><span class="w"> </span><span class="sd">"""Create a new object."""</span>
</span><span id="__span-0-554"><a id="__codelineno-0-554" name="__codelineno-0-554"></a> <span class="n">properties</span> <span class="o">=</span> <span class="n">properties</span> <span class="ow">or</span> <span class="p">{}</span>
</span><span id="__span-0-555"><a id="__codelineno-0-555" name="__codelineno-0-555"></a> <span class="n">code</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">"""</span>
</span><span id="__span-0-556"><a id="__codelineno-0-556" name="__codelineno-0-556"></a><span class="s2">doc = FreeCAD.ActiveDocument if </span><span class="si">{</span><span class="n">doc_name</span><span class="si">!r}</span><span class="s2"> is None else FreeCAD.getDocument(</span><span class="si">{</span><span class="n">doc_name</span><span class="si">!r}</span><span class="s2">)</span>
</span><span id="__span-0-557"><a id="__codelineno-0-557" name="__codelineno-0-557"></a><span class="s2">if doc is None:</span>
</span><span id="__span-0-558"><a id="__codelineno-0-558" name="__codelineno-0-558"></a><span class="s2"> raise ValueError("No document found")</span>
</span><span id="__span-0-559"><a id="__codelineno-0-559" name="__codelineno-0-559"></a>
</span><span id="__span-0-560"><a id="__codelineno-0-560" name="__codelineno-0-560"></a><span class="s2">obj = doc.addObject(</span><span class="si">{</span><span class="n">type_id</span><span class="si">!r}</span><span class="s2">, </span><span class="si">{</span><span class="n">name</span><span class="si">!r}</span><span class="s2"> or "")</span>
</span><span id="__span-0-561"><a id="__codelineno-0-561" name="__codelineno-0-561"></a>
</span><span id="__span-0-562"><a id="__codelineno-0-562" name="__codelineno-0-562"></a><span class="s2"># Set properties</span>
</span><span id="__span-0-563"><a id="__codelineno-0-563" name="__codelineno-0-563"></a><span class="s2">for prop_name, prop_val in </span><span class="si">{</span><span class="n">properties</span><span class="si">!r}</span><span class="s2">.items():</span>
</span><span id="__span-0-564"><a id="__codelineno-0-564" name="__codelineno-0-564"></a><span class="s2"> if hasattr(obj, prop_name):</span>
</span><span id="__span-0-565"><a id="__codelineno-0-565" name="__codelineno-0-565"></a><span class="s2"> setattr(obj, prop_name, prop_val)</span>
</span><span id="__span-0-566"><a id="__codelineno-0-566" name="__codelineno-0-566"></a>
</span><span id="__span-0-567"><a id="__codelineno-0-567" name="__codelineno-0-567"></a><span class="s2">doc.recompute()</span>
</span><span id="__span-0-568"><a id="__codelineno-0-568" name="__codelineno-0-568"></a>
</span><span id="__span-0-569"><a id="__codelineno-0-569" name="__codelineno-0-569"></a><span class="s2">_result_ = </span><span class="se">{{</span>
</span><span id="__span-0-570"><a id="__codelineno-0-570" name="__codelineno-0-570"></a><span class="s2"> "name": obj.Name,</span>
</span><span id="__span-0-571"><a id="__codelineno-0-571" name="__codelineno-0-571"></a><span class="s2"> "label": obj.Label,</span>
</span><span id="__span-0-572"><a id="__codelineno-0-572" name="__codelineno-0-572"></a><span class="s2"> "type_id": obj.TypeId,</span>
</span><span id="__span-0-573"><a id="__codelineno-0-573" name="__codelineno-0-573"></a><span class="s2"> "visibility": True,</span>
</span><span id="__span-0-574"><a id="__codelineno-0-574" name="__codelineno-0-574"></a><span class="s2"> "children": [c.Name for c in obj.OutList] if hasattr(obj, "OutList") else [],</span>
</span><span id="__span-0-575"><a id="__codelineno-0-575" name="__codelineno-0-575"></a><span class="s2"> "parents": [p.Name for p in obj.InList] if hasattr(obj, "InList") else [],</span>
</span><span id="__span-0-576"><a id="__codelineno-0-576" name="__codelineno-0-576"></a><span class="se">}}</span>
</span><span id="__span-0-577"><a id="__codelineno-0-577" name="__codelineno-0-577"></a><span class="s2">"""</span>
</span><span id="__span-0-578"><a id="__codelineno-0-578" name="__codelineno-0-578"></a> <span class="n">result</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">execute_python</span><span class="p">(</span><span class="n">code</span><span class="p">)</span>
</span><span id="__span-0-579"><a id="__codelineno-0-579" name="__codelineno-0-579"></a>
</span><span id="__span-0-580"><a id="__codelineno-0-580" name="__codelineno-0-580"></a> <span class="k">if</span> <span class="n">result</span><span class="o">.</span><span class="n">success</span> <span class="ow">and</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">:</span>
</span><span id="__span-0-581"><a id="__codelineno-0-581" name="__codelineno-0-581"></a> <span class="k">return</span> <span class="n">ObjectInfo</span><span class="p">(</span><span class="o">**</span><span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">)</span>
</span><span id="__span-0-582"><a id="__codelineno-0-582" name="__codelineno-0-582"></a>
</span><span id="__span-0-583"><a id="__codelineno-0-583" name="__codelineno-0-583"></a> <span class="n">error_msg</span> <span class="o">=</span> <span class="n">result</span><span class="o">.</span><span class="n">error_traceback</span> <span class="ow">or</span> <span class="s2">"Failed to create object"</span>
</span><span id="__span-0-584"><a id="__codelineno-0-584" name="__codelineno-0-584"></a> <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="n">error_msg</span><span class="p">)</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> </div> </div> <div class="doc doc-object doc-function"> <h6 id="freecad_mcp.bridge.xmlrpc.XmlRpcBridge.delete_object" class="doc doc-heading"> <code class="highlight language-python"><span class="n">delete_object</span><span class="p">(</span><span class="n">obj_name</span><span class="p">,</span> <span class="n">doc_name</span><span class="o">=</span><span class="kc">None</span><span class="p">)</span></code> <span class="doc doc-labels"> <small class="doc doc-label doc-label-async"><code>async</code></small> </span> <a href="#freecad_mcp.bridge.xmlrpc.XmlRpcBridge.delete_object" class="headerlink" title="Permanent link">¶</a></h6> <div class="doc doc-contents "> <p>Delete an object.</p> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/xmlrpc.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-626">626</a></span>
<span class="normal"><a href="#__codelineno-0-627">627</a></span>
<span class="normal"><a href="#__codelineno-0-628">628</a></span>
<span class="normal"><a href="#__codelineno-0-629">629</a></span>
<span class="normal"><a href="#__codelineno-0-630">630</a></span>
<span class="normal"><a href="#__codelineno-0-631">631</a></span>
<span class="normal"><a href="#__codelineno-0-632">632</a></span>
<span class="normal"><a href="#__codelineno-0-633">633</a></span>
<span class="normal"><a href="#__codelineno-0-634">634</a></span>
<span class="normal"><a href="#__codelineno-0-635">635</a></span>
<span class="normal"><a href="#__codelineno-0-636">636</a></span>
<span class="normal"><a href="#__codelineno-0-637">637</a></span>
<span class="normal"><a href="#__codelineno-0-638">638</a></span>
<span class="normal"><a href="#__codelineno-0-639">639</a></span>
<span class="normal"><a href="#__codelineno-0-640">640</a></span>
<span class="normal"><a href="#__codelineno-0-641">641</a></span>
<span class="normal"><a href="#__codelineno-0-642">642</a></span>
<span class="normal"><a href="#__codelineno-0-643">643</a></span>
<span class="normal"><a href="#__codelineno-0-644">644</a></span>
<span class="normal"><a href="#__codelineno-0-645">645</a></span>
<span class="normal"><a href="#__codelineno-0-646">646</a></span>
<span class="normal"><a href="#__codelineno-0-647">647</a></span>
<span class="normal"><a href="#__codelineno-0-648">648</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-626"><a id="__codelineno-0-626" name="__codelineno-0-626"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">delete_object</span><span class="p">(</span>
</span><span id="__span-0-627"><a id="__codelineno-0-627" name="__codelineno-0-627"></a> <span class="bp">self</span><span class="p">,</span>
</span><span id="__span-0-628"><a id="__codelineno-0-628" name="__codelineno-0-628"></a> <span class="n">obj_name</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span>
</span><span id="__span-0-629"><a id="__codelineno-0-629" name="__codelineno-0-629"></a> <span class="n">doc_name</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-630"><a id="__codelineno-0-630" name="__codelineno-0-630"></a> <span class="p">)</span> <span class="o">-&gt;</span> <span class="kc">None</span><span class="p">:</span>
</span><span id="__span-0-631"><a id="__codelineno-0-631" name="__codelineno-0-631"></a><span class="w"> </span><span class="sd">"""Delete an object."""</span>
</span><span id="__span-0-632"><a id="__codelineno-0-632" name="__codelineno-0-632"></a> <span class="n">code</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">"""</span>
</span><span id="__span-0-633"><a id="__codelineno-0-633" name="__codelineno-0-633"></a><span class="s2">doc = FreeCAD.ActiveDocument if </span><span class="si">{</span><span class="n">doc_name</span><span class="si">!r}</span><span class="s2"> is None else FreeCAD.getDocument(</span><span class="si">{</span><span class="n">doc_name</span><span class="si">!r}</span><span class="s2">)</span>
</span><span id="__span-0-634"><a id="__codelineno-0-634" name="__codelineno-0-634"></a><span class="s2">if doc is None:</span>
</span><span id="__span-0-635"><a id="__codelineno-0-635" name="__codelineno-0-635"></a><span class="s2"> raise ValueError("No document found")</span>
</span><span id="__span-0-636"><a id="__codelineno-0-636" name="__codelineno-0-636"></a>
</span><span id="__span-0-637"><a id="__codelineno-0-637" name="__codelineno-0-637"></a><span class="s2">obj = doc.getObject(</span><span class="si">{</span><span class="n">obj_name</span><span class="si">!r}</span><span class="s2">)</span>
</span><span id="__span-0-638"><a id="__codelineno-0-638" name="__codelineno-0-638"></a><span class="s2">if obj is None:</span>
</span><span id="__span-0-639"><a id="__codelineno-0-639" name="__codelineno-0-639"></a><span class="s2"> raise ValueError(f"Object not found: </span><span class="si">{</span><span class="n">obj_name</span><span class="si">!r}</span><span class="s2">")</span>
</span><span id="__span-0-640"><a id="__codelineno-0-640" name="__codelineno-0-640"></a>
</span><span id="__span-0-641"><a id="__codelineno-0-641" name="__codelineno-0-641"></a><span class="s2">doc.removeObject(</span><span class="si">{</span><span class="n">obj_name</span><span class="si">!r}</span><span class="s2">)</span>
</span><span id="__span-0-642"><a id="__codelineno-0-642" name="__codelineno-0-642"></a><span class="s2">_result_ = True</span>
</span><span id="__span-0-643"><a id="__codelineno-0-643" name="__codelineno-0-643"></a><span class="s2">"""</span>
</span><span id="__span-0-644"><a id="__codelineno-0-644" name="__codelineno-0-644"></a> <span class="n">result</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">execute_python</span><span class="p">(</span><span class="n">code</span><span class="p">)</span>
</span><span id="__span-0-645"><a id="__codelineno-0-645" name="__codelineno-0-645"></a>
</span><span id="__span-0-646"><a id="__codelineno-0-646" name="__codelineno-0-646"></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">result</span><span class="o">.</span><span class="n">success</span><span class="p">:</span>
</span><span id="__span-0-647"><a id="__codelineno-0-647" name="__codelineno-0-647"></a> <span class="n">error_msg</span> <span class="o">=</span> <span class="n">result</span><span class="o">.</span><span class="n">error_traceback</span> <span class="ow">or</span> <span class="s2">"Failed to delete object"</span>
</span><span id="__span-0-648"><a id="__codelineno-0-648" name="__codelineno-0-648"></a> <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="n">error_msg</span><span class="p">)</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> </div> </div> <div class="doc doc-object doc-function"> <h6 id="freecad_mcp.bridge.xmlrpc.XmlRpcBridge.disconnect" class="doc doc-heading"> <code class="highlight language-python"><span class="n">disconnect</span><span class="p">()</span></code> <span class="doc doc-labels"> <small class="doc doc-label doc-label-async"><code>async</code></small> </span> <a href="#freecad_mcp.bridge.xmlrpc.XmlRpcBridge.disconnect" class="headerlink" title="Permanent link">¶</a></h6> <div class="doc doc-contents "> <p>Close connection to FreeCAD XML-RPC server.</p> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/xmlrpc.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-140">140</a></span>
<span class="normal"><a href="#__codelineno-0-141">141</a></span>
<span class="normal"><a href="#__codelineno-0-142">142</a></span>
<span class="normal"><a href="#__codelineno-0-143">143</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-140"><a id="__codelineno-0-140" name="__codelineno-0-140"></a><span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">disconnect</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kc">None</span><span class="p">:</span>
</span><span id="__span-0-141"><a id="__codelineno-0-141" name="__codelineno-0-141"></a><span class="w"> </span><span class="sd">"""Close connection to FreeCAD XML-RPC server."""</span>
</span><span id="__span-0-142"><a id="__codelineno-0-142" name="__codelineno-0-142"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_proxy</span> <span class="o">=</span> <span class="kc">None</span>
</span><span id="__span-0-143"><a id="__codelineno-0-143" name="__codelineno-0-143"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_connected</span> <span class="o">=</span> <span class="kc">False</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> </div> </div> <div class="doc doc-object doc-function"> <h6 id="freecad_mcp.bridge.xmlrpc.XmlRpcBridge.edit_object" class="doc doc-heading"> <code class="highlight language-python"><span class="n">edit_object</span><span class="p">(</span><span class="n">obj_name</span><span class="p">,</span> <span class="n">properties</span><span class="p">,</span> <span class="n">doc_name</span><span class="o">=</span><span class="kc">None</span><span class="p">)</span></code> <span class="doc doc-labels"> <small class="doc doc-label doc-label-async"><code>async</code></small> </span> <a href="#freecad_mcp.bridge.xmlrpc.XmlRpcBridge.edit_object" class="headerlink" title="Permanent link">¶</a></h6> <div class="doc doc-contents "> <p>Edit object properties.</p> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/xmlrpc.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-586">586</a></span>
<span class="normal"><a href="#__codelineno-0-587">587</a></span>
<span class="normal"><a href="#__codelineno-0-588">588</a></span>
<span class="normal"><a href="#__codelineno-0-589">589</a></span>
<span class="normal"><a href="#__codelineno-0-590">590</a></span>
<span class="normal"><a href="#__codelineno-0-591">591</a></span>
<span class="normal"><a href="#__codelineno-0-592">592</a></span>
<span class="normal"><a href="#__codelineno-0-593">593</a></span>
<span class="normal"><a href="#__codelineno-0-594">594</a></span>
<span class="normal"><a href="#__codelineno-0-595">595</a></span>
<span class="normal"><a href="#__codelineno-0-596">596</a></span>
<span class="normal"><a href="#__codelineno-0-597">597</a></span>
<span class="normal"><a href="#__codelineno-0-598">598</a></span>
<span class="normal"><a href="#__codelineno-0-599">599</a></span>
<span class="normal"><a href="#__codelineno-0-600">600</a></span>
<span class="normal"><a href="#__codelineno-0-601">601</a></span>
<span class="normal"><a href="#__codelineno-0-602">602</a></span>
<span class="normal"><a href="#__codelineno-0-603">603</a></span>
<span class="normal"><a href="#__codelineno-0-604">604</a></span>
<span class="normal"><a href="#__codelineno-0-605">605</a></span>
<span class="normal"><a href="#__codelineno-0-606">606</a></span>
<span class="normal"><a href="#__codelineno-0-607">607</a></span>
<span class="normal"><a href="#__codelineno-0-608">608</a></span>
<span class="normal"><a href="#__codelineno-0-609">609</a></span>
<span class="normal"><a href="#__codelineno-0-610">610</a></span>
<span class="normal"><a href="#__codelineno-0-611">611</a></span>
<span class="normal"><a href="#__codelineno-0-612">612</a></span>
<span class="normal"><a href="#__codelineno-0-613">613</a></span>
<span class="normal"><a href="#__codelineno-0-614">614</a></span>
<span class="normal"><a href="#__codelineno-0-615">615</a></span>
<span class="normal"><a href="#__codelineno-0-616">616</a></span>
<span class="normal"><a href="#__codelineno-0-617">617</a></span>
<span class="normal"><a href="#__codelineno-0-618">618</a></span>
<span class="normal"><a href="#__codelineno-0-619">619</a></span>
<span class="normal"><a href="#__codelineno-0-620">620</a></span>
<span class="normal"><a href="#__codelineno-0-621">621</a></span>
<span class="normal"><a href="#__codelineno-0-622">622</a></span>
<span class="normal"><a href="#__codelineno-0-623">623</a></span>
<span class="normal"><a href="#__codelineno-0-624">624</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-586"><a id="__codelineno-0-586" name="__codelineno-0-586"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">edit_object</span><span class="p">(</span>
</span><span id="__span-0-587"><a id="__codelineno-0-587" name="__codelineno-0-587"></a> <span class="bp">self</span><span class="p">,</span>
</span><span id="__span-0-588"><a id="__codelineno-0-588" name="__codelineno-0-588"></a> <span class="n">obj_name</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span>
</span><span id="__span-0-589"><a id="__codelineno-0-589" name="__codelineno-0-589"></a> <span class="n">properties</span><span class="p">:</span> <span class="nb">dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Any</span><span class="p">],</span>
</span><span id="__span-0-590"><a id="__codelineno-0-590" name="__codelineno-0-590"></a> <span class="n">doc_name</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-591"><a id="__codelineno-0-591" name="__codelineno-0-591"></a> <span class="p">)</span> <span class="o">-&gt;</span> <span class="n">ObjectInfo</span><span class="p">:</span>
</span><span id="__span-0-592"><a id="__codelineno-0-592" name="__codelineno-0-592"></a><span class="w"> </span><span class="sd">"""Edit object properties."""</span>
</span><span id="__span-0-593"><a id="__codelineno-0-593" name="__codelineno-0-593"></a> <span class="n">code</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">"""</span>
</span><span id="__span-0-594"><a id="__codelineno-0-594" name="__codelineno-0-594"></a><span class="s2">doc = FreeCAD.ActiveDocument if </span><span class="si">{</span><span class="n">doc_name</span><span class="si">!r}</span><span class="s2"> is None else FreeCAD.getDocument(</span><span class="si">{</span><span class="n">doc_name</span><span class="si">!r}</span><span class="s2">)</span>
</span><span id="__span-0-595"><a id="__codelineno-0-595" name="__codelineno-0-595"></a><span class="s2">if doc is None:</span>
</span><span id="__span-0-596"><a id="__codelineno-0-596" name="__codelineno-0-596"></a><span class="s2"> raise ValueError("No document found")</span>
</span><span id="__span-0-597"><a id="__codelineno-0-597" name="__codelineno-0-597"></a>
</span><span id="__span-0-598"><a id="__codelineno-0-598" name="__codelineno-0-598"></a><span class="s2">obj = doc.getObject(</span><span class="si">{</span><span class="n">obj_name</span><span class="si">!r}</span><span class="s2">)</span>
</span><span id="__span-0-599"><a id="__codelineno-0-599" name="__codelineno-0-599"></a><span class="s2">if obj is None:</span>
</span><span id="__span-0-600"><a id="__codelineno-0-600" name="__codelineno-0-600"></a><span class="s2"> raise ValueError(f"Object not found: </span><span class="si">{</span><span class="n">obj_name</span><span class="si">!r}</span><span class="s2">")</span>
</span><span id="__span-0-601"><a id="__codelineno-0-601" name="__codelineno-0-601"></a>
</span><span id="__span-0-602"><a id="__codelineno-0-602" name="__codelineno-0-602"></a><span class="s2"># Set properties</span>
</span><span id="__span-0-603"><a id="__codelineno-0-603" name="__codelineno-0-603"></a><span class="s2">for prop_name, prop_val in </span><span class="si">{</span><span class="n">properties</span><span class="si">!r}</span><span class="s2">.items():</span>
</span><span id="__span-0-604"><a id="__codelineno-0-604" name="__codelineno-0-604"></a><span class="s2"> if hasattr(obj, prop_name):</span>
</span><span id="__span-0-605"><a id="__codelineno-0-605" name="__codelineno-0-605"></a><span class="s2"> setattr(obj, prop_name, prop_val)</span>
</span><span id="__span-0-606"><a id="__codelineno-0-606" name="__codelineno-0-606"></a>
</span><span id="__span-0-607"><a id="__codelineno-0-607" name="__codelineno-0-607"></a><span class="s2">doc.recompute()</span>
</span><span id="__span-0-608"><a id="__codelineno-0-608" name="__codelineno-0-608"></a>
</span><span id="__span-0-609"><a id="__codelineno-0-609" name="__codelineno-0-609"></a><span class="s2">_result_ = </span><span class="se">{{</span>
</span><span id="__span-0-610"><a id="__codelineno-0-610" name="__codelineno-0-610"></a><span class="s2"> "name": obj.Name,</span>
</span><span id="__span-0-611"><a id="__codelineno-0-611" name="__codelineno-0-611"></a><span class="s2"> "label": obj.Label,</span>
</span><span id="__span-0-612"><a id="__codelineno-0-612" name="__codelineno-0-612"></a><span class="s2"> "type_id": obj.TypeId,</span>
</span><span id="__span-0-613"><a id="__codelineno-0-613" name="__codelineno-0-613"></a><span class="s2"> "visibility": obj.ViewObject.Visibility if hasattr(obj, "ViewObject") and obj.ViewObject else True,</span>
</span><span id="__span-0-614"><a id="__codelineno-0-614" name="__codelineno-0-614"></a><span class="s2"> "children": [c.Name for c in obj.OutList] if hasattr(obj, "OutList") else [],</span>
</span><span id="__span-0-615"><a id="__codelineno-0-615" name="__codelineno-0-615"></a><span class="s2"> "parents": [p.Name for p in obj.InList] if hasattr(obj, "InList") else [],</span>
</span><span id="__span-0-616"><a id="__codelineno-0-616" name="__codelineno-0-616"></a><span class="se">}}</span>
</span><span id="__span-0-617"><a id="__codelineno-0-617" name="__codelineno-0-617"></a><span class="s2">"""</span>
</span><span id="__span-0-618"><a id="__codelineno-0-618" name="__codelineno-0-618"></a> <span class="n">result</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">execute_python</span><span class="p">(</span><span class="n">code</span><span class="p">)</span>
</span><span id="__span-0-619"><a id="__codelineno-0-619" name="__codelineno-0-619"></a>
</span><span id="__span-0-620"><a id="__codelineno-0-620" name="__codelineno-0-620"></a> <span class="k">if</span> <span class="n">result</span><span class="o">.</span><span class="n">success</span> <span class="ow">and</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">:</span>
</span><span id="__span-0-621"><a id="__codelineno-0-621" name="__codelineno-0-621"></a> <span class="k">return</span> <span class="n">ObjectInfo</span><span class="p">(</span><span class="o">**</span><span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">)</span>
</span><span id="__span-0-622"><a id="__codelineno-0-622" name="__codelineno-0-622"></a>
</span><span id="__span-0-623"><a id="__codelineno-0-623" name="__codelineno-0-623"></a> <span class="n">error_msg</span> <span class="o">=</span> <span class="n">result</span><span class="o">.</span><span class="n">error_traceback</span> <span class="ow">or</span> <span class="s2">"Failed to edit object"</span>
</span><span id="__span-0-624"><a id="__codelineno-0-624" name="__codelineno-0-624"></a> <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="n">error_msg</span><span class="p">)</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> </div> </div> <div class="doc doc-object doc-function"> <h6 id="freecad_mcp.bridge.xmlrpc.XmlRpcBridge.execute_python" class="doc doc-heading"> <code class="highlight language-python"><span class="n">execute_python</span><span class="p">(</span><span class="n">code</span><span class="p">,</span> <span class="n">timeout_ms</span><span class="o">=</span><span class="mi">30000</span><span class="p">)</span></code> <span class="doc doc-labels"> <small class="doc doc-label doc-label-async"><code>async</code></small> </span> <a href="#freecad_mcp.bridge.xmlrpc.XmlRpcBridge.execute_python" class="headerlink" title="Permanent link">¶</a></h6> <div class="doc doc-contents "> <p>Execute Python code in FreeCAD context via XML-RPC.</p> <p><span class="doc-section-title">Parameters:</span></p> <table> <thead> <tr> <th>Name</th> <th>Type</th> <th>Description</th> <th>Default</th> </tr> </thead> <tbody> <tr class="doc-section-item"> <td> <code>code</code> </td> <td> <code><span title="str">str</span></code> </td> <td> <div class="doc-md-description"> <p>Python code to execute.</p> </div> </td> <td> <em>required</em> </td> </tr> <tr class="doc-section-item"> <td> <code>timeout_ms</code> </td> <td> <code><span title="int">int</span></code> </td> <td> <div class="doc-md-description"> <p>Maximum execution time in milliseconds.</p> </div> </td> <td> <code>30000</code> </td> </tr> </tbody> </table> <p><span class="doc-section-title">Returns:</span></p> <table> <thead> <tr> <th>Type</th> <th>Description</th> </tr> </thead> <tbody> <tr class="doc-section-item"> <td> <code><a class="autorefs autorefs-internal" title="ExecutionResult
dataclass
(freecad_mcp.bridge.base.ExecutionResult)" href="#freecad_mcp.bridge.base.ExecutionResult">ExecutionResult</a></code> </td> <td> <div class="doc-md-description"> <p>ExecutionResult with execution outcome.</p> </div> </td> </tr> </tbody> </table> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/xmlrpc.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-231">231</a></span>
<span class="normal"><a href="#__codelineno-0-232">232</a></span>
<span class="normal"><a href="#__codelineno-0-233">233</a></span>
<span class="normal"><a href="#__codelineno-0-234">234</a></span>
<span class="normal"><a href="#__codelineno-0-235">235</a></span>
<span class="normal"><a href="#__codelineno-0-236">236</a></span>
<span class="normal"><a href="#__codelineno-0-237">237</a></span>
<span class="normal"><a href="#__codelineno-0-238">238</a></span>
<span class="normal"><a href="#__codelineno-0-239">239</a></span>
<span class="normal"><a href="#__codelineno-0-240">240</a></span>
<span class="normal"><a href="#__codelineno-0-241">241</a></span>
<span class="normal"><a href="#__codelineno-0-242">242</a></span>
<span class="normal"><a href="#__codelineno-0-243">243</a></span>
<span class="normal"><a href="#__codelineno-0-244">244</a></span>
<span class="normal"><a href="#__codelineno-0-245">245</a></span>
<span class="normal"><a href="#__codelineno-0-246">246</a></span>
<span class="normal"><a href="#__codelineno-0-247">247</a></span>
<span class="normal"><a href="#__codelineno-0-248">248</a></span>
<span class="normal"><a href="#__codelineno-0-249">249</a></span>
<span class="normal"><a href="#__codelineno-0-250">250</a></span>
<span class="normal"><a href="#__codelineno-0-251">251</a></span>
<span class="normal"><a href="#__codelineno-0-252">252</a></span>
<span class="normal"><a href="#__codelineno-0-253">253</a></span>
<span class="normal"><a href="#__codelineno-0-254">254</a></span>
<span class="normal"><a href="#__codelineno-0-255">255</a></span>
<span class="normal"><a href="#__codelineno-0-256">256</a></span>
<span class="normal"><a href="#__codelineno-0-257">257</a></span>
<span class="normal"><a href="#__codelineno-0-258">258</a></span>
<span class="normal"><a href="#__codelineno-0-259">259</a></span>
<span class="normal"><a href="#__codelineno-0-260">260</a></span>
<span class="normal"><a href="#__codelineno-0-261">261</a></span>
<span class="normal"><a href="#__codelineno-0-262">262</a></span>
<span class="normal"><a href="#__codelineno-0-263">263</a></span>
<span class="normal"><a href="#__codelineno-0-264">264</a></span>
<span class="normal"><a href="#__codelineno-0-265">265</a></span>
<span class="normal"><a href="#__codelineno-0-266">266</a></span>
<span class="normal"><a href="#__codelineno-0-267">267</a></span>
<span class="normal"><a href="#__codelineno-0-268">268</a></span>
<span class="normal"><a href="#__codelineno-0-269">269</a></span>
<span class="normal"><a href="#__codelineno-0-270">270</a></span>
<span class="normal"><a href="#__codelineno-0-271">271</a></span>
<span class="normal"><a href="#__codelineno-0-272">272</a></span>
<span class="normal"><a href="#__codelineno-0-273">273</a></span>
<span class="normal"><a href="#__codelineno-0-274">274</a></span>
<span class="normal"><a href="#__codelineno-0-275">275</a></span>
<span class="normal"><a href="#__codelineno-0-276">276</a></span>
<span class="normal"><a href="#__codelineno-0-277">277</a></span>
<span class="normal"><a href="#__codelineno-0-278">278</a></span>
<span class="normal"><a href="#__codelineno-0-279">279</a></span>
<span class="normal"><a href="#__codelineno-0-280">280</a></span>
<span class="normal"><a href="#__codelineno-0-281">281</a></span>
<span class="normal"><a href="#__codelineno-0-282">282</a></span>
<span class="normal"><a href="#__codelineno-0-283">283</a></span>
<span class="normal"><a href="#__codelineno-0-284">284</a></span>
<span class="normal"><a href="#__codelineno-0-285">285</a></span>
<span class="normal"><a href="#__codelineno-0-286">286</a></span>
<span class="normal"><a href="#__codelineno-0-287">287</a></span>
<span class="normal"><a href="#__codelineno-0-288">288</a></span>
<span class="normal"><a href="#__codelineno-0-289">289</a></span>
<span class="normal"><a href="#__codelineno-0-290">290</a></span>
<span class="normal"><a href="#__codelineno-0-291">291</a></span>
<span class="normal"><a href="#__codelineno-0-292">292</a></span>
<span class="normal"><a href="#__codelineno-0-293">293</a></span>
<span class="normal"><a href="#__codelineno-0-294">294</a></span>
<span class="normal"><a href="#__codelineno-0-295">295</a></span>
<span class="normal"><a href="#__codelineno-0-296">296</a></span>
<span class="normal"><a href="#__codelineno-0-297">297</a></span>
<span class="normal"><a href="#__codelineno-0-298">298</a></span>
<span class="normal"><a href="#__codelineno-0-299">299</a></span>
<span class="normal"><a href="#__codelineno-0-300">300</a></span>
<span class="normal"><a href="#__codelineno-0-301">301</a></span>
<span class="normal"><a href="#__codelineno-0-302">302</a></span>
<span class="normal"><a href="#__codelineno-0-303">303</a></span>
<span class="normal"><a href="#__codelineno-0-304">304</a></span>
<span class="normal"><a href="#__codelineno-0-305">305</a></span>
<span class="normal"><a href="#__codelineno-0-306">306</a></span>
<span class="normal"><a href="#__codelineno-0-307">307</a></span>
<span class="normal"><a href="#__codelineno-0-308">308</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-231"><a id="__codelineno-0-231" name="__codelineno-0-231"></a><span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">execute_python</span><span class="p">(</span>
</span><span id="__span-0-232"><a id="__codelineno-0-232" name="__codelineno-0-232"></a> <span class="bp">self</span><span class="p">,</span>
</span><span id="__span-0-233"><a id="__codelineno-0-233" name="__codelineno-0-233"></a> <span class="n">code</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span>
</span><span id="__span-0-234"><a id="__codelineno-0-234" name="__codelineno-0-234"></a> <span class="n">timeout_ms</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">30000</span><span class="p">,</span>
</span><span id="__span-0-235"><a id="__codelineno-0-235" name="__codelineno-0-235"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">ExecutionResult</span><span class="p">:</span>
</span><span id="__span-0-236"><a id="__codelineno-0-236" name="__codelineno-0-236"></a><span class="w"> </span><span class="sd">"""Execute Python code in FreeCAD context via XML-RPC.</span>
</span><span id="__span-0-237"><a id="__codelineno-0-237" name="__codelineno-0-237"></a>
</span><span id="__span-0-238"><a id="__codelineno-0-238" name="__codelineno-0-238"></a><span class="sd"> Args:</span>
</span><span id="__span-0-239"><a id="__codelineno-0-239" name="__codelineno-0-239"></a><span class="sd"> code: Python code to execute.</span>
</span><span id="__span-0-240"><a id="__codelineno-0-240" name="__codelineno-0-240"></a><span class="sd"> timeout_ms: Maximum execution time in milliseconds.</span>
</span><span id="__span-0-241"><a id="__codelineno-0-241" name="__codelineno-0-241"></a>
</span><span id="__span-0-242"><a id="__codelineno-0-242" name="__codelineno-0-242"></a><span class="sd"> Returns:</span>
</span><span id="__span-0-243"><a id="__codelineno-0-243" name="__codelineno-0-243"></a><span class="sd"> ExecutionResult with execution outcome.</span>
</span><span id="__span-0-244"><a id="__codelineno-0-244" name="__codelineno-0-244"></a><span class="sd"> """</span>
</span><span id="__span-0-245"><a id="__codelineno-0-245" name="__codelineno-0-245"></a> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_proxy</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
</span><span id="__span-0-246"><a id="__codelineno-0-246" name="__codelineno-0-246"></a> <span class="k">return</span> <span class="n">ExecutionResult</span><span class="p">(</span>
</span><span id="__span-0-247"><a id="__codelineno-0-247" name="__codelineno-0-247"></a> <span class="n">success</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
</span><span id="__span-0-248"><a id="__codelineno-0-248" name="__codelineno-0-248"></a> <span class="n">result</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-249"><a id="__codelineno-0-249" name="__codelineno-0-249"></a> <span class="n">stdout</span><span class="o">=</span><span class="s2">""</span><span class="p">,</span>
</span><span id="__span-0-250"><a id="__codelineno-0-250" name="__codelineno-0-250"></a> <span class="n">stderr</span><span class="o">=</span><span class="s2">"Not connected to XML-RPC server"</span><span class="p">,</span>
</span><span id="__span-0-251"><a id="__codelineno-0-251" name="__codelineno-0-251"></a> <span class="n">execution_time_ms</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span>
</span><span id="__span-0-252"><a id="__codelineno-0-252" name="__codelineno-0-252"></a> <span class="n">error_type</span><span class="o">=</span><span class="s2">"ConnectionError"</span><span class="p">,</span>
</span><span id="__span-0-253"><a id="__codelineno-0-253" name="__codelineno-0-253"></a> <span class="p">)</span>
</span><span id="__span-0-254"><a id="__codelineno-0-254" name="__codelineno-0-254"></a>
</span><span id="__span-0-255"><a id="__codelineno-0-255" name="__codelineno-0-255"></a> <span class="n">loop</span> <span class="o">=</span> <span class="n">asyncio</span><span class="o">.</span><span class="n">get_event_loop</span><span class="p">()</span>
</span><span id="__span-0-256"><a id="__codelineno-0-256" name="__codelineno-0-256"></a> <span class="n">start</span> <span class="o">=</span> <span class="n">time</span><span class="o">.</span><span class="n">perf_counter</span><span class="p">()</span>
</span><span id="__span-0-257"><a id="__codelineno-0-257" name="__codelineno-0-257"></a> <span class="n">proxy</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_proxy</span> <span class="c1"># Local reference for lambda</span>
</span><span id="__span-0-258"><a id="__codelineno-0-258" name="__codelineno-0-258"></a>
</span><span id="__span-0-259"><a id="__codelineno-0-259" name="__codelineno-0-259"></a> <span class="k">try</span><span class="p">:</span>
</span><span id="__span-0-260"><a id="__codelineno-0-260" name="__codelineno-0-260"></a> <span class="n">result</span> <span class="o">=</span> <span class="k">await</span> <span class="n">asyncio</span><span class="o">.</span><span class="n">wait_for</span><span class="p">(</span>
</span><span id="__span-0-261"><a id="__codelineno-0-261" name="__codelineno-0-261"></a> <span class="n">loop</span><span class="o">.</span><span class="n">run_in_executor</span><span class="p">(</span>
</span><span id="__span-0-262"><a id="__codelineno-0-262" name="__codelineno-0-262"></a> <span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-263"><a id="__codelineno-0-263" name="__codelineno-0-263"></a> <span class="k">lambda</span><span class="p">:</span> <span class="n">proxy</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="n">code</span><span class="p">),</span>
</span><span id="__span-0-264"><a id="__codelineno-0-264" name="__codelineno-0-264"></a> <span class="p">),</span>
</span><span id="__span-0-265"><a id="__codelineno-0-265" name="__codelineno-0-265"></a> <span class="n">timeout</span><span class="o">=</span><span class="n">timeout_ms</span> <span class="o">/</span> <span class="mi">1000</span><span class="p">,</span>
</span><span id="__span-0-266"><a id="__codelineno-0-266" name="__codelineno-0-266"></a> <span class="p">)</span>
</span><span id="__span-0-267"><a id="__codelineno-0-267" name="__codelineno-0-267"></a> <span class="n">elapsed</span> <span class="o">=</span> <span class="p">(</span><span class="n">time</span><span class="o">.</span><span class="n">perf_counter</span><span class="p">()</span> <span class="o">-</span> <span class="n">start</span><span class="p">)</span> <span class="o">*</span> <span class="mi">1000</span>
</span><span id="__span-0-268"><a id="__codelineno-0-268" name="__codelineno-0-268"></a>
</span><span id="__span-0-269"><a id="__codelineno-0-269" name="__codelineno-0-269"></a> <span class="c1"># Parse result from XML-RPC server</span>
</span><span id="__span-0-270"><a id="__codelineno-0-270" name="__codelineno-0-270"></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">result</span><span class="p">,</span> <span class="nb">dict</span><span class="p">):</span>
</span><span id="__span-0-271"><a id="__codelineno-0-271" name="__codelineno-0-271"></a> <span class="k">return</span> <span class="n">ExecutionResult</span><span class="p">(</span>
</span><span id="__span-0-272"><a id="__codelineno-0-272" name="__codelineno-0-272"></a> <span class="n">success</span><span class="o">=</span><span class="n">result</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"success"</span><span class="p">,</span> <span class="kc">False</span><span class="p">),</span>
</span><span id="__span-0-273"><a id="__codelineno-0-273" name="__codelineno-0-273"></a> <span class="n">result</span><span class="o">=</span><span class="n">result</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"result"</span><span class="p">),</span>
</span><span id="__span-0-274"><a id="__codelineno-0-274" name="__codelineno-0-274"></a> <span class="n">stdout</span><span class="o">=</span><span class="n">result</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"stdout"</span><span class="p">,</span> <span class="s2">""</span><span class="p">),</span>
</span><span id="__span-0-275"><a id="__codelineno-0-275" name="__codelineno-0-275"></a> <span class="n">stderr</span><span class="o">=</span><span class="n">result</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"stderr"</span><span class="p">,</span> <span class="s2">""</span><span class="p">),</span>
</span><span id="__span-0-276"><a id="__codelineno-0-276" name="__codelineno-0-276"></a> <span class="n">execution_time_ms</span><span class="o">=</span><span class="n">elapsed</span><span class="p">,</span>
</span><span id="__span-0-277"><a id="__codelineno-0-277" name="__codelineno-0-277"></a> <span class="n">error_type</span><span class="o">=</span><span class="n">result</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"error_type"</span><span class="p">),</span>
</span><span id="__span-0-278"><a id="__codelineno-0-278" name="__codelineno-0-278"></a> <span class="n">error_traceback</span><span class="o">=</span><span class="n">result</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"error_traceback"</span><span class="p">),</span>
</span><span id="__span-0-279"><a id="__codelineno-0-279" name="__codelineno-0-279"></a> <span class="p">)</span>
</span><span id="__span-0-280"><a id="__codelineno-0-280" name="__codelineno-0-280"></a> <span class="k">else</span><span class="p">:</span>
</span><span id="__span-0-281"><a id="__codelineno-0-281" name="__codelineno-0-281"></a> <span class="c1"># Simple result format</span>
</span><span id="__span-0-282"><a id="__codelineno-0-282" name="__codelineno-0-282"></a> <span class="k">return</span> <span class="n">ExecutionResult</span><span class="p">(</span>
</span><span id="__span-0-283"><a id="__codelineno-0-283" name="__codelineno-0-283"></a> <span class="n">success</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span>
</span><span id="__span-0-284"><a id="__codelineno-0-284" name="__codelineno-0-284"></a> <span class="n">result</span><span class="o">=</span><span class="n">result</span><span class="p">,</span>
</span><span id="__span-0-285"><a id="__codelineno-0-285" name="__codelineno-0-285"></a> <span class="n">stdout</span><span class="o">=</span><span class="s2">""</span><span class="p">,</span>
</span><span id="__span-0-286"><a id="__codelineno-0-286" name="__codelineno-0-286"></a> <span class="n">stderr</span><span class="o">=</span><span class="s2">""</span><span class="p">,</span>
</span><span id="__span-0-287"><a id="__codelineno-0-287" name="__codelineno-0-287"></a> <span class="n">execution_time_ms</span><span class="o">=</span><span class="n">elapsed</span><span class="p">,</span>
</span><span id="__span-0-288"><a id="__codelineno-0-288" name="__codelineno-0-288"></a> <span class="p">)</span>
</span><span id="__span-0-289"><a id="__codelineno-0-289" name="__codelineno-0-289"></a>
</span><span id="__span-0-290"><a id="__codelineno-0-290" name="__codelineno-0-290"></a> <span class="k">except</span> <span class="ne">TimeoutError</span><span class="p">:</span>
</span><span id="__span-0-291"><a id="__codelineno-0-291" name="__codelineno-0-291"></a> <span class="k">return</span> <span class="n">ExecutionResult</span><span class="p">(</span>
</span><span id="__span-0-292"><a id="__codelineno-0-292" name="__codelineno-0-292"></a> <span class="n">success</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
</span><span id="__span-0-293"><a id="__codelineno-0-293" name="__codelineno-0-293"></a> <span class="n">result</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-294"><a id="__codelineno-0-294" name="__codelineno-0-294"></a> <span class="n">stdout</span><span class="o">=</span><span class="s2">""</span><span class="p">,</span>
</span><span id="__span-0-295"><a id="__codelineno-0-295" name="__codelineno-0-295"></a> <span class="n">stderr</span><span class="o">=</span><span class="sa">f</span><span class="s2">"Execution timed out after </span><span class="si">{</span><span class="n">timeout_ms</span><span class="si">}</span><span class="s2">ms"</span><span class="p">,</span>
</span><span id="__span-0-296"><a id="__codelineno-0-296" name="__codelineno-0-296"></a> <span class="n">execution_time_ms</span><span class="o">=</span><span class="nb">float</span><span class="p">(</span><span class="n">timeout_ms</span><span class="p">),</span>
</span><span id="__span-0-297"><a id="__codelineno-0-297" name="__codelineno-0-297"></a> <span class="n">error_type</span><span class="o">=</span><span class="s2">"TimeoutError"</span><span class="p">,</span>
</span><span id="__span-0-298"><a id="__codelineno-0-298" name="__codelineno-0-298"></a> <span class="p">)</span>
</span><span id="__span-0-299"><a id="__codelineno-0-299" name="__codelineno-0-299"></a> <span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
</span><span id="__span-0-300"><a id="__codelineno-0-300" name="__codelineno-0-300"></a> <span class="n">elapsed</span> <span class="o">=</span> <span class="p">(</span><span class="n">time</span><span class="o">.</span><span class="n">perf_counter</span><span class="p">()</span> <span class="o">-</span> <span class="n">start</span><span class="p">)</span> <span class="o">*</span> <span class="mi">1000</span>
</span><span id="__span-0-301"><a id="__codelineno-0-301" name="__codelineno-0-301"></a> <span class="k">return</span> <span class="n">ExecutionResult</span><span class="p">(</span>
</span><span id="__span-0-302"><a id="__codelineno-0-302" name="__codelineno-0-302"></a> <span class="n">success</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
</span><span id="__span-0-303"><a id="__codelineno-0-303" name="__codelineno-0-303"></a> <span class="n">result</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-304"><a id="__codelineno-0-304" name="__codelineno-0-304"></a> <span class="n">stdout</span><span class="o">=</span><span class="s2">""</span><span class="p">,</span>
</span><span id="__span-0-305"><a id="__codelineno-0-305" name="__codelineno-0-305"></a> <span class="n">stderr</span><span class="o">=</span><span class="nb">str</span><span class="p">(</span><span class="n">e</span><span class="p">),</span>
</span><span id="__span-0-306"><a id="__codelineno-0-306" name="__codelineno-0-306"></a> <span class="n">execution_time_ms</span><span class="o">=</span><span class="n">elapsed</span><span class="p">,</span>
</span><span id="__span-0-307"><a id="__codelineno-0-307" name="__codelineno-0-307"></a> <span class="n">error_type</span><span class="o">=</span><span class="nb">type</span><span class="p">(</span><span class="n">e</span><span class="p">)</span><span class="o">.</span><span class="vm">__name__</span><span class="p">,</span>
</span><span id="__span-0-308"><a id="__codelineno-0-308" name="__codelineno-0-308"></a> <span class="p">)</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> </div> </div> <div class="doc doc-object doc-function"> <h6 id="freecad_mcp.bridge.xmlrpc.XmlRpcBridge.get_active_document" class="doc doc-heading"> <code class="highlight language-python"><span class="n">get_active_document</span><span class="p">()</span></code> <span class="doc doc-labels"> <small class="doc doc-label doc-label-async"><code>async</code></small> </span> <a href="#freecad_mcp.bridge.xmlrpc.XmlRpcBridge.get_active_document" class="headerlink" title="Permanent link">¶</a></h6> <div class="doc doc-contents "> <p>Get the active document.</p> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/xmlrpc.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-335">335</a></span>
<span class="normal"><a href="#__codelineno-0-336">336</a></span>
<span class="normal"><a href="#__codelineno-0-337">337</a></span>
<span class="normal"><a href="#__codelineno-0-338">338</a></span>
<span class="normal"><a href="#__codelineno-0-339">339</a></span>
<span class="normal"><a href="#__codelineno-0-340">340</a></span>
<span class="normal"><a href="#__codelineno-0-341">341</a></span>
<span class="normal"><a href="#__codelineno-0-342">342</a></span>
<span class="normal"><a href="#__codelineno-0-343">343</a></span>
<span class="normal"><a href="#__codelineno-0-344">344</a></span>
<span class="normal"><a href="#__codelineno-0-345">345</a></span>
<span class="normal"><a href="#__codelineno-0-346">346</a></span>
<span class="normal"><a href="#__codelineno-0-347">347</a></span>
<span class="normal"><a href="#__codelineno-0-348">348</a></span>
<span class="normal"><a href="#__codelineno-0-349">349</a></span>
<span class="normal"><a href="#__codelineno-0-350">350</a></span>
<span class="normal"><a href="#__codelineno-0-351">351</a></span>
<span class="normal"><a href="#__codelineno-0-352">352</a></span>
<span class="normal"><a href="#__codelineno-0-353">353</a></span>
<span class="normal"><a href="#__codelineno-0-354">354</a></span>
<span class="normal"><a href="#__codelineno-0-355">355</a></span>
<span class="normal"><a href="#__codelineno-0-356">356</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-335"><a id="__codelineno-0-335" name="__codelineno-0-335"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">get_active_document</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">DocumentInfo</span> <span class="o">|</span> <span class="kc">None</span><span class="p">:</span>
</span><span id="__span-0-336"><a id="__codelineno-0-336" name="__codelineno-0-336"></a><span class="w"> </span><span class="sd">"""Get the active document."""</span>
</span><span id="__span-0-337"><a id="__codelineno-0-337" name="__codelineno-0-337"></a> <span class="n">result</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">execute_python</span><span class="p">(</span>
</span><span id="__span-0-338"><a id="__codelineno-0-338" name="__codelineno-0-338"></a><span class="w"> </span><span class="sd">"""</span>
</span><span id="__span-0-339"><a id="__codelineno-0-339" name="__codelineno-0-339"></a><span class="sd">doc = FreeCAD.ActiveDocument</span>
</span><span id="__span-0-340"><a id="__codelineno-0-340" name="__codelineno-0-340"></a><span class="sd">if doc:</span>
</span><span id="__span-0-341"><a id="__codelineno-0-341" name="__codelineno-0-341"></a><span class="sd"> _result_ = {</span>
</span><span id="__span-0-342"><a id="__codelineno-0-342" name="__codelineno-0-342"></a><span class="sd"> "name": doc.Name,</span>
</span><span id="__span-0-343"><a id="__codelineno-0-343" name="__codelineno-0-343"></a><span class="sd"> "label": doc.Label,</span>
</span><span id="__span-0-344"><a id="__codelineno-0-344" name="__codelineno-0-344"></a><span class="sd"> "path": doc.FileName or None,</span>
</span><span id="__span-0-345"><a id="__codelineno-0-345" name="__codelineno-0-345"></a><span class="sd"> "objects": [obj.Name for obj in doc.Objects],</span>
</span><span id="__span-0-346"><a id="__codelineno-0-346" name="__codelineno-0-346"></a><span class="sd"> "is_modified": doc.Modified if hasattr(doc, "Modified") else False,</span>
</span><span id="__span-0-347"><a id="__codelineno-0-347" name="__codelineno-0-347"></a><span class="sd"> "active_object": doc.ActiveObject.Name if doc.ActiveObject else None,</span>
</span><span id="__span-0-348"><a id="__codelineno-0-348" name="__codelineno-0-348"></a><span class="sd"> }</span>
</span><span id="__span-0-349"><a id="__codelineno-0-349" name="__codelineno-0-349"></a><span class="sd">else:</span>
</span><span id="__span-0-350"><a id="__codelineno-0-350" name="__codelineno-0-350"></a><span class="sd"> _result_ = None</span>
</span><span id="__span-0-351"><a id="__codelineno-0-351" name="__codelineno-0-351"></a><span class="sd">"""</span>
</span><span id="__span-0-352"><a id="__codelineno-0-352" name="__codelineno-0-352"></a> <span class="p">)</span>
</span><span id="__span-0-353"><a id="__codelineno-0-353" name="__codelineno-0-353"></a>
</span><span id="__span-0-354"><a id="__codelineno-0-354" name="__codelineno-0-354"></a> <span class="k">if</span> <span class="n">result</span><span class="o">.</span><span class="n">success</span> <span class="ow">and</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">:</span>
</span><span id="__span-0-355"><a id="__codelineno-0-355" name="__codelineno-0-355"></a> <span class="k">return</span> <span class="n">DocumentInfo</span><span class="p">(</span><span class="o">**</span><span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">)</span>
</span><span id="__span-0-356"><a id="__codelineno-0-356" name="__codelineno-0-356"></a> <span class="k">return</span> <span class="kc">None</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> </div> </div> <div class="doc doc-object doc-function"> <h6 id="freecad_mcp.bridge.xmlrpc.XmlRpcBridge.get_console_output" class="doc doc-heading"> <code class="highlight language-python"><span class="n">get_console_output</span><span class="p">(</span><span class="n">lines</span><span class="o">=</span><span class="mi">100</span><span class="p">)</span></code> <span class="doc doc-labels"> <small class="doc doc-label doc-label-async"><code>async</code></small> </span> <a href="#freecad_mcp.bridge.xmlrpc.XmlRpcBridge.get_console_output" class="headerlink" title="Permanent link">¶</a></h6> <div class="doc doc-contents "> <p>Get recent console output.</p> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/xmlrpc.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-1026">1026</a></span>
<span class="normal"><a href="#__codelineno-0-1027">1027</a></span>
<span class="normal"><a href="#__codelineno-0-1028">1028</a></span>
<span class="normal"><a href="#__codelineno-0-1029">1029</a></span>
<span class="normal"><a href="#__codelineno-0-1030">1030</a></span>
<span class="normal"><a href="#__codelineno-0-1031">1031</a></span>
<span class="normal"><a href="#__codelineno-0-1032">1032</a></span>
<span class="normal"><a href="#__codelineno-0-1033">1033</a></span>
<span class="normal"><a href="#__codelineno-0-1034">1034</a></span>
<span class="normal"><a href="#__codelineno-0-1035">1035</a></span>
<span class="normal"><a href="#__codelineno-0-1036">1036</a></span>
<span class="normal"><a href="#__codelineno-0-1037">1037</a></span>
<span class="normal"><a href="#__codelineno-0-1038">1038</a></span>
<span class="normal"><a href="#__codelineno-0-1039">1039</a></span>
<span class="normal"><a href="#__codelineno-0-1040">1040</a></span>
<span class="normal"><a href="#__codelineno-0-1041">1041</a></span>
<span class="normal"><a href="#__codelineno-0-1042">1042</a></span>
<span class="normal"><a href="#__codelineno-0-1043">1043</a></span>
<span class="normal"><a href="#__codelineno-0-1044">1044</a></span>
<span class="normal"><a href="#__codelineno-0-1045">1045</a></span>
<span class="normal"><a href="#__codelineno-0-1046">1046</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-1026"><a id="__codelineno-0-1026" name="__codelineno-0-1026"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">get_console_output</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">lines</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">100</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">list</span><span class="p">[</span><span class="nb">str</span><span class="p">]:</span>
</span><span id="__span-0-1027"><a id="__codelineno-0-1027" name="__codelineno-0-1027"></a><span class="w"> </span><span class="sd">"""Get recent console output."""</span>
</span><span id="__span-0-1028"><a id="__codelineno-0-1028" name="__codelineno-0-1028"></a> <span class="n">code</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">"""</span>
</span><span id="__span-0-1029"><a id="__codelineno-0-1029" name="__codelineno-0-1029"></a><span class="s2"># Try to get console output from FreeCAD</span>
</span><span id="__span-0-1030"><a id="__codelineno-0-1030" name="__codelineno-0-1030"></a><span class="s2">output_lines = []</span>
</span><span id="__span-0-1031"><a id="__codelineno-0-1031" name="__codelineno-0-1031"></a>
</span><span id="__span-0-1032"><a id="__codelineno-0-1032" name="__codelineno-0-1032"></a><span class="s2"># Try FreeCAD.Console if available</span>
</span><span id="__span-0-1033"><a id="__codelineno-0-1033" name="__codelineno-0-1033"></a><span class="s2">if hasattr(FreeCAD, 'Console'):</span>
</span><span id="__span-0-1034"><a id="__codelineno-0-1034" name="__codelineno-0-1034"></a><span class="s2"> console = FreeCAD.Console</span>
</span><span id="__span-0-1035"><a id="__codelineno-0-1035" name="__codelineno-0-1035"></a><span class="s2"> if hasattr(console, 'GetLog'):</span>
</span><span id="__span-0-1036"><a id="__codelineno-0-1036" name="__codelineno-0-1036"></a><span class="s2"> log = console.GetLog()</span>
</span><span id="__span-0-1037"><a id="__codelineno-0-1037" name="__codelineno-0-1037"></a><span class="s2"> if log:</span>
</span><span id="__span-0-1038"><a id="__codelineno-0-1038" name="__codelineno-0-1038"></a><span class="s2"> output_lines = log.split('</span><span class="se">\\</span><span class="s2">n')[-</span><span class="si">{</span><span class="n">lines</span><span class="si">}</span><span class="s2">:]</span>
</span><span id="__span-0-1039"><a id="__codelineno-0-1039" name="__codelineno-0-1039"></a>
</span><span id="__span-0-1040"><a id="__codelineno-0-1040" name="__codelineno-0-1040"></a><span class="s2">_result_ = output_lines</span>
</span><span id="__span-0-1041"><a id="__codelineno-0-1041" name="__codelineno-0-1041"></a><span class="s2">"""</span>
</span><span id="__span-0-1042"><a id="__codelineno-0-1042" name="__codelineno-0-1042"></a> <span class="n">result</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">execute_python</span><span class="p">(</span><span class="n">code</span><span class="p">)</span>
</span><span id="__span-0-1043"><a id="__codelineno-0-1043" name="__codelineno-0-1043"></a>
</span><span id="__span-0-1044"><a id="__codelineno-0-1044" name="__codelineno-0-1044"></a> <span class="k">if</span> <span class="n">result</span><span class="o">.</span><span class="n">success</span> <span class="ow">and</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">:</span>
</span><span id="__span-0-1045"><a id="__codelineno-0-1045" name="__codelineno-0-1045"></a> <span class="k">return</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span>
</span><span id="__span-0-1046"><a id="__codelineno-0-1046" name="__codelineno-0-1046"></a> <span class="k">return</span> <span class="p">[]</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> </div> </div> <div class="doc doc-object doc-function"> <h6 id="freecad_mcp.bridge.xmlrpc.XmlRpcBridge.get_documents" class="doc doc-heading"> <code class="highlight language-python"><span class="n">get_documents</span><span class="p">()</span></code> <span class="doc doc-labels"> <small class="doc doc-label doc-label-async"><code>async</code></small> </span> <a href="#freecad_mcp.bridge.xmlrpc.XmlRpcBridge.get_documents" class="headerlink" title="Permanent link">¶</a></h6> <div class="doc doc-contents "> <p>Get list of open documents.</p> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/xmlrpc.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-314">314</a></span>
<span class="normal"><a href="#__codelineno-0-315">315</a></span>
<span class="normal"><a href="#__codelineno-0-316">316</a></span>
<span class="normal"><a href="#__codelineno-0-317">317</a></span>
<span class="normal"><a href="#__codelineno-0-318">318</a></span>
<span class="normal"><a href="#__codelineno-0-319">319</a></span>
<span class="normal"><a href="#__codelineno-0-320">320</a></span>
<span class="normal"><a href="#__codelineno-0-321">321</a></span>
<span class="normal"><a href="#__codelineno-0-322">322</a></span>
<span class="normal"><a href="#__codelineno-0-323">323</a></span>
<span class="normal"><a href="#__codelineno-0-324">324</a></span>
<span class="normal"><a href="#__codelineno-0-325">325</a></span>
<span class="normal"><a href="#__codelineno-0-326">326</a></span>
<span class="normal"><a href="#__codelineno-0-327">327</a></span>
<span class="normal"><a href="#__codelineno-0-328">328</a></span>
<span class="normal"><a href="#__codelineno-0-329">329</a></span>
<span class="normal"><a href="#__codelineno-0-330">330</a></span>
<span class="normal"><a href="#__codelineno-0-331">331</a></span>
<span class="normal"><a href="#__codelineno-0-332">332</a></span>
<span class="normal"><a href="#__codelineno-0-333">333</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-314"><a id="__codelineno-0-314" name="__codelineno-0-314"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">get_documents</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">list</span><span class="p">[</span><span class="n">DocumentInfo</span><span class="p">]:</span>
</span><span id="__span-0-315"><a id="__codelineno-0-315" name="__codelineno-0-315"></a><span class="w"> </span><span class="sd">"""Get list of open documents."""</span>
</span><span id="__span-0-316"><a id="__codelineno-0-316" name="__codelineno-0-316"></a> <span class="n">result</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">execute_python</span><span class="p">(</span>
</span><span id="__span-0-317"><a id="__codelineno-0-317" name="__codelineno-0-317"></a><span class="w"> </span><span class="sd">"""</span>
</span><span id="__span-0-318"><a id="__codelineno-0-318" name="__codelineno-0-318"></a><span class="sd">_result_ = []</span>
</span><span id="__span-0-319"><a id="__codelineno-0-319" name="__codelineno-0-319"></a><span class="sd">for doc in FreeCAD.listDocuments().values():</span>
</span><span id="__span-0-320"><a id="__codelineno-0-320" name="__codelineno-0-320"></a><span class="sd"> _result_.append({</span>
</span><span id="__span-0-321"><a id="__codelineno-0-321" name="__codelineno-0-321"></a><span class="sd"> "name": doc.Name,</span>
</span><span id="__span-0-322"><a id="__codelineno-0-322" name="__codelineno-0-322"></a><span class="sd"> "label": doc.Label,</span>
</span><span id="__span-0-323"><a id="__codelineno-0-323" name="__codelineno-0-323"></a><span class="sd"> "path": doc.FileName or None,</span>
</span><span id="__span-0-324"><a id="__codelineno-0-324" name="__codelineno-0-324"></a><span class="sd"> "objects": [obj.Name for obj in doc.Objects],</span>
</span><span id="__span-0-325"><a id="__codelineno-0-325" name="__codelineno-0-325"></a><span class="sd"> "is_modified": doc.Modified if hasattr(doc, "Modified") else False,</span>
</span><span id="__span-0-326"><a id="__codelineno-0-326" name="__codelineno-0-326"></a><span class="sd"> "active_object": doc.ActiveObject.Name if doc.ActiveObject else None,</span>
</span><span id="__span-0-327"><a id="__codelineno-0-327" name="__codelineno-0-327"></a><span class="sd"> })</span>
</span><span id="__span-0-328"><a id="__codelineno-0-328" name="__codelineno-0-328"></a><span class="sd">"""</span>
</span><span id="__span-0-329"><a id="__codelineno-0-329" name="__codelineno-0-329"></a> <span class="p">)</span>
</span><span id="__span-0-330"><a id="__codelineno-0-330" name="__codelineno-0-330"></a>
</span><span id="__span-0-331"><a id="__codelineno-0-331" name="__codelineno-0-331"></a> <span class="k">if</span> <span class="n">result</span><span class="o">.</span><span class="n">success</span> <span class="ow">and</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">:</span>
</span><span id="__span-0-332"><a id="__codelineno-0-332" name="__codelineno-0-332"></a> <span class="k">return</span> <span class="p">[</span><span class="n">DocumentInfo</span><span class="p">(</span><span class="o">**</span><span class="n">doc</span><span class="p">)</span> <span class="k">for</span> <span class="n">doc</span> <span class="ow">in</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">]</span>
</span><span id="__span-0-333"><a id="__codelineno-0-333" name="__codelineno-0-333"></a> <span class="k">return</span> <span class="p">[]</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> </div> </div> <div class="doc doc-object doc-function"> <h6 id="freecad_mcp.bridge.xmlrpc.XmlRpcBridge.get_freecad_version" class="doc doc-heading"> <code class="highlight language-python"><span class="n">get_freecad_version</span><span class="p">()</span></code> <span class="doc doc-labels"> <small class="doc doc-label doc-label-async"><code>async</code></small> </span> <a href="#freecad_mcp.bridge.xmlrpc.XmlRpcBridge.get_freecad_version" class="headerlink" title="Permanent link">¶</a></h6> <div class="doc doc-contents "> <p>Get FreeCAD version information.</p> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/xmlrpc.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-992"> 992</a></span>
<span class="normal"><a href="#__codelineno-0-993"> 993</a></span>
<span class="normal"><a href="#__codelineno-0-994"> 994</a></span>
<span class="normal"><a href="#__codelineno-0-995"> 995</a></span>
<span class="normal"><a href="#__codelineno-0-996"> 996</a></span>
<span class="normal"><a href="#__codelineno-0-997"> 997</a></span>
<span class="normal"><a href="#__codelineno-0-998"> 998</a></span>
<span class="normal"><a href="#__codelineno-0-999"> 999</a></span>
<span class="normal"><a href="#__codelineno-0-1000">1000</a></span>
<span class="normal"><a href="#__codelineno-0-1001">1001</a></span>
<span class="normal"><a href="#__codelineno-0-1002">1002</a></span>
<span class="normal"><a href="#__codelineno-0-1003">1003</a></span>
<span class="normal"><a href="#__codelineno-0-1004">1004</a></span>
<span class="normal"><a href="#__codelineno-0-1005">1005</a></span>
<span class="normal"><a href="#__codelineno-0-1006">1006</a></span>
<span class="normal"><a href="#__codelineno-0-1007">1007</a></span>
<span class="normal"><a href="#__codelineno-0-1008">1008</a></span>
<span class="normal"><a href="#__codelineno-0-1009">1009</a></span>
<span class="normal"><a href="#__codelineno-0-1010">1010</a></span>
<span class="normal"><a href="#__codelineno-0-1011">1011</a></span>
<span class="normal"><a href="#__codelineno-0-1012">1012</a></span>
<span class="normal"><a href="#__codelineno-0-1013">1013</a></span>
<span class="normal"><a href="#__codelineno-0-1014">1014</a></span>
<span class="normal"><a href="#__codelineno-0-1015">1015</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-992"><a id="__codelineno-0-992" name="__codelineno-0-992"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">get_freecad_version</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Any</span><span class="p">]:</span>
</span><span id="__span-0-993"><a id="__codelineno-0-993" name="__codelineno-0-993"></a><span class="w"> </span><span class="sd">"""Get FreeCAD version information."""</span>
</span><span id="__span-0-994"><a id="__codelineno-0-994" name="__codelineno-0-994"></a> <span class="n">code</span> <span class="o">=</span> <span class="s2">"""</span>
</span><span id="__span-0-995"><a id="__codelineno-0-995" name="__codelineno-0-995"></a><span class="s2">import sys</span>
</span><span id="__span-0-996"><a id="__codelineno-0-996" name="__codelineno-0-996"></a><span class="s2">_result_ = {</span>
</span><span id="__span-0-997"><a id="__codelineno-0-997" name="__codelineno-0-997"></a><span class="s2"> "version": ".".join(str(x) for x in FreeCAD.Version()[:3]),</span>
</span><span id="__span-0-998"><a id="__codelineno-0-998" name="__codelineno-0-998"></a><span class="s2"> "version_tuple": FreeCAD.Version()[:3],</span>
</span><span id="__span-0-999"><a id="__codelineno-0-999" name="__codelineno-0-999"></a><span class="s2"> "build_date": FreeCAD.Version()[3] if len(FreeCAD.Version()) &gt; 3 else "unknown",</span>
</span><span id="__span-0-1000"><a id="__codelineno-0-1000" name="__codelineno-0-1000"></a><span class="s2"> "python_version": sys.version,</span>
</span><span id="__span-0-1001"><a id="__codelineno-0-1001" name="__codelineno-0-1001"></a><span class="s2"> "gui_available": FreeCAD.GuiUp,</span>
</span><span id="__span-0-1002"><a id="__codelineno-0-1002" name="__codelineno-0-1002"></a><span class="s2">}</span>
</span><span id="__span-0-1003"><a id="__codelineno-0-1003" name="__codelineno-0-1003"></a><span class="s2">"""</span>
</span><span id="__span-0-1004"><a id="__codelineno-0-1004" name="__codelineno-0-1004"></a> <span class="n">result</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">execute_python</span><span class="p">(</span><span class="n">code</span><span class="p">)</span>
</span><span id="__span-0-1005"><a id="__codelineno-0-1005" name="__codelineno-0-1005"></a>
</span><span id="__span-0-1006"><a id="__codelineno-0-1006" name="__codelineno-0-1006"></a> <span class="k">if</span> <span class="n">result</span><span class="o">.</span><span class="n">success</span> <span class="ow">and</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">:</span>
</span><span id="__span-0-1007"><a id="__codelineno-0-1007" name="__codelineno-0-1007"></a> <span class="k">return</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span>
</span><span id="__span-0-1008"><a id="__codelineno-0-1008" name="__codelineno-0-1008"></a>
</span><span id="__span-0-1009"><a id="__codelineno-0-1009" name="__codelineno-0-1009"></a> <span class="k">return</span> <span class="p">{</span>
</span><span id="__span-0-1010"><a id="__codelineno-0-1010" name="__codelineno-0-1010"></a> <span class="s2">"version"</span><span class="p">:</span> <span class="s2">"unknown"</span><span class="p">,</span>
</span><span id="__span-0-1011"><a id="__codelineno-0-1011" name="__codelineno-0-1011"></a> <span class="s2">"version_tuple"</span><span class="p">:</span> <span class="p">[],</span>
</span><span id="__span-0-1012"><a id="__codelineno-0-1012" name="__codelineno-0-1012"></a> <span class="s2">"build_date"</span><span class="p">:</span> <span class="s2">"unknown"</span><span class="p">,</span>
</span><span id="__span-0-1013"><a id="__codelineno-0-1013" name="__codelineno-0-1013"></a> <span class="s2">"python_version"</span><span class="p">:</span> <span class="s2">""</span><span class="p">,</span>
</span><span id="__span-0-1014"><a id="__codelineno-0-1014" name="__codelineno-0-1014"></a> <span class="s2">"gui_available"</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span>
</span><span id="__span-0-1015"><a id="__codelineno-0-1015" name="__codelineno-0-1015"></a> <span class="p">}</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> </div> </div> <div class="doc doc-object doc-function"> <h6 id="freecad_mcp.bridge.xmlrpc.XmlRpcBridge.get_macros" class="doc doc-heading"> <code class="highlight language-python"><span class="n">get_macros</span><span class="p">()</span></code> <span class="doc doc-labels"> <small class="doc doc-label doc-label-async"><code>async</code></small> </span> <a href="#freecad_mcp.bridge.xmlrpc.XmlRpcBridge.get_macros" class="headerlink" title="Permanent link">¶</a></h6> <div class="doc doc-contents "> <p>Get list of available macros.</p> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/xmlrpc.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-790">790</a></span>
<span class="normal"><a href="#__codelineno-0-791">791</a></span>
<span class="normal"><a href="#__codelineno-0-792">792</a></span>
<span class="normal"><a href="#__codelineno-0-793">793</a></span>
<span class="normal"><a href="#__codelineno-0-794">794</a></span>
<span class="normal"><a href="#__codelineno-0-795">795</a></span>
<span class="normal"><a href="#__codelineno-0-796">796</a></span>
<span class="normal"><a href="#__codelineno-0-797">797</a></span>
<span class="normal"><a href="#__codelineno-0-798">798</a></span>
<span class="normal"><a href="#__codelineno-0-799">799</a></span>
<span class="normal"><a href="#__codelineno-0-800">800</a></span>
<span class="normal"><a href="#__codelineno-0-801">801</a></span>
<span class="normal"><a href="#__codelineno-0-802">802</a></span>
<span class="normal"><a href="#__codelineno-0-803">803</a></span>
<span class="normal"><a href="#__codelineno-0-804">804</a></span>
<span class="normal"><a href="#__codelineno-0-805">805</a></span>
<span class="normal"><a href="#__codelineno-0-806">806</a></span>
<span class="normal"><a href="#__codelineno-0-807">807</a></span>
<span class="normal"><a href="#__codelineno-0-808">808</a></span>
<span class="normal"><a href="#__codelineno-0-809">809</a></span>
<span class="normal"><a href="#__codelineno-0-810">810</a></span>
<span class="normal"><a href="#__codelineno-0-811">811</a></span>
<span class="normal"><a href="#__codelineno-0-812">812</a></span>
<span class="normal"><a href="#__codelineno-0-813">813</a></span>
<span class="normal"><a href="#__codelineno-0-814">814</a></span>
<span class="normal"><a href="#__codelineno-0-815">815</a></span>
<span class="normal"><a href="#__codelineno-0-816">816</a></span>
<span class="normal"><a href="#__codelineno-0-817">817</a></span>
<span class="normal"><a href="#__codelineno-0-818">818</a></span>
<span class="normal"><a href="#__codelineno-0-819">819</a></span>
<span class="normal"><a href="#__codelineno-0-820">820</a></span>
<span class="normal"><a href="#__codelineno-0-821">821</a></span>
<span class="normal"><a href="#__codelineno-0-822">822</a></span>
<span class="normal"><a href="#__codelineno-0-823">823</a></span>
<span class="normal"><a href="#__codelineno-0-824">824</a></span>
<span class="normal"><a href="#__codelineno-0-825">825</a></span>
<span class="normal"><a href="#__codelineno-0-826">826</a></span>
<span class="normal"><a href="#__codelineno-0-827">827</a></span>
<span class="normal"><a href="#__codelineno-0-828">828</a></span>
<span class="normal"><a href="#__codelineno-0-829">829</a></span>
<span class="normal"><a href="#__codelineno-0-830">830</a></span>
<span class="normal"><a href="#__codelineno-0-831">831</a></span>
<span class="normal"><a href="#__codelineno-0-832">832</a></span>
<span class="normal"><a href="#__codelineno-0-833">833</a></span>
<span class="normal"><a href="#__codelineno-0-834">834</a></span>
<span class="normal"><a href="#__codelineno-0-835">835</a></span>
<span class="normal"><a href="#__codelineno-0-836">836</a></span>
<span class="normal"><a href="#__codelineno-0-837">837</a></span>
<span class="normal"><a href="#__codelineno-0-838">838</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-790"><a id="__codelineno-0-790" name="__codelineno-0-790"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">get_macros</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">list</span><span class="p">[</span><span class="n">MacroInfo</span><span class="p">]:</span>
</span><span id="__span-0-791"><a id="__codelineno-0-791" name="__codelineno-0-791"></a><span class="w"> </span><span class="sd">"""Get list of available macros."""</span>
</span><span id="__span-0-792"><a id="__codelineno-0-792" name="__codelineno-0-792"></a> <span class="n">code</span> <span class="o">=</span> <span class="s2">"""</span>
</span><span id="__span-0-793"><a id="__codelineno-0-793" name="__codelineno-0-793"></a><span class="s2">import os</span>
</span><span id="__span-0-794"><a id="__codelineno-0-794" name="__codelineno-0-794"></a>
</span><span id="__span-0-795"><a id="__codelineno-0-795" name="__codelineno-0-795"></a><span class="s2"># Get macro paths</span>
</span><span id="__span-0-796"><a id="__codelineno-0-796" name="__codelineno-0-796"></a><span class="s2">macro_paths = []</span>
</span><span id="__span-0-797"><a id="__codelineno-0-797" name="__codelineno-0-797"></a>
</span><span id="__span-0-798"><a id="__codelineno-0-798" name="__codelineno-0-798"></a><span class="s2"># User macro path</span>
</span><span id="__span-0-799"><a id="__codelineno-0-799" name="__codelineno-0-799"></a><span class="s2">user_path = FreeCAD.getUserMacroDir(True)</span>
</span><span id="__span-0-800"><a id="__codelineno-0-800" name="__codelineno-0-800"></a><span class="s2">if os.path.exists(user_path):</span>
</span><span id="__span-0-801"><a id="__codelineno-0-801" name="__codelineno-0-801"></a><span class="s2"> macro_paths.append(("user", user_path))</span>
</span><span id="__span-0-802"><a id="__codelineno-0-802" name="__codelineno-0-802"></a>
</span><span id="__span-0-803"><a id="__codelineno-0-803" name="__codelineno-0-803"></a><span class="s2"># System macro path</span>
</span><span id="__span-0-804"><a id="__codelineno-0-804" name="__codelineno-0-804"></a><span class="s2">system_path = FreeCAD.getResourceDir() + "Macro"</span>
</span><span id="__span-0-805"><a id="__codelineno-0-805" name="__codelineno-0-805"></a><span class="s2">if os.path.exists(system_path):</span>
</span><span id="__span-0-806"><a id="__codelineno-0-806" name="__codelineno-0-806"></a><span class="s2"> macro_paths.append(("system", system_path))</span>
</span><span id="__span-0-807"><a id="__codelineno-0-807" name="__codelineno-0-807"></a>
</span><span id="__span-0-808"><a id="__codelineno-0-808" name="__codelineno-0-808"></a><span class="s2">macros = []</span>
</span><span id="__span-0-809"><a id="__codelineno-0-809" name="__codelineno-0-809"></a><span class="s2">for source, path in macro_paths:</span>
</span><span id="__span-0-810"><a id="__codelineno-0-810" name="__codelineno-0-810"></a><span class="s2"> for filename in os.listdir(path):</span>
</span><span id="__span-0-811"><a id="__codelineno-0-811" name="__codelineno-0-811"></a><span class="s2"> if filename.endswith(".FCMacro"):</span>
</span><span id="__span-0-812"><a id="__codelineno-0-812" name="__codelineno-0-812"></a><span class="s2"> macro_file = os.path.join(path, filename)</span>
</span><span id="__span-0-813"><a id="__codelineno-0-813" name="__codelineno-0-813"></a><span class="s2"> description = ""</span>
</span><span id="__span-0-814"><a id="__codelineno-0-814" name="__codelineno-0-814"></a><span class="s2"> try:</span>
</span><span id="__span-0-815"><a id="__codelineno-0-815" name="__codelineno-0-815"></a><span class="s2"> with open(macro_file, "r") as f:</span>
</span><span id="__span-0-816"><a id="__codelineno-0-816" name="__codelineno-0-816"></a><span class="s2"> for line in f:</span>
</span><span id="__span-0-817"><a id="__codelineno-0-817" name="__codelineno-0-817"></a><span class="s2"> if line.startswith("#"):</span>
</span><span id="__span-0-818"><a id="__codelineno-0-818" name="__codelineno-0-818"></a><span class="s2"> desc = line.lstrip("#").strip()</span>
</span><span id="__span-0-819"><a id="__codelineno-0-819" name="__codelineno-0-819"></a><span class="s2"> if desc and not desc.startswith("!") and not desc.startswith("-*-"):</span>
</span><span id="__span-0-820"><a id="__codelineno-0-820" name="__codelineno-0-820"></a><span class="s2"> description = desc</span>
</span><span id="__span-0-821"><a id="__codelineno-0-821" name="__codelineno-0-821"></a><span class="s2"> break</span>
</span><span id="__span-0-822"><a id="__codelineno-0-822" name="__codelineno-0-822"></a><span class="s2"> except Exception:</span>
</span><span id="__span-0-823"><a id="__codelineno-0-823" name="__codelineno-0-823"></a><span class="s2"> pass</span>
</span><span id="__span-0-824"><a id="__codelineno-0-824" name="__codelineno-0-824"></a>
</span><span id="__span-0-825"><a id="__codelineno-0-825" name="__codelineno-0-825"></a><span class="s2"> macros.append({</span>
</span><span id="__span-0-826"><a id="__codelineno-0-826" name="__codelineno-0-826"></a><span class="s2"> "name": filename[:-8], # Remove .FCMacro</span>
</span><span id="__span-0-827"><a id="__codelineno-0-827" name="__codelineno-0-827"></a><span class="s2"> "path": macro_file,</span>
</span><span id="__span-0-828"><a id="__codelineno-0-828" name="__codelineno-0-828"></a><span class="s2"> "description": description,</span>
</span><span id="__span-0-829"><a id="__codelineno-0-829" name="__codelineno-0-829"></a><span class="s2"> "is_system": source == "system",</span>
</span><span id="__span-0-830"><a id="__codelineno-0-830" name="__codelineno-0-830"></a><span class="s2"> })</span>
</span><span id="__span-0-831"><a id="__codelineno-0-831" name="__codelineno-0-831"></a>
</span><span id="__span-0-832"><a id="__codelineno-0-832" name="__codelineno-0-832"></a><span class="s2">_result_ = macros</span>
</span><span id="__span-0-833"><a id="__codelineno-0-833" name="__codelineno-0-833"></a><span class="s2">"""</span>
</span><span id="__span-0-834"><a id="__codelineno-0-834" name="__codelineno-0-834"></a> <span class="n">result</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">execute_python</span><span class="p">(</span><span class="n">code</span><span class="p">)</span>
</span><span id="__span-0-835"><a id="__codelineno-0-835" name="__codelineno-0-835"></a>
</span><span id="__span-0-836"><a id="__codelineno-0-836" name="__codelineno-0-836"></a> <span class="k">if</span> <span class="n">result</span><span class="o">.</span><span class="n">success</span> <span class="ow">and</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">:</span>
</span><span id="__span-0-837"><a id="__codelineno-0-837" name="__codelineno-0-837"></a> <span class="k">return</span> <span class="p">[</span><span class="n">MacroInfo</span><span class="p">(</span><span class="o">**</span><span class="n">m</span><span class="p">)</span> <span class="k">for</span> <span class="n">m</span> <span class="ow">in</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">]</span>
</span><span id="__span-0-838"><a id="__codelineno-0-838" name="__codelineno-0-838"></a> <span class="k">return</span> <span class="p">[]</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> </div> </div> <div class="doc doc-object doc-function"> <h6 id="freecad_mcp.bridge.xmlrpc.XmlRpcBridge.get_object" class="doc doc-heading"> <code class="highlight language-python"><span class="n">get_object</span><span class="p">(</span><span class="n">obj_name</span><span class="p">,</span> <span class="n">doc_name</span><span class="o">=</span><span class="kc">None</span><span class="p">)</span></code> <span class="doc doc-labels"> <small class="doc doc-label doc-label-async"><code>async</code></small> </span> <a href="#freecad_mcp.bridge.xmlrpc.XmlRpcBridge.get_object" class="headerlink" title="Permanent link">¶</a></h6> <div class="doc doc-contents "> <p>Get detailed object information.</p> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/xmlrpc.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-488">488</a></span>
<span class="normal"><a href="#__codelineno-0-489">489</a></span>
<span class="normal"><a href="#__codelineno-0-490">490</a></span>
<span class="normal"><a href="#__codelineno-0-491">491</a></span>
<span class="normal"><a href="#__codelineno-0-492">492</a></span>
<span class="normal"><a href="#__codelineno-0-493">493</a></span>
<span class="normal"><a href="#__codelineno-0-494">494</a></span>
<span class="normal"><a href="#__codelineno-0-495">495</a></span>
<span class="normal"><a href="#__codelineno-0-496">496</a></span>
<span class="normal"><a href="#__codelineno-0-497">497</a></span>
<span class="normal"><a href="#__codelineno-0-498">498</a></span>
<span class="normal"><a href="#__codelineno-0-499">499</a></span>
<span class="normal"><a href="#__codelineno-0-500">500</a></span>
<span class="normal"><a href="#__codelineno-0-501">501</a></span>
<span class="normal"><a href="#__codelineno-0-502">502</a></span>
<span class="normal"><a href="#__codelineno-0-503">503</a></span>
<span class="normal"><a href="#__codelineno-0-504">504</a></span>
<span class="normal"><a href="#__codelineno-0-505">505</a></span>
<span class="normal"><a href="#__codelineno-0-506">506</a></span>
<span class="normal"><a href="#__codelineno-0-507">507</a></span>
<span class="normal"><a href="#__codelineno-0-508">508</a></span>
<span class="normal"><a href="#__codelineno-0-509">509</a></span>
<span class="normal"><a href="#__codelineno-0-510">510</a></span>
<span class="normal"><a href="#__codelineno-0-511">511</a></span>
<span class="normal"><a href="#__codelineno-0-512">512</a></span>
<span class="normal"><a href="#__codelineno-0-513">513</a></span>
<span class="normal"><a href="#__codelineno-0-514">514</a></span>
<span class="normal"><a href="#__codelineno-0-515">515</a></span>
<span class="normal"><a href="#__codelineno-0-516">516</a></span>
<span class="normal"><a href="#__codelineno-0-517">517</a></span>
<span class="normal"><a href="#__codelineno-0-518">518</a></span>
<span class="normal"><a href="#__codelineno-0-519">519</a></span>
<span class="normal"><a href="#__codelineno-0-520">520</a></span>
<span class="normal"><a href="#__codelineno-0-521">521</a></span>
<span class="normal"><a href="#__codelineno-0-522">522</a></span>
<span class="normal"><a href="#__codelineno-0-523">523</a></span>
<span class="normal"><a href="#__codelineno-0-524">524</a></span>
<span class="normal"><a href="#__codelineno-0-525">525</a></span>
<span class="normal"><a href="#__codelineno-0-526">526</a></span>
<span class="normal"><a href="#__codelineno-0-527">527</a></span>
<span class="normal"><a href="#__codelineno-0-528">528</a></span>
<span class="normal"><a href="#__codelineno-0-529">529</a></span>
<span class="normal"><a href="#__codelineno-0-530">530</a></span>
<span class="normal"><a href="#__codelineno-0-531">531</a></span>
<span class="normal"><a href="#__codelineno-0-532">532</a></span>
<span class="normal"><a href="#__codelineno-0-533">533</a></span>
<span class="normal"><a href="#__codelineno-0-534">534</a></span>
<span class="normal"><a href="#__codelineno-0-535">535</a></span>
<span class="normal"><a href="#__codelineno-0-536">536</a></span>
<span class="normal"><a href="#__codelineno-0-537">537</a></span>
<span class="normal"><a href="#__codelineno-0-538">538</a></span>
<span class="normal"><a href="#__codelineno-0-539">539</a></span>
<span class="normal"><a href="#__codelineno-0-540">540</a></span>
<span class="normal"><a href="#__codelineno-0-541">541</a></span>
<span class="normal"><a href="#__codelineno-0-542">542</a></span>
<span class="normal"><a href="#__codelineno-0-543">543</a></span>
<span class="normal"><a href="#__codelineno-0-544">544</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-488"><a id="__codelineno-0-488" name="__codelineno-0-488"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">get_object</span><span class="p">(</span>
</span><span id="__span-0-489"><a id="__codelineno-0-489" name="__codelineno-0-489"></a> <span class="bp">self</span><span class="p">,</span>
</span><span id="__span-0-490"><a id="__codelineno-0-490" name="__codelineno-0-490"></a> <span class="n">obj_name</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span>
</span><span id="__span-0-491"><a id="__codelineno-0-491" name="__codelineno-0-491"></a> <span class="n">doc_name</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-492"><a id="__codelineno-0-492" name="__codelineno-0-492"></a> <span class="p">)</span> <span class="o">-&gt;</span> <span class="n">ObjectInfo</span><span class="p">:</span>
</span><span id="__span-0-493"><a id="__codelineno-0-493" name="__codelineno-0-493"></a><span class="w"> </span><span class="sd">"""Get detailed object information."""</span>
</span><span id="__span-0-494"><a id="__codelineno-0-494" name="__codelineno-0-494"></a> <span class="n">code</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">"""</span>
</span><span id="__span-0-495"><a id="__codelineno-0-495" name="__codelineno-0-495"></a><span class="s2">doc = FreeCAD.ActiveDocument if </span><span class="si">{</span><span class="n">doc_name</span><span class="si">!r}</span><span class="s2"> is None else FreeCAD.getDocument(</span><span class="si">{</span><span class="n">doc_name</span><span class="si">!r}</span><span class="s2">)</span>
</span><span id="__span-0-496"><a id="__codelineno-0-496" name="__codelineno-0-496"></a><span class="s2">if doc is None:</span>
</span><span id="__span-0-497"><a id="__codelineno-0-497" name="__codelineno-0-497"></a><span class="s2"> raise ValueError("No document found")</span>
</span><span id="__span-0-498"><a id="__codelineno-0-498" name="__codelineno-0-498"></a>
</span><span id="__span-0-499"><a id="__codelineno-0-499" name="__codelineno-0-499"></a><span class="s2">obj = doc.getObject(</span><span class="si">{</span><span class="n">obj_name</span><span class="si">!r}</span><span class="s2">)</span>
</span><span id="__span-0-500"><a id="__codelineno-0-500" name="__codelineno-0-500"></a><span class="s2">if obj is None:</span>
</span><span id="__span-0-501"><a id="__codelineno-0-501" name="__codelineno-0-501"></a><span class="s2"> raise ValueError(f"Object not found: </span><span class="si">{</span><span class="n">obj_name</span><span class="si">!r}</span><span class="s2">")</span>
</span><span id="__span-0-502"><a id="__codelineno-0-502" name="__codelineno-0-502"></a>
</span><span id="__span-0-503"><a id="__codelineno-0-503" name="__codelineno-0-503"></a><span class="s2">props = </span><span class="se">{{}}</span>
</span><span id="__span-0-504"><a id="__codelineno-0-504" name="__codelineno-0-504"></a><span class="s2">for prop in obj.PropertiesList:</span>
</span><span id="__span-0-505"><a id="__codelineno-0-505" name="__codelineno-0-505"></a><span class="s2"> try:</span>
</span><span id="__span-0-506"><a id="__codelineno-0-506" name="__codelineno-0-506"></a><span class="s2"> val = getattr(obj, prop)</span>
</span><span id="__span-0-507"><a id="__codelineno-0-507" name="__codelineno-0-507"></a><span class="s2"> if hasattr(val, '__class__') and val.__class__.__module__ != 'builtins':</span>
</span><span id="__span-0-508"><a id="__codelineno-0-508" name="__codelineno-0-508"></a><span class="s2"> val = str(val)</span>
</span><span id="__span-0-509"><a id="__codelineno-0-509" name="__codelineno-0-509"></a><span class="s2"> props[prop] = val</span>
</span><span id="__span-0-510"><a id="__codelineno-0-510" name="__codelineno-0-510"></a><span class="s2"> except Exception:</span>
</span><span id="__span-0-511"><a id="__codelineno-0-511" name="__codelineno-0-511"></a><span class="s2"> props[prop] = "&lt;unreadable&gt;"</span>
</span><span id="__span-0-512"><a id="__codelineno-0-512" name="__codelineno-0-512"></a>
</span><span id="__span-0-513"><a id="__codelineno-0-513" name="__codelineno-0-513"></a><span class="s2">shape_info = None</span>
</span><span id="__span-0-514"><a id="__codelineno-0-514" name="__codelineno-0-514"></a><span class="s2">if hasattr(obj, "Shape"):</span>
</span><span id="__span-0-515"><a id="__codelineno-0-515" name="__codelineno-0-515"></a><span class="s2"> shape = obj.Shape</span>
</span><span id="__span-0-516"><a id="__codelineno-0-516" name="__codelineno-0-516"></a><span class="s2"> shape_info = </span><span class="se">{{</span>
</span><span id="__span-0-517"><a id="__codelineno-0-517" name="__codelineno-0-517"></a><span class="s2"> "shape_type": shape.ShapeType,</span>
</span><span id="__span-0-518"><a id="__codelineno-0-518" name="__codelineno-0-518"></a><span class="s2"> "volume": shape.Volume if hasattr(shape, "Volume") else None,</span>
</span><span id="__span-0-519"><a id="__codelineno-0-519" name="__codelineno-0-519"></a><span class="s2"> "area": shape.Area if hasattr(shape, "Area") else None,</span>
</span><span id="__span-0-520"><a id="__codelineno-0-520" name="__codelineno-0-520"></a><span class="s2"> "is_valid": shape.isValid(),</span>
</span><span id="__span-0-521"><a id="__codelineno-0-521" name="__codelineno-0-521"></a><span class="s2"> "is_closed": shape.isClosed() if hasattr(shape, "isClosed") else False,</span>
</span><span id="__span-0-522"><a id="__codelineno-0-522" name="__codelineno-0-522"></a><span class="s2"> "vertex_count": len(shape.Vertexes) if hasattr(shape, "Vertexes") else 0,</span>
</span><span id="__span-0-523"><a id="__codelineno-0-523" name="__codelineno-0-523"></a><span class="s2"> "edge_count": len(shape.Edges) if hasattr(shape, "Edges") else 0,</span>
</span><span id="__span-0-524"><a id="__codelineno-0-524" name="__codelineno-0-524"></a><span class="s2"> "face_count": len(shape.Faces) if hasattr(shape, "Faces") else 0,</span>
</span><span id="__span-0-525"><a id="__codelineno-0-525" name="__codelineno-0-525"></a><span class="s2"> </span><span class="se">}}</span>
</span><span id="__span-0-526"><a id="__codelineno-0-526" name="__codelineno-0-526"></a>
</span><span id="__span-0-527"><a id="__codelineno-0-527" name="__codelineno-0-527"></a><span class="s2">_result_ = </span><span class="se">{{</span>
</span><span id="__span-0-528"><a id="__codelineno-0-528" name="__codelineno-0-528"></a><span class="s2"> "name": obj.Name,</span>
</span><span id="__span-0-529"><a id="__codelineno-0-529" name="__codelineno-0-529"></a><span class="s2"> "label": obj.Label,</span>
</span><span id="__span-0-530"><a id="__codelineno-0-530" name="__codelineno-0-530"></a><span class="s2"> "type_id": obj.TypeId,</span>
</span><span id="__span-0-531"><a id="__codelineno-0-531" name="__codelineno-0-531"></a><span class="s2"> "properties": props,</span>
</span><span id="__span-0-532"><a id="__codelineno-0-532" name="__codelineno-0-532"></a><span class="s2"> "shape_info": shape_info,</span>
</span><span id="__span-0-533"><a id="__codelineno-0-533" name="__codelineno-0-533"></a><span class="s2"> "children": [c.Name for c in obj.OutList] if hasattr(obj, "OutList") else [],</span>
</span><span id="__span-0-534"><a id="__codelineno-0-534" name="__codelineno-0-534"></a><span class="s2"> "parents": [p.Name for p in obj.InList] if hasattr(obj, "InList") else [],</span>
</span><span id="__span-0-535"><a id="__codelineno-0-535" name="__codelineno-0-535"></a><span class="s2"> "visibility": obj.ViewObject.Visibility if hasattr(obj, "ViewObject") and obj.ViewObject else True,</span>
</span><span id="__span-0-536"><a id="__codelineno-0-536" name="__codelineno-0-536"></a><span class="se">}}</span>
</span><span id="__span-0-537"><a id="__codelineno-0-537" name="__codelineno-0-537"></a><span class="s2">"""</span>
</span><span id="__span-0-538"><a id="__codelineno-0-538" name="__codelineno-0-538"></a> <span class="n">result</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">execute_python</span><span class="p">(</span><span class="n">code</span><span class="p">)</span>
</span><span id="__span-0-539"><a id="__codelineno-0-539" name="__codelineno-0-539"></a>
</span><span id="__span-0-540"><a id="__codelineno-0-540" name="__codelineno-0-540"></a> <span class="k">if</span> <span class="n">result</span><span class="o">.</span><span class="n">success</span> <span class="ow">and</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">:</span>
</span><span id="__span-0-541"><a id="__codelineno-0-541" name="__codelineno-0-541"></a> <span class="k">return</span> <span class="n">ObjectInfo</span><span class="p">(</span><span class="o">**</span><span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">)</span>
</span><span id="__span-0-542"><a id="__codelineno-0-542" name="__codelineno-0-542"></a>
</span><span id="__span-0-543"><a id="__codelineno-0-543" name="__codelineno-0-543"></a> <span class="n">error_msg</span> <span class="o">=</span> <span class="n">result</span><span class="o">.</span><span class="n">error_traceback</span> <span class="ow">or</span> <span class="s2">"Failed to get object"</span>
</span><span id="__span-0-544"><a id="__codelineno-0-544" name="__codelineno-0-544"></a> <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="n">error_msg</span><span class="p">)</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> </div> </div> <div class="doc doc-object doc-function"> <h6 id="freecad_mcp.bridge.xmlrpc.XmlRpcBridge.get_objects" class="doc doc-heading"> <code class="highlight language-python"><span class="n">get_objects</span><span class="p">(</span><span class="n">doc_name</span><span class="o">=</span><span class="kc">None</span><span class="p">)</span></code> <span class="doc doc-labels"> <small class="doc doc-label doc-label-async"><code>async</code></small> </span> <a href="#freecad_mcp.bridge.xmlrpc.XmlRpcBridge.get_objects" class="headerlink" title="Permanent link">¶</a></h6> <div class="doc doc-contents "> <p>Get all objects in a document.</p> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/xmlrpc.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-461">461</a></span>
<span class="normal"><a href="#__codelineno-0-462">462</a></span>
<span class="normal"><a href="#__codelineno-0-463">463</a></span>
<span class="normal"><a href="#__codelineno-0-464">464</a></span>
<span class="normal"><a href="#__codelineno-0-465">465</a></span>
<span class="normal"><a href="#__codelineno-0-466">466</a></span>
<span class="normal"><a href="#__codelineno-0-467">467</a></span>
<span class="normal"><a href="#__codelineno-0-468">468</a></span>
<span class="normal"><a href="#__codelineno-0-469">469</a></span>
<span class="normal"><a href="#__codelineno-0-470">470</a></span>
<span class="normal"><a href="#__codelineno-0-471">471</a></span>
<span class="normal"><a href="#__codelineno-0-472">472</a></span>
<span class="normal"><a href="#__codelineno-0-473">473</a></span>
<span class="normal"><a href="#__codelineno-0-474">474</a></span>
<span class="normal"><a href="#__codelineno-0-475">475</a></span>
<span class="normal"><a href="#__codelineno-0-476">476</a></span>
<span class="normal"><a href="#__codelineno-0-477">477</a></span>
<span class="normal"><a href="#__codelineno-0-478">478</a></span>
<span class="normal"><a href="#__codelineno-0-479">479</a></span>
<span class="normal"><a href="#__codelineno-0-480">480</a></span>
<span class="normal"><a href="#__codelineno-0-481">481</a></span>
<span class="normal"><a href="#__codelineno-0-482">482</a></span>
<span class="normal"><a href="#__codelineno-0-483">483</a></span>
<span class="normal"><a href="#__codelineno-0-484">484</a></span>
<span class="normal"><a href="#__codelineno-0-485">485</a></span>
<span class="normal"><a href="#__codelineno-0-486">486</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-461"><a id="__codelineno-0-461" name="__codelineno-0-461"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">get_objects</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">doc_name</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">list</span><span class="p">[</span><span class="n">ObjectInfo</span><span class="p">]:</span>
</span><span id="__span-0-462"><a id="__codelineno-0-462" name="__codelineno-0-462"></a><span class="w"> </span><span class="sd">"""Get all objects in a document."""</span>
</span><span id="__span-0-463"><a id="__codelineno-0-463" name="__codelineno-0-463"></a> <span class="n">code</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">"""</span>
</span><span id="__span-0-464"><a id="__codelineno-0-464" name="__codelineno-0-464"></a><span class="s2">doc = FreeCAD.ActiveDocument if </span><span class="si">{</span><span class="n">doc_name</span><span class="si">!r}</span><span class="s2"> is None else FreeCAD.getDocument(</span><span class="si">{</span><span class="n">doc_name</span><span class="si">!r}</span><span class="s2">)</span>
</span><span id="__span-0-465"><a id="__codelineno-0-465" name="__codelineno-0-465"></a><span class="s2">if doc is None:</span>
</span><span id="__span-0-466"><a id="__codelineno-0-466" name="__codelineno-0-466"></a><span class="s2"> raise ValueError("No document found")</span>
</span><span id="__span-0-467"><a id="__codelineno-0-467" name="__codelineno-0-467"></a>
</span><span id="__span-0-468"><a id="__codelineno-0-468" name="__codelineno-0-468"></a><span class="s2">objects = []</span>
</span><span id="__span-0-469"><a id="__codelineno-0-469" name="__codelineno-0-469"></a><span class="s2">for obj in doc.Objects:</span>
</span><span id="__span-0-470"><a id="__codelineno-0-470" name="__codelineno-0-470"></a><span class="s2"> obj_info = </span><span class="se">{{</span>
</span><span id="__span-0-471"><a id="__codelineno-0-471" name="__codelineno-0-471"></a><span class="s2"> "name": obj.Name,</span>
</span><span id="__span-0-472"><a id="__codelineno-0-472" name="__codelineno-0-472"></a><span class="s2"> "label": obj.Label,</span>
</span><span id="__span-0-473"><a id="__codelineno-0-473" name="__codelineno-0-473"></a><span class="s2"> "type_id": obj.TypeId,</span>
</span><span id="__span-0-474"><a id="__codelineno-0-474" name="__codelineno-0-474"></a><span class="s2"> "visibility": obj.ViewObject.Visibility if hasattr(obj, "ViewObject") and obj.ViewObject else True,</span>
</span><span id="__span-0-475"><a id="__codelineno-0-475" name="__codelineno-0-475"></a><span class="s2"> "children": [c.Name for c in obj.OutList] if hasattr(obj, "OutList") else [],</span>
</span><span id="__span-0-476"><a id="__codelineno-0-476" name="__codelineno-0-476"></a><span class="s2"> "parents": [p.Name for p in obj.InList] if hasattr(obj, "InList") else [],</span>
</span><span id="__span-0-477"><a id="__codelineno-0-477" name="__codelineno-0-477"></a><span class="s2"> </span><span class="se">}}</span>
</span><span id="__span-0-478"><a id="__codelineno-0-478" name="__codelineno-0-478"></a><span class="s2"> objects.append(obj_info)</span>
</span><span id="__span-0-479"><a id="__codelineno-0-479" name="__codelineno-0-479"></a>
</span><span id="__span-0-480"><a id="__codelineno-0-480" name="__codelineno-0-480"></a><span class="s2">_result_ = objects</span>
</span><span id="__span-0-481"><a id="__codelineno-0-481" name="__codelineno-0-481"></a><span class="s2">"""</span>
</span><span id="__span-0-482"><a id="__codelineno-0-482" name="__codelineno-0-482"></a> <span class="n">result</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">execute_python</span><span class="p">(</span><span class="n">code</span><span class="p">)</span>
</span><span id="__span-0-483"><a id="__codelineno-0-483" name="__codelineno-0-483"></a>
</span><span id="__span-0-484"><a id="__codelineno-0-484" name="__codelineno-0-484"></a> <span class="k">if</span> <span class="n">result</span><span class="o">.</span><span class="n">success</span> <span class="ow">and</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">:</span>
</span><span id="__span-0-485"><a id="__codelineno-0-485" name="__codelineno-0-485"></a> <span class="k">return</span> <span class="p">[</span><span class="n">ObjectInfo</span><span class="p">(</span><span class="o">**</span><span class="n">obj</span><span class="p">)</span> <span class="k">for</span> <span class="n">obj</span> <span class="ow">in</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">]</span>
</span><span id="__span-0-486"><a id="__codelineno-0-486" name="__codelineno-0-486"></a> <span class="k">return</span> <span class="p">[]</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> </div> </div> <div class="doc doc-object doc-function"> <h6 id="freecad_mcp.bridge.xmlrpc.XmlRpcBridge.get_screenshot" class="doc doc-heading"> <code class="highlight language-python"><span class="n">get_screenshot</span><span class="p">(</span><span class="n">view_angle</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">width</span><span class="o">=</span><span class="mi">800</span><span class="p">,</span> <span class="n">height</span><span class="o">=</span><span class="mi">600</span><span class="p">,</span> <span class="n">doc_name</span><span class="o">=</span><span class="kc">None</span><span class="p">)</span></code> <span class="doc doc-labels"> <small class="doc doc-label doc-label-async"><code>async</code></small> </span> <a href="#freecad_mcp.bridge.xmlrpc.XmlRpcBridge.get_screenshot" class="headerlink" title="Permanent link">¶</a></h6> <div class="doc doc-contents "> <p>Capture a screenshot of the 3D view via XML-RPC.</p> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/xmlrpc.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-654">654</a></span>
<span class="normal"><a href="#__codelineno-0-655">655</a></span>
<span class="normal"><a href="#__codelineno-0-656">656</a></span>
<span class="normal"><a href="#__codelineno-0-657">657</a></span>
<span class="normal"><a href="#__codelineno-0-658">658</a></span>
<span class="normal"><a href="#__codelineno-0-659">659</a></span>
<span class="normal"><a href="#__codelineno-0-660">660</a></span>
<span class="normal"><a href="#__codelineno-0-661">661</a></span>
<span class="normal"><a href="#__codelineno-0-662">662</a></span>
<span class="normal"><a href="#__codelineno-0-663">663</a></span>
<span class="normal"><a href="#__codelineno-0-664">664</a></span>
<span class="normal"><a href="#__codelineno-0-665">665</a></span>
<span class="normal"><a href="#__codelineno-0-666">666</a></span>
<span class="normal"><a href="#__codelineno-0-667">667</a></span>
<span class="normal"><a href="#__codelineno-0-668">668</a></span>
<span class="normal"><a href="#__codelineno-0-669">669</a></span>
<span class="normal"><a href="#__codelineno-0-670">670</a></span>
<span class="normal"><a href="#__codelineno-0-671">671</a></span>
<span class="normal"><a href="#__codelineno-0-672">672</a></span>
<span class="normal"><a href="#__codelineno-0-673">673</a></span>
<span class="normal"><a href="#__codelineno-0-674">674</a></span>
<span class="normal"><a href="#__codelineno-0-675">675</a></span>
<span class="normal"><a href="#__codelineno-0-676">676</a></span>
<span class="normal"><a href="#__codelineno-0-677">677</a></span>
<span class="normal"><a href="#__codelineno-0-678">678</a></span>
<span class="normal"><a href="#__codelineno-0-679">679</a></span>
<span class="normal"><a href="#__codelineno-0-680">680</a></span>
<span class="normal"><a href="#__codelineno-0-681">681</a></span>
<span class="normal"><a href="#__codelineno-0-682">682</a></span>
<span class="normal"><a href="#__codelineno-0-683">683</a></span>
<span class="normal"><a href="#__codelineno-0-684">684</a></span>
<span class="normal"><a href="#__codelineno-0-685">685</a></span>
<span class="normal"><a href="#__codelineno-0-686">686</a></span>
<span class="normal"><a href="#__codelineno-0-687">687</a></span>
<span class="normal"><a href="#__codelineno-0-688">688</a></span>
<span class="normal"><a href="#__codelineno-0-689">689</a></span>
<span class="normal"><a href="#__codelineno-0-690">690</a></span>
<span class="normal"><a href="#__codelineno-0-691">691</a></span>
<span class="normal"><a href="#__codelineno-0-692">692</a></span>
<span class="normal"><a href="#__codelineno-0-693">693</a></span>
<span class="normal"><a href="#__codelineno-0-694">694</a></span>
<span class="normal"><a href="#__codelineno-0-695">695</a></span>
<span class="normal"><a href="#__codelineno-0-696">696</a></span>
<span class="normal"><a href="#__codelineno-0-697">697</a></span>
<span class="normal"><a href="#__codelineno-0-698">698</a></span>
<span class="normal"><a href="#__codelineno-0-699">699</a></span>
<span class="normal"><a href="#__codelineno-0-700">700</a></span>
<span class="normal"><a href="#__codelineno-0-701">701</a></span>
<span class="normal"><a href="#__codelineno-0-702">702</a></span>
<span class="normal"><a href="#__codelineno-0-703">703</a></span>
<span class="normal"><a href="#__codelineno-0-704">704</a></span>
<span class="normal"><a href="#__codelineno-0-705">705</a></span>
<span class="normal"><a href="#__codelineno-0-706">706</a></span>
<span class="normal"><a href="#__codelineno-0-707">707</a></span>
<span class="normal"><a href="#__codelineno-0-708">708</a></span>
<span class="normal"><a href="#__codelineno-0-709">709</a></span>
<span class="normal"><a href="#__codelineno-0-710">710</a></span>
<span class="normal"><a href="#__codelineno-0-711">711</a></span>
<span class="normal"><a href="#__codelineno-0-712">712</a></span>
<span class="normal"><a href="#__codelineno-0-713">713</a></span>
<span class="normal"><a href="#__codelineno-0-714">714</a></span>
<span class="normal"><a href="#__codelineno-0-715">715</a></span>
<span class="normal"><a href="#__codelineno-0-716">716</a></span>
<span class="normal"><a href="#__codelineno-0-717">717</a></span>
<span class="normal"><a href="#__codelineno-0-718">718</a></span>
<span class="normal"><a href="#__codelineno-0-719">719</a></span>
<span class="normal"><a href="#__codelineno-0-720">720</a></span>
<span class="normal"><a href="#__codelineno-0-721">721</a></span>
<span class="normal"><a href="#__codelineno-0-722">722</a></span>
<span class="normal"><a href="#__codelineno-0-723">723</a></span>
<span class="normal"><a href="#__codelineno-0-724">724</a></span>
<span class="normal"><a href="#__codelineno-0-725">725</a></span>
<span class="normal"><a href="#__codelineno-0-726">726</a></span>
<span class="normal"><a href="#__codelineno-0-727">727</a></span>
<span class="normal"><a href="#__codelineno-0-728">728</a></span>
<span class="normal"><a href="#__codelineno-0-729">729</a></span>
<span class="normal"><a href="#__codelineno-0-730">730</a></span>
<span class="normal"><a href="#__codelineno-0-731">731</a></span>
<span class="normal"><a href="#__codelineno-0-732">732</a></span>
<span class="normal"><a href="#__codelineno-0-733">733</a></span>
<span class="normal"><a href="#__codelineno-0-734">734</a></span>
<span class="normal"><a href="#__codelineno-0-735">735</a></span>
<span class="normal"><a href="#__codelineno-0-736">736</a></span>
<span class="normal"><a href="#__codelineno-0-737">737</a></span>
<span class="normal"><a href="#__codelineno-0-738">738</a></span>
<span class="normal"><a href="#__codelineno-0-739">739</a></span>
<span class="normal"><a href="#__codelineno-0-740">740</a></span>
<span class="normal"><a href="#__codelineno-0-741">741</a></span>
<span class="normal"><a href="#__codelineno-0-742">742</a></span>
<span class="normal"><a href="#__codelineno-0-743">743</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-654"><a id="__codelineno-0-654" name="__codelineno-0-654"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">get_screenshot</span><span class="p">(</span>
</span><span id="__span-0-655"><a id="__codelineno-0-655" name="__codelineno-0-655"></a> <span class="bp">self</span><span class="p">,</span>
</span><span id="__span-0-656"><a id="__codelineno-0-656" name="__codelineno-0-656"></a> <span class="n">view_angle</span><span class="p">:</span> <span class="n">ViewAngle</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-657"><a id="__codelineno-0-657" name="__codelineno-0-657"></a> <span class="n">width</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">800</span><span class="p">,</span>
</span><span id="__span-0-658"><a id="__codelineno-0-658" name="__codelineno-0-658"></a> <span class="n">height</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">600</span><span class="p">,</span>
</span><span id="__span-0-659"><a id="__codelineno-0-659" name="__codelineno-0-659"></a> <span class="n">doc_name</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-660"><a id="__codelineno-0-660" name="__codelineno-0-660"></a> <span class="p">)</span> <span class="o">-&gt;</span> <span class="n">ScreenshotResult</span><span class="p">:</span>
</span><span id="__span-0-661"><a id="__codelineno-0-661" name="__codelineno-0-661"></a><span class="w"> </span><span class="sd">"""Capture a screenshot of the 3D view via XML-RPC."""</span>
</span><span id="__span-0-662"><a id="__codelineno-0-662" name="__codelineno-0-662"></a> <span class="n">view_angle_str</span> <span class="o">=</span> <span class="n">view_angle</span><span class="o">.</span><span class="n">value</span> <span class="k">if</span> <span class="n">view_angle</span> <span class="k">else</span> <span class="s2">"Isometric"</span>
</span><span id="__span-0-663"><a id="__codelineno-0-663" name="__codelineno-0-663"></a> <span class="n">code</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">"""</span>
</span><span id="__span-0-664"><a id="__codelineno-0-664" name="__codelineno-0-664"></a><span class="s2">import base64</span>
</span><span id="__span-0-665"><a id="__codelineno-0-665" name="__codelineno-0-665"></a><span class="s2">import tempfile</span>
</span><span id="__span-0-666"><a id="__codelineno-0-666" name="__codelineno-0-666"></a><span class="s2">import os</span>
</span><span id="__span-0-667"><a id="__codelineno-0-667" name="__codelineno-0-667"></a>
</span><span id="__span-0-668"><a id="__codelineno-0-668" name="__codelineno-0-668"></a><span class="s2">doc = FreeCAD.ActiveDocument if </span><span class="si">{</span><span class="n">doc_name</span><span class="si">!r}</span><span class="s2"> is None else FreeCAD.getDocument(</span><span class="si">{</span><span class="n">doc_name</span><span class="si">!r}</span><span class="s2">)</span>
</span><span id="__span-0-669"><a id="__codelineno-0-669" name="__codelineno-0-669"></a><span class="s2">if doc is None:</span>
</span><span id="__span-0-670"><a id="__codelineno-0-670" name="__codelineno-0-670"></a><span class="s2"> raise ValueError("No document found")</span>
</span><span id="__span-0-671"><a id="__codelineno-0-671" name="__codelineno-0-671"></a>
</span><span id="__span-0-672"><a id="__codelineno-0-672" name="__codelineno-0-672"></a><span class="s2"># Check if GUI is available</span>
</span><span id="__span-0-673"><a id="__codelineno-0-673" name="__codelineno-0-673"></a><span class="s2">if not FreeCAD.GuiUp:</span>
</span><span id="__span-0-674"><a id="__codelineno-0-674" name="__codelineno-0-674"></a><span class="s2"> raise RuntimeError("GUI not available")</span>
</span><span id="__span-0-675"><a id="__codelineno-0-675" name="__codelineno-0-675"></a>
</span><span id="__span-0-676"><a id="__codelineno-0-676" name="__codelineno-0-676"></a><span class="s2">view = FreeCADGui.ActiveDocument.ActiveView</span>
</span><span id="__span-0-677"><a id="__codelineno-0-677" name="__codelineno-0-677"></a><span class="s2">if view is None:</span>
</span><span id="__span-0-678"><a id="__codelineno-0-678" name="__codelineno-0-678"></a><span class="s2"> raise ValueError("No active view")</span>
</span><span id="__span-0-679"><a id="__codelineno-0-679" name="__codelineno-0-679"></a>
</span><span id="__span-0-680"><a id="__codelineno-0-680" name="__codelineno-0-680"></a><span class="s2"># Check if this is a 3D view (not TechDraw, Spreadsheet, etc.)</span>
</span><span id="__span-0-681"><a id="__codelineno-0-681" name="__codelineno-0-681"></a><span class="s2">view_type = view.__class__.__name__</span>
</span><span id="__span-0-682"><a id="__codelineno-0-682" name="__codelineno-0-682"></a><span class="s2">if view_type not in ["View3DInventor", "View3DInventorPy"]:</span>
</span><span id="__span-0-683"><a id="__codelineno-0-683" name="__codelineno-0-683"></a><span class="s2"> raise ValueError(f"Cannot capture screenshot from </span><span class="se">{{</span><span class="s2">view_type</span><span class="se">}}</span><span class="s2"> view")</span>
</span><span id="__span-0-684"><a id="__codelineno-0-684" name="__codelineno-0-684"></a>
</span><span id="__span-0-685"><a id="__codelineno-0-685" name="__codelineno-0-685"></a><span class="s2"># Set view angle</span>
</span><span id="__span-0-686"><a id="__codelineno-0-686" name="__codelineno-0-686"></a><span class="s2">view_type_str = </span><span class="si">{</span><span class="n">view_angle_str</span><span class="si">!r}</span>
</span><span id="__span-0-687"><a id="__codelineno-0-687" name="__codelineno-0-687"></a><span class="s2">if view_type_str == "FitAll":</span>
</span><span id="__span-0-688"><a id="__codelineno-0-688" name="__codelineno-0-688"></a><span class="s2"> view.fitAll()</span>
</span><span id="__span-0-689"><a id="__codelineno-0-689" name="__codelineno-0-689"></a><span class="s2">elif view_type_str == "Isometric":</span>
</span><span id="__span-0-690"><a id="__codelineno-0-690" name="__codelineno-0-690"></a><span class="s2"> view.viewIsometric()</span>
</span><span id="__span-0-691"><a id="__codelineno-0-691" name="__codelineno-0-691"></a><span class="s2">elif view_type_str == "Front":</span>
</span><span id="__span-0-692"><a id="__codelineno-0-692" name="__codelineno-0-692"></a><span class="s2"> view.viewFront()</span>
</span><span id="__span-0-693"><a id="__codelineno-0-693" name="__codelineno-0-693"></a><span class="s2">elif view_type_str == "Back":</span>
</span><span id="__span-0-694"><a id="__codelineno-0-694" name="__codelineno-0-694"></a><span class="s2"> view.viewRear()</span>
</span><span id="__span-0-695"><a id="__codelineno-0-695" name="__codelineno-0-695"></a><span class="s2">elif view_type_str == "Top":</span>
</span><span id="__span-0-696"><a id="__codelineno-0-696" name="__codelineno-0-696"></a><span class="s2"> view.viewTop()</span>
</span><span id="__span-0-697"><a id="__codelineno-0-697" name="__codelineno-0-697"></a><span class="s2">elif view_type_str == "Bottom":</span>
</span><span id="__span-0-698"><a id="__codelineno-0-698" name="__codelineno-0-698"></a><span class="s2"> view.viewBottom()</span>
</span><span id="__span-0-699"><a id="__codelineno-0-699" name="__codelineno-0-699"></a><span class="s2">elif view_type_str == "Left":</span>
</span><span id="__span-0-700"><a id="__codelineno-0-700" name="__codelineno-0-700"></a><span class="s2"> view.viewLeft()</span>
</span><span id="__span-0-701"><a id="__codelineno-0-701" name="__codelineno-0-701"></a><span class="s2">elif view_type_str == "Right":</span>
</span><span id="__span-0-702"><a id="__codelineno-0-702" name="__codelineno-0-702"></a><span class="s2"> view.viewRight()</span>
</span><span id="__span-0-703"><a id="__codelineno-0-703" name="__codelineno-0-703"></a>
</span><span id="__span-0-704"><a id="__codelineno-0-704" name="__codelineno-0-704"></a><span class="s2"># Save to temp file and read</span>
</span><span id="__span-0-705"><a id="__codelineno-0-705" name="__codelineno-0-705"></a><span class="s2">with tempfile.NamedTemporaryFile(suffix=".png", delete=False) as f:</span>
</span><span id="__span-0-706"><a id="__codelineno-0-706" name="__codelineno-0-706"></a><span class="s2"> temp_path = f.name</span>
</span><span id="__span-0-707"><a id="__codelineno-0-707" name="__codelineno-0-707"></a>
</span><span id="__span-0-708"><a id="__codelineno-0-708" name="__codelineno-0-708"></a><span class="s2">view.saveImage(temp_path, </span><span class="si">{</span><span class="n">width</span><span class="si">}</span><span class="s2">, </span><span class="si">{</span><span class="n">height</span><span class="si">}</span><span class="s2">, "Current")</span>
</span><span id="__span-0-709"><a id="__codelineno-0-709" name="__codelineno-0-709"></a>
</span><span id="__span-0-710"><a id="__codelineno-0-710" name="__codelineno-0-710"></a><span class="s2">with open(temp_path, "rb") as f:</span>
</span><span id="__span-0-711"><a id="__codelineno-0-711" name="__codelineno-0-711"></a><span class="s2"> image_data = base64.b64encode(f.read()).decode("utf-8")</span>
</span><span id="__span-0-712"><a id="__codelineno-0-712" name="__codelineno-0-712"></a>
</span><span id="__span-0-713"><a id="__codelineno-0-713" name="__codelineno-0-713"></a><span class="s2">os.unlink(temp_path)</span>
</span><span id="__span-0-714"><a id="__codelineno-0-714" name="__codelineno-0-714"></a>
</span><span id="__span-0-715"><a id="__codelineno-0-715" name="__codelineno-0-715"></a><span class="s2">_result_ = </span><span class="se">{{</span>
</span><span id="__span-0-716"><a id="__codelineno-0-716" name="__codelineno-0-716"></a><span class="s2"> "success": True,</span>
</span><span id="__span-0-717"><a id="__codelineno-0-717" name="__codelineno-0-717"></a><span class="s2"> "data": image_data,</span>
</span><span id="__span-0-718"><a id="__codelineno-0-718" name="__codelineno-0-718"></a><span class="s2"> "format": "png",</span>
</span><span id="__span-0-719"><a id="__codelineno-0-719" name="__codelineno-0-719"></a><span class="s2"> "width": </span><span class="si">{</span><span class="n">width</span><span class="si">}</span><span class="s2">,</span>
</span><span id="__span-0-720"><a id="__codelineno-0-720" name="__codelineno-0-720"></a><span class="s2"> "height": </span><span class="si">{</span><span class="n">height</span><span class="si">}</span><span class="s2">,</span>
</span><span id="__span-0-721"><a id="__codelineno-0-721" name="__codelineno-0-721"></a><span class="se">}}</span>
</span><span id="__span-0-722"><a id="__codelineno-0-722" name="__codelineno-0-722"></a><span class="s2">"""</span>
</span><span id="__span-0-723"><a id="__codelineno-0-723" name="__codelineno-0-723"></a> <span class="n">result</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">execute_python</span><span class="p">(</span><span class="n">code</span><span class="p">)</span>
</span><span id="__span-0-724"><a id="__codelineno-0-724" name="__codelineno-0-724"></a>
</span><span id="__span-0-725"><a id="__codelineno-0-725" name="__codelineno-0-725"></a> <span class="k">if</span> <span class="n">result</span><span class="o">.</span><span class="n">success</span> <span class="ow">and</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">:</span>
</span><span id="__span-0-726"><a id="__codelineno-0-726" name="__codelineno-0-726"></a> <span class="k">return</span> <span class="n">ScreenshotResult</span><span class="p">(</span>
</span><span id="__span-0-727"><a id="__codelineno-0-727" name="__codelineno-0-727"></a> <span class="n">success</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span>
</span><span id="__span-0-728"><a id="__codelineno-0-728" name="__codelineno-0-728"></a> <span class="n">data</span><span class="o">=</span><span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">[</span><span class="s2">"data"</span><span class="p">],</span>
</span><span id="__span-0-729"><a id="__codelineno-0-729" name="__codelineno-0-729"></a> <span class="nb">format</span><span class="o">=</span><span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">[</span><span class="s2">"format"</span><span class="p">],</span>
</span><span id="__span-0-730"><a id="__codelineno-0-730" name="__codelineno-0-730"></a> <span class="n">width</span><span class="o">=</span><span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">[</span><span class="s2">"width"</span><span class="p">],</span>
</span><span id="__span-0-731"><a id="__codelineno-0-731" name="__codelineno-0-731"></a> <span class="n">height</span><span class="o">=</span><span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">[</span><span class="s2">"height"</span><span class="p">],</span>
</span><span id="__span-0-732"><a id="__codelineno-0-732" name="__codelineno-0-732"></a> <span class="n">view_angle</span><span class="o">=</span><span class="n">view_angle</span><span class="p">,</span>
</span><span id="__span-0-733"><a id="__codelineno-0-733" name="__codelineno-0-733"></a> <span class="p">)</span>
</span><span id="__span-0-734"><a id="__codelineno-0-734" name="__codelineno-0-734"></a>
</span><span id="__span-0-735"><a id="__codelineno-0-735" name="__codelineno-0-735"></a> <span class="k">return</span> <span class="n">ScreenshotResult</span><span class="p">(</span>
</span><span id="__span-0-736"><a id="__codelineno-0-736" name="__codelineno-0-736"></a> <span class="n">success</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
</span><span id="__span-0-737"><a id="__codelineno-0-737" name="__codelineno-0-737"></a> <span class="n">error</span><span class="o">=</span><span class="n">result</span><span class="o">.</span><span class="n">error_traceback</span>
</span><span id="__span-0-738"><a id="__codelineno-0-738" name="__codelineno-0-738"></a> <span class="ow">or</span> <span class="n">result</span><span class="o">.</span><span class="n">stderr</span>
</span><span id="__span-0-739"><a id="__codelineno-0-739" name="__codelineno-0-739"></a> <span class="ow">or</span> <span class="s2">"Failed to capture screenshot"</span><span class="p">,</span>
</span><span id="__span-0-740"><a id="__codelineno-0-740" name="__codelineno-0-740"></a> <span class="n">width</span><span class="o">=</span><span class="n">width</span><span class="p">,</span>
</span><span id="__span-0-741"><a id="__codelineno-0-741" name="__codelineno-0-741"></a> <span class="n">height</span><span class="o">=</span><span class="n">height</span><span class="p">,</span>
</span><span id="__span-0-742"><a id="__codelineno-0-742" name="__codelineno-0-742"></a> <span class="n">view_angle</span><span class="o">=</span><span class="n">view_angle</span><span class="p">,</span>
</span><span id="__span-0-743"><a id="__codelineno-0-743" name="__codelineno-0-743"></a> <span class="p">)</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> </div> </div> <div class="doc doc-object doc-function"> <h6 id="freecad_mcp.bridge.xmlrpc.XmlRpcBridge.get_status" class="doc doc-heading"> <code class="highlight language-python"><span class="n">get_status</span><span class="p">()</span></code> <span class="doc doc-labels"> <small class="doc doc-label doc-label-async"><code>async</code></small> </span> <a href="#freecad_mcp.bridge.xmlrpc.XmlRpcBridge.get_status" class="headerlink" title="Permanent link">¶</a></h6> <div class="doc doc-contents "> <p>Get detailed connection status.</p> <p><span class="doc-section-title">Returns:</span></p> <table> <thead> <tr> <th>Type</th> <th>Description</th> </tr> </thead> <tbody> <tr class="doc-section-item"> <td> <code><a class="autorefs autorefs-internal" title="ConnectionStatus
dataclass
(freecad_mcp.bridge.base.ConnectionStatus)" href="#freecad_mcp.bridge.base.ConnectionStatus">ConnectionStatus</a></code> </td> <td> <div class="doc-md-description"> <p>ConnectionStatus with full status information.</p> </div> </td> </tr> </tbody> </table> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/xmlrpc.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-195">195</a></span>
<span class="normal"><a href="#__codelineno-0-196">196</a></span>
<span class="normal"><a href="#__codelineno-0-197">197</a></span>
<span class="normal"><a href="#__codelineno-0-198">198</a></span>
<span class="normal"><a href="#__codelineno-0-199">199</a></span>
<span class="normal"><a href="#__codelineno-0-200">200</a></span>
<span class="normal"><a href="#__codelineno-0-201">201</a></span>
<span class="normal"><a href="#__codelineno-0-202">202</a></span>
<span class="normal"><a href="#__codelineno-0-203">203</a></span>
<span class="normal"><a href="#__codelineno-0-204">204</a></span>
<span class="normal"><a href="#__codelineno-0-205">205</a></span>
<span class="normal"><a href="#__codelineno-0-206">206</a></span>
<span class="normal"><a href="#__codelineno-0-207">207</a></span>
<span class="normal"><a href="#__codelineno-0-208">208</a></span>
<span class="normal"><a href="#__codelineno-0-209">209</a></span>
<span class="normal"><a href="#__codelineno-0-210">210</a></span>
<span class="normal"><a href="#__codelineno-0-211">211</a></span>
<span class="normal"><a href="#__codelineno-0-212">212</a></span>
<span class="normal"><a href="#__codelineno-0-213">213</a></span>
<span class="normal"><a href="#__codelineno-0-214">214</a></span>
<span class="normal"><a href="#__codelineno-0-215">215</a></span>
<span class="normal"><a href="#__codelineno-0-216">216</a></span>
<span class="normal"><a href="#__codelineno-0-217">217</a></span>
<span class="normal"><a href="#__codelineno-0-218">218</a></span>
<span class="normal"><a href="#__codelineno-0-219">219</a></span>
<span class="normal"><a href="#__codelineno-0-220">220</a></span>
<span class="normal"><a href="#__codelineno-0-221">221</a></span>
<span class="normal"><a href="#__codelineno-0-222">222</a></span>
<span class="normal"><a href="#__codelineno-0-223">223</a></span>
<span class="normal"><a href="#__codelineno-0-224">224</a></span>
<span class="normal"><a href="#__codelineno-0-225">225</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-195"><a id="__codelineno-0-195" name="__codelineno-0-195"></a><span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">get_status</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">ConnectionStatus</span><span class="p">:</span>
</span><span id="__span-0-196"><a id="__codelineno-0-196" name="__codelineno-0-196"></a><span class="w"> </span><span class="sd">"""Get detailed connection status.</span>
</span><span id="__span-0-197"><a id="__codelineno-0-197" name="__codelineno-0-197"></a>
</span><span id="__span-0-198"><a id="__codelineno-0-198" name="__codelineno-0-198"></a><span class="sd"> Returns:</span>
</span><span id="__span-0-199"><a id="__codelineno-0-199" name="__codelineno-0-199"></a><span class="sd"> ConnectionStatus with full status information.</span>
</span><span id="__span-0-200"><a id="__codelineno-0-200" name="__codelineno-0-200"></a><span class="sd"> """</span>
</span><span id="__span-0-201"><a id="__codelineno-0-201" name="__codelineno-0-201"></a> <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">_connected</span> <span class="ow">or</span> <span class="bp">self</span><span class="o">.</span><span class="n">_proxy</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
</span><span id="__span-0-202"><a id="__codelineno-0-202" name="__codelineno-0-202"></a> <span class="k">return</span> <span class="n">ConnectionStatus</span><span class="p">(</span>
</span><span id="__span-0-203"><a id="__codelineno-0-203" name="__codelineno-0-203"></a> <span class="n">connected</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
</span><span id="__span-0-204"><a id="__codelineno-0-204" name="__codelineno-0-204"></a> <span class="n">mode</span><span class="o">=</span><span class="s2">"xmlrpc"</span><span class="p">,</span>
</span><span id="__span-0-205"><a id="__codelineno-0-205" name="__codelineno-0-205"></a> <span class="n">error</span><span class="o">=</span><span class="s2">"Not connected"</span><span class="p">,</span>
</span><span id="__span-0-206"><a id="__codelineno-0-206" name="__codelineno-0-206"></a> <span class="p">)</span>
</span><span id="__span-0-207"><a id="__codelineno-0-207" name="__codelineno-0-207"></a>
</span><span id="__span-0-208"><a id="__codelineno-0-208" name="__codelineno-0-208"></a> <span class="k">try</span><span class="p">:</span>
</span><span id="__span-0-209"><a id="__codelineno-0-209" name="__codelineno-0-209"></a> <span class="n">ping_ms</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">ping</span><span class="p">()</span>
</span><span id="__span-0-210"><a id="__codelineno-0-210" name="__codelineno-0-210"></a> <span class="n">version_info</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_freecad_version</span><span class="p">()</span>
</span><span id="__span-0-211"><a id="__codelineno-0-211" name="__codelineno-0-211"></a> <span class="n">gui_available</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">is_gui_available</span><span class="p">()</span>
</span><span id="__span-0-212"><a id="__codelineno-0-212" name="__codelineno-0-212"></a>
</span><span id="__span-0-213"><a id="__codelineno-0-213" name="__codelineno-0-213"></a> <span class="k">return</span> <span class="n">ConnectionStatus</span><span class="p">(</span>
</span><span id="__span-0-214"><a id="__codelineno-0-214" name="__codelineno-0-214"></a> <span class="n">connected</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span>
</span><span id="__span-0-215"><a id="__codelineno-0-215" name="__codelineno-0-215"></a> <span class="n">mode</span><span class="o">=</span><span class="s2">"xmlrpc"</span><span class="p">,</span>
</span><span id="__span-0-216"><a id="__codelineno-0-216" name="__codelineno-0-216"></a> <span class="n">freecad_version</span><span class="o">=</span><span class="n">version_info</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"version"</span><span class="p">,</span> <span class="s2">"unknown"</span><span class="p">),</span>
</span><span id="__span-0-217"><a id="__codelineno-0-217" name="__codelineno-0-217"></a> <span class="n">gui_available</span><span class="o">=</span><span class="n">gui_available</span><span class="p">,</span>
</span><span id="__span-0-218"><a id="__codelineno-0-218" name="__codelineno-0-218"></a> <span class="n">last_ping_ms</span><span class="o">=</span><span class="n">ping_ms</span><span class="p">,</span>
</span><span id="__span-0-219"><a id="__codelineno-0-219" name="__codelineno-0-219"></a> <span class="p">)</span>
</span><span id="__span-0-220"><a id="__codelineno-0-220" name="__codelineno-0-220"></a> <span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
</span><span id="__span-0-221"><a id="__codelineno-0-221" name="__codelineno-0-221"></a> <span class="k">return</span> <span class="n">ConnectionStatus</span><span class="p">(</span>
</span><span id="__span-0-222"><a id="__codelineno-0-222" name="__codelineno-0-222"></a> <span class="n">connected</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
</span><span id="__span-0-223"><a id="__codelineno-0-223" name="__codelineno-0-223"></a> <span class="n">mode</span><span class="o">=</span><span class="s2">"xmlrpc"</span><span class="p">,</span>
</span><span id="__span-0-224"><a id="__codelineno-0-224" name="__codelineno-0-224"></a> <span class="n">error</span><span class="o">=</span><span class="nb">str</span><span class="p">(</span><span class="n">e</span><span class="p">),</span>
</span><span id="__span-0-225"><a id="__codelineno-0-225" name="__codelineno-0-225"></a> <span class="p">)</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> </div> </div> <div class="doc doc-object doc-function"> <h6 id="freecad_mcp.bridge.xmlrpc.XmlRpcBridge.get_workbenches" class="doc doc-heading"> <code class="highlight language-python"><span class="n">get_workbenches</span><span class="p">()</span></code> <span class="doc doc-labels"> <small class="doc doc-label doc-label-async"><code>async</code></small> </span> <a href="#freecad_mcp.bridge.xmlrpc.XmlRpcBridge.get_workbenches" class="headerlink" title="Permanent link">¶</a></h6> <div class="doc doc-contents "> <p>Get list of available workbenches.</p> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/xmlrpc.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-934">934</a></span>
<span class="normal"><a href="#__codelineno-0-935">935</a></span>
<span class="normal"><a href="#__codelineno-0-936">936</a></span>
<span class="normal"><a href="#__codelineno-0-937">937</a></span>
<span class="normal"><a href="#__codelineno-0-938">938</a></span>
<span class="normal"><a href="#__codelineno-0-939">939</a></span>
<span class="normal"><a href="#__codelineno-0-940">940</a></span>
<span class="normal"><a href="#__codelineno-0-941">941</a></span>
<span class="normal"><a href="#__codelineno-0-942">942</a></span>
<span class="normal"><a href="#__codelineno-0-943">943</a></span>
<span class="normal"><a href="#__codelineno-0-944">944</a></span>
<span class="normal"><a href="#__codelineno-0-945">945</a></span>
<span class="normal"><a href="#__codelineno-0-946">946</a></span>
<span class="normal"><a href="#__codelineno-0-947">947</a></span>
<span class="normal"><a href="#__codelineno-0-948">948</a></span>
<span class="normal"><a href="#__codelineno-0-949">949</a></span>
<span class="normal"><a href="#__codelineno-0-950">950</a></span>
<span class="normal"><a href="#__codelineno-0-951">951</a></span>
<span class="normal"><a href="#__codelineno-0-952">952</a></span>
<span class="normal"><a href="#__codelineno-0-953">953</a></span>
<span class="normal"><a href="#__codelineno-0-954">954</a></span>
<span class="normal"><a href="#__codelineno-0-955">955</a></span>
<span class="normal"><a href="#__codelineno-0-956">956</a></span>
<span class="normal"><a href="#__codelineno-0-957">957</a></span>
<span class="normal"><a href="#__codelineno-0-958">958</a></span>
<span class="normal"><a href="#__codelineno-0-959">959</a></span>
<span class="normal"><a href="#__codelineno-0-960">960</a></span>
<span class="normal"><a href="#__codelineno-0-961">961</a></span>
<span class="normal"><a href="#__codelineno-0-962">962</a></span>
<span class="normal"><a href="#__codelineno-0-963">963</a></span>
<span class="normal"><a href="#__codelineno-0-964">964</a></span>
<span class="normal"><a href="#__codelineno-0-965">965</a></span>
<span class="normal"><a href="#__codelineno-0-966">966</a></span>
<span class="normal"><a href="#__codelineno-0-967">967</a></span>
<span class="normal"><a href="#__codelineno-0-968">968</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-934"><a id="__codelineno-0-934" name="__codelineno-0-934"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">get_workbenches</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">list</span><span class="p">[</span><span class="n">WorkbenchInfo</span><span class="p">]:</span>
</span><span id="__span-0-935"><a id="__codelineno-0-935" name="__codelineno-0-935"></a><span class="w"> </span><span class="sd">"""Get list of available workbenches."""</span>
</span><span id="__span-0-936"><a id="__codelineno-0-936" name="__codelineno-0-936"></a> <span class="n">code</span> <span class="o">=</span> <span class="s2">"""</span>
</span><span id="__span-0-937"><a id="__codelineno-0-937" name="__codelineno-0-937"></a><span class="s2">workbenches = []</span>
</span><span id="__span-0-938"><a id="__codelineno-0-938" name="__codelineno-0-938"></a><span class="s2">active_wb = FreeCADGui.activeWorkbench() if FreeCAD.GuiUp else None</span>
</span><span id="__span-0-939"><a id="__codelineno-0-939" name="__codelineno-0-939"></a><span class="s2">active_name = active_wb.__class__.__name__ if active_wb else None</span>
</span><span id="__span-0-940"><a id="__codelineno-0-940" name="__codelineno-0-940"></a>
</span><span id="__span-0-941"><a id="__codelineno-0-941" name="__codelineno-0-941"></a><span class="s2">if FreeCAD.GuiUp:</span>
</span><span id="__span-0-942"><a id="__codelineno-0-942" name="__codelineno-0-942"></a><span class="s2"> for name in FreeCADGui.listWorkbenches():</span>
</span><span id="__span-0-943"><a id="__codelineno-0-943" name="__codelineno-0-943"></a><span class="s2"> wb = FreeCADGui.getWorkbench(name)</span>
</span><span id="__span-0-944"><a id="__codelineno-0-944" name="__codelineno-0-944"></a><span class="s2"> workbenches.append({</span>
</span><span id="__span-0-945"><a id="__codelineno-0-945" name="__codelineno-0-945"></a><span class="s2"> "name": name,</span>
</span><span id="__span-0-946"><a id="__codelineno-0-946" name="__codelineno-0-946"></a><span class="s2"> "label": wb.MenuText if hasattr(wb, "MenuText") else name,</span>
</span><span id="__span-0-947"><a id="__codelineno-0-947" name="__codelineno-0-947"></a><span class="s2"> "icon": wb.Icon if hasattr(wb, "Icon") else "",</span>
</span><span id="__span-0-948"><a id="__codelineno-0-948" name="__codelineno-0-948"></a><span class="s2"> "is_active": name == active_name,</span>
</span><span id="__span-0-949"><a id="__codelineno-0-949" name="__codelineno-0-949"></a><span class="s2"> })</span>
</span><span id="__span-0-950"><a id="__codelineno-0-950" name="__codelineno-0-950"></a><span class="s2">else:</span>
</span><span id="__span-0-951"><a id="__codelineno-0-951" name="__codelineno-0-951"></a><span class="s2"> # Return common workbenches for headless mode</span>
</span><span id="__span-0-952"><a id="__codelineno-0-952" name="__codelineno-0-952"></a><span class="s2"> common = ["StartWorkbench", "PartWorkbench", "PartDesignWorkbench",</span>
</span><span id="__span-0-953"><a id="__codelineno-0-953" name="__codelineno-0-953"></a><span class="s2"> "DraftWorkbench", "SketcherWorkbench", "MeshWorkbench"]</span>
</span><span id="__span-0-954"><a id="__codelineno-0-954" name="__codelineno-0-954"></a><span class="s2"> for name in common:</span>
</span><span id="__span-0-955"><a id="__codelineno-0-955" name="__codelineno-0-955"></a><span class="s2"> workbenches.append({</span>
</span><span id="__span-0-956"><a id="__codelineno-0-956" name="__codelineno-0-956"></a><span class="s2"> "name": name,</span>
</span><span id="__span-0-957"><a id="__codelineno-0-957" name="__codelineno-0-957"></a><span class="s2"> "label": name.replace("Workbench", ""),</span>
</span><span id="__span-0-958"><a id="__codelineno-0-958" name="__codelineno-0-958"></a><span class="s2"> "icon": "",</span>
</span><span id="__span-0-959"><a id="__codelineno-0-959" name="__codelineno-0-959"></a><span class="s2"> "is_active": False,</span>
</span><span id="__span-0-960"><a id="__codelineno-0-960" name="__codelineno-0-960"></a><span class="s2"> })</span>
</span><span id="__span-0-961"><a id="__codelineno-0-961" name="__codelineno-0-961"></a>
</span><span id="__span-0-962"><a id="__codelineno-0-962" name="__codelineno-0-962"></a><span class="s2">_result_ = workbenches</span>
</span><span id="__span-0-963"><a id="__codelineno-0-963" name="__codelineno-0-963"></a><span class="s2">"""</span>
</span><span id="__span-0-964"><a id="__codelineno-0-964" name="__codelineno-0-964"></a> <span class="n">result</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">execute_python</span><span class="p">(</span><span class="n">code</span><span class="p">)</span>
</span><span id="__span-0-965"><a id="__codelineno-0-965" name="__codelineno-0-965"></a>
</span><span id="__span-0-966"><a id="__codelineno-0-966" name="__codelineno-0-966"></a> <span class="k">if</span> <span class="n">result</span><span class="o">.</span><span class="n">success</span> <span class="ow">and</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">:</span>
</span><span id="__span-0-967"><a id="__codelineno-0-967" name="__codelineno-0-967"></a> <span class="k">return</span> <span class="p">[</span><span class="n">WorkbenchInfo</span><span class="p">(</span><span class="o">**</span><span class="n">wb</span><span class="p">)</span> <span class="k">for</span> <span class="n">wb</span> <span class="ow">in</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">]</span>
</span><span id="__span-0-968"><a id="__codelineno-0-968" name="__codelineno-0-968"></a> <span class="k">return</span> <span class="p">[]</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> </div> </div> <div class="doc doc-object doc-function"> <h6 id="freecad_mcp.bridge.xmlrpc.XmlRpcBridge.is_connected" class="doc doc-heading"> <code class="highlight language-python"><span class="n">is_connected</span><span class="p">()</span></code> <span class="doc doc-labels"> <small class="doc doc-label doc-label-async"><code>async</code></small> </span> <a href="#freecad_mcp.bridge.xmlrpc.XmlRpcBridge.is_connected" class="headerlink" title="Permanent link">¶</a></h6> <div class="doc doc-contents "> <p>Check if bridge is connected to FreeCAD.</p> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/xmlrpc.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-145">145</a></span>
<span class="normal"><a href="#__codelineno-0-146">146</a></span>
<span class="normal"><a href="#__codelineno-0-147">147</a></span>
<span class="normal"><a href="#__codelineno-0-148">148</a></span>
<span class="normal"><a href="#__codelineno-0-149">149</a></span>
<span class="normal"><a href="#__codelineno-0-150">150</a></span>
<span class="normal"><a href="#__codelineno-0-151">151</a></span>
<span class="normal"><a href="#__codelineno-0-152">152</a></span>
<span class="normal"><a href="#__codelineno-0-153">153</a></span>
<span class="normal"><a href="#__codelineno-0-154">154</a></span>
<span class="normal"><a href="#__codelineno-0-155">155</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-145"><a id="__codelineno-0-145" name="__codelineno-0-145"></a><span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">is_connected</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">bool</span><span class="p">:</span>
</span><span id="__span-0-146"><a id="__codelineno-0-146" name="__codelineno-0-146"></a><span class="w"> </span><span class="sd">"""Check if bridge is connected to FreeCAD."""</span>
</span><span id="__span-0-147"><a id="__codelineno-0-147" name="__codelineno-0-147"></a> <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">_connected</span> <span class="ow">or</span> <span class="bp">self</span><span class="o">.</span><span class="n">_proxy</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
</span><span id="__span-0-148"><a id="__codelineno-0-148" name="__codelineno-0-148"></a> <span class="k">return</span> <span class="kc">False</span>
</span><span id="__span-0-149"><a id="__codelineno-0-149" name="__codelineno-0-149"></a>
</span><span id="__span-0-150"><a id="__codelineno-0-150" name="__codelineno-0-150"></a> <span class="k">try</span><span class="p">:</span>
</span><span id="__span-0-151"><a id="__codelineno-0-151" name="__codelineno-0-151"></a> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">ping</span><span class="p">()</span>
</span><span id="__span-0-152"><a id="__codelineno-0-152" name="__codelineno-0-152"></a> <span class="k">return</span> <span class="kc">True</span>
</span><span id="__span-0-153"><a id="__codelineno-0-153" name="__codelineno-0-153"></a> <span class="k">except</span> <span class="ne">Exception</span><span class="p">:</span>
</span><span id="__span-0-154"><a id="__codelineno-0-154" name="__codelineno-0-154"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_connected</span> <span class="o">=</span> <span class="kc">False</span>
</span><span id="__span-0-155"><a id="__codelineno-0-155" name="__codelineno-0-155"></a> <span class="k">return</span> <span class="kc">False</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> </div> </div> <div class="doc doc-object doc-function"> <h6 id="freecad_mcp.bridge.xmlrpc.XmlRpcBridge.is_gui_available" class="doc doc-heading"> <code class="highlight language-python"><span class="n">is_gui_available</span><span class="p">()</span></code> <span class="doc doc-labels"> <small class="doc doc-label doc-label-async"><code>async</code></small> </span> <a href="#freecad_mcp.bridge.xmlrpc.XmlRpcBridge.is_gui_available" class="headerlink" title="Permanent link">¶</a></h6> <div class="doc doc-contents "> <p>Check if FreeCAD GUI is available.</p> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/xmlrpc.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-1017">1017</a></span>
<span class="normal"><a href="#__codelineno-0-1018">1018</a></span>
<span class="normal"><a href="#__codelineno-0-1019">1019</a></span>
<span class="normal"><a href="#__codelineno-0-1020">1020</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-1017"><a id="__codelineno-0-1017" name="__codelineno-0-1017"></a><span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">is_gui_available</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">bool</span><span class="p">:</span>
</span><span id="__span-0-1018"><a id="__codelineno-0-1018" name="__codelineno-0-1018"></a><span class="w"> </span><span class="sd">"""Check if FreeCAD GUI is available."""</span>
</span><span id="__span-0-1019"><a id="__codelineno-0-1019" name="__codelineno-0-1019"></a> <span class="n">result</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">execute_python</span><span class="p">(</span><span class="s2">"_result_ = FreeCAD.GuiUp"</span><span class="p">)</span>
</span><span id="__span-0-1020"><a id="__codelineno-0-1020" name="__codelineno-0-1020"></a> <span class="k">return</span> <span class="nb">bool</span><span class="p">(</span><span class="n">result</span><span class="o">.</span><span class="n">success</span> <span class="ow">and</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">)</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> </div> </div> <div class="doc doc-object doc-function"> <h6 id="freecad_mcp.bridge.xmlrpc.XmlRpcBridge.open_document" class="doc doc-heading"> <code class="highlight language-python"><span class="n">open_document</span><span class="p">(</span><span class="n">path</span><span class="p">)</span></code> <span class="doc doc-labels"> <small class="doc doc-label doc-label-async"><code>async</code></small> </span> <a href="#freecad_mcp.bridge.xmlrpc.XmlRpcBridge.open_document" class="headerlink" title="Permanent link">¶</a></h6> <div class="doc doc-contents "> <p>Open an existing document.</p> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/xmlrpc.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-383">383</a></span>
<span class="normal"><a href="#__codelineno-0-384">384</a></span>
<span class="normal"><a href="#__codelineno-0-385">385</a></span>
<span class="normal"><a href="#__codelineno-0-386">386</a></span>
<span class="normal"><a href="#__codelineno-0-387">387</a></span>
<span class="normal"><a href="#__codelineno-0-388">388</a></span>
<span class="normal"><a href="#__codelineno-0-389">389</a></span>
<span class="normal"><a href="#__codelineno-0-390">390</a></span>
<span class="normal"><a href="#__codelineno-0-391">391</a></span>
<span class="normal"><a href="#__codelineno-0-392">392</a></span>
<span class="normal"><a href="#__codelineno-0-393">393</a></span>
<span class="normal"><a href="#__codelineno-0-394">394</a></span>
<span class="normal"><a href="#__codelineno-0-395">395</a></span>
<span class="normal"><a href="#__codelineno-0-396">396</a></span>
<span class="normal"><a href="#__codelineno-0-397">397</a></span>
<span class="normal"><a href="#__codelineno-0-398">398</a></span>
<span class="normal"><a href="#__codelineno-0-399">399</a></span>
<span class="normal"><a href="#__codelineno-0-400">400</a></span>
<span class="normal"><a href="#__codelineno-0-401">401</a></span>
<span class="normal"><a href="#__codelineno-0-402">402</a></span>
<span class="normal"><a href="#__codelineno-0-403">403</a></span>
<span class="normal"><a href="#__codelineno-0-404">404</a></span>
<span class="normal"><a href="#__codelineno-0-405">405</a></span>
<span class="normal"><a href="#__codelineno-0-406">406</a></span>
<span class="normal"><a href="#__codelineno-0-407">407</a></span>
<span class="normal"><a href="#__codelineno-0-408">408</a></span>
<span class="normal"><a href="#__codelineno-0-409">409</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-383"><a id="__codelineno-0-383" name="__codelineno-0-383"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">open_document</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">path</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">DocumentInfo</span><span class="p">:</span>
</span><span id="__span-0-384"><a id="__codelineno-0-384" name="__codelineno-0-384"></a><span class="w"> </span><span class="sd">"""Open an existing document."""</span>
</span><span id="__span-0-385"><a id="__codelineno-0-385" name="__codelineno-0-385"></a> <span class="n">result</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">execute_python</span><span class="p">(</span>
</span><span id="__span-0-386"><a id="__codelineno-0-386" name="__codelineno-0-386"></a> <span class="sa">f</span><span class="s2">"""</span>
</span><span id="__span-0-387"><a id="__codelineno-0-387" name="__codelineno-0-387"></a><span class="s2">import os</span>
</span><span id="__span-0-388"><a id="__codelineno-0-388" name="__codelineno-0-388"></a><span class="s2">if not os.path.exists(</span><span class="si">{</span><span class="n">path</span><span class="si">!r}</span><span class="s2">):</span>
</span><span id="__span-0-389"><a id="__codelineno-0-389" name="__codelineno-0-389"></a><span class="s2"> raise FileNotFoundError(f"File not found: </span><span class="si">{</span><span class="n">path</span><span class="si">!r}</span><span class="s2">")</span>
</span><span id="__span-0-390"><a id="__codelineno-0-390" name="__codelineno-0-390"></a>
</span><span id="__span-0-391"><a id="__codelineno-0-391" name="__codelineno-0-391"></a><span class="s2">doc = FreeCAD.openDocument(</span><span class="si">{</span><span class="n">path</span><span class="si">!r}</span><span class="s2">)</span>
</span><span id="__span-0-392"><a id="__codelineno-0-392" name="__codelineno-0-392"></a><span class="s2">_result_ = </span><span class="se">{{</span>
</span><span id="__span-0-393"><a id="__codelineno-0-393" name="__codelineno-0-393"></a><span class="s2"> "name": doc.Name,</span>
</span><span id="__span-0-394"><a id="__codelineno-0-394" name="__codelineno-0-394"></a><span class="s2"> "label": doc.Label,</span>
</span><span id="__span-0-395"><a id="__codelineno-0-395" name="__codelineno-0-395"></a><span class="s2"> "path": doc.FileName or None,</span>
</span><span id="__span-0-396"><a id="__codelineno-0-396" name="__codelineno-0-396"></a><span class="s2"> "objects": [obj.Name for obj in doc.Objects],</span>
</span><span id="__span-0-397"><a id="__codelineno-0-397" name="__codelineno-0-397"></a><span class="s2"> "is_modified": doc.Modified if hasattr(doc, "Modified") else False,</span>
</span><span id="__span-0-398"><a id="__codelineno-0-398" name="__codelineno-0-398"></a><span class="se">}}</span>
</span><span id="__span-0-399"><a id="__codelineno-0-399" name="__codelineno-0-399"></a><span class="s2">"""</span>
</span><span id="__span-0-400"><a id="__codelineno-0-400" name="__codelineno-0-400"></a> <span class="p">)</span>
</span><span id="__span-0-401"><a id="__codelineno-0-401" name="__codelineno-0-401"></a>
</span><span id="__span-0-402"><a id="__codelineno-0-402" name="__codelineno-0-402"></a> <span class="k">if</span> <span class="n">result</span><span class="o">.</span><span class="n">success</span> <span class="ow">and</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">:</span>
</span><span id="__span-0-403"><a id="__codelineno-0-403" name="__codelineno-0-403"></a> <span class="k">return</span> <span class="n">DocumentInfo</span><span class="p">(</span><span class="o">**</span><span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">)</span>
</span><span id="__span-0-404"><a id="__codelineno-0-404" name="__codelineno-0-404"></a>
</span><span id="__span-0-405"><a id="__codelineno-0-405" name="__codelineno-0-405"></a> <span class="k">if</span> <span class="s2">"FileNotFoundError"</span> <span class="ow">in</span> <span class="p">(</span><span class="n">result</span><span class="o">.</span><span class="n">error_type</span> <span class="ow">or</span> <span class="s2">""</span><span class="p">):</span>
</span><span id="__span-0-406"><a id="__codelineno-0-406" name="__codelineno-0-406"></a> <span class="k">raise</span> <span class="ne">FileNotFoundError</span><span class="p">(</span><span class="n">result</span><span class="o">.</span><span class="n">stderr</span><span class="p">)</span>
</span><span id="__span-0-407"><a id="__codelineno-0-407" name="__codelineno-0-407"></a>
</span><span id="__span-0-408"><a id="__codelineno-0-408" name="__codelineno-0-408"></a> <span class="n">error_msg</span> <span class="o">=</span> <span class="n">result</span><span class="o">.</span><span class="n">error_traceback</span> <span class="ow">or</span> <span class="s2">"Failed to open document"</span>
</span><span id="__span-0-409"><a id="__codelineno-0-409" name="__codelineno-0-409"></a> <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="n">error_msg</span><span class="p">)</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> </div> </div> <div class="doc doc-object doc-function"> <h6 id="freecad_mcp.bridge.xmlrpc.XmlRpcBridge.ping" class="doc doc-heading"> <code class="highlight language-python"><span class="n">ping</span><span class="p">()</span></code> <span class="doc doc-labels"> <small class="doc doc-label doc-label-async"><code>async</code></small> </span> <a href="#freecad_mcp.bridge.xmlrpc.XmlRpcBridge.ping" class="headerlink" title="Permanent link">¶</a></h6> <div class="doc doc-contents "> <p>Ping FreeCAD to check connection and measure latency.</p> <p><span class="doc-section-title">Returns:</span></p> <table> <thead> <tr> <th>Type</th> <th>Description</th> </tr> </thead> <tbody> <tr class="doc-section-item"> <td> <code><span title="float">float</span></code> </td> <td> <div class="doc-md-description"> <p>Round-trip time in milliseconds.</p> </div> </td> </tr> </tbody> </table> <p><span class="doc-section-title">Raises:</span></p> <table> <thead> <tr> <th>Type</th> <th>Description</th> </tr> </thead> <tbody> <tr class="doc-section-item"> <td> <code><span title="ConnectionError">ConnectionError</span></code> </td> <td> <div class="doc-md-description"> <p>If not connected.</p> </div> </td> </tr> </tbody> </table> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/xmlrpc.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-157">157</a></span>
<span class="normal"><a href="#__codelineno-0-158">158</a></span>
<span class="normal"><a href="#__codelineno-0-159">159</a></span>
<span class="normal"><a href="#__codelineno-0-160">160</a></span>
<span class="normal"><a href="#__codelineno-0-161">161</a></span>
<span class="normal"><a href="#__codelineno-0-162">162</a></span>
<span class="normal"><a href="#__codelineno-0-163">163</a></span>
<span class="normal"><a href="#__codelineno-0-164">164</a></span>
<span class="normal"><a href="#__codelineno-0-165">165</a></span>
<span class="normal"><a href="#__codelineno-0-166">166</a></span>
<span class="normal"><a href="#__codelineno-0-167">167</a></span>
<span class="normal"><a href="#__codelineno-0-168">168</a></span>
<span class="normal"><a href="#__codelineno-0-169">169</a></span>
<span class="normal"><a href="#__codelineno-0-170">170</a></span>
<span class="normal"><a href="#__codelineno-0-171">171</a></span>
<span class="normal"><a href="#__codelineno-0-172">172</a></span>
<span class="normal"><a href="#__codelineno-0-173">173</a></span>
<span class="normal"><a href="#__codelineno-0-174">174</a></span>
<span class="normal"><a href="#__codelineno-0-175">175</a></span>
<span class="normal"><a href="#__codelineno-0-176">176</a></span>
<span class="normal"><a href="#__codelineno-0-177">177</a></span>
<span class="normal"><a href="#__codelineno-0-178">178</a></span>
<span class="normal"><a href="#__codelineno-0-179">179</a></span>
<span class="normal"><a href="#__codelineno-0-180">180</a></span>
<span class="normal"><a href="#__codelineno-0-181">181</a></span>
<span class="normal"><a href="#__codelineno-0-182">182</a></span>
<span class="normal"><a href="#__codelineno-0-183">183</a></span>
<span class="normal"><a href="#__codelineno-0-184">184</a></span>
<span class="normal"><a href="#__codelineno-0-185">185</a></span>
<span class="normal"><a href="#__codelineno-0-186">186</a></span>
<span class="normal"><a href="#__codelineno-0-187">187</a></span>
<span class="normal"><a href="#__codelineno-0-188">188</a></span>
<span class="normal"><a href="#__codelineno-0-189">189</a></span>
<span class="normal"><a href="#__codelineno-0-190">190</a></span>
<span class="normal"><a href="#__codelineno-0-191">191</a></span>
<span class="normal"><a href="#__codelineno-0-192">192</a></span>
<span class="normal"><a href="#__codelineno-0-193">193</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-157"><a id="__codelineno-0-157" name="__codelineno-0-157"></a><span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">ping</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">float</span><span class="p">:</span>
</span><span id="__span-0-158"><a id="__codelineno-0-158" name="__codelineno-0-158"></a><span class="w"> </span><span class="sd">"""Ping FreeCAD to check connection and measure latency.</span>
</span><span id="__span-0-159"><a id="__codelineno-0-159" name="__codelineno-0-159"></a>
</span><span id="__span-0-160"><a id="__codelineno-0-160" name="__codelineno-0-160"></a><span class="sd"> Returns:</span>
</span><span id="__span-0-161"><a id="__codelineno-0-161" name="__codelineno-0-161"></a><span class="sd"> Round-trip time in milliseconds.</span>
</span><span id="__span-0-162"><a id="__codelineno-0-162" name="__codelineno-0-162"></a>
</span><span id="__span-0-163"><a id="__codelineno-0-163" name="__codelineno-0-163"></a><span class="sd"> Raises:</span>
</span><span id="__span-0-164"><a id="__codelineno-0-164" name="__codelineno-0-164"></a><span class="sd"> ConnectionError: If not connected.</span>
</span><span id="__span-0-165"><a id="__codelineno-0-165" name="__codelineno-0-165"></a><span class="sd"> """</span>
</span><span id="__span-0-166"><a id="__codelineno-0-166" name="__codelineno-0-166"></a> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_proxy</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
</span><span id="__span-0-167"><a id="__codelineno-0-167" name="__codelineno-0-167"></a> <span class="n">msg</span> <span class="o">=</span> <span class="s2">"Not connected to XML-RPC server"</span>
</span><span id="__span-0-168"><a id="__codelineno-0-168" name="__codelineno-0-168"></a> <span class="k">raise</span> <span class="ne">ConnectionError</span><span class="p">(</span><span class="n">msg</span><span class="p">)</span>
</span><span id="__span-0-169"><a id="__codelineno-0-169" name="__codelineno-0-169"></a>
</span><span id="__span-0-170"><a id="__codelineno-0-170" name="__codelineno-0-170"></a> <span class="n">loop</span> <span class="o">=</span> <span class="n">asyncio</span><span class="o">.</span><span class="n">get_event_loop</span><span class="p">()</span>
</span><span id="__span-0-171"><a id="__codelineno-0-171" name="__codelineno-0-171"></a> <span class="n">start</span> <span class="o">=</span> <span class="n">time</span><span class="o">.</span><span class="n">perf_counter</span><span class="p">()</span>
</span><span id="__span-0-172"><a id="__codelineno-0-172" name="__codelineno-0-172"></a>
</span><span id="__span-0-173"><a id="__codelineno-0-173" name="__codelineno-0-173"></a> <span class="k">try</span><span class="p">:</span>
</span><span id="__span-0-174"><a id="__codelineno-0-174" name="__codelineno-0-174"></a> <span class="c1"># Try standard system.listMethods or a simple execute</span>
</span><span id="__span-0-175"><a id="__codelineno-0-175" name="__codelineno-0-175"></a> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_proxy</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
</span><span id="__span-0-176"><a id="__codelineno-0-176" name="__codelineno-0-176"></a> <span class="n">msg</span> <span class="o">=</span> <span class="s2">"Not connected"</span>
</span><span id="__span-0-177"><a id="__codelineno-0-177" name="__codelineno-0-177"></a> <span class="k">raise</span> <span class="ne">ConnectionError</span><span class="p">(</span><span class="n">msg</span><span class="p">)</span>
</span><span id="__span-0-178"><a id="__codelineno-0-178" name="__codelineno-0-178"></a> <span class="n">proxy</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_proxy</span> <span class="c1"># Local reference for lambda</span>
</span><span id="__span-0-179"><a id="__codelineno-0-179" name="__codelineno-0-179"></a> <span class="k">await</span> <span class="n">asyncio</span><span class="o">.</span><span class="n">wait_for</span><span class="p">(</span>
</span><span id="__span-0-180"><a id="__codelineno-0-180" name="__codelineno-0-180"></a> <span class="n">loop</span><span class="o">.</span><span class="n">run_in_executor</span><span class="p">(</span>
</span><span id="__span-0-181"><a id="__codelineno-0-181" name="__codelineno-0-181"></a> <span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-182"><a id="__codelineno-0-182" name="__codelineno-0-182"></a> <span class="k">lambda</span><span class="p">:</span> <span class="n">proxy</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s2">"_result_ = True"</span><span class="p">),</span>
</span><span id="__span-0-183"><a id="__codelineno-0-183" name="__codelineno-0-183"></a> <span class="p">),</span>
</span><span id="__span-0-184"><a id="__codelineno-0-184" name="__codelineno-0-184"></a> <span class="n">timeout</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">_timeout</span><span class="p">,</span>
</span><span id="__span-0-185"><a id="__codelineno-0-185" name="__codelineno-0-185"></a> <span class="p">)</span>
</span><span id="__span-0-186"><a id="__codelineno-0-186" name="__codelineno-0-186"></a> <span class="k">except</span> <span class="ne">TimeoutError</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
</span><span id="__span-0-187"><a id="__codelineno-0-187" name="__codelineno-0-187"></a> <span class="n">msg</span> <span class="o">=</span> <span class="s2">"Ping timed out"</span>
</span><span id="__span-0-188"><a id="__codelineno-0-188" name="__codelineno-0-188"></a> <span class="k">raise</span> <span class="ne">ConnectionError</span><span class="p">(</span><span class="n">msg</span><span class="p">)</span> <span class="kn">from</span><span class="w"> </span><span class="nn">e</span>
</span><span id="__span-0-189"><a id="__codelineno-0-189" name="__codelineno-0-189"></a> <span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
</span><span id="__span-0-190"><a id="__codelineno-0-190" name="__codelineno-0-190"></a> <span class="n">msg</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">"Ping failed: </span><span class="si">{</span><span class="n">e</span><span class="si">}</span><span class="s2">"</span>
</span><span id="__span-0-191"><a id="__codelineno-0-191" name="__codelineno-0-191"></a> <span class="k">raise</span> <span class="ne">ConnectionError</span><span class="p">(</span><span class="n">msg</span><span class="p">)</span> <span class="kn">from</span><span class="w"> </span><span class="nn">e</span>
</span><span id="__span-0-192"><a id="__codelineno-0-192" name="__codelineno-0-192"></a>
</span><span id="__span-0-193"><a id="__codelineno-0-193" name="__codelineno-0-193"></a> <span class="k">return</span> <span class="p">(</span><span class="n">time</span><span class="o">.</span><span class="n">perf_counter</span><span class="p">()</span> <span class="o">-</span> <span class="n">start</span><span class="p">)</span> <span class="o">*</span> <span class="mi">1000</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> </div> </div> <div class="doc doc-object doc-function"> <h6 id="freecad_mcp.bridge.xmlrpc.XmlRpcBridge.run_macro" class="doc doc-heading"> <code class="highlight language-python"><span class="n">run_macro</span><span class="p">(</span><span class="n">macro_name</span><span class="p">,</span> <span class="n">args</span><span class="o">=</span><span class="kc">None</span><span class="p">)</span></code> <span class="doc doc-labels"> <small class="doc doc-label doc-label-async"><code>async</code></small> </span> <a href="#freecad_mcp.bridge.xmlrpc.XmlRpcBridge.run_macro" class="headerlink" title="Permanent link">¶</a></h6> <div class="doc doc-contents "> <p>Run a macro by name.</p> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/xmlrpc.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-840">840</a></span>
<span class="normal"><a href="#__codelineno-0-841">841</a></span>
<span class="normal"><a href="#__codelineno-0-842">842</a></span>
<span class="normal"><a href="#__codelineno-0-843">843</a></span>
<span class="normal"><a href="#__codelineno-0-844">844</a></span>
<span class="normal"><a href="#__codelineno-0-845">845</a></span>
<span class="normal"><a href="#__codelineno-0-846">846</a></span>
<span class="normal"><a href="#__codelineno-0-847">847</a></span>
<span class="normal"><a href="#__codelineno-0-848">848</a></span>
<span class="normal"><a href="#__codelineno-0-849">849</a></span>
<span class="normal"><a href="#__codelineno-0-850">850</a></span>
<span class="normal"><a href="#__codelineno-0-851">851</a></span>
<span class="normal"><a href="#__codelineno-0-852">852</a></span>
<span class="normal"><a href="#__codelineno-0-853">853</a></span>
<span class="normal"><a href="#__codelineno-0-854">854</a></span>
<span class="normal"><a href="#__codelineno-0-855">855</a></span>
<span class="normal"><a href="#__codelineno-0-856">856</a></span>
<span class="normal"><a href="#__codelineno-0-857">857</a></span>
<span class="normal"><a href="#__codelineno-0-858">858</a></span>
<span class="normal"><a href="#__codelineno-0-859">859</a></span>
<span class="normal"><a href="#__codelineno-0-860">860</a></span>
<span class="normal"><a href="#__codelineno-0-861">861</a></span>
<span class="normal"><a href="#__codelineno-0-862">862</a></span>
<span class="normal"><a href="#__codelineno-0-863">863</a></span>
<span class="normal"><a href="#__codelineno-0-864">864</a></span>
<span class="normal"><a href="#__codelineno-0-865">865</a></span>
<span class="normal"><a href="#__codelineno-0-866">866</a></span>
<span class="normal"><a href="#__codelineno-0-867">867</a></span>
<span class="normal"><a href="#__codelineno-0-868">868</a></span>
<span class="normal"><a href="#__codelineno-0-869">869</a></span>
<span class="normal"><a href="#__codelineno-0-870">870</a></span>
<span class="normal"><a href="#__codelineno-0-871">871</a></span>
<span class="normal"><a href="#__codelineno-0-872">872</a></span>
<span class="normal"><a href="#__codelineno-0-873">873</a></span>
<span class="normal"><a href="#__codelineno-0-874">874</a></span>
<span class="normal"><a href="#__codelineno-0-875">875</a></span>
<span class="normal"><a href="#__codelineno-0-876">876</a></span>
<span class="normal"><a href="#__codelineno-0-877">877</a></span>
<span class="normal"><a href="#__codelineno-0-878">878</a></span>
<span class="normal"><a href="#__codelineno-0-879">879</a></span>
<span class="normal"><a href="#__codelineno-0-880">880</a></span>
<span class="normal"><a href="#__codelineno-0-881">881</a></span>
<span class="normal"><a href="#__codelineno-0-882">882</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-840"><a id="__codelineno-0-840" name="__codelineno-0-840"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">run_macro</span><span class="p">(</span>
</span><span id="__span-0-841"><a id="__codelineno-0-841" name="__codelineno-0-841"></a> <span class="bp">self</span><span class="p">,</span>
</span><span id="__span-0-842"><a id="__codelineno-0-842" name="__codelineno-0-842"></a> <span class="n">macro_name</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span>
</span><span id="__span-0-843"><a id="__codelineno-0-843" name="__codelineno-0-843"></a> <span class="n">args</span><span class="p">:</span> <span class="nb">dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Any</span><span class="p">]</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-844"><a id="__codelineno-0-844" name="__codelineno-0-844"></a> <span class="p">)</span> <span class="o">-&gt;</span> <span class="n">ExecutionResult</span><span class="p">:</span>
</span><span id="__span-0-845"><a id="__codelineno-0-845" name="__codelineno-0-845"></a><span class="w"> </span><span class="sd">"""Run a macro by name."""</span>
</span><span id="__span-0-846"><a id="__codelineno-0-846" name="__codelineno-0-846"></a> <span class="n">args</span> <span class="o">=</span> <span class="n">args</span> <span class="ow">or</span> <span class="p">{}</span>
</span><span id="__span-0-847"><a id="__codelineno-0-847" name="__codelineno-0-847"></a> <span class="n">code</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">"""</span>
</span><span id="__span-0-848"><a id="__codelineno-0-848" name="__codelineno-0-848"></a><span class="s2">import os</span>
</span><span id="__span-0-849"><a id="__codelineno-0-849" name="__codelineno-0-849"></a>
</span><span id="__span-0-850"><a id="__codelineno-0-850" name="__codelineno-0-850"></a><span class="s2"># Find macro file</span>
</span><span id="__span-0-851"><a id="__codelineno-0-851" name="__codelineno-0-851"></a><span class="s2">macro_name = </span><span class="si">{</span><span class="n">macro_name</span><span class="si">!r}</span>
</span><span id="__span-0-852"><a id="__codelineno-0-852" name="__codelineno-0-852"></a><span class="s2">macro_file = None</span>
</span><span id="__span-0-853"><a id="__codelineno-0-853" name="__codelineno-0-853"></a>
</span><span id="__span-0-854"><a id="__codelineno-0-854" name="__codelineno-0-854"></a><span class="s2"># Check user macros first</span>
</span><span id="__span-0-855"><a id="__codelineno-0-855" name="__codelineno-0-855"></a><span class="s2">user_path = FreeCAD.getUserMacroDir(True)</span>
</span><span id="__span-0-856"><a id="__codelineno-0-856" name="__codelineno-0-856"></a><span class="s2">user_macro = os.path.join(user_path, macro_name + ".FCMacro")</span>
</span><span id="__span-0-857"><a id="__codelineno-0-857" name="__codelineno-0-857"></a><span class="s2">if os.path.exists(user_macro):</span>
</span><span id="__span-0-858"><a id="__codelineno-0-858" name="__codelineno-0-858"></a><span class="s2"> macro_file = user_macro</span>
</span><span id="__span-0-859"><a id="__codelineno-0-859" name="__codelineno-0-859"></a>
</span><span id="__span-0-860"><a id="__codelineno-0-860" name="__codelineno-0-860"></a><span class="s2"># Check system macros</span>
</span><span id="__span-0-861"><a id="__codelineno-0-861" name="__codelineno-0-861"></a><span class="s2">if not macro_file:</span>
</span><span id="__span-0-862"><a id="__codelineno-0-862" name="__codelineno-0-862"></a><span class="s2"> system_path = FreeCAD.getResourceDir() + "Macro"</span>
</span><span id="__span-0-863"><a id="__codelineno-0-863" name="__codelineno-0-863"></a><span class="s2"> system_macro = os.path.join(system_path, macro_name + ".FCMacro")</span>
</span><span id="__span-0-864"><a id="__codelineno-0-864" name="__codelineno-0-864"></a><span class="s2"> if os.path.exists(system_macro):</span>
</span><span id="__span-0-865"><a id="__codelineno-0-865" name="__codelineno-0-865"></a><span class="s2"> macro_file = system_macro</span>
</span><span id="__span-0-866"><a id="__codelineno-0-866" name="__codelineno-0-866"></a>
</span><span id="__span-0-867"><a id="__codelineno-0-867" name="__codelineno-0-867"></a><span class="s2">if not macro_file:</span>
</span><span id="__span-0-868"><a id="__codelineno-0-868" name="__codelineno-0-868"></a><span class="s2"> raise FileNotFoundError(f"Macro not found: </span><span class="se">{{</span><span class="s2">macro_name</span><span class="se">}}</span><span class="s2">")</span>
</span><span id="__span-0-869"><a id="__codelineno-0-869" name="__codelineno-0-869"></a>
</span><span id="__span-0-870"><a id="__codelineno-0-870" name="__codelineno-0-870"></a><span class="s2"># Set up arguments</span>
</span><span id="__span-0-871"><a id="__codelineno-0-871" name="__codelineno-0-871"></a><span class="s2">args = </span><span class="si">{</span><span class="n">args</span><span class="si">!r}</span>
</span><span id="__span-0-872"><a id="__codelineno-0-872" name="__codelineno-0-872"></a><span class="s2">for k, v in args.items():</span>
</span><span id="__span-0-873"><a id="__codelineno-0-873" name="__codelineno-0-873"></a><span class="s2"> exec(f"</span><span class="se">{{</span><span class="s2">k</span><span class="se">}}</span><span class="s2"> = </span><span class="se">{{</span><span class="s2">v!r</span><span class="se">}}</span><span class="s2">")</span>
</span><span id="__span-0-874"><a id="__codelineno-0-874" name="__codelineno-0-874"></a>
</span><span id="__span-0-875"><a id="__codelineno-0-875" name="__codelineno-0-875"></a><span class="s2"># Execute macro</span>
</span><span id="__span-0-876"><a id="__codelineno-0-876" name="__codelineno-0-876"></a><span class="s2">with open(macro_file, "r") as f:</span>
</span><span id="__span-0-877"><a id="__codelineno-0-877" name="__codelineno-0-877"></a><span class="s2"> macro_code = f.read()</span>
</span><span id="__span-0-878"><a id="__codelineno-0-878" name="__codelineno-0-878"></a>
</span><span id="__span-0-879"><a id="__codelineno-0-879" name="__codelineno-0-879"></a><span class="s2">exec(macro_code)</span>
</span><span id="__span-0-880"><a id="__codelineno-0-880" name="__codelineno-0-880"></a><span class="s2">_result_ = True</span>
</span><span id="__span-0-881"><a id="__codelineno-0-881" name="__codelineno-0-881"></a><span class="s2">"""</span>
</span><span id="__span-0-882"><a id="__codelineno-0-882" name="__codelineno-0-882"></a> <span class="k">return</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">execute_python</span><span class="p">(</span><span class="n">code</span><span class="p">)</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> </div> </div> <div class="doc doc-object doc-function"> <h6 id="freecad_mcp.bridge.xmlrpc.XmlRpcBridge.save_document" class="doc doc-heading"> <code class="highlight language-python"><span class="n">save_document</span><span class="p">(</span><span class="n">doc_name</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">path</span><span class="o">=</span><span class="kc">None</span><span class="p">)</span></code> <span class="doc doc-labels"> <small class="doc doc-label doc-label-async"><code>async</code></small> </span> <a href="#freecad_mcp.bridge.xmlrpc.XmlRpcBridge.save_document" class="headerlink" title="Permanent link">¶</a></h6> <div class="doc doc-contents "> <p>Save a document.</p> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/xmlrpc.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-411">411</a></span>
<span class="normal"><a href="#__codelineno-0-412">412</a></span>
<span class="normal"><a href="#__codelineno-0-413">413</a></span>
<span class="normal"><a href="#__codelineno-0-414">414</a></span>
<span class="normal"><a href="#__codelineno-0-415">415</a></span>
<span class="normal"><a href="#__codelineno-0-416">416</a></span>
<span class="normal"><a href="#__codelineno-0-417">417</a></span>
<span class="normal"><a href="#__codelineno-0-418">418</a></span>
<span class="normal"><a href="#__codelineno-0-419">419</a></span>
<span class="normal"><a href="#__codelineno-0-420">420</a></span>
<span class="normal"><a href="#__codelineno-0-421">421</a></span>
<span class="normal"><a href="#__codelineno-0-422">422</a></span>
<span class="normal"><a href="#__codelineno-0-423">423</a></span>
<span class="normal"><a href="#__codelineno-0-424">424</a></span>
<span class="normal"><a href="#__codelineno-0-425">425</a></span>
<span class="normal"><a href="#__codelineno-0-426">426</a></span>
<span class="normal"><a href="#__codelineno-0-427">427</a></span>
<span class="normal"><a href="#__codelineno-0-428">428</a></span>
<span class="normal"><a href="#__codelineno-0-429">429</a></span>
<span class="normal"><a href="#__codelineno-0-430">430</a></span>
<span class="normal"><a href="#__codelineno-0-431">431</a></span>
<span class="normal"><a href="#__codelineno-0-432">432</a></span>
<span class="normal"><a href="#__codelineno-0-433">433</a></span>
<span class="normal"><a href="#__codelineno-0-434">434</a></span>
<span class="normal"><a href="#__codelineno-0-435">435</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-411"><a id="__codelineno-0-411" name="__codelineno-0-411"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">save_document</span><span class="p">(</span>
</span><span id="__span-0-412"><a id="__codelineno-0-412" name="__codelineno-0-412"></a> <span class="bp">self</span><span class="p">,</span>
</span><span id="__span-0-413"><a id="__codelineno-0-413" name="__codelineno-0-413"></a> <span class="n">doc_name</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-414"><a id="__codelineno-0-414" name="__codelineno-0-414"></a> <span class="n">path</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-415"><a id="__codelineno-0-415" name="__codelineno-0-415"></a> <span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">str</span><span class="p">:</span>
</span><span id="__span-0-416"><a id="__codelineno-0-416" name="__codelineno-0-416"></a><span class="w"> </span><span class="sd">"""Save a document."""</span>
</span><span id="__span-0-417"><a id="__codelineno-0-417" name="__codelineno-0-417"></a> <span class="n">code</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">"""</span>
</span><span id="__span-0-418"><a id="__codelineno-0-418" name="__codelineno-0-418"></a><span class="s2">doc = FreeCAD.ActiveDocument if </span><span class="si">{</span><span class="n">doc_name</span><span class="si">!r}</span><span class="s2"> is None else FreeCAD.getDocument(</span><span class="si">{</span><span class="n">doc_name</span><span class="si">!r}</span><span class="s2">)</span>
</span><span id="__span-0-419"><a id="__codelineno-0-419" name="__codelineno-0-419"></a><span class="s2">if doc is None:</span>
</span><span id="__span-0-420"><a id="__codelineno-0-420" name="__codelineno-0-420"></a><span class="s2"> raise ValueError("No active document" if </span><span class="si">{</span><span class="n">doc_name</span><span class="si">!r}</span><span class="s2"> is None else f"Document not found: </span><span class="si">{</span><span class="n">doc_name</span><span class="si">!r}</span><span class="s2">")</span>
</span><span id="__span-0-421"><a id="__codelineno-0-421" name="__codelineno-0-421"></a>
</span><span id="__span-0-422"><a id="__codelineno-0-422" name="__codelineno-0-422"></a><span class="s2">save_path = </span><span class="si">{</span><span class="n">path</span><span class="si">!r}</span><span class="s2"> or doc.FileName</span>
</span><span id="__span-0-423"><a id="__codelineno-0-423" name="__codelineno-0-423"></a><span class="s2">if not save_path:</span>
</span><span id="__span-0-424"><a id="__codelineno-0-424" name="__codelineno-0-424"></a><span class="s2"> raise ValueError("No path specified for new document")</span>
</span><span id="__span-0-425"><a id="__codelineno-0-425" name="__codelineno-0-425"></a>
</span><span id="__span-0-426"><a id="__codelineno-0-426" name="__codelineno-0-426"></a><span class="s2">doc.saveAs(save_path)</span>
</span><span id="__span-0-427"><a id="__codelineno-0-427" name="__codelineno-0-427"></a><span class="s2">_result_ = save_path</span>
</span><span id="__span-0-428"><a id="__codelineno-0-428" name="__codelineno-0-428"></a><span class="s2">"""</span>
</span><span id="__span-0-429"><a id="__codelineno-0-429" name="__codelineno-0-429"></a> <span class="n">result</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">execute_python</span><span class="p">(</span><span class="n">code</span><span class="p">)</span>
</span><span id="__span-0-430"><a id="__codelineno-0-430" name="__codelineno-0-430"></a>
</span><span id="__span-0-431"><a id="__codelineno-0-431" name="__codelineno-0-431"></a> <span class="k">if</span> <span class="n">result</span><span class="o">.</span><span class="n">success</span> <span class="ow">and</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">:</span>
</span><span id="__span-0-432"><a id="__codelineno-0-432" name="__codelineno-0-432"></a> <span class="k">return</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span>
</span><span id="__span-0-433"><a id="__codelineno-0-433" name="__codelineno-0-433"></a>
</span><span id="__span-0-434"><a id="__codelineno-0-434" name="__codelineno-0-434"></a> <span class="n">error_msg</span> <span class="o">=</span> <span class="n">result</span><span class="o">.</span><span class="n">error_traceback</span> <span class="ow">or</span> <span class="s2">"Failed to save document"</span>
</span><span id="__span-0-435"><a id="__codelineno-0-435" name="__codelineno-0-435"></a> <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="n">error_msg</span><span class="p">)</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> </div> </div> <div class="doc doc-object doc-function"> <h6 id="freecad_mcp.bridge.xmlrpc.XmlRpcBridge.set_view" class="doc doc-heading"> <code class="highlight language-python"><span class="n">set_view</span><span class="p">(</span><span class="n">view_angle</span><span class="p">,</span> <span class="n">doc_name</span><span class="o">=</span><span class="kc">None</span><span class="p">)</span></code> <span class="doc doc-labels"> <small class="doc doc-label doc-label-async"><code>async</code></small> </span> <a href="#freecad_mcp.bridge.xmlrpc.XmlRpcBridge.set_view" class="headerlink" title="Permanent link">¶</a></h6> <div class="doc doc-contents "> <p>Set the 3D view angle.</p> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/xmlrpc.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-745">745</a></span>
<span class="normal"><a href="#__codelineno-0-746">746</a></span>
<span class="normal"><a href="#__codelineno-0-747">747</a></span>
<span class="normal"><a href="#__codelineno-0-748">748</a></span>
<span class="normal"><a href="#__codelineno-0-749">749</a></span>
<span class="normal"><a href="#__codelineno-0-750">750</a></span>
<span class="normal"><a href="#__codelineno-0-751">751</a></span>
<span class="normal"><a href="#__codelineno-0-752">752</a></span>
<span class="normal"><a href="#__codelineno-0-753">753</a></span>
<span class="normal"><a href="#__codelineno-0-754">754</a></span>
<span class="normal"><a href="#__codelineno-0-755">755</a></span>
<span class="normal"><a href="#__codelineno-0-756">756</a></span>
<span class="normal"><a href="#__codelineno-0-757">757</a></span>
<span class="normal"><a href="#__codelineno-0-758">758</a></span>
<span class="normal"><a href="#__codelineno-0-759">759</a></span>
<span class="normal"><a href="#__codelineno-0-760">760</a></span>
<span class="normal"><a href="#__codelineno-0-761">761</a></span>
<span class="normal"><a href="#__codelineno-0-762">762</a></span>
<span class="normal"><a href="#__codelineno-0-763">763</a></span>
<span class="normal"><a href="#__codelineno-0-764">764</a></span>
<span class="normal"><a href="#__codelineno-0-765">765</a></span>
<span class="normal"><a href="#__codelineno-0-766">766</a></span>
<span class="normal"><a href="#__codelineno-0-767">767</a></span>
<span class="normal"><a href="#__codelineno-0-768">768</a></span>
<span class="normal"><a href="#__codelineno-0-769">769</a></span>
<span class="normal"><a href="#__codelineno-0-770">770</a></span>
<span class="normal"><a href="#__codelineno-0-771">771</a></span>
<span class="normal"><a href="#__codelineno-0-772">772</a></span>
<span class="normal"><a href="#__codelineno-0-773">773</a></span>
<span class="normal"><a href="#__codelineno-0-774">774</a></span>
<span class="normal"><a href="#__codelineno-0-775">775</a></span>
<span class="normal"><a href="#__codelineno-0-776">776</a></span>
<span class="normal"><a href="#__codelineno-0-777">777</a></span>
<span class="normal"><a href="#__codelineno-0-778">778</a></span>
<span class="normal"><a href="#__codelineno-0-779">779</a></span>
<span class="normal"><a href="#__codelineno-0-780">780</a></span>
<span class="normal"><a href="#__codelineno-0-781">781</a></span>
<span class="normal"><a href="#__codelineno-0-782">782</a></span>
<span class="normal"><a href="#__codelineno-0-783">783</a></span>
<span class="normal"><a href="#__codelineno-0-784">784</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-745"><a id="__codelineno-0-745" name="__codelineno-0-745"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">set_view</span><span class="p">(</span>
</span><span id="__span-0-746"><a id="__codelineno-0-746" name="__codelineno-0-746"></a> <span class="bp">self</span><span class="p">,</span>
</span><span id="__span-0-747"><a id="__codelineno-0-747" name="__codelineno-0-747"></a> <span class="n">view_angle</span><span class="p">:</span> <span class="n">ViewAngle</span><span class="p">,</span>
</span><span id="__span-0-748"><a id="__codelineno-0-748" name="__codelineno-0-748"></a> <span class="n">doc_name</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-749"><a id="__codelineno-0-749" name="__codelineno-0-749"></a> <span class="p">)</span> <span class="o">-&gt;</span> <span class="kc">None</span><span class="p">:</span>
</span><span id="__span-0-750"><a id="__codelineno-0-750" name="__codelineno-0-750"></a><span class="w"> </span><span class="sd">"""Set the 3D view angle."""</span>
</span><span id="__span-0-751"><a id="__codelineno-0-751" name="__codelineno-0-751"></a> <span class="n">view_angle_str</span> <span class="o">=</span> <span class="n">view_angle</span><span class="o">.</span><span class="n">value</span>
</span><span id="__span-0-752"><a id="__codelineno-0-752" name="__codelineno-0-752"></a> <span class="n">code</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">"""</span>
</span><span id="__span-0-753"><a id="__codelineno-0-753" name="__codelineno-0-753"></a><span class="s2">doc = FreeCAD.ActiveDocument if </span><span class="si">{</span><span class="n">doc_name</span><span class="si">!r}</span><span class="s2"> is None else FreeCAD.getDocument(</span><span class="si">{</span><span class="n">doc_name</span><span class="si">!r}</span><span class="s2">)</span>
</span><span id="__span-0-754"><a id="__codelineno-0-754" name="__codelineno-0-754"></a><span class="s2">if doc is None:</span>
</span><span id="__span-0-755"><a id="__codelineno-0-755" name="__codelineno-0-755"></a><span class="s2"> raise ValueError("No document found")</span>
</span><span id="__span-0-756"><a id="__codelineno-0-756" name="__codelineno-0-756"></a>
</span><span id="__span-0-757"><a id="__codelineno-0-757" name="__codelineno-0-757"></a><span class="s2">if not FreeCAD.GuiUp:</span>
</span><span id="__span-0-758"><a id="__codelineno-0-758" name="__codelineno-0-758"></a><span class="s2"> _result_ = True # Silently succeed in headless mode</span>
</span><span id="__span-0-759"><a id="__codelineno-0-759" name="__codelineno-0-759"></a><span class="s2">else:</span>
</span><span id="__span-0-760"><a id="__codelineno-0-760" name="__codelineno-0-760"></a><span class="s2"> view = FreeCADGui.ActiveDocument.ActiveView</span>
</span><span id="__span-0-761"><a id="__codelineno-0-761" name="__codelineno-0-761"></a><span class="s2"> if view is None:</span>
</span><span id="__span-0-762"><a id="__codelineno-0-762" name="__codelineno-0-762"></a><span class="s2"> raise ValueError("No active view")</span>
</span><span id="__span-0-763"><a id="__codelineno-0-763" name="__codelineno-0-763"></a>
</span><span id="__span-0-764"><a id="__codelineno-0-764" name="__codelineno-0-764"></a><span class="s2"> view_type = </span><span class="si">{</span><span class="n">view_angle_str</span><span class="si">!r}</span>
</span><span id="__span-0-765"><a id="__codelineno-0-765" name="__codelineno-0-765"></a><span class="s2"> if view_type == "FitAll":</span>
</span><span id="__span-0-766"><a id="__codelineno-0-766" name="__codelineno-0-766"></a><span class="s2"> view.fitAll()</span>
</span><span id="__span-0-767"><a id="__codelineno-0-767" name="__codelineno-0-767"></a><span class="s2"> elif view_type == "Isometric":</span>
</span><span id="__span-0-768"><a id="__codelineno-0-768" name="__codelineno-0-768"></a><span class="s2"> view.viewIsometric()</span>
</span><span id="__span-0-769"><a id="__codelineno-0-769" name="__codelineno-0-769"></a><span class="s2"> elif view_type == "Front":</span>
</span><span id="__span-0-770"><a id="__codelineno-0-770" name="__codelineno-0-770"></a><span class="s2"> view.viewFront()</span>
</span><span id="__span-0-771"><a id="__codelineno-0-771" name="__codelineno-0-771"></a><span class="s2"> elif view_type == "Back":</span>
</span><span id="__span-0-772"><a id="__codelineno-0-772" name="__codelineno-0-772"></a><span class="s2"> view.viewRear()</span>
</span><span id="__span-0-773"><a id="__codelineno-0-773" name="__codelineno-0-773"></a><span class="s2"> elif view_type == "Top":</span>
</span><span id="__span-0-774"><a id="__codelineno-0-774" name="__codelineno-0-774"></a><span class="s2"> view.viewTop()</span>
</span><span id="__span-0-775"><a id="__codelineno-0-775" name="__codelineno-0-775"></a><span class="s2"> elif view_type == "Bottom":</span>
</span><span id="__span-0-776"><a id="__codelineno-0-776" name="__codelineno-0-776"></a><span class="s2"> view.viewBottom()</span>
</span><span id="__span-0-777"><a id="__codelineno-0-777" name="__codelineno-0-777"></a><span class="s2"> elif view_type == "Left":</span>
</span><span id="__span-0-778"><a id="__codelineno-0-778" name="__codelineno-0-778"></a><span class="s2"> view.viewLeft()</span>
</span><span id="__span-0-779"><a id="__codelineno-0-779" name="__codelineno-0-779"></a><span class="s2"> elif view_type == "Right":</span>
</span><span id="__span-0-780"><a id="__codelineno-0-780" name="__codelineno-0-780"></a><span class="s2"> view.viewRight()</span>
</span><span id="__span-0-781"><a id="__codelineno-0-781" name="__codelineno-0-781"></a>
</span><span id="__span-0-782"><a id="__codelineno-0-782" name="__codelineno-0-782"></a><span class="s2"> _result_ = True</span>
</span><span id="__span-0-783"><a id="__codelineno-0-783" name="__codelineno-0-783"></a><span class="s2">"""</span>
</span><span id="__span-0-784"><a id="__codelineno-0-784" name="__codelineno-0-784"></a> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">execute_python</span><span class="p">(</span><span class="n">code</span><span class="p">)</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> </div> </div> </div> </div> </div> </div> </div> </div><p>options: show_root_heading: true show_source: true</p> <h2 id="socket-bridge">Socket Bridge<a class="headerlink" href="#socket-bridge" title="Permanent link">¶</a></h2> <div class="doc doc-object doc-module"> <h2 id="freecad_mcp.bridge.socket" class="doc doc-heading"> <code>freecad_mcp.bridge.socket</code> <a href="#freecad_mcp.bridge.socket" class="headerlink" title="Permanent link">¶</a></h2> <div class="doc doc-contents first"> <p>Socket bridge for FreeCAD communication via JSON-RPC.</p> <p>This bridge communicates with FreeCAD using JSON-RPC over TCP sockets, providing a modern, lightweight alternative to XML-RPC.</p> <p>Based on learnings from competitive analysis: - Simple socket-based approach (inspired by bonninr/freecad_mcp) - Connection recovery mechanisms (from jango-blockchained) - Automatic reconnection on connection loss</p> <div class="doc doc-children"> <h3 id="freecad_mcp.bridge.socket-classes">Classes<a href="#freecad_mcp.bridge.socket-classes" class="headerlink" title="Permanent link">¶</a></h3> <div class="doc doc-object doc-class"> <h4 id="freecad_mcp.bridge.socket.JsonRpcError" class="doc doc-heading"> <code>JsonRpcError</code> <a href="#freecad_mcp.bridge.socket.JsonRpcError" class="headerlink" title="Permanent link">¶</a></h4> <div class="doc doc-contents "> <p class="doc doc-class-bases"> Bases: <code><span title="Exception">Exception</span></code></p> <p>JSON-RPC error response.</p> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/socket.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-36">36</a></span>
<span class="normal"><a href="#__codelineno-0-37">37</a></span>
<span class="normal"><a href="#__codelineno-0-38">38</a></span>
<span class="normal"><a href="#__codelineno-0-39">39</a></span>
<span class="normal"><a href="#__codelineno-0-40">40</a></span>
<span class="normal"><a href="#__codelineno-0-41">41</a></span>
<span class="normal"><a href="#__codelineno-0-42">42</a></span>
<span class="normal"><a href="#__codelineno-0-43">43</a></span>
<span class="normal"><a href="#__codelineno-0-44">44</a></span>
<span class="normal"><a href="#__codelineno-0-45">45</a></span>
<span class="normal"><a href="#__codelineno-0-46">46</a></span>
<span class="normal"><a href="#__codelineno-0-47">47</a></span>
<span class="normal"><a href="#__codelineno-0-48">48</a></span>
<span class="normal"><a href="#__codelineno-0-49">49</a></span>
<span class="normal"><a href="#__codelineno-0-50">50</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-36"><a id="__codelineno-0-36" name="__codelineno-0-36"></a><span class="k">class</span><span class="w"> </span><span class="nc">JsonRpcError</span><span class="p">(</span><span class="ne">Exception</span><span class="p">):</span>
</span><span id="__span-0-37"><a id="__codelineno-0-37" name="__codelineno-0-37"></a><span class="w"> </span><span class="sd">"""JSON-RPC error response."""</span>
</span><span id="__span-0-38"><a id="__codelineno-0-38" name="__codelineno-0-38"></a>
</span><span id="__span-0-39"><a id="__codelineno-0-39" name="__codelineno-0-39"></a> <span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">code</span><span class="p">:</span> <span class="nb">int</span><span class="p">,</span> <span class="n">message</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">data</span><span class="p">:</span> <span class="n">Any</span> <span class="o">=</span> <span class="kc">None</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kc">None</span><span class="p">:</span>
</span><span id="__span-0-40"><a id="__codelineno-0-40" name="__codelineno-0-40"></a><span class="w"> </span><span class="sd">"""Initialize JSON-RPC error.</span>
</span><span id="__span-0-41"><a id="__codelineno-0-41" name="__codelineno-0-41"></a>
</span><span id="__span-0-42"><a id="__codelineno-0-42" name="__codelineno-0-42"></a><span class="sd"> Args:</span>
</span><span id="__span-0-43"><a id="__codelineno-0-43" name="__codelineno-0-43"></a><span class="sd"> code: Error code.</span>
</span><span id="__span-0-44"><a id="__codelineno-0-44" name="__codelineno-0-44"></a><span class="sd"> message: Error message.</span>
</span><span id="__span-0-45"><a id="__codelineno-0-45" name="__codelineno-0-45"></a><span class="sd"> data: Additional error data.</span>
</span><span id="__span-0-46"><a id="__codelineno-0-46" name="__codelineno-0-46"></a><span class="sd"> """</span>
</span><span id="__span-0-47"><a id="__codelineno-0-47" name="__codelineno-0-47"></a> <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="n">message</span><span class="p">)</span>
</span><span id="__span-0-48"><a id="__codelineno-0-48" name="__codelineno-0-48"></a> <span class="bp">self</span><span class="o">.</span><span class="n">code</span> <span class="o">=</span> <span class="n">code</span>
</span><span id="__span-0-49"><a id="__codelineno-0-49" name="__codelineno-0-49"></a> <span class="bp">self</span><span class="o">.</span><span class="n">message</span> <span class="o">=</span> <span class="n">message</span>
</span><span id="__span-0-50"><a id="__codelineno-0-50" name="__codelineno-0-50"></a> <span class="bp">self</span><span class="o">.</span><span class="n">data</span> <span class="o">=</span> <span class="n">data</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> <div class="doc doc-children"> <h5 id="freecad_mcp.bridge.socket.JsonRpcError-functions">Functions<a href="#freecad_mcp.bridge.socket.JsonRpcError-functions" class="headerlink" title="Permanent link">¶</a></h5> <div class="doc doc-object doc-function"> <h6 id="freecad_mcp.bridge.socket.JsonRpcError.__init__" class="doc doc-heading"> <code class="highlight language-python"><span class="fm">__init__</span><span class="p">(</span><span class="n">code</span><span class="p">,</span> <span class="n">message</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="kc">None</span><span class="p">)</span></code> <a href="#freecad_mcp.bridge.socket.JsonRpcError.__init__" class="headerlink" title="Permanent link">¶</a></h6> <div class="doc doc-contents "> <p>Initialize JSON-RPC error.</p> <p><span class="doc-section-title">Parameters:</span></p> <table> <thead> <tr> <th>Name</th> <th>Type</th> <th>Description</th> <th>Default</th> </tr> </thead> <tbody> <tr class="doc-section-item"> <td> <code>code</code> </td> <td> <code><span title="int">int</span></code> </td> <td> <div class="doc-md-description"> <p>Error code.</p> </div> </td> <td> <em>required</em> </td> </tr> <tr class="doc-section-item"> <td> <code>message</code> </td> <td> <code><span title="str">str</span></code> </td> <td> <div class="doc-md-description"> <p>Error message.</p> </div> </td> <td> <em>required</em> </td> </tr> <tr class="doc-section-item"> <td> <code>data</code> </td> <td> <code><span title="typing.Any">Any</span></code> </td> <td> <div class="doc-md-description"> <p>Additional error data.</p> </div> </td> <td> <code>None</code> </td> </tr> </tbody> </table> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/socket.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-39">39</a></span>
<span class="normal"><a href="#__codelineno-0-40">40</a></span>
<span class="normal"><a href="#__codelineno-0-41">41</a></span>
<span class="normal"><a href="#__codelineno-0-42">42</a></span>
<span class="normal"><a href="#__codelineno-0-43">43</a></span>
<span class="normal"><a href="#__codelineno-0-44">44</a></span>
<span class="normal"><a href="#__codelineno-0-45">45</a></span>
<span class="normal"><a href="#__codelineno-0-46">46</a></span>
<span class="normal"><a href="#__codelineno-0-47">47</a></span>
<span class="normal"><a href="#__codelineno-0-48">48</a></span>
<span class="normal"><a href="#__codelineno-0-49">49</a></span>
<span class="normal"><a href="#__codelineno-0-50">50</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-39"><a id="__codelineno-0-39" name="__codelineno-0-39"></a><span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">code</span><span class="p">:</span> <span class="nb">int</span><span class="p">,</span> <span class="n">message</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">data</span><span class="p">:</span> <span class="n">Any</span> <span class="o">=</span> <span class="kc">None</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kc">None</span><span class="p">:</span>
</span><span id="__span-0-40"><a id="__codelineno-0-40" name="__codelineno-0-40"></a><span class="w"> </span><span class="sd">"""Initialize JSON-RPC error.</span>
</span><span id="__span-0-41"><a id="__codelineno-0-41" name="__codelineno-0-41"></a>
</span><span id="__span-0-42"><a id="__codelineno-0-42" name="__codelineno-0-42"></a><span class="sd"> Args:</span>
</span><span id="__span-0-43"><a id="__codelineno-0-43" name="__codelineno-0-43"></a><span class="sd"> code: Error code.</span>
</span><span id="__span-0-44"><a id="__codelineno-0-44" name="__codelineno-0-44"></a><span class="sd"> message: Error message.</span>
</span><span id="__span-0-45"><a id="__codelineno-0-45" name="__codelineno-0-45"></a><span class="sd"> data: Additional error data.</span>
</span><span id="__span-0-46"><a id="__codelineno-0-46" name="__codelineno-0-46"></a><span class="sd"> """</span>
</span><span id="__span-0-47"><a id="__codelineno-0-47" name="__codelineno-0-47"></a> <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="n">message</span><span class="p">)</span>
</span><span id="__span-0-48"><a id="__codelineno-0-48" name="__codelineno-0-48"></a> <span class="bp">self</span><span class="o">.</span><span class="n">code</span> <span class="o">=</span> <span class="n">code</span>
</span><span id="__span-0-49"><a id="__codelineno-0-49" name="__codelineno-0-49"></a> <span class="bp">self</span><span class="o">.</span><span class="n">message</span> <span class="o">=</span> <span class="n">message</span>
</span><span id="__span-0-50"><a id="__codelineno-0-50" name="__codelineno-0-50"></a> <span class="bp">self</span><span class="o">.</span><span class="n">data</span> <span class="o">=</span> <span class="n">data</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> </div> </div> </div> </div> </div> <div class="doc doc-object doc-class"> <h4 id="freecad_mcp.bridge.socket.SocketBridge" class="doc doc-heading"> <code>SocketBridge</code> <a href="#freecad_mcp.bridge.socket.SocketBridge" class="headerlink" title="Permanent link">¶</a></h4> <div class="doc doc-contents "> <p class="doc doc-class-bases"> Bases: <code><a class="autorefs autorefs-internal" title="FreecadBridge (freecad_mcp.bridge.base.FreecadBridge)" href="#freecad_mcp.bridge.base.FreecadBridge">FreecadBridge</a></code></p> <p>Bridge that communicates with FreeCAD via JSON-RPC over sockets.</p> <p>This bridge provides a lightweight, modern protocol for FreeCAD communication. It supports automatic reconnection and connection health monitoring.</p> <p><span class="doc-section-title">Attributes:</span></p> <table> <thead> <tr> <th>Name</th> <th>Type</th> <th>Description</th> </tr> </thead> <tbody> <tr class="doc-section-item"> <td><code><span title="freecad_mcp.bridge.socket.SocketBridge.host">host</span></code></td> <td> </td> <td> <div class="doc-md-description"> <p>Socket server hostname.</p> </div> </td> </tr> <tr class="doc-section-item"> <td><code><span title="freecad_mcp.bridge.socket.SocketBridge.port">port</span></code></td> <td> </td> <td> <div class="doc-md-description"> <p>Socket server port.</p> </div> </td> </tr> <tr class="doc-section-item"> <td><code><span title="freecad_mcp.bridge.socket.SocketBridge.timeout">timeout</span></code></td> <td> </td> <td> <div class="doc-md-description"> <p>Connection and request timeout in seconds.</p> </div> </td> </tr> </tbody> </table> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/socket.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-53"> 53</a></span>
<span class="normal"><a href="#__codelineno-0-54"> 54</a></span>
<span class="normal"><a href="#__codelineno-0-55"> 55</a></span>
<span class="normal"><a href="#__codelineno-0-56"> 56</a></span>
<span class="normal"><a href="#__codelineno-0-57"> 57</a></span>
<span class="normal"><a href="#__codelineno-0-58"> 58</a></span>
<span class="normal"><a href="#__codelineno-0-59"> 59</a></span>
<span class="normal"><a href="#__codelineno-0-60"> 60</a></span>
<span class="normal"><a href="#__codelineno-0-61"> 61</a></span>
<span class="normal"><a href="#__codelineno-0-62"> 62</a></span>
<span class="normal"><a href="#__codelineno-0-63"> 63</a></span>
<span class="normal"><a href="#__codelineno-0-64"> 64</a></span>
<span class="normal"><a href="#__codelineno-0-65"> 65</a></span>
<span class="normal"><a href="#__codelineno-0-66"> 66</a></span>
<span class="normal"><a href="#__codelineno-0-67"> 67</a></span>
<span class="normal"><a href="#__codelineno-0-68"> 68</a></span>
<span class="normal"><a href="#__codelineno-0-69"> 69</a></span>
<span class="normal"><a href="#__codelineno-0-70"> 70</a></span>
<span class="normal"><a href="#__codelineno-0-71"> 71</a></span>
<span class="normal"><a href="#__codelineno-0-72"> 72</a></span>
<span class="normal"><a href="#__codelineno-0-73"> 73</a></span>
<span class="normal"><a href="#__codelineno-0-74"> 74</a></span>
<span class="normal"><a href="#__codelineno-0-75"> 75</a></span>
<span class="normal"><a href="#__codelineno-0-76"> 76</a></span>
<span class="normal"><a href="#__codelineno-0-77"> 77</a></span>
<span class="normal"><a href="#__codelineno-0-78"> 78</a></span>
<span class="normal"><a href="#__codelineno-0-79"> 79</a></span>
<span class="normal"><a href="#__codelineno-0-80"> 80</a></span>
<span class="normal"><a href="#__codelineno-0-81"> 81</a></span>
<span class="normal"><a href="#__codelineno-0-82"> 82</a></span>
<span class="normal"><a href="#__codelineno-0-83"> 83</a></span>
<span class="normal"><a href="#__codelineno-0-84"> 84</a></span>
<span class="normal"><a href="#__codelineno-0-85"> 85</a></span>
<span class="normal"><a href="#__codelineno-0-86"> 86</a></span>
<span class="normal"><a href="#__codelineno-0-87"> 87</a></span>
<span class="normal"><a href="#__codelineno-0-88"> 88</a></span>
<span class="normal"><a href="#__codelineno-0-89"> 89</a></span>
<span class="normal"><a href="#__codelineno-0-90"> 90</a></span>
<span class="normal"><a href="#__codelineno-0-91"> 91</a></span>
<span class="normal"><a href="#__codelineno-0-92"> 92</a></span>
<span class="normal"><a href="#__codelineno-0-93"> 93</a></span>
<span class="normal"><a href="#__codelineno-0-94"> 94</a></span>
<span class="normal"><a href="#__codelineno-0-95"> 95</a></span>
<span class="normal"><a href="#__codelineno-0-96"> 96</a></span>
<span class="normal"><a href="#__codelineno-0-97"> 97</a></span>
<span class="normal"><a href="#__codelineno-0-98"> 98</a></span>
<span class="normal"><a href="#__codelineno-0-99"> 99</a></span>
<span class="normal"><a href="#__codelineno-0-100"> 100</a></span>
<span class="normal"><a href="#__codelineno-0-101"> 101</a></span>
<span class="normal"><a href="#__codelineno-0-102"> 102</a></span>
<span class="normal"><a href="#__codelineno-0-103"> 103</a></span>
<span class="normal"><a href="#__codelineno-0-104"> 104</a></span>
<span class="normal"><a href="#__codelineno-0-105"> 105</a></span>
<span class="normal"><a href="#__codelineno-0-106"> 106</a></span>
<span class="normal"><a href="#__codelineno-0-107"> 107</a></span>
<span class="normal"><a href="#__codelineno-0-108"> 108</a></span>
<span class="normal"><a href="#__codelineno-0-109"> 109</a></span>
<span class="normal"><a href="#__codelineno-0-110"> 110</a></span>
<span class="normal"><a href="#__codelineno-0-111"> 111</a></span>
<span class="normal"><a href="#__codelineno-0-112"> 112</a></span>
<span class="normal"><a href="#__codelineno-0-113"> 113</a></span>
<span class="normal"><a href="#__codelineno-0-114"> 114</a></span>
<span class="normal"><a href="#__codelineno-0-115"> 115</a></span>
<span class="normal"><a href="#__codelineno-0-116"> 116</a></span>
<span class="normal"><a href="#__codelineno-0-117"> 117</a></span>
<span class="normal"><a href="#__codelineno-0-118"> 118</a></span>
<span class="normal"><a href="#__codelineno-0-119"> 119</a></span>
<span class="normal"><a href="#__codelineno-0-120"> 120</a></span>
<span class="normal"><a href="#__codelineno-0-121"> 121</a></span>
<span class="normal"><a href="#__codelineno-0-122"> 122</a></span>
<span class="normal"><a href="#__codelineno-0-123"> 123</a></span>
<span class="normal"><a href="#__codelineno-0-124"> 124</a></span>
<span class="normal"><a href="#__codelineno-0-125"> 125</a></span>
<span class="normal"><a href="#__codelineno-0-126"> 126</a></span>
<span class="normal"><a href="#__codelineno-0-127"> 127</a></span>
<span class="normal"><a href="#__codelineno-0-128"> 128</a></span>
<span class="normal"><a href="#__codelineno-0-129"> 129</a></span>
<span class="normal"><a href="#__codelineno-0-130"> 130</a></span>
<span class="normal"><a href="#__codelineno-0-131"> 131</a></span>
<span class="normal"><a href="#__codelineno-0-132"> 132</a></span>
<span class="normal"><a href="#__codelineno-0-133"> 133</a></span>
<span class="normal"><a href="#__codelineno-0-134"> 134</a></span>
<span class="normal"><a href="#__codelineno-0-135"> 135</a></span>
<span class="normal"><a href="#__codelineno-0-136"> 136</a></span>
<span class="normal"><a href="#__codelineno-0-137"> 137</a></span>
<span class="normal"><a href="#__codelineno-0-138"> 138</a></span>
<span class="normal"><a href="#__codelineno-0-139"> 139</a></span>
<span class="normal"><a href="#__codelineno-0-140"> 140</a></span>
<span class="normal"><a href="#__codelineno-0-141"> 141</a></span>
<span class="normal"><a href="#__codelineno-0-142"> 142</a></span>
<span class="normal"><a href="#__codelineno-0-143"> 143</a></span>
<span class="normal"><a href="#__codelineno-0-144"> 144</a></span>
<span class="normal"><a href="#__codelineno-0-145"> 145</a></span>
<span class="normal"><a href="#__codelineno-0-146"> 146</a></span>
<span class="normal"><a href="#__codelineno-0-147"> 147</a></span>
<span class="normal"><a href="#__codelineno-0-148"> 148</a></span>
<span class="normal"><a href="#__codelineno-0-149"> 149</a></span>
<span class="normal"><a href="#__codelineno-0-150"> 150</a></span>
<span class="normal"><a href="#__codelineno-0-151"> 151</a></span>
<span class="normal"><a href="#__codelineno-0-152"> 152</a></span>
<span class="normal"><a href="#__codelineno-0-153"> 153</a></span>
<span class="normal"><a href="#__codelineno-0-154"> 154</a></span>
<span class="normal"><a href="#__codelineno-0-155"> 155</a></span>
<span class="normal"><a href="#__codelineno-0-156"> 156</a></span>
<span class="normal"><a href="#__codelineno-0-157"> 157</a></span>
<span class="normal"><a href="#__codelineno-0-158"> 158</a></span>
<span class="normal"><a href="#__codelineno-0-159"> 159</a></span>
<span class="normal"><a href="#__codelineno-0-160"> 160</a></span>
<span class="normal"><a href="#__codelineno-0-161"> 161</a></span>
<span class="normal"><a href="#__codelineno-0-162"> 162</a></span>
<span class="normal"><a href="#__codelineno-0-163"> 163</a></span>
<span class="normal"><a href="#__codelineno-0-164"> 164</a></span>
<span class="normal"><a href="#__codelineno-0-165"> 165</a></span>
<span class="normal"><a href="#__codelineno-0-166"> 166</a></span>
<span class="normal"><a href="#__codelineno-0-167"> 167</a></span>
<span class="normal"><a href="#__codelineno-0-168"> 168</a></span>
<span class="normal"><a href="#__codelineno-0-169"> 169</a></span>
<span class="normal"><a href="#__codelineno-0-170"> 170</a></span>
<span class="normal"><a href="#__codelineno-0-171"> 171</a></span>
<span class="normal"><a href="#__codelineno-0-172"> 172</a></span>
<span class="normal"><a href="#__codelineno-0-173"> 173</a></span>
<span class="normal"><a href="#__codelineno-0-174"> 174</a></span>
<span class="normal"><a href="#__codelineno-0-175"> 175</a></span>
<span class="normal"><a href="#__codelineno-0-176"> 176</a></span>
<span class="normal"><a href="#__codelineno-0-177"> 177</a></span>
<span class="normal"><a href="#__codelineno-0-178"> 178</a></span>
<span class="normal"><a href="#__codelineno-0-179"> 179</a></span>
<span class="normal"><a href="#__codelineno-0-180"> 180</a></span>
<span class="normal"><a href="#__codelineno-0-181"> 181</a></span>
<span class="normal"><a href="#__codelineno-0-182"> 182</a></span>
<span class="normal"><a href="#__codelineno-0-183"> 183</a></span>
<span class="normal"><a href="#__codelineno-0-184"> 184</a></span>
<span class="normal"><a href="#__codelineno-0-185"> 185</a></span>
<span class="normal"><a href="#__codelineno-0-186"> 186</a></span>
<span class="normal"><a href="#__codelineno-0-187"> 187</a></span>
<span class="normal"><a href="#__codelineno-0-188"> 188</a></span>
<span class="normal"><a href="#__codelineno-0-189"> 189</a></span>
<span class="normal"><a href="#__codelineno-0-190"> 190</a></span>
<span class="normal"><a href="#__codelineno-0-191"> 191</a></span>
<span class="normal"><a href="#__codelineno-0-192"> 192</a></span>
<span class="normal"><a href="#__codelineno-0-193"> 193</a></span>
<span class="normal"><a href="#__codelineno-0-194"> 194</a></span>
<span class="normal"><a href="#__codelineno-0-195"> 195</a></span>
<span class="normal"><a href="#__codelineno-0-196"> 196</a></span>
<span class="normal"><a href="#__codelineno-0-197"> 197</a></span>
<span class="normal"><a href="#__codelineno-0-198"> 198</a></span>
<span class="normal"><a href="#__codelineno-0-199"> 199</a></span>
<span class="normal"><a href="#__codelineno-0-200"> 200</a></span>
<span class="normal"><a href="#__codelineno-0-201"> 201</a></span>
<span class="normal"><a href="#__codelineno-0-202"> 202</a></span>
<span class="normal"><a href="#__codelineno-0-203"> 203</a></span>
<span class="normal"><a href="#__codelineno-0-204"> 204</a></span>
<span class="normal"><a href="#__codelineno-0-205"> 205</a></span>
<span class="normal"><a href="#__codelineno-0-206"> 206</a></span>
<span class="normal"><a href="#__codelineno-0-207"> 207</a></span>
<span class="normal"><a href="#__codelineno-0-208"> 208</a></span>
<span class="normal"><a href="#__codelineno-0-209"> 209</a></span>
<span class="normal"><a href="#__codelineno-0-210"> 210</a></span>
<span class="normal"><a href="#__codelineno-0-211"> 211</a></span>
<span class="normal"><a href="#__codelineno-0-212"> 212</a></span>
<span class="normal"><a href="#__codelineno-0-213"> 213</a></span>
<span class="normal"><a href="#__codelineno-0-214"> 214</a></span>
<span class="normal"><a href="#__codelineno-0-215"> 215</a></span>
<span class="normal"><a href="#__codelineno-0-216"> 216</a></span>
<span class="normal"><a href="#__codelineno-0-217"> 217</a></span>
<span class="normal"><a href="#__codelineno-0-218"> 218</a></span>
<span class="normal"><a href="#__codelineno-0-219"> 219</a></span>
<span class="normal"><a href="#__codelineno-0-220"> 220</a></span>
<span class="normal"><a href="#__codelineno-0-221"> 221</a></span>
<span class="normal"><a href="#__codelineno-0-222"> 222</a></span>
<span class="normal"><a href="#__codelineno-0-223"> 223</a></span>
<span class="normal"><a href="#__codelineno-0-224"> 224</a></span>
<span class="normal"><a href="#__codelineno-0-225"> 225</a></span>
<span class="normal"><a href="#__codelineno-0-226"> 226</a></span>
<span class="normal"><a href="#__codelineno-0-227"> 227</a></span>
<span class="normal"><a href="#__codelineno-0-228"> 228</a></span>
<span class="normal"><a href="#__codelineno-0-229"> 229</a></span>
<span class="normal"><a href="#__codelineno-0-230"> 230</a></span>
<span class="normal"><a href="#__codelineno-0-231"> 231</a></span>
<span class="normal"><a href="#__codelineno-0-232"> 232</a></span>
<span class="normal"><a href="#__codelineno-0-233"> 233</a></span>
<span class="normal"><a href="#__codelineno-0-234"> 234</a></span>
<span class="normal"><a href="#__codelineno-0-235"> 235</a></span>
<span class="normal"><a href="#__codelineno-0-236"> 236</a></span>
<span class="normal"><a href="#__codelineno-0-237"> 237</a></span>
<span class="normal"><a href="#__codelineno-0-238"> 238</a></span>
<span class="normal"><a href="#__codelineno-0-239"> 239</a></span>
<span class="normal"><a href="#__codelineno-0-240"> 240</a></span>
<span class="normal"><a href="#__codelineno-0-241"> 241</a></span>
<span class="normal"><a href="#__codelineno-0-242"> 242</a></span>
<span class="normal"><a href="#__codelineno-0-243"> 243</a></span>
<span class="normal"><a href="#__codelineno-0-244"> 244</a></span>
<span class="normal"><a href="#__codelineno-0-245"> 245</a></span>
<span class="normal"><a href="#__codelineno-0-246"> 246</a></span>
<span class="normal"><a href="#__codelineno-0-247"> 247</a></span>
<span class="normal"><a href="#__codelineno-0-248"> 248</a></span>
<span class="normal"><a href="#__codelineno-0-249"> 249</a></span>
<span class="normal"><a href="#__codelineno-0-250"> 250</a></span>
<span class="normal"><a href="#__codelineno-0-251"> 251</a></span>
<span class="normal"><a href="#__codelineno-0-252"> 252</a></span>
<span class="normal"><a href="#__codelineno-0-253"> 253</a></span>
<span class="normal"><a href="#__codelineno-0-254"> 254</a></span>
<span class="normal"><a href="#__codelineno-0-255"> 255</a></span>
<span class="normal"><a href="#__codelineno-0-256"> 256</a></span>
<span class="normal"><a href="#__codelineno-0-257"> 257</a></span>
<span class="normal"><a href="#__codelineno-0-258"> 258</a></span>
<span class="normal"><a href="#__codelineno-0-259"> 259</a></span>
<span class="normal"><a href="#__codelineno-0-260"> 260</a></span>
<span class="normal"><a href="#__codelineno-0-261"> 261</a></span>
<span class="normal"><a href="#__codelineno-0-262"> 262</a></span>
<span class="normal"><a href="#__codelineno-0-263"> 263</a></span>
<span class="normal"><a href="#__codelineno-0-264"> 264</a></span>
<span class="normal"><a href="#__codelineno-0-265"> 265</a></span>
<span class="normal"><a href="#__codelineno-0-266"> 266</a></span>
<span class="normal"><a href="#__codelineno-0-267"> 267</a></span>
<span class="normal"><a href="#__codelineno-0-268"> 268</a></span>
<span class="normal"><a href="#__codelineno-0-269"> 269</a></span>
<span class="normal"><a href="#__codelineno-0-270"> 270</a></span>
<span class="normal"><a href="#__codelineno-0-271"> 271</a></span>
<span class="normal"><a href="#__codelineno-0-272"> 272</a></span>
<span class="normal"><a href="#__codelineno-0-273"> 273</a></span>
<span class="normal"><a href="#__codelineno-0-274"> 274</a></span>
<span class="normal"><a href="#__codelineno-0-275"> 275</a></span>
<span class="normal"><a href="#__codelineno-0-276"> 276</a></span>
<span class="normal"><a href="#__codelineno-0-277"> 277</a></span>
<span class="normal"><a href="#__codelineno-0-278"> 278</a></span>
<span class="normal"><a href="#__codelineno-0-279"> 279</a></span>
<span class="normal"><a href="#__codelineno-0-280"> 280</a></span>
<span class="normal"><a href="#__codelineno-0-281"> 281</a></span>
<span class="normal"><a href="#__codelineno-0-282"> 282</a></span>
<span class="normal"><a href="#__codelineno-0-283"> 283</a></span>
<span class="normal"><a href="#__codelineno-0-284"> 284</a></span>
<span class="normal"><a href="#__codelineno-0-285"> 285</a></span>
<span class="normal"><a href="#__codelineno-0-286"> 286</a></span>
<span class="normal"><a href="#__codelineno-0-287"> 287</a></span>
<span class="normal"><a href="#__codelineno-0-288"> 288</a></span>
<span class="normal"><a href="#__codelineno-0-289"> 289</a></span>
<span class="normal"><a href="#__codelineno-0-290"> 290</a></span>
<span class="normal"><a href="#__codelineno-0-291"> 291</a></span>
<span class="normal"><a href="#__codelineno-0-292"> 292</a></span>
<span class="normal"><a href="#__codelineno-0-293"> 293</a></span>
<span class="normal"><a href="#__codelineno-0-294"> 294</a></span>
<span class="normal"><a href="#__codelineno-0-295"> 295</a></span>
<span class="normal"><a href="#__codelineno-0-296"> 296</a></span>
<span class="normal"><a href="#__codelineno-0-297"> 297</a></span>
<span class="normal"><a href="#__codelineno-0-298"> 298</a></span>
<span class="normal"><a href="#__codelineno-0-299"> 299</a></span>
<span class="normal"><a href="#__codelineno-0-300"> 300</a></span>
<span class="normal"><a href="#__codelineno-0-301"> 301</a></span>
<span class="normal"><a href="#__codelineno-0-302"> 302</a></span>
<span class="normal"><a href="#__codelineno-0-303"> 303</a></span>
<span class="normal"><a href="#__codelineno-0-304"> 304</a></span>
<span class="normal"><a href="#__codelineno-0-305"> 305</a></span>
<span class="normal"><a href="#__codelineno-0-306"> 306</a></span>
<span class="normal"><a href="#__codelineno-0-307"> 307</a></span>
<span class="normal"><a href="#__codelineno-0-308"> 308</a></span>
<span class="normal"><a href="#__codelineno-0-309"> 309</a></span>
<span class="normal"><a href="#__codelineno-0-310"> 310</a></span>
<span class="normal"><a href="#__codelineno-0-311"> 311</a></span>
<span class="normal"><a href="#__codelineno-0-312"> 312</a></span>
<span class="normal"><a href="#__codelineno-0-313"> 313</a></span>
<span class="normal"><a href="#__codelineno-0-314"> 314</a></span>
<span class="normal"><a href="#__codelineno-0-315"> 315</a></span>
<span class="normal"><a href="#__codelineno-0-316"> 316</a></span>
<span class="normal"><a href="#__codelineno-0-317"> 317</a></span>
<span class="normal"><a href="#__codelineno-0-318"> 318</a></span>
<span class="normal"><a href="#__codelineno-0-319"> 319</a></span>
<span class="normal"><a href="#__codelineno-0-320"> 320</a></span>
<span class="normal"><a href="#__codelineno-0-321"> 321</a></span>
<span class="normal"><a href="#__codelineno-0-322"> 322</a></span>
<span class="normal"><a href="#__codelineno-0-323"> 323</a></span>
<span class="normal"><a href="#__codelineno-0-324"> 324</a></span>
<span class="normal"><a href="#__codelineno-0-325"> 325</a></span>
<span class="normal"><a href="#__codelineno-0-326"> 326</a></span>
<span class="normal"><a href="#__codelineno-0-327"> 327</a></span>
<span class="normal"><a href="#__codelineno-0-328"> 328</a></span>
<span class="normal"><a href="#__codelineno-0-329"> 329</a></span>
<span class="normal"><a href="#__codelineno-0-330"> 330</a></span>
<span class="normal"><a href="#__codelineno-0-331"> 331</a></span>
<span class="normal"><a href="#__codelineno-0-332"> 332</a></span>
<span class="normal"><a href="#__codelineno-0-333"> 333</a></span>
<span class="normal"><a href="#__codelineno-0-334"> 334</a></span>
<span class="normal"><a href="#__codelineno-0-335"> 335</a></span>
<span class="normal"><a href="#__codelineno-0-336"> 336</a></span>
<span class="normal"><a href="#__codelineno-0-337"> 337</a></span>
<span class="normal"><a href="#__codelineno-0-338"> 338</a></span>
<span class="normal"><a href="#__codelineno-0-339"> 339</a></span>
<span class="normal"><a href="#__codelineno-0-340"> 340</a></span>
<span class="normal"><a href="#__codelineno-0-341"> 341</a></span>
<span class="normal"><a href="#__codelineno-0-342"> 342</a></span>
<span class="normal"><a href="#__codelineno-0-343"> 343</a></span>
<span class="normal"><a href="#__codelineno-0-344"> 344</a></span>
<span class="normal"><a href="#__codelineno-0-345"> 345</a></span>
<span class="normal"><a href="#__codelineno-0-346"> 346</a></span>
<span class="normal"><a href="#__codelineno-0-347"> 347</a></span>
<span class="normal"><a href="#__codelineno-0-348"> 348</a></span>
<span class="normal"><a href="#__codelineno-0-349"> 349</a></span>
<span class="normal"><a href="#__codelineno-0-350"> 350</a></span>
<span class="normal"><a href="#__codelineno-0-351"> 351</a></span>
<span class="normal"><a href="#__codelineno-0-352"> 352</a></span>
<span class="normal"><a href="#__codelineno-0-353"> 353</a></span>
<span class="normal"><a href="#__codelineno-0-354"> 354</a></span>
<span class="normal"><a href="#__codelineno-0-355"> 355</a></span>
<span class="normal"><a href="#__codelineno-0-356"> 356</a></span>
<span class="normal"><a href="#__codelineno-0-357"> 357</a></span>
<span class="normal"><a href="#__codelineno-0-358"> 358</a></span>
<span class="normal"><a href="#__codelineno-0-359"> 359</a></span>
<span class="normal"><a href="#__codelineno-0-360"> 360</a></span>
<span class="normal"><a href="#__codelineno-0-361"> 361</a></span>
<span class="normal"><a href="#__codelineno-0-362"> 362</a></span>
<span class="normal"><a href="#__codelineno-0-363"> 363</a></span>
<span class="normal"><a href="#__codelineno-0-364"> 364</a></span>
<span class="normal"><a href="#__codelineno-0-365"> 365</a></span>
<span class="normal"><a href="#__codelineno-0-366"> 366</a></span>
<span class="normal"><a href="#__codelineno-0-367"> 367</a></span>
<span class="normal"><a href="#__codelineno-0-368"> 368</a></span>
<span class="normal"><a href="#__codelineno-0-369"> 369</a></span>
<span class="normal"><a href="#__codelineno-0-370"> 370</a></span>
<span class="normal"><a href="#__codelineno-0-371"> 371</a></span>
<span class="normal"><a href="#__codelineno-0-372"> 372</a></span>
<span class="normal"><a href="#__codelineno-0-373"> 373</a></span>
<span class="normal"><a href="#__codelineno-0-374"> 374</a></span>
<span class="normal"><a href="#__codelineno-0-375"> 375</a></span>
<span class="normal"><a href="#__codelineno-0-376"> 376</a></span>
<span class="normal"><a href="#__codelineno-0-377"> 377</a></span>
<span class="normal"><a href="#__codelineno-0-378"> 378</a></span>
<span class="normal"><a href="#__codelineno-0-379"> 379</a></span>
<span class="normal"><a href="#__codelineno-0-380"> 380</a></span>
<span class="normal"><a href="#__codelineno-0-381"> 381</a></span>
<span class="normal"><a href="#__codelineno-0-382"> 382</a></span>
<span class="normal"><a href="#__codelineno-0-383"> 383</a></span>
<span class="normal"><a href="#__codelineno-0-384"> 384</a></span>
<span class="normal"><a href="#__codelineno-0-385"> 385</a></span>
<span class="normal"><a href="#__codelineno-0-386"> 386</a></span>
<span class="normal"><a href="#__codelineno-0-387"> 387</a></span>
<span class="normal"><a href="#__codelineno-0-388"> 388</a></span>
<span class="normal"><a href="#__codelineno-0-389"> 389</a></span>
<span class="normal"><a href="#__codelineno-0-390"> 390</a></span>
<span class="normal"><a href="#__codelineno-0-391"> 391</a></span>
<span class="normal"><a href="#__codelineno-0-392"> 392</a></span>
<span class="normal"><a href="#__codelineno-0-393"> 393</a></span>
<span class="normal"><a href="#__codelineno-0-394"> 394</a></span>
<span class="normal"><a href="#__codelineno-0-395"> 395</a></span>
<span class="normal"><a href="#__codelineno-0-396"> 396</a></span>
<span class="normal"><a href="#__codelineno-0-397"> 397</a></span>
<span class="normal"><a href="#__codelineno-0-398"> 398</a></span>
<span class="normal"><a href="#__codelineno-0-399"> 399</a></span>
<span class="normal"><a href="#__codelineno-0-400"> 400</a></span>
<span class="normal"><a href="#__codelineno-0-401"> 401</a></span>
<span class="normal"><a href="#__codelineno-0-402"> 402</a></span>
<span class="normal"><a href="#__codelineno-0-403"> 403</a></span>
<span class="normal"><a href="#__codelineno-0-404"> 404</a></span>
<span class="normal"><a href="#__codelineno-0-405"> 405</a></span>
<span class="normal"><a href="#__codelineno-0-406"> 406</a></span>
<span class="normal"><a href="#__codelineno-0-407"> 407</a></span>
<span class="normal"><a href="#__codelineno-0-408"> 408</a></span>
<span class="normal"><a href="#__codelineno-0-409"> 409</a></span>
<span class="normal"><a href="#__codelineno-0-410"> 410</a></span>
<span class="normal"><a href="#__codelineno-0-411"> 411</a></span>
<span class="normal"><a href="#__codelineno-0-412"> 412</a></span>
<span class="normal"><a href="#__codelineno-0-413"> 413</a></span>
<span class="normal"><a href="#__codelineno-0-414"> 414</a></span>
<span class="normal"><a href="#__codelineno-0-415"> 415</a></span>
<span class="normal"><a href="#__codelineno-0-416"> 416</a></span>
<span class="normal"><a href="#__codelineno-0-417"> 417</a></span>
<span class="normal"><a href="#__codelineno-0-418"> 418</a></span>
<span class="normal"><a href="#__codelineno-0-419"> 419</a></span>
<span class="normal"><a href="#__codelineno-0-420"> 420</a></span>
<span class="normal"><a href="#__codelineno-0-421"> 421</a></span>
<span class="normal"><a href="#__codelineno-0-422"> 422</a></span>
<span class="normal"><a href="#__codelineno-0-423"> 423</a></span>
<span class="normal"><a href="#__codelineno-0-424"> 424</a></span>
<span class="normal"><a href="#__codelineno-0-425"> 425</a></span>
<span class="normal"><a href="#__codelineno-0-426"> 426</a></span>
<span class="normal"><a href="#__codelineno-0-427"> 427</a></span>
<span class="normal"><a href="#__codelineno-0-428"> 428</a></span>
<span class="normal"><a href="#__codelineno-0-429"> 429</a></span>
<span class="normal"><a href="#__codelineno-0-430"> 430</a></span>
<span class="normal"><a href="#__codelineno-0-431"> 431</a></span>
<span class="normal"><a href="#__codelineno-0-432"> 432</a></span>
<span class="normal"><a href="#__codelineno-0-433"> 433</a></span>
<span class="normal"><a href="#__codelineno-0-434"> 434</a></span>
<span class="normal"><a href="#__codelineno-0-435"> 435</a></span>
<span class="normal"><a href="#__codelineno-0-436"> 436</a></span>
<span class="normal"><a href="#__codelineno-0-437"> 437</a></span>
<span class="normal"><a href="#__codelineno-0-438"> 438</a></span>
<span class="normal"><a href="#__codelineno-0-439"> 439</a></span>
<span class="normal"><a href="#__codelineno-0-440"> 440</a></span>
<span class="normal"><a href="#__codelineno-0-441"> 441</a></span>
<span class="normal"><a href="#__codelineno-0-442"> 442</a></span>
<span class="normal"><a href="#__codelineno-0-443"> 443</a></span>
<span class="normal"><a href="#__codelineno-0-444"> 444</a></span>
<span class="normal"><a href="#__codelineno-0-445"> 445</a></span>
<span class="normal"><a href="#__codelineno-0-446"> 446</a></span>
<span class="normal"><a href="#__codelineno-0-447"> 447</a></span>
<span class="normal"><a href="#__codelineno-0-448"> 448</a></span>
<span class="normal"><a href="#__codelineno-0-449"> 449</a></span>
<span class="normal"><a href="#__codelineno-0-450"> 450</a></span>
<span class="normal"><a href="#__codelineno-0-451"> 451</a></span>
<span class="normal"><a href="#__codelineno-0-452"> 452</a></span>
<span class="normal"><a href="#__codelineno-0-453"> 453</a></span>
<span class="normal"><a href="#__codelineno-0-454"> 454</a></span>
<span class="normal"><a href="#__codelineno-0-455"> 455</a></span>
<span class="normal"><a href="#__codelineno-0-456"> 456</a></span>
<span class="normal"><a href="#__codelineno-0-457"> 457</a></span>
<span class="normal"><a href="#__codelineno-0-458"> 458</a></span>
<span class="normal"><a href="#__codelineno-0-459"> 459</a></span>
<span class="normal"><a href="#__codelineno-0-460"> 460</a></span>
<span class="normal"><a href="#__codelineno-0-461"> 461</a></span>
<span class="normal"><a href="#__codelineno-0-462"> 462</a></span>
<span class="normal"><a href="#__codelineno-0-463"> 463</a></span>
<span class="normal"><a href="#__codelineno-0-464"> 464</a></span>
<span class="normal"><a href="#__codelineno-0-465"> 465</a></span>
<span class="normal"><a href="#__codelineno-0-466"> 466</a></span>
<span class="normal"><a href="#__codelineno-0-467"> 467</a></span>
<span class="normal"><a href="#__codelineno-0-468"> 468</a></span>
<span class="normal"><a href="#__codelineno-0-469"> 469</a></span>
<span class="normal"><a href="#__codelineno-0-470"> 470</a></span>
<span class="normal"><a href="#__codelineno-0-471"> 471</a></span>
<span class="normal"><a href="#__codelineno-0-472"> 472</a></span>
<span class="normal"><a href="#__codelineno-0-473"> 473</a></span>
<span class="normal"><a href="#__codelineno-0-474"> 474</a></span>
<span class="normal"><a href="#__codelineno-0-475"> 475</a></span>
<span class="normal"><a href="#__codelineno-0-476"> 476</a></span>
<span class="normal"><a href="#__codelineno-0-477"> 477</a></span>
<span class="normal"><a href="#__codelineno-0-478"> 478</a></span>
<span class="normal"><a href="#__codelineno-0-479"> 479</a></span>
<span class="normal"><a href="#__codelineno-0-480"> 480</a></span>
<span class="normal"><a href="#__codelineno-0-481"> 481</a></span>
<span class="normal"><a href="#__codelineno-0-482"> 482</a></span>
<span class="normal"><a href="#__codelineno-0-483"> 483</a></span>
<span class="normal"><a href="#__codelineno-0-484"> 484</a></span>
<span class="normal"><a href="#__codelineno-0-485"> 485</a></span>
<span class="normal"><a href="#__codelineno-0-486"> 486</a></span>
<span class="normal"><a href="#__codelineno-0-487"> 487</a></span>
<span class="normal"><a href="#__codelineno-0-488"> 488</a></span>
<span class="normal"><a href="#__codelineno-0-489"> 489</a></span>
<span class="normal"><a href="#__codelineno-0-490"> 490</a></span>
<span class="normal"><a href="#__codelineno-0-491"> 491</a></span>
<span class="normal"><a href="#__codelineno-0-492"> 492</a></span>
<span class="normal"><a href="#__codelineno-0-493"> 493</a></span>
<span class="normal"><a href="#__codelineno-0-494"> 494</a></span>
<span class="normal"><a href="#__codelineno-0-495"> 495</a></span>
<span class="normal"><a href="#__codelineno-0-496"> 496</a></span>
<span class="normal"><a href="#__codelineno-0-497"> 497</a></span>
<span class="normal"><a href="#__codelineno-0-498"> 498</a></span>
<span class="normal"><a href="#__codelineno-0-499"> 499</a></span>
<span class="normal"><a href="#__codelineno-0-500"> 500</a></span>
<span class="normal"><a href="#__codelineno-0-501"> 501</a></span>
<span class="normal"><a href="#__codelineno-0-502"> 502</a></span>
<span class="normal"><a href="#__codelineno-0-503"> 503</a></span>
<span class="normal"><a href="#__codelineno-0-504"> 504</a></span>
<span class="normal"><a href="#__codelineno-0-505"> 505</a></span>
<span class="normal"><a href="#__codelineno-0-506"> 506</a></span>
<span class="normal"><a href="#__codelineno-0-507"> 507</a></span>
<span class="normal"><a href="#__codelineno-0-508"> 508</a></span>
<span class="normal"><a href="#__codelineno-0-509"> 509</a></span>
<span class="normal"><a href="#__codelineno-0-510"> 510</a></span>
<span class="normal"><a href="#__codelineno-0-511"> 511</a></span>
<span class="normal"><a href="#__codelineno-0-512"> 512</a></span>
<span class="normal"><a href="#__codelineno-0-513"> 513</a></span>
<span class="normal"><a href="#__codelineno-0-514"> 514</a></span>
<span class="normal"><a href="#__codelineno-0-515"> 515</a></span>
<span class="normal"><a href="#__codelineno-0-516"> 516</a></span>
<span class="normal"><a href="#__codelineno-0-517"> 517</a></span>
<span class="normal"><a href="#__codelineno-0-518"> 518</a></span>
<span class="normal"><a href="#__codelineno-0-519"> 519</a></span>
<span class="normal"><a href="#__codelineno-0-520"> 520</a></span>
<span class="normal"><a href="#__codelineno-0-521"> 521</a></span>
<span class="normal"><a href="#__codelineno-0-522"> 522</a></span>
<span class="normal"><a href="#__codelineno-0-523"> 523</a></span>
<span class="normal"><a href="#__codelineno-0-524"> 524</a></span>
<span class="normal"><a href="#__codelineno-0-525"> 525</a></span>
<span class="normal"><a href="#__codelineno-0-526"> 526</a></span>
<span class="normal"><a href="#__codelineno-0-527"> 527</a></span>
<span class="normal"><a href="#__codelineno-0-528"> 528</a></span>
<span class="normal"><a href="#__codelineno-0-529"> 529</a></span>
<span class="normal"><a href="#__codelineno-0-530"> 530</a></span>
<span class="normal"><a href="#__codelineno-0-531"> 531</a></span>
<span class="normal"><a href="#__codelineno-0-532"> 532</a></span>
<span class="normal"><a href="#__codelineno-0-533"> 533</a></span>
<span class="normal"><a href="#__codelineno-0-534"> 534</a></span>
<span class="normal"><a href="#__codelineno-0-535"> 535</a></span>
<span class="normal"><a href="#__codelineno-0-536"> 536</a></span>
<span class="normal"><a href="#__codelineno-0-537"> 537</a></span>
<span class="normal"><a href="#__codelineno-0-538"> 538</a></span>
<span class="normal"><a href="#__codelineno-0-539"> 539</a></span>
<span class="normal"><a href="#__codelineno-0-540"> 540</a></span>
<span class="normal"><a href="#__codelineno-0-541"> 541</a></span>
<span class="normal"><a href="#__codelineno-0-542"> 542</a></span>
<span class="normal"><a href="#__codelineno-0-543"> 543</a></span>
<span class="normal"><a href="#__codelineno-0-544"> 544</a></span>
<span class="normal"><a href="#__codelineno-0-545"> 545</a></span>
<span class="normal"><a href="#__codelineno-0-546"> 546</a></span>
<span class="normal"><a href="#__codelineno-0-547"> 547</a></span>
<span class="normal"><a href="#__codelineno-0-548"> 548</a></span>
<span class="normal"><a href="#__codelineno-0-549"> 549</a></span>
<span class="normal"><a href="#__codelineno-0-550"> 550</a></span>
<span class="normal"><a href="#__codelineno-0-551"> 551</a></span>
<span class="normal"><a href="#__codelineno-0-552"> 552</a></span>
<span class="normal"><a href="#__codelineno-0-553"> 553</a></span>
<span class="normal"><a href="#__codelineno-0-554"> 554</a></span>
<span class="normal"><a href="#__codelineno-0-555"> 555</a></span>
<span class="normal"><a href="#__codelineno-0-556"> 556</a></span>
<span class="normal"><a href="#__codelineno-0-557"> 557</a></span>
<span class="normal"><a href="#__codelineno-0-558"> 558</a></span>
<span class="normal"><a href="#__codelineno-0-559"> 559</a></span>
<span class="normal"><a href="#__codelineno-0-560"> 560</a></span>
<span class="normal"><a href="#__codelineno-0-561"> 561</a></span>
<span class="normal"><a href="#__codelineno-0-562"> 562</a></span>
<span class="normal"><a href="#__codelineno-0-563"> 563</a></span>
<span class="normal"><a href="#__codelineno-0-564"> 564</a></span>
<span class="normal"><a href="#__codelineno-0-565"> 565</a></span>
<span class="normal"><a href="#__codelineno-0-566"> 566</a></span>
<span class="normal"><a href="#__codelineno-0-567"> 567</a></span>
<span class="normal"><a href="#__codelineno-0-568"> 568</a></span>
<span class="normal"><a href="#__codelineno-0-569"> 569</a></span>
<span class="normal"><a href="#__codelineno-0-570"> 570</a></span>
<span class="normal"><a href="#__codelineno-0-571"> 571</a></span>
<span class="normal"><a href="#__codelineno-0-572"> 572</a></span>
<span class="normal"><a href="#__codelineno-0-573"> 573</a></span>
<span class="normal"><a href="#__codelineno-0-574"> 574</a></span>
<span class="normal"><a href="#__codelineno-0-575"> 575</a></span>
<span class="normal"><a href="#__codelineno-0-576"> 576</a></span>
<span class="normal"><a href="#__codelineno-0-577"> 577</a></span>
<span class="normal"><a href="#__codelineno-0-578"> 578</a></span>
<span class="normal"><a href="#__codelineno-0-579"> 579</a></span>
<span class="normal"><a href="#__codelineno-0-580"> 580</a></span>
<span class="normal"><a href="#__codelineno-0-581"> 581</a></span>
<span class="normal"><a href="#__codelineno-0-582"> 582</a></span>
<span class="normal"><a href="#__codelineno-0-583"> 583</a></span>
<span class="normal"><a href="#__codelineno-0-584"> 584</a></span>
<span class="normal"><a href="#__codelineno-0-585"> 585</a></span>
<span class="normal"><a href="#__codelineno-0-586"> 586</a></span>
<span class="normal"><a href="#__codelineno-0-587"> 587</a></span>
<span class="normal"><a href="#__codelineno-0-588"> 588</a></span>
<span class="normal"><a href="#__codelineno-0-589"> 589</a></span>
<span class="normal"><a href="#__codelineno-0-590"> 590</a></span>
<span class="normal"><a href="#__codelineno-0-591"> 591</a></span>
<span class="normal"><a href="#__codelineno-0-592"> 592</a></span>
<span class="normal"><a href="#__codelineno-0-593"> 593</a></span>
<span class="normal"><a href="#__codelineno-0-594"> 594</a></span>
<span class="normal"><a href="#__codelineno-0-595"> 595</a></span>
<span class="normal"><a href="#__codelineno-0-596"> 596</a></span>
<span class="normal"><a href="#__codelineno-0-597"> 597</a></span>
<span class="normal"><a href="#__codelineno-0-598"> 598</a></span>
<span class="normal"><a href="#__codelineno-0-599"> 599</a></span>
<span class="normal"><a href="#__codelineno-0-600"> 600</a></span>
<span class="normal"><a href="#__codelineno-0-601"> 601</a></span>
<span class="normal"><a href="#__codelineno-0-602"> 602</a></span>
<span class="normal"><a href="#__codelineno-0-603"> 603</a></span>
<span class="normal"><a href="#__codelineno-0-604"> 604</a></span>
<span class="normal"><a href="#__codelineno-0-605"> 605</a></span>
<span class="normal"><a href="#__codelineno-0-606"> 606</a></span>
<span class="normal"><a href="#__codelineno-0-607"> 607</a></span>
<span class="normal"><a href="#__codelineno-0-608"> 608</a></span>
<span class="normal"><a href="#__codelineno-0-609"> 609</a></span>
<span class="normal"><a href="#__codelineno-0-610"> 610</a></span>
<span class="normal"><a href="#__codelineno-0-611"> 611</a></span>
<span class="normal"><a href="#__codelineno-0-612"> 612</a></span>
<span class="normal"><a href="#__codelineno-0-613"> 613</a></span>
<span class="normal"><a href="#__codelineno-0-614"> 614</a></span>
<span class="normal"><a href="#__codelineno-0-615"> 615</a></span>
<span class="normal"><a href="#__codelineno-0-616"> 616</a></span>
<span class="normal"><a href="#__codelineno-0-617"> 617</a></span>
<span class="normal"><a href="#__codelineno-0-618"> 618</a></span>
<span class="normal"><a href="#__codelineno-0-619"> 619</a></span>
<span class="normal"><a href="#__codelineno-0-620"> 620</a></span>
<span class="normal"><a href="#__codelineno-0-621"> 621</a></span>
<span class="normal"><a href="#__codelineno-0-622"> 622</a></span>
<span class="normal"><a href="#__codelineno-0-623"> 623</a></span>
<span class="normal"><a href="#__codelineno-0-624"> 624</a></span>
<span class="normal"><a href="#__codelineno-0-625"> 625</a></span>
<span class="normal"><a href="#__codelineno-0-626"> 626</a></span>
<span class="normal"><a href="#__codelineno-0-627"> 627</a></span>
<span class="normal"><a href="#__codelineno-0-628"> 628</a></span>
<span class="normal"><a href="#__codelineno-0-629"> 629</a></span>
<span class="normal"><a href="#__codelineno-0-630"> 630</a></span>
<span class="normal"><a href="#__codelineno-0-631"> 631</a></span>
<span class="normal"><a href="#__codelineno-0-632"> 632</a></span>
<span class="normal"><a href="#__codelineno-0-633"> 633</a></span>
<span class="normal"><a href="#__codelineno-0-634"> 634</a></span>
<span class="normal"><a href="#__codelineno-0-635"> 635</a></span>
<span class="normal"><a href="#__codelineno-0-636"> 636</a></span>
<span class="normal"><a href="#__codelineno-0-637"> 637</a></span>
<span class="normal"><a href="#__codelineno-0-638"> 638</a></span>
<span class="normal"><a href="#__codelineno-0-639"> 639</a></span>
<span class="normal"><a href="#__codelineno-0-640"> 640</a></span>
<span class="normal"><a href="#__codelineno-0-641"> 641</a></span>
<span class="normal"><a href="#__codelineno-0-642"> 642</a></span>
<span class="normal"><a href="#__codelineno-0-643"> 643</a></span>
<span class="normal"><a href="#__codelineno-0-644"> 644</a></span>
<span class="normal"><a href="#__codelineno-0-645"> 645</a></span>
<span class="normal"><a href="#__codelineno-0-646"> 646</a></span>
<span class="normal"><a href="#__codelineno-0-647"> 647</a></span>
<span class="normal"><a href="#__codelineno-0-648"> 648</a></span>
<span class="normal"><a href="#__codelineno-0-649"> 649</a></span>
<span class="normal"><a href="#__codelineno-0-650"> 650</a></span>
<span class="normal"><a href="#__codelineno-0-651"> 651</a></span>
<span class="normal"><a href="#__codelineno-0-652"> 652</a></span>
<span class="normal"><a href="#__codelineno-0-653"> 653</a></span>
<span class="normal"><a href="#__codelineno-0-654"> 654</a></span>
<span class="normal"><a href="#__codelineno-0-655"> 655</a></span>
<span class="normal"><a href="#__codelineno-0-656"> 656</a></span>
<span class="normal"><a href="#__codelineno-0-657"> 657</a></span>
<span class="normal"><a href="#__codelineno-0-658"> 658</a></span>
<span class="normal"><a href="#__codelineno-0-659"> 659</a></span>
<span class="normal"><a href="#__codelineno-0-660"> 660</a></span>
<span class="normal"><a href="#__codelineno-0-661"> 661</a></span>
<span class="normal"><a href="#__codelineno-0-662"> 662</a></span>
<span class="normal"><a href="#__codelineno-0-663"> 663</a></span>
<span class="normal"><a href="#__codelineno-0-664"> 664</a></span>
<span class="normal"><a href="#__codelineno-0-665"> 665</a></span>
<span class="normal"><a href="#__codelineno-0-666"> 666</a></span>
<span class="normal"><a href="#__codelineno-0-667"> 667</a></span>
<span class="normal"><a href="#__codelineno-0-668"> 668</a></span>
<span class="normal"><a href="#__codelineno-0-669"> 669</a></span>
<span class="normal"><a href="#__codelineno-0-670"> 670</a></span>
<span class="normal"><a href="#__codelineno-0-671"> 671</a></span>
<span class="normal"><a href="#__codelineno-0-672"> 672</a></span>
<span class="normal"><a href="#__codelineno-0-673"> 673</a></span>
<span class="normal"><a href="#__codelineno-0-674"> 674</a></span>
<span class="normal"><a href="#__codelineno-0-675"> 675</a></span>
<span class="normal"><a href="#__codelineno-0-676"> 676</a></span>
<span class="normal"><a href="#__codelineno-0-677"> 677</a></span>
<span class="normal"><a href="#__codelineno-0-678"> 678</a></span>
<span class="normal"><a href="#__codelineno-0-679"> 679</a></span>
<span class="normal"><a href="#__codelineno-0-680"> 680</a></span>
<span class="normal"><a href="#__codelineno-0-681"> 681</a></span>
<span class="normal"><a href="#__codelineno-0-682"> 682</a></span>
<span class="normal"><a href="#__codelineno-0-683"> 683</a></span>
<span class="normal"><a href="#__codelineno-0-684"> 684</a></span>
<span class="normal"><a href="#__codelineno-0-685"> 685</a></span>
<span class="normal"><a href="#__codelineno-0-686"> 686</a></span>
<span class="normal"><a href="#__codelineno-0-687"> 687</a></span>
<span class="normal"><a href="#__codelineno-0-688"> 688</a></span>
<span class="normal"><a href="#__codelineno-0-689"> 689</a></span>
<span class="normal"><a href="#__codelineno-0-690"> 690</a></span>
<span class="normal"><a href="#__codelineno-0-691"> 691</a></span>
<span class="normal"><a href="#__codelineno-0-692"> 692</a></span>
<span class="normal"><a href="#__codelineno-0-693"> 693</a></span>
<span class="normal"><a href="#__codelineno-0-694"> 694</a></span>
<span class="normal"><a href="#__codelineno-0-695"> 695</a></span>
<span class="normal"><a href="#__codelineno-0-696"> 696</a></span>
<span class="normal"><a href="#__codelineno-0-697"> 697</a></span>
<span class="normal"><a href="#__codelineno-0-698"> 698</a></span>
<span class="normal"><a href="#__codelineno-0-699"> 699</a></span>
<span class="normal"><a href="#__codelineno-0-700"> 700</a></span>
<span class="normal"><a href="#__codelineno-0-701"> 701</a></span>
<span class="normal"><a href="#__codelineno-0-702"> 702</a></span>
<span class="normal"><a href="#__codelineno-0-703"> 703</a></span>
<span class="normal"><a href="#__codelineno-0-704"> 704</a></span>
<span class="normal"><a href="#__codelineno-0-705"> 705</a></span>
<span class="normal"><a href="#__codelineno-0-706"> 706</a></span>
<span class="normal"><a href="#__codelineno-0-707"> 707</a></span>
<span class="normal"><a href="#__codelineno-0-708"> 708</a></span>
<span class="normal"><a href="#__codelineno-0-709"> 709</a></span>
<span class="normal"><a href="#__codelineno-0-710"> 710</a></span>
<span class="normal"><a href="#__codelineno-0-711"> 711</a></span>
<span class="normal"><a href="#__codelineno-0-712"> 712</a></span>
<span class="normal"><a href="#__codelineno-0-713"> 713</a></span>
<span class="normal"><a href="#__codelineno-0-714"> 714</a></span>
<span class="normal"><a href="#__codelineno-0-715"> 715</a></span>
<span class="normal"><a href="#__codelineno-0-716"> 716</a></span>
<span class="normal"><a href="#__codelineno-0-717"> 717</a></span>
<span class="normal"><a href="#__codelineno-0-718"> 718</a></span>
<span class="normal"><a href="#__codelineno-0-719"> 719</a></span>
<span class="normal"><a href="#__codelineno-0-720"> 720</a></span>
<span class="normal"><a href="#__codelineno-0-721"> 721</a></span>
<span class="normal"><a href="#__codelineno-0-722"> 722</a></span>
<span class="normal"><a href="#__codelineno-0-723"> 723</a></span>
<span class="normal"><a href="#__codelineno-0-724"> 724</a></span>
<span class="normal"><a href="#__codelineno-0-725"> 725</a></span>
<span class="normal"><a href="#__codelineno-0-726"> 726</a></span>
<span class="normal"><a href="#__codelineno-0-727"> 727</a></span>
<span class="normal"><a href="#__codelineno-0-728"> 728</a></span>
<span class="normal"><a href="#__codelineno-0-729"> 729</a></span>
<span class="normal"><a href="#__codelineno-0-730"> 730</a></span>
<span class="normal"><a href="#__codelineno-0-731"> 731</a></span>
<span class="normal"><a href="#__codelineno-0-732"> 732</a></span>
<span class="normal"><a href="#__codelineno-0-733"> 733</a></span>
<span class="normal"><a href="#__codelineno-0-734"> 734</a></span>
<span class="normal"><a href="#__codelineno-0-735"> 735</a></span>
<span class="normal"><a href="#__codelineno-0-736"> 736</a></span>
<span class="normal"><a href="#__codelineno-0-737"> 737</a></span>
<span class="normal"><a href="#__codelineno-0-738"> 738</a></span>
<span class="normal"><a href="#__codelineno-0-739"> 739</a></span>
<span class="normal"><a href="#__codelineno-0-740"> 740</a></span>
<span class="normal"><a href="#__codelineno-0-741"> 741</a></span>
<span class="normal"><a href="#__codelineno-0-742"> 742</a></span>
<span class="normal"><a href="#__codelineno-0-743"> 743</a></span>
<span class="normal"><a href="#__codelineno-0-744"> 744</a></span>
<span class="normal"><a href="#__codelineno-0-745"> 745</a></span>
<span class="normal"><a href="#__codelineno-0-746"> 746</a></span>
<span class="normal"><a href="#__codelineno-0-747"> 747</a></span>
<span class="normal"><a href="#__codelineno-0-748"> 748</a></span>
<span class="normal"><a href="#__codelineno-0-749"> 749</a></span>
<span class="normal"><a href="#__codelineno-0-750"> 750</a></span>
<span class="normal"><a href="#__codelineno-0-751"> 751</a></span>
<span class="normal"><a href="#__codelineno-0-752"> 752</a></span>
<span class="normal"><a href="#__codelineno-0-753"> 753</a></span>
<span class="normal"><a href="#__codelineno-0-754"> 754</a></span>
<span class="normal"><a href="#__codelineno-0-755"> 755</a></span>
<span class="normal"><a href="#__codelineno-0-756"> 756</a></span>
<span class="normal"><a href="#__codelineno-0-757"> 757</a></span>
<span class="normal"><a href="#__codelineno-0-758"> 758</a></span>
<span class="normal"><a href="#__codelineno-0-759"> 759</a></span>
<span class="normal"><a href="#__codelineno-0-760"> 760</a></span>
<span class="normal"><a href="#__codelineno-0-761"> 761</a></span>
<span class="normal"><a href="#__codelineno-0-762"> 762</a></span>
<span class="normal"><a href="#__codelineno-0-763"> 763</a></span>
<span class="normal"><a href="#__codelineno-0-764"> 764</a></span>
<span class="normal"><a href="#__codelineno-0-765"> 765</a></span>
<span class="normal"><a href="#__codelineno-0-766"> 766</a></span>
<span class="normal"><a href="#__codelineno-0-767"> 767</a></span>
<span class="normal"><a href="#__codelineno-0-768"> 768</a></span>
<span class="normal"><a href="#__codelineno-0-769"> 769</a></span>
<span class="normal"><a href="#__codelineno-0-770"> 770</a></span>
<span class="normal"><a href="#__codelineno-0-771"> 771</a></span>
<span class="normal"><a href="#__codelineno-0-772"> 772</a></span>
<span class="normal"><a href="#__codelineno-0-773"> 773</a></span>
<span class="normal"><a href="#__codelineno-0-774"> 774</a></span>
<span class="normal"><a href="#__codelineno-0-775"> 775</a></span>
<span class="normal"><a href="#__codelineno-0-776"> 776</a></span>
<span class="normal"><a href="#__codelineno-0-777"> 777</a></span>
<span class="normal"><a href="#__codelineno-0-778"> 778</a></span>
<span class="normal"><a href="#__codelineno-0-779"> 779</a></span>
<span class="normal"><a href="#__codelineno-0-780"> 780</a></span>
<span class="normal"><a href="#__codelineno-0-781"> 781</a></span>
<span class="normal"><a href="#__codelineno-0-782"> 782</a></span>
<span class="normal"><a href="#__codelineno-0-783"> 783</a></span>
<span class="normal"><a href="#__codelineno-0-784"> 784</a></span>
<span class="normal"><a href="#__codelineno-0-785"> 785</a></span>
<span class="normal"><a href="#__codelineno-0-786"> 786</a></span>
<span class="normal"><a href="#__codelineno-0-787"> 787</a></span>
<span class="normal"><a href="#__codelineno-0-788"> 788</a></span>
<span class="normal"><a href="#__codelineno-0-789"> 789</a></span>
<span class="normal"><a href="#__codelineno-0-790"> 790</a></span>
<span class="normal"><a href="#__codelineno-0-791"> 791</a></span>
<span class="normal"><a href="#__codelineno-0-792"> 792</a></span>
<span class="normal"><a href="#__codelineno-0-793"> 793</a></span>
<span class="normal"><a href="#__codelineno-0-794"> 794</a></span>
<span class="normal"><a href="#__codelineno-0-795"> 795</a></span>
<span class="normal"><a href="#__codelineno-0-796"> 796</a></span>
<span class="normal"><a href="#__codelineno-0-797"> 797</a></span>
<span class="normal"><a href="#__codelineno-0-798"> 798</a></span>
<span class="normal"><a href="#__codelineno-0-799"> 799</a></span>
<span class="normal"><a href="#__codelineno-0-800"> 800</a></span>
<span class="normal"><a href="#__codelineno-0-801"> 801</a></span>
<span class="normal"><a href="#__codelineno-0-802"> 802</a></span>
<span class="normal"><a href="#__codelineno-0-803"> 803</a></span>
<span class="normal"><a href="#__codelineno-0-804"> 804</a></span>
<span class="normal"><a href="#__codelineno-0-805"> 805</a></span>
<span class="normal"><a href="#__codelineno-0-806"> 806</a></span>
<span class="normal"><a href="#__codelineno-0-807"> 807</a></span>
<span class="normal"><a href="#__codelineno-0-808"> 808</a></span>
<span class="normal"><a href="#__codelineno-0-809"> 809</a></span>
<span class="normal"><a href="#__codelineno-0-810"> 810</a></span>
<span class="normal"><a href="#__codelineno-0-811"> 811</a></span>
<span class="normal"><a href="#__codelineno-0-812"> 812</a></span>
<span class="normal"><a href="#__codelineno-0-813"> 813</a></span>
<span class="normal"><a href="#__codelineno-0-814"> 814</a></span>
<span class="normal"><a href="#__codelineno-0-815"> 815</a></span>
<span class="normal"><a href="#__codelineno-0-816"> 816</a></span>
<span class="normal"><a href="#__codelineno-0-817"> 817</a></span>
<span class="normal"><a href="#__codelineno-0-818"> 818</a></span>
<span class="normal"><a href="#__codelineno-0-819"> 819</a></span>
<span class="normal"><a href="#__codelineno-0-820"> 820</a></span>
<span class="normal"><a href="#__codelineno-0-821"> 821</a></span>
<span class="normal"><a href="#__codelineno-0-822"> 822</a></span>
<span class="normal"><a href="#__codelineno-0-823"> 823</a></span>
<span class="normal"><a href="#__codelineno-0-824"> 824</a></span>
<span class="normal"><a href="#__codelineno-0-825"> 825</a></span>
<span class="normal"><a href="#__codelineno-0-826"> 826</a></span>
<span class="normal"><a href="#__codelineno-0-827"> 827</a></span>
<span class="normal"><a href="#__codelineno-0-828"> 828</a></span>
<span class="normal"><a href="#__codelineno-0-829"> 829</a></span>
<span class="normal"><a href="#__codelineno-0-830"> 830</a></span>
<span class="normal"><a href="#__codelineno-0-831"> 831</a></span>
<span class="normal"><a href="#__codelineno-0-832"> 832</a></span>
<span class="normal"><a href="#__codelineno-0-833"> 833</a></span>
<span class="normal"><a href="#__codelineno-0-834"> 834</a></span>
<span class="normal"><a href="#__codelineno-0-835"> 835</a></span>
<span class="normal"><a href="#__codelineno-0-836"> 836</a></span>
<span class="normal"><a href="#__codelineno-0-837"> 837</a></span>
<span class="normal"><a href="#__codelineno-0-838"> 838</a></span>
<span class="normal"><a href="#__codelineno-0-839"> 839</a></span>
<span class="normal"><a href="#__codelineno-0-840"> 840</a></span>
<span class="normal"><a href="#__codelineno-0-841"> 841</a></span>
<span class="normal"><a href="#__codelineno-0-842"> 842</a></span>
<span class="normal"><a href="#__codelineno-0-843"> 843</a></span>
<span class="normal"><a href="#__codelineno-0-844"> 844</a></span>
<span class="normal"><a href="#__codelineno-0-845"> 845</a></span>
<span class="normal"><a href="#__codelineno-0-846"> 846</a></span>
<span class="normal"><a href="#__codelineno-0-847"> 847</a></span>
<span class="normal"><a href="#__codelineno-0-848"> 848</a></span>
<span class="normal"><a href="#__codelineno-0-849"> 849</a></span>
<span class="normal"><a href="#__codelineno-0-850"> 850</a></span>
<span class="normal"><a href="#__codelineno-0-851"> 851</a></span>
<span class="normal"><a href="#__codelineno-0-852"> 852</a></span>
<span class="normal"><a href="#__codelineno-0-853"> 853</a></span>
<span class="normal"><a href="#__codelineno-0-854"> 854</a></span>
<span class="normal"><a href="#__codelineno-0-855"> 855</a></span>
<span class="normal"><a href="#__codelineno-0-856"> 856</a></span>
<span class="normal"><a href="#__codelineno-0-857"> 857</a></span>
<span class="normal"><a href="#__codelineno-0-858"> 858</a></span>
<span class="normal"><a href="#__codelineno-0-859"> 859</a></span>
<span class="normal"><a href="#__codelineno-0-860"> 860</a></span>
<span class="normal"><a href="#__codelineno-0-861"> 861</a></span>
<span class="normal"><a href="#__codelineno-0-862"> 862</a></span>
<span class="normal"><a href="#__codelineno-0-863"> 863</a></span>
<span class="normal"><a href="#__codelineno-0-864"> 864</a></span>
<span class="normal"><a href="#__codelineno-0-865"> 865</a></span>
<span class="normal"><a href="#__codelineno-0-866"> 866</a></span>
<span class="normal"><a href="#__codelineno-0-867"> 867</a></span>
<span class="normal"><a href="#__codelineno-0-868"> 868</a></span>
<span class="normal"><a href="#__codelineno-0-869"> 869</a></span>
<span class="normal"><a href="#__codelineno-0-870"> 870</a></span>
<span class="normal"><a href="#__codelineno-0-871"> 871</a></span>
<span class="normal"><a href="#__codelineno-0-872"> 872</a></span>
<span class="normal"><a href="#__codelineno-0-873"> 873</a></span>
<span class="normal"><a href="#__codelineno-0-874"> 874</a></span>
<span class="normal"><a href="#__codelineno-0-875"> 875</a></span>
<span class="normal"><a href="#__codelineno-0-876"> 876</a></span>
<span class="normal"><a href="#__codelineno-0-877"> 877</a></span>
<span class="normal"><a href="#__codelineno-0-878"> 878</a></span>
<span class="normal"><a href="#__codelineno-0-879"> 879</a></span>
<span class="normal"><a href="#__codelineno-0-880"> 880</a></span>
<span class="normal"><a href="#__codelineno-0-881"> 881</a></span>
<span class="normal"><a href="#__codelineno-0-882"> 882</a></span>
<span class="normal"><a href="#__codelineno-0-883"> 883</a></span>
<span class="normal"><a href="#__codelineno-0-884"> 884</a></span>
<span class="normal"><a href="#__codelineno-0-885"> 885</a></span>
<span class="normal"><a href="#__codelineno-0-886"> 886</a></span>
<span class="normal"><a href="#__codelineno-0-887"> 887</a></span>
<span class="normal"><a href="#__codelineno-0-888"> 888</a></span>
<span class="normal"><a href="#__codelineno-0-889"> 889</a></span>
<span class="normal"><a href="#__codelineno-0-890"> 890</a></span>
<span class="normal"><a href="#__codelineno-0-891"> 891</a></span>
<span class="normal"><a href="#__codelineno-0-892"> 892</a></span>
<span class="normal"><a href="#__codelineno-0-893"> 893</a></span>
<span class="normal"><a href="#__codelineno-0-894"> 894</a></span>
<span class="normal"><a href="#__codelineno-0-895"> 895</a></span>
<span class="normal"><a href="#__codelineno-0-896"> 896</a></span>
<span class="normal"><a href="#__codelineno-0-897"> 897</a></span>
<span class="normal"><a href="#__codelineno-0-898"> 898</a></span>
<span class="normal"><a href="#__codelineno-0-899"> 899</a></span>
<span class="normal"><a href="#__codelineno-0-900"> 900</a></span>
<span class="normal"><a href="#__codelineno-0-901"> 901</a></span>
<span class="normal"><a href="#__codelineno-0-902"> 902</a></span>
<span class="normal"><a href="#__codelineno-0-903"> 903</a></span>
<span class="normal"><a href="#__codelineno-0-904"> 904</a></span>
<span class="normal"><a href="#__codelineno-0-905"> 905</a></span>
<span class="normal"><a href="#__codelineno-0-906"> 906</a></span>
<span class="normal"><a href="#__codelineno-0-907"> 907</a></span>
<span class="normal"><a href="#__codelineno-0-908"> 908</a></span>
<span class="normal"><a href="#__codelineno-0-909"> 909</a></span>
<span class="normal"><a href="#__codelineno-0-910"> 910</a></span>
<span class="normal"><a href="#__codelineno-0-911"> 911</a></span>
<span class="normal"><a href="#__codelineno-0-912"> 912</a></span>
<span class="normal"><a href="#__codelineno-0-913"> 913</a></span>
<span class="normal"><a href="#__codelineno-0-914"> 914</a></span>
<span class="normal"><a href="#__codelineno-0-915"> 915</a></span>
<span class="normal"><a href="#__codelineno-0-916"> 916</a></span>
<span class="normal"><a href="#__codelineno-0-917"> 917</a></span>
<span class="normal"><a href="#__codelineno-0-918"> 918</a></span>
<span class="normal"><a href="#__codelineno-0-919"> 919</a></span>
<span class="normal"><a href="#__codelineno-0-920"> 920</a></span>
<span class="normal"><a href="#__codelineno-0-921"> 921</a></span>
<span class="normal"><a href="#__codelineno-0-922"> 922</a></span>
<span class="normal"><a href="#__codelineno-0-923"> 923</a></span>
<span class="normal"><a href="#__codelineno-0-924"> 924</a></span>
<span class="normal"><a href="#__codelineno-0-925"> 925</a></span>
<span class="normal"><a href="#__codelineno-0-926"> 926</a></span>
<span class="normal"><a href="#__codelineno-0-927"> 927</a></span>
<span class="normal"><a href="#__codelineno-0-928"> 928</a></span>
<span class="normal"><a href="#__codelineno-0-929"> 929</a></span>
<span class="normal"><a href="#__codelineno-0-930"> 930</a></span>
<span class="normal"><a href="#__codelineno-0-931"> 931</a></span>
<span class="normal"><a href="#__codelineno-0-932"> 932</a></span>
<span class="normal"><a href="#__codelineno-0-933"> 933</a></span>
<span class="normal"><a href="#__codelineno-0-934"> 934</a></span>
<span class="normal"><a href="#__codelineno-0-935"> 935</a></span>
<span class="normal"><a href="#__codelineno-0-936"> 936</a></span>
<span class="normal"><a href="#__codelineno-0-937"> 937</a></span>
<span class="normal"><a href="#__codelineno-0-938"> 938</a></span>
<span class="normal"><a href="#__codelineno-0-939"> 939</a></span>
<span class="normal"><a href="#__codelineno-0-940"> 940</a></span>
<span class="normal"><a href="#__codelineno-0-941"> 941</a></span>
<span class="normal"><a href="#__codelineno-0-942"> 942</a></span>
<span class="normal"><a href="#__codelineno-0-943"> 943</a></span>
<span class="normal"><a href="#__codelineno-0-944"> 944</a></span>
<span class="normal"><a href="#__codelineno-0-945"> 945</a></span>
<span class="normal"><a href="#__codelineno-0-946"> 946</a></span>
<span class="normal"><a href="#__codelineno-0-947"> 947</a></span>
<span class="normal"><a href="#__codelineno-0-948"> 948</a></span>
<span class="normal"><a href="#__codelineno-0-949"> 949</a></span>
<span class="normal"><a href="#__codelineno-0-950"> 950</a></span>
<span class="normal"><a href="#__codelineno-0-951"> 951</a></span>
<span class="normal"><a href="#__codelineno-0-952"> 952</a></span>
<span class="normal"><a href="#__codelineno-0-953"> 953</a></span>
<span class="normal"><a href="#__codelineno-0-954"> 954</a></span>
<span class="normal"><a href="#__codelineno-0-955"> 955</a></span>
<span class="normal"><a href="#__codelineno-0-956"> 956</a></span>
<span class="normal"><a href="#__codelineno-0-957"> 957</a></span>
<span class="normal"><a href="#__codelineno-0-958"> 958</a></span>
<span class="normal"><a href="#__codelineno-0-959"> 959</a></span>
<span class="normal"><a href="#__codelineno-0-960"> 960</a></span>
<span class="normal"><a href="#__codelineno-0-961"> 961</a></span>
<span class="normal"><a href="#__codelineno-0-962"> 962</a></span>
<span class="normal"><a href="#__codelineno-0-963"> 963</a></span>
<span class="normal"><a href="#__codelineno-0-964"> 964</a></span>
<span class="normal"><a href="#__codelineno-0-965"> 965</a></span>
<span class="normal"><a href="#__codelineno-0-966"> 966</a></span>
<span class="normal"><a href="#__codelineno-0-967"> 967</a></span>
<span class="normal"><a href="#__codelineno-0-968"> 968</a></span>
<span class="normal"><a href="#__codelineno-0-969"> 969</a></span>
<span class="normal"><a href="#__codelineno-0-970"> 970</a></span>
<span class="normal"><a href="#__codelineno-0-971"> 971</a></span>
<span class="normal"><a href="#__codelineno-0-972"> 972</a></span>
<span class="normal"><a href="#__codelineno-0-973"> 973</a></span>
<span class="normal"><a href="#__codelineno-0-974"> 974</a></span>
<span class="normal"><a href="#__codelineno-0-975"> 975</a></span>
<span class="normal"><a href="#__codelineno-0-976"> 976</a></span>
<span class="normal"><a href="#__codelineno-0-977"> 977</a></span>
<span class="normal"><a href="#__codelineno-0-978"> 978</a></span>
<span class="normal"><a href="#__codelineno-0-979"> 979</a></span>
<span class="normal"><a href="#__codelineno-0-980"> 980</a></span>
<span class="normal"><a href="#__codelineno-0-981"> 981</a></span>
<span class="normal"><a href="#__codelineno-0-982"> 982</a></span>
<span class="normal"><a href="#__codelineno-0-983"> 983</a></span>
<span class="normal"><a href="#__codelineno-0-984"> 984</a></span>
<span class="normal"><a href="#__codelineno-0-985"> 985</a></span>
<span class="normal"><a href="#__codelineno-0-986"> 986</a></span>
<span class="normal"><a href="#__codelineno-0-987"> 987</a></span>
<span class="normal"><a href="#__codelineno-0-988"> 988</a></span>
<span class="normal"><a href="#__codelineno-0-989"> 989</a></span>
<span class="normal"><a href="#__codelineno-0-990"> 990</a></span>
<span class="normal"><a href="#__codelineno-0-991"> 991</a></span>
<span class="normal"><a href="#__codelineno-0-992"> 992</a></span>
<span class="normal"><a href="#__codelineno-0-993"> 993</a></span>
<span class="normal"><a href="#__codelineno-0-994"> 994</a></span>
<span class="normal"><a href="#__codelineno-0-995"> 995</a></span>
<span class="normal"><a href="#__codelineno-0-996"> 996</a></span>
<span class="normal"><a href="#__codelineno-0-997"> 997</a></span>
<span class="normal"><a href="#__codelineno-0-998"> 998</a></span>
<span class="normal"><a href="#__codelineno-0-999"> 999</a></span>
<span class="normal"><a href="#__codelineno-0-1000">1000</a></span>
<span class="normal"><a href="#__codelineno-0-1001">1001</a></span>
<span class="normal"><a href="#__codelineno-0-1002">1002</a></span>
<span class="normal"><a href="#__codelineno-0-1003">1003</a></span>
<span class="normal"><a href="#__codelineno-0-1004">1004</a></span>
<span class="normal"><a href="#__codelineno-0-1005">1005</a></span>
<span class="normal"><a href="#__codelineno-0-1006">1006</a></span>
<span class="normal"><a href="#__codelineno-0-1007">1007</a></span>
<span class="normal"><a href="#__codelineno-0-1008">1008</a></span>
<span class="normal"><a href="#__codelineno-0-1009">1009</a></span>
<span class="normal"><a href="#__codelineno-0-1010">1010</a></span>
<span class="normal"><a href="#__codelineno-0-1011">1011</a></span>
<span class="normal"><a href="#__codelineno-0-1012">1012</a></span>
<span class="normal"><a href="#__codelineno-0-1013">1013</a></span>
<span class="normal"><a href="#__codelineno-0-1014">1014</a></span>
<span class="normal"><a href="#__codelineno-0-1015">1015</a></span>
<span class="normal"><a href="#__codelineno-0-1016">1016</a></span>
<span class="normal"><a href="#__codelineno-0-1017">1017</a></span>
<span class="normal"><a href="#__codelineno-0-1018">1018</a></span>
<span class="normal"><a href="#__codelineno-0-1019">1019</a></span>
<span class="normal"><a href="#__codelineno-0-1020">1020</a></span>
<span class="normal"><a href="#__codelineno-0-1021">1021</a></span>
<span class="normal"><a href="#__codelineno-0-1022">1022</a></span>
<span class="normal"><a href="#__codelineno-0-1023">1023</a></span>
<span class="normal"><a href="#__codelineno-0-1024">1024</a></span>
<span class="normal"><a href="#__codelineno-0-1025">1025</a></span>
<span class="normal"><a href="#__codelineno-0-1026">1026</a></span>
<span class="normal"><a href="#__codelineno-0-1027">1027</a></span>
<span class="normal"><a href="#__codelineno-0-1028">1028</a></span>
<span class="normal"><a href="#__codelineno-0-1029">1029</a></span>
<span class="normal"><a href="#__codelineno-0-1030">1030</a></span>
<span class="normal"><a href="#__codelineno-0-1031">1031</a></span>
<span class="normal"><a href="#__codelineno-0-1032">1032</a></span>
<span class="normal"><a href="#__codelineno-0-1033">1033</a></span>
<span class="normal"><a href="#__codelineno-0-1034">1034</a></span>
<span class="normal"><a href="#__codelineno-0-1035">1035</a></span>
<span class="normal"><a href="#__codelineno-0-1036">1036</a></span>
<span class="normal"><a href="#__codelineno-0-1037">1037</a></span>
<span class="normal"><a href="#__codelineno-0-1038">1038</a></span>
<span class="normal"><a href="#__codelineno-0-1039">1039</a></span>
<span class="normal"><a href="#__codelineno-0-1040">1040</a></span>
<span class="normal"><a href="#__codelineno-0-1041">1041</a></span>
<span class="normal"><a href="#__codelineno-0-1042">1042</a></span>
<span class="normal"><a href="#__codelineno-0-1043">1043</a></span>
<span class="normal"><a href="#__codelineno-0-1044">1044</a></span>
<span class="normal"><a href="#__codelineno-0-1045">1045</a></span>
<span class="normal"><a href="#__codelineno-0-1046">1046</a></span>
<span class="normal"><a href="#__codelineno-0-1047">1047</a></span>
<span class="normal"><a href="#__codelineno-0-1048">1048</a></span>
<span class="normal"><a href="#__codelineno-0-1049">1049</a></span>
<span class="normal"><a href="#__codelineno-0-1050">1050</a></span>
<span class="normal"><a href="#__codelineno-0-1051">1051</a></span>
<span class="normal"><a href="#__codelineno-0-1052">1052</a></span>
<span class="normal"><a href="#__codelineno-0-1053">1053</a></span>
<span class="normal"><a href="#__codelineno-0-1054">1054</a></span>
<span class="normal"><a href="#__codelineno-0-1055">1055</a></span>
<span class="normal"><a href="#__codelineno-0-1056">1056</a></span>
<span class="normal"><a href="#__codelineno-0-1057">1057</a></span>
<span class="normal"><a href="#__codelineno-0-1058">1058</a></span>
<span class="normal"><a href="#__codelineno-0-1059">1059</a></span>
<span class="normal"><a href="#__codelineno-0-1060">1060</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-53"><a id="__codelineno-0-53" name="__codelineno-0-53"></a><span class="k">class</span><span class="w"> </span><span class="nc">SocketBridge</span><span class="p">(</span><span class="n">FreecadBridge</span><span class="p">):</span>
</span><span id="__span-0-54"><a id="__codelineno-0-54" name="__codelineno-0-54"></a><span class="w"> </span><span class="sd">"""Bridge that communicates with FreeCAD via JSON-RPC over sockets.</span>
</span><span id="__span-0-55"><a id="__codelineno-0-55" name="__codelineno-0-55"></a>
</span><span id="__span-0-56"><a id="__codelineno-0-56" name="__codelineno-0-56"></a><span class="sd"> This bridge provides a lightweight, modern protocol for FreeCAD</span>
</span><span id="__span-0-57"><a id="__codelineno-0-57" name="__codelineno-0-57"></a><span class="sd"> communication. It supports automatic reconnection and connection</span>
</span><span id="__span-0-58"><a id="__codelineno-0-58" name="__codelineno-0-58"></a><span class="sd"> health monitoring.</span>
</span><span id="__span-0-59"><a id="__codelineno-0-59" name="__codelineno-0-59"></a>
</span><span id="__span-0-60"><a id="__codelineno-0-60" name="__codelineno-0-60"></a><span class="sd"> Attributes:</span>
</span><span id="__span-0-61"><a id="__codelineno-0-61" name="__codelineno-0-61"></a><span class="sd"> host: Socket server hostname.</span>
</span><span id="__span-0-62"><a id="__codelineno-0-62" name="__codelineno-0-62"></a><span class="sd"> port: Socket server port.</span>
</span><span id="__span-0-63"><a id="__codelineno-0-63" name="__codelineno-0-63"></a><span class="sd"> timeout: Connection and request timeout in seconds.</span>
</span><span id="__span-0-64"><a id="__codelineno-0-64" name="__codelineno-0-64"></a><span class="sd"> """</span>
</span><span id="__span-0-65"><a id="__codelineno-0-65" name="__codelineno-0-65"></a>
</span><span id="__span-0-66"><a id="__codelineno-0-66" name="__codelineno-0-66"></a> <span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span>
</span><span id="__span-0-67"><a id="__codelineno-0-67" name="__codelineno-0-67"></a> <span class="bp">self</span><span class="p">,</span>
</span><span id="__span-0-68"><a id="__codelineno-0-68" name="__codelineno-0-68"></a> <span class="n">host</span><span class="p">:</span> <span class="nb">str</span> <span class="o">=</span> <span class="n">DEFAULT_SOCKET_HOST</span><span class="p">,</span>
</span><span id="__span-0-69"><a id="__codelineno-0-69" name="__codelineno-0-69"></a> <span class="n">port</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="n">DEFAULT_SOCKET_PORT</span><span class="p">,</span>
</span><span id="__span-0-70"><a id="__codelineno-0-70" name="__codelineno-0-70"></a> <span class="n">timeout</span><span class="p">:</span> <span class="nb">float</span> <span class="o">=</span> <span class="n">DEFAULT_TIMEOUT</span><span class="p">,</span>
</span><span id="__span-0-71"><a id="__codelineno-0-71" name="__codelineno-0-71"></a> <span class="n">auto_reconnect</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">True</span><span class="p">,</span>
</span><span id="__span-0-72"><a id="__codelineno-0-72" name="__codelineno-0-72"></a> <span class="p">)</span> <span class="o">-&gt;</span> <span class="kc">None</span><span class="p">:</span>
</span><span id="__span-0-73"><a id="__codelineno-0-73" name="__codelineno-0-73"></a><span class="w"> </span><span class="sd">"""Initialize the socket bridge.</span>
</span><span id="__span-0-74"><a id="__codelineno-0-74" name="__codelineno-0-74"></a>
</span><span id="__span-0-75"><a id="__codelineno-0-75" name="__codelineno-0-75"></a><span class="sd"> Args:</span>
</span><span id="__span-0-76"><a id="__codelineno-0-76" name="__codelineno-0-76"></a><span class="sd"> host: Socket server hostname.</span>
</span><span id="__span-0-77"><a id="__codelineno-0-77" name="__codelineno-0-77"></a><span class="sd"> port: Socket server port.</span>
</span><span id="__span-0-78"><a id="__codelineno-0-78" name="__codelineno-0-78"></a><span class="sd"> timeout: Connection and request timeout in seconds.</span>
</span><span id="__span-0-79"><a id="__codelineno-0-79" name="__codelineno-0-79"></a><span class="sd"> auto_reconnect: Whether to automatically reconnect on connection loss.</span>
</span><span id="__span-0-80"><a id="__codelineno-0-80" name="__codelineno-0-80"></a><span class="sd"> """</span>
</span><span id="__span-0-81"><a id="__codelineno-0-81" name="__codelineno-0-81"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_host</span> <span class="o">=</span> <span class="n">host</span>
</span><span id="__span-0-82"><a id="__codelineno-0-82" name="__codelineno-0-82"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_port</span> <span class="o">=</span> <span class="n">port</span>
</span><span id="__span-0-83"><a id="__codelineno-0-83" name="__codelineno-0-83"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_timeout</span> <span class="o">=</span> <span class="n">timeout</span>
</span><span id="__span-0-84"><a id="__codelineno-0-84" name="__codelineno-0-84"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_auto_reconnect</span> <span class="o">=</span> <span class="n">auto_reconnect</span>
</span><span id="__span-0-85"><a id="__codelineno-0-85" name="__codelineno-0-85"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_reader</span><span class="p">:</span> <span class="n">asyncio</span><span class="o">.</span><span class="n">StreamReader</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span>
</span><span id="__span-0-86"><a id="__codelineno-0-86" name="__codelineno-0-86"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_writer</span><span class="p">:</span> <span class="n">asyncio</span><span class="o">.</span><span class="n">StreamWriter</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span>
</span><span id="__span-0-87"><a id="__codelineno-0-87" name="__codelineno-0-87"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_connected</span> <span class="o">=</span> <span class="kc">False</span>
</span><span id="__span-0-88"><a id="__codelineno-0-88" name="__codelineno-0-88"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_lock</span> <span class="o">=</span> <span class="n">asyncio</span><span class="o">.</span><span class="n">Lock</span><span class="p">()</span>
</span><span id="__span-0-89"><a id="__codelineno-0-89" name="__codelineno-0-89"></a>
</span><span id="__span-0-90"><a id="__codelineno-0-90" name="__codelineno-0-90"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">connect</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kc">None</span><span class="p">:</span>
</span><span id="__span-0-91"><a id="__codelineno-0-91" name="__codelineno-0-91"></a><span class="w"> </span><span class="sd">"""Establish connection to FreeCAD socket server.</span>
</span><span id="__span-0-92"><a id="__codelineno-0-92" name="__codelineno-0-92"></a>
</span><span id="__span-0-93"><a id="__codelineno-0-93" name="__codelineno-0-93"></a><span class="sd"> Raises:</span>
</span><span id="__span-0-94"><a id="__codelineno-0-94" name="__codelineno-0-94"></a><span class="sd"> ConnectionError: If connection cannot be established.</span>
</span><span id="__span-0-95"><a id="__codelineno-0-95" name="__codelineno-0-95"></a><span class="sd"> """</span>
</span><span id="__span-0-96"><a id="__codelineno-0-96" name="__codelineno-0-96"></a> <span class="k">try</span><span class="p">:</span>
</span><span id="__span-0-97"><a id="__codelineno-0-97" name="__codelineno-0-97"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_reader</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">_writer</span> <span class="o">=</span> <span class="k">await</span> <span class="n">asyncio</span><span class="o">.</span><span class="n">wait_for</span><span class="p">(</span>
</span><span id="__span-0-98"><a id="__codelineno-0-98" name="__codelineno-0-98"></a> <span class="n">asyncio</span><span class="o">.</span><span class="n">open_connection</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_host</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">_port</span><span class="p">),</span>
</span><span id="__span-0-99"><a id="__codelineno-0-99" name="__codelineno-0-99"></a> <span class="n">timeout</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">_timeout</span><span class="p">,</span>
</span><span id="__span-0-100"><a id="__codelineno-0-100" name="__codelineno-0-100"></a> <span class="p">)</span>
</span><span id="__span-0-101"><a id="__codelineno-0-101" name="__codelineno-0-101"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_connected</span> <span class="o">=</span> <span class="kc">True</span>
</span><span id="__span-0-102"><a id="__codelineno-0-102" name="__codelineno-0-102"></a>
</span><span id="__span-0-103"><a id="__codelineno-0-103" name="__codelineno-0-103"></a> <span class="c1"># Verify connection with a ping</span>
</span><span id="__span-0-104"><a id="__codelineno-0-104" name="__codelineno-0-104"></a> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">ping</span><span class="p">()</span>
</span><span id="__span-0-105"><a id="__codelineno-0-105" name="__codelineno-0-105"></a> <span class="k">except</span> <span class="ne">TimeoutError</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
</span><span id="__span-0-106"><a id="__codelineno-0-106" name="__codelineno-0-106"></a> <span class="n">msg</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">"Connection to </span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">_host</span><span class="si">}</span><span class="s2">:</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">_port</span><span class="si">}</span><span class="s2"> timed out"</span>
</span><span id="__span-0-107"><a id="__codelineno-0-107" name="__codelineno-0-107"></a> <span class="k">raise</span> <span class="ne">ConnectionError</span><span class="p">(</span><span class="n">msg</span><span class="p">)</span> <span class="kn">from</span><span class="w"> </span><span class="nn">e</span>
</span><span id="__span-0-108"><a id="__codelineno-0-108" name="__codelineno-0-108"></a> <span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
</span><span id="__span-0-109"><a id="__codelineno-0-109" name="__codelineno-0-109"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_connected</span> <span class="o">=</span> <span class="kc">False</span>
</span><span id="__span-0-110"><a id="__codelineno-0-110" name="__codelineno-0-110"></a> <span class="n">msg</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">"Failed to connect to </span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">_host</span><span class="si">}</span><span class="s2">:</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">_port</span><span class="si">}</span><span class="s2">: </span><span class="si">{</span><span class="n">e</span><span class="si">}</span><span class="s2">"</span>
</span><span id="__span-0-111"><a id="__codelineno-0-111" name="__codelineno-0-111"></a> <span class="k">raise</span> <span class="ne">ConnectionError</span><span class="p">(</span><span class="n">msg</span><span class="p">)</span> <span class="kn">from</span><span class="w"> </span><span class="nn">e</span>
</span><span id="__span-0-112"><a id="__codelineno-0-112" name="__codelineno-0-112"></a>
</span><span id="__span-0-113"><a id="__codelineno-0-113" name="__codelineno-0-113"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">disconnect</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kc">None</span><span class="p">:</span>
</span><span id="__span-0-114"><a id="__codelineno-0-114" name="__codelineno-0-114"></a><span class="w"> </span><span class="sd">"""Close connection to FreeCAD socket server."""</span>
</span><span id="__span-0-115"><a id="__codelineno-0-115" name="__codelineno-0-115"></a> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_writer</span><span class="p">:</span>
</span><span id="__span-0-116"><a id="__codelineno-0-116" name="__codelineno-0-116"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_writer</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
</span><span id="__span-0-117"><a id="__codelineno-0-117" name="__codelineno-0-117"></a> <span class="k">with</span> <span class="n">contextlib</span><span class="o">.</span><span class="n">suppress</span><span class="p">(</span><span class="ne">Exception</span><span class="p">):</span>
</span><span id="__span-0-118"><a id="__codelineno-0-118" name="__codelineno-0-118"></a> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">_writer</span><span class="o">.</span><span class="n">wait_closed</span><span class="p">()</span>
</span><span id="__span-0-119"><a id="__codelineno-0-119" name="__codelineno-0-119"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_reader</span> <span class="o">=</span> <span class="kc">None</span>
</span><span id="__span-0-120"><a id="__codelineno-0-120" name="__codelineno-0-120"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_writer</span> <span class="o">=</span> <span class="kc">None</span>
</span><span id="__span-0-121"><a id="__codelineno-0-121" name="__codelineno-0-121"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_connected</span> <span class="o">=</span> <span class="kc">False</span>
</span><span id="__span-0-122"><a id="__codelineno-0-122" name="__codelineno-0-122"></a>
</span><span id="__span-0-123"><a id="__codelineno-0-123" name="__codelineno-0-123"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">is_connected</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">bool</span><span class="p">:</span>
</span><span id="__span-0-124"><a id="__codelineno-0-124" name="__codelineno-0-124"></a><span class="w"> </span><span class="sd">"""Check if bridge is connected to FreeCAD."""</span>
</span><span id="__span-0-125"><a id="__codelineno-0-125" name="__codelineno-0-125"></a> <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">_connected</span> <span class="ow">or</span> <span class="bp">self</span><span class="o">.</span><span class="n">_writer</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
</span><span id="__span-0-126"><a id="__codelineno-0-126" name="__codelineno-0-126"></a> <span class="k">return</span> <span class="kc">False</span>
</span><span id="__span-0-127"><a id="__codelineno-0-127" name="__codelineno-0-127"></a>
</span><span id="__span-0-128"><a id="__codelineno-0-128" name="__codelineno-0-128"></a> <span class="k">try</span><span class="p">:</span>
</span><span id="__span-0-129"><a id="__codelineno-0-129" name="__codelineno-0-129"></a> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">ping</span><span class="p">()</span>
</span><span id="__span-0-130"><a id="__codelineno-0-130" name="__codelineno-0-130"></a> <span class="k">return</span> <span class="kc">True</span>
</span><span id="__span-0-131"><a id="__codelineno-0-131" name="__codelineno-0-131"></a> <span class="k">except</span> <span class="ne">Exception</span><span class="p">:</span>
</span><span id="__span-0-132"><a id="__codelineno-0-132" name="__codelineno-0-132"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_connected</span> <span class="o">=</span> <span class="kc">False</span>
</span><span id="__span-0-133"><a id="__codelineno-0-133" name="__codelineno-0-133"></a> <span class="k">return</span> <span class="kc">False</span>
</span><span id="__span-0-134"><a id="__codelineno-0-134" name="__codelineno-0-134"></a>
</span><span id="__span-0-135"><a id="__codelineno-0-135" name="__codelineno-0-135"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">_send_request</span><span class="p">(</span>
</span><span id="__span-0-136"><a id="__codelineno-0-136" name="__codelineno-0-136"></a> <span class="bp">self</span><span class="p">,</span>
</span><span id="__span-0-137"><a id="__codelineno-0-137" name="__codelineno-0-137"></a> <span class="n">method</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span>
</span><span id="__span-0-138"><a id="__codelineno-0-138" name="__codelineno-0-138"></a> <span class="n">params</span><span class="p">:</span> <span class="nb">dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Any</span><span class="p">]</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-139"><a id="__codelineno-0-139" name="__codelineno-0-139"></a> <span class="p">)</span> <span class="o">-&gt;</span> <span class="n">Any</span><span class="p">:</span>
</span><span id="__span-0-140"><a id="__codelineno-0-140" name="__codelineno-0-140"></a><span class="w"> </span><span class="sd">"""Send a JSON-RPC request and wait for response.</span>
</span><span id="__span-0-141"><a id="__codelineno-0-141" name="__codelineno-0-141"></a>
</span><span id="__span-0-142"><a id="__codelineno-0-142" name="__codelineno-0-142"></a><span class="sd"> Args:</span>
</span><span id="__span-0-143"><a id="__codelineno-0-143" name="__codelineno-0-143"></a><span class="sd"> method: Method name to call.</span>
</span><span id="__span-0-144"><a id="__codelineno-0-144" name="__codelineno-0-144"></a><span class="sd"> params: Method parameters.</span>
</span><span id="__span-0-145"><a id="__codelineno-0-145" name="__codelineno-0-145"></a>
</span><span id="__span-0-146"><a id="__codelineno-0-146" name="__codelineno-0-146"></a><span class="sd"> Returns:</span>
</span><span id="__span-0-147"><a id="__codelineno-0-147" name="__codelineno-0-147"></a><span class="sd"> Result from the JSON-RPC response.</span>
</span><span id="__span-0-148"><a id="__codelineno-0-148" name="__codelineno-0-148"></a>
</span><span id="__span-0-149"><a id="__codelineno-0-149" name="__codelineno-0-149"></a><span class="sd"> Raises:</span>
</span><span id="__span-0-150"><a id="__codelineno-0-150" name="__codelineno-0-150"></a><span class="sd"> ConnectionError: If not connected.</span>
</span><span id="__span-0-151"><a id="__codelineno-0-151" name="__codelineno-0-151"></a><span class="sd"> JsonRpcError: If server returns an error.</span>
</span><span id="__span-0-152"><a id="__codelineno-0-152" name="__codelineno-0-152"></a><span class="sd"> """</span>
</span><span id="__span-0-153"><a id="__codelineno-0-153" name="__codelineno-0-153"></a> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_writer</span> <span class="ow">is</span> <span class="kc">None</span> <span class="ow">or</span> <span class="bp">self</span><span class="o">.</span><span class="n">_reader</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
</span><span id="__span-0-154"><a id="__codelineno-0-154" name="__codelineno-0-154"></a> <span class="n">msg</span> <span class="o">=</span> <span class="s2">"Not connected to socket server"</span>
</span><span id="__span-0-155"><a id="__codelineno-0-155" name="__codelineno-0-155"></a> <span class="k">raise</span> <span class="ne">ConnectionError</span><span class="p">(</span><span class="n">msg</span><span class="p">)</span>
</span><span id="__span-0-156"><a id="__codelineno-0-156" name="__codelineno-0-156"></a>
</span><span id="__span-0-157"><a id="__codelineno-0-157" name="__codelineno-0-157"></a> <span class="c1"># Build JSON-RPC request</span>
</span><span id="__span-0-158"><a id="__codelineno-0-158" name="__codelineno-0-158"></a> <span class="n">request_id</span> <span class="o">=</span> <span class="nb">str</span><span class="p">(</span><span class="n">uuid</span><span class="o">.</span><span class="n">uuid4</span><span class="p">())</span>
</span><span id="__span-0-159"><a id="__codelineno-0-159" name="__codelineno-0-159"></a> <span class="n">request</span> <span class="o">=</span> <span class="p">{</span>
</span><span id="__span-0-160"><a id="__codelineno-0-160" name="__codelineno-0-160"></a> <span class="s2">"jsonrpc"</span><span class="p">:</span> <span class="s2">"2.0"</span><span class="p">,</span>
</span><span id="__span-0-161"><a id="__codelineno-0-161" name="__codelineno-0-161"></a> <span class="s2">"id"</span><span class="p">:</span> <span class="n">request_id</span><span class="p">,</span>
</span><span id="__span-0-162"><a id="__codelineno-0-162" name="__codelineno-0-162"></a> <span class="s2">"method"</span><span class="p">:</span> <span class="n">method</span><span class="p">,</span>
</span><span id="__span-0-163"><a id="__codelineno-0-163" name="__codelineno-0-163"></a> <span class="s2">"params"</span><span class="p">:</span> <span class="n">params</span> <span class="ow">or</span> <span class="p">{},</span>
</span><span id="__span-0-164"><a id="__codelineno-0-164" name="__codelineno-0-164"></a> <span class="p">}</span>
</span><span id="__span-0-165"><a id="__codelineno-0-165" name="__codelineno-0-165"></a>
</span><span id="__span-0-166"><a id="__codelineno-0-166" name="__codelineno-0-166"></a> <span class="k">async</span> <span class="k">with</span> <span class="bp">self</span><span class="o">.</span><span class="n">_lock</span><span class="p">:</span>
</span><span id="__span-0-167"><a id="__codelineno-0-167" name="__codelineno-0-167"></a> <span class="k">try</span><span class="p">:</span>
</span><span id="__span-0-168"><a id="__codelineno-0-168" name="__codelineno-0-168"></a> <span class="c1"># Send request</span>
</span><span id="__span-0-169"><a id="__codelineno-0-169" name="__codelineno-0-169"></a> <span class="n">request_data</span> <span class="o">=</span> <span class="n">json</span><span class="o">.</span><span class="n">dumps</span><span class="p">(</span><span class="n">request</span><span class="p">)</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s2">"utf-8"</span><span class="p">)</span> <span class="o">+</span> <span class="sa">b</span><span class="s2">"</span><span class="se">\n</span><span class="s2">"</span>
</span><span id="__span-0-170"><a id="__codelineno-0-170" name="__codelineno-0-170"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_writer</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">request_data</span><span class="p">)</span>
</span><span id="__span-0-171"><a id="__codelineno-0-171" name="__codelineno-0-171"></a> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">_writer</span><span class="o">.</span><span class="n">drain</span><span class="p">()</span>
</span><span id="__span-0-172"><a id="__codelineno-0-172" name="__codelineno-0-172"></a>
</span><span id="__span-0-173"><a id="__codelineno-0-173" name="__codelineno-0-173"></a> <span class="c1"># Read response</span>
</span><span id="__span-0-174"><a id="__codelineno-0-174" name="__codelineno-0-174"></a> <span class="n">response_data</span> <span class="o">=</span> <span class="k">await</span> <span class="n">asyncio</span><span class="o">.</span><span class="n">wait_for</span><span class="p">(</span>
</span><span id="__span-0-175"><a id="__codelineno-0-175" name="__codelineno-0-175"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_reader</span><span class="o">.</span><span class="n">readline</span><span class="p">(),</span>
</span><span id="__span-0-176"><a id="__codelineno-0-176" name="__codelineno-0-176"></a> <span class="n">timeout</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">_timeout</span><span class="p">,</span>
</span><span id="__span-0-177"><a id="__codelineno-0-177" name="__codelineno-0-177"></a> <span class="p">)</span>
</span><span id="__span-0-178"><a id="__codelineno-0-178" name="__codelineno-0-178"></a>
</span><span id="__span-0-179"><a id="__codelineno-0-179" name="__codelineno-0-179"></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">response_data</span><span class="p">:</span>
</span><span id="__span-0-180"><a id="__codelineno-0-180" name="__codelineno-0-180"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_connected</span> <span class="o">=</span> <span class="kc">False</span>
</span><span id="__span-0-181"><a id="__codelineno-0-181" name="__codelineno-0-181"></a> <span class="n">msg</span> <span class="o">=</span> <span class="s2">"Connection closed by server"</span>
</span><span id="__span-0-182"><a id="__codelineno-0-182" name="__codelineno-0-182"></a> <span class="k">raise</span> <span class="ne">ConnectionError</span><span class="p">(</span><span class="n">msg</span><span class="p">)</span>
</span><span id="__span-0-183"><a id="__codelineno-0-183" name="__codelineno-0-183"></a>
</span><span id="__span-0-184"><a id="__codelineno-0-184" name="__codelineno-0-184"></a> <span class="n">response</span> <span class="o">=</span> <span class="n">json</span><span class="o">.</span><span class="n">loads</span><span class="p">(</span><span class="n">response_data</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="s2">"utf-8"</span><span class="p">))</span>
</span><span id="__span-0-185"><a id="__codelineno-0-185" name="__codelineno-0-185"></a>
</span><span id="__span-0-186"><a id="__codelineno-0-186" name="__codelineno-0-186"></a> <span class="c1"># Check for error</span>
</span><span id="__span-0-187"><a id="__codelineno-0-187" name="__codelineno-0-187"></a> <span class="k">if</span> <span class="s2">"error"</span> <span class="ow">in</span> <span class="n">response</span><span class="p">:</span>
</span><span id="__span-0-188"><a id="__codelineno-0-188" name="__codelineno-0-188"></a> <span class="n">error</span> <span class="o">=</span> <span class="n">response</span><span class="p">[</span><span class="s2">"error"</span><span class="p">]</span>
</span><span id="__span-0-189"><a id="__codelineno-0-189" name="__codelineno-0-189"></a> <span class="k">raise</span> <span class="n">JsonRpcError</span><span class="p">(</span>
</span><span id="__span-0-190"><a id="__codelineno-0-190" name="__codelineno-0-190"></a> <span class="n">code</span><span class="o">=</span><span class="n">error</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"code"</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span><span class="p">),</span>
</span><span id="__span-0-191"><a id="__codelineno-0-191" name="__codelineno-0-191"></a> <span class="n">message</span><span class="o">=</span><span class="n">error</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"message"</span><span class="p">,</span> <span class="s2">"Unknown error"</span><span class="p">),</span>
</span><span id="__span-0-192"><a id="__codelineno-0-192" name="__codelineno-0-192"></a> <span class="n">data</span><span class="o">=</span><span class="n">error</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"data"</span><span class="p">),</span>
</span><span id="__span-0-193"><a id="__codelineno-0-193" name="__codelineno-0-193"></a> <span class="p">)</span>
</span><span id="__span-0-194"><a id="__codelineno-0-194" name="__codelineno-0-194"></a>
</span><span id="__span-0-195"><a id="__codelineno-0-195" name="__codelineno-0-195"></a> <span class="k">return</span> <span class="n">response</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"result"</span><span class="p">)</span>
</span><span id="__span-0-196"><a id="__codelineno-0-196" name="__codelineno-0-196"></a>
</span><span id="__span-0-197"><a id="__codelineno-0-197" name="__codelineno-0-197"></a> <span class="k">except</span> <span class="ne">TimeoutError</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
</span><span id="__span-0-198"><a id="__codelineno-0-198" name="__codelineno-0-198"></a> <span class="n">msg</span> <span class="o">=</span> <span class="s2">"Request timed out"</span>
</span><span id="__span-0-199"><a id="__codelineno-0-199" name="__codelineno-0-199"></a> <span class="k">raise</span> <span class="ne">ConnectionError</span><span class="p">(</span><span class="n">msg</span><span class="p">)</span> <span class="kn">from</span><span class="w"> </span><span class="nn">e</span>
</span><span id="__span-0-200"><a id="__codelineno-0-200" name="__codelineno-0-200"></a> <span class="k">except</span> <span class="n">json</span><span class="o">.</span><span class="n">JSONDecodeError</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
</span><span id="__span-0-201"><a id="__codelineno-0-201" name="__codelineno-0-201"></a> <span class="n">msg</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">"Invalid JSON response: </span><span class="si">{</span><span class="n">e</span><span class="si">}</span><span class="s2">"</span>
</span><span id="__span-0-202"><a id="__codelineno-0-202" name="__codelineno-0-202"></a> <span class="k">raise</span> <span class="ne">ConnectionError</span><span class="p">(</span><span class="n">msg</span><span class="p">)</span> <span class="kn">from</span><span class="w"> </span><span class="nn">e</span>
</span><span id="__span-0-203"><a id="__codelineno-0-203" name="__codelineno-0-203"></a> <span class="k">except</span> <span class="p">(</span><span class="ne">ConnectionResetError</span><span class="p">,</span> <span class="ne">BrokenPipeError</span><span class="p">)</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
</span><span id="__span-0-204"><a id="__codelineno-0-204" name="__codelineno-0-204"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_connected</span> <span class="o">=</span> <span class="kc">False</span>
</span><span id="__span-0-205"><a id="__codelineno-0-205" name="__codelineno-0-205"></a> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_auto_reconnect</span><span class="p">:</span>
</span><span id="__span-0-206"><a id="__codelineno-0-206" name="__codelineno-0-206"></a> <span class="c1"># Try to reconnect</span>
</span><span id="__span-0-207"><a id="__codelineno-0-207" name="__codelineno-0-207"></a> <span class="k">try</span><span class="p">:</span>
</span><span id="__span-0-208"><a id="__codelineno-0-208" name="__codelineno-0-208"></a> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">connect</span><span class="p">()</span>
</span><span id="__span-0-209"><a id="__codelineno-0-209" name="__codelineno-0-209"></a> <span class="k">return</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">_send_request</span><span class="p">(</span><span class="n">method</span><span class="p">,</span> <span class="n">params</span><span class="p">)</span>
</span><span id="__span-0-210"><a id="__codelineno-0-210" name="__codelineno-0-210"></a> <span class="k">except</span> <span class="ne">Exception</span><span class="p">:</span>
</span><span id="__span-0-211"><a id="__codelineno-0-211" name="__codelineno-0-211"></a> <span class="k">pass</span>
</span><span id="__span-0-212"><a id="__codelineno-0-212" name="__codelineno-0-212"></a> <span class="n">msg</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">"Connection lost: </span><span class="si">{</span><span class="n">e</span><span class="si">}</span><span class="s2">"</span>
</span><span id="__span-0-213"><a id="__codelineno-0-213" name="__codelineno-0-213"></a> <span class="k">raise</span> <span class="ne">ConnectionError</span><span class="p">(</span><span class="n">msg</span><span class="p">)</span> <span class="kn">from</span><span class="w"> </span><span class="nn">e</span>
</span><span id="__span-0-214"><a id="__codelineno-0-214" name="__codelineno-0-214"></a>
</span><span id="__span-0-215"><a id="__codelineno-0-215" name="__codelineno-0-215"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">ping</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">float</span><span class="p">:</span>
</span><span id="__span-0-216"><a id="__codelineno-0-216" name="__codelineno-0-216"></a><span class="w"> </span><span class="sd">"""Ping FreeCAD to check connection and measure latency.</span>
</span><span id="__span-0-217"><a id="__codelineno-0-217" name="__codelineno-0-217"></a>
</span><span id="__span-0-218"><a id="__codelineno-0-218" name="__codelineno-0-218"></a><span class="sd"> Returns:</span>
</span><span id="__span-0-219"><a id="__codelineno-0-219" name="__codelineno-0-219"></a><span class="sd"> Round-trip time in milliseconds.</span>
</span><span id="__span-0-220"><a id="__codelineno-0-220" name="__codelineno-0-220"></a>
</span><span id="__span-0-221"><a id="__codelineno-0-221" name="__codelineno-0-221"></a><span class="sd"> Raises:</span>
</span><span id="__span-0-222"><a id="__codelineno-0-222" name="__codelineno-0-222"></a><span class="sd"> ConnectionError: If not connected.</span>
</span><span id="__span-0-223"><a id="__codelineno-0-223" name="__codelineno-0-223"></a><span class="sd"> """</span>
</span><span id="__span-0-224"><a id="__codelineno-0-224" name="__codelineno-0-224"></a> <span class="n">start</span> <span class="o">=</span> <span class="n">time</span><span class="o">.</span><span class="n">perf_counter</span><span class="p">()</span>
</span><span id="__span-0-225"><a id="__codelineno-0-225" name="__codelineno-0-225"></a> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">_send_request</span><span class="p">(</span><span class="s2">"ping"</span><span class="p">)</span>
</span><span id="__span-0-226"><a id="__codelineno-0-226" name="__codelineno-0-226"></a> <span class="k">return</span> <span class="p">(</span><span class="n">time</span><span class="o">.</span><span class="n">perf_counter</span><span class="p">()</span> <span class="o">-</span> <span class="n">start</span><span class="p">)</span> <span class="o">*</span> <span class="mi">1000</span>
</span><span id="__span-0-227"><a id="__codelineno-0-227" name="__codelineno-0-227"></a>
</span><span id="__span-0-228"><a id="__codelineno-0-228" name="__codelineno-0-228"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">get_status</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">ConnectionStatus</span><span class="p">:</span>
</span><span id="__span-0-229"><a id="__codelineno-0-229" name="__codelineno-0-229"></a><span class="w"> </span><span class="sd">"""Get detailed connection status.</span>
</span><span id="__span-0-230"><a id="__codelineno-0-230" name="__codelineno-0-230"></a>
</span><span id="__span-0-231"><a id="__codelineno-0-231" name="__codelineno-0-231"></a><span class="sd"> Returns:</span>
</span><span id="__span-0-232"><a id="__codelineno-0-232" name="__codelineno-0-232"></a><span class="sd"> ConnectionStatus with full status information.</span>
</span><span id="__span-0-233"><a id="__codelineno-0-233" name="__codelineno-0-233"></a><span class="sd"> """</span>
</span><span id="__span-0-234"><a id="__codelineno-0-234" name="__codelineno-0-234"></a> <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">_connected</span><span class="p">:</span>
</span><span id="__span-0-235"><a id="__codelineno-0-235" name="__codelineno-0-235"></a> <span class="k">return</span> <span class="n">ConnectionStatus</span><span class="p">(</span>
</span><span id="__span-0-236"><a id="__codelineno-0-236" name="__codelineno-0-236"></a> <span class="n">connected</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
</span><span id="__span-0-237"><a id="__codelineno-0-237" name="__codelineno-0-237"></a> <span class="n">mode</span><span class="o">=</span><span class="s2">"socket"</span><span class="p">,</span>
</span><span id="__span-0-238"><a id="__codelineno-0-238" name="__codelineno-0-238"></a> <span class="n">error</span><span class="o">=</span><span class="s2">"Not connected"</span><span class="p">,</span>
</span><span id="__span-0-239"><a id="__codelineno-0-239" name="__codelineno-0-239"></a> <span class="p">)</span>
</span><span id="__span-0-240"><a id="__codelineno-0-240" name="__codelineno-0-240"></a>
</span><span id="__span-0-241"><a id="__codelineno-0-241" name="__codelineno-0-241"></a> <span class="k">try</span><span class="p">:</span>
</span><span id="__span-0-242"><a id="__codelineno-0-242" name="__codelineno-0-242"></a> <span class="n">ping_ms</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">ping</span><span class="p">()</span>
</span><span id="__span-0-243"><a id="__codelineno-0-243" name="__codelineno-0-243"></a> <span class="n">version_info</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_freecad_version</span><span class="p">()</span>
</span><span id="__span-0-244"><a id="__codelineno-0-244" name="__codelineno-0-244"></a> <span class="n">gui_available</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">is_gui_available</span><span class="p">()</span>
</span><span id="__span-0-245"><a id="__codelineno-0-245" name="__codelineno-0-245"></a>
</span><span id="__span-0-246"><a id="__codelineno-0-246" name="__codelineno-0-246"></a> <span class="k">return</span> <span class="n">ConnectionStatus</span><span class="p">(</span>
</span><span id="__span-0-247"><a id="__codelineno-0-247" name="__codelineno-0-247"></a> <span class="n">connected</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span>
</span><span id="__span-0-248"><a id="__codelineno-0-248" name="__codelineno-0-248"></a> <span class="n">mode</span><span class="o">=</span><span class="s2">"socket"</span><span class="p">,</span>
</span><span id="__span-0-249"><a id="__codelineno-0-249" name="__codelineno-0-249"></a> <span class="n">freecad_version</span><span class="o">=</span><span class="n">version_info</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"version"</span><span class="p">,</span> <span class="s2">"unknown"</span><span class="p">),</span>
</span><span id="__span-0-250"><a id="__codelineno-0-250" name="__codelineno-0-250"></a> <span class="n">gui_available</span><span class="o">=</span><span class="n">gui_available</span><span class="p">,</span>
</span><span id="__span-0-251"><a id="__codelineno-0-251" name="__codelineno-0-251"></a> <span class="n">last_ping_ms</span><span class="o">=</span><span class="n">ping_ms</span><span class="p">,</span>
</span><span id="__span-0-252"><a id="__codelineno-0-252" name="__codelineno-0-252"></a> <span class="p">)</span>
</span><span id="__span-0-253"><a id="__codelineno-0-253" name="__codelineno-0-253"></a> <span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
</span><span id="__span-0-254"><a id="__codelineno-0-254" name="__codelineno-0-254"></a> <span class="k">return</span> <span class="n">ConnectionStatus</span><span class="p">(</span>
</span><span id="__span-0-255"><a id="__codelineno-0-255" name="__codelineno-0-255"></a> <span class="n">connected</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
</span><span id="__span-0-256"><a id="__codelineno-0-256" name="__codelineno-0-256"></a> <span class="n">mode</span><span class="o">=</span><span class="s2">"socket"</span><span class="p">,</span>
</span><span id="__span-0-257"><a id="__codelineno-0-257" name="__codelineno-0-257"></a> <span class="n">error</span><span class="o">=</span><span class="nb">str</span><span class="p">(</span><span class="n">e</span><span class="p">),</span>
</span><span id="__span-0-258"><a id="__codelineno-0-258" name="__codelineno-0-258"></a> <span class="p">)</span>
</span><span id="__span-0-259"><a id="__codelineno-0-259" name="__codelineno-0-259"></a>
</span><span id="__span-0-260"><a id="__codelineno-0-260" name="__codelineno-0-260"></a> <span class="c1"># =========================================================================</span>
</span><span id="__span-0-261"><a id="__codelineno-0-261" name="__codelineno-0-261"></a> <span class="c1"># Code Execution</span>
</span><span id="__span-0-262"><a id="__codelineno-0-262" name="__codelineno-0-262"></a> <span class="c1"># =========================================================================</span>
</span><span id="__span-0-263"><a id="__codelineno-0-263" name="__codelineno-0-263"></a>
</span><span id="__span-0-264"><a id="__codelineno-0-264" name="__codelineno-0-264"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">execute_python</span><span class="p">(</span>
</span><span id="__span-0-265"><a id="__codelineno-0-265" name="__codelineno-0-265"></a> <span class="bp">self</span><span class="p">,</span>
</span><span id="__span-0-266"><a id="__codelineno-0-266" name="__codelineno-0-266"></a> <span class="n">code</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span>
</span><span id="__span-0-267"><a id="__codelineno-0-267" name="__codelineno-0-267"></a> <span class="n">timeout_ms</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">30000</span><span class="p">,</span>
</span><span id="__span-0-268"><a id="__codelineno-0-268" name="__codelineno-0-268"></a> <span class="p">)</span> <span class="o">-&gt;</span> <span class="n">ExecutionResult</span><span class="p">:</span>
</span><span id="__span-0-269"><a id="__codelineno-0-269" name="__codelineno-0-269"></a><span class="w"> </span><span class="sd">"""Execute Python code in FreeCAD context via socket.</span>
</span><span id="__span-0-270"><a id="__codelineno-0-270" name="__codelineno-0-270"></a>
</span><span id="__span-0-271"><a id="__codelineno-0-271" name="__codelineno-0-271"></a><span class="sd"> Args:</span>
</span><span id="__span-0-272"><a id="__codelineno-0-272" name="__codelineno-0-272"></a><span class="sd"> code: Python code to execute.</span>
</span><span id="__span-0-273"><a id="__codelineno-0-273" name="__codelineno-0-273"></a><span class="sd"> timeout_ms: Maximum execution time in milliseconds.</span>
</span><span id="__span-0-274"><a id="__codelineno-0-274" name="__codelineno-0-274"></a>
</span><span id="__span-0-275"><a id="__codelineno-0-275" name="__codelineno-0-275"></a><span class="sd"> Returns:</span>
</span><span id="__span-0-276"><a id="__codelineno-0-276" name="__codelineno-0-276"></a><span class="sd"> ExecutionResult with execution outcome.</span>
</span><span id="__span-0-277"><a id="__codelineno-0-277" name="__codelineno-0-277"></a><span class="sd"> """</span>
</span><span id="__span-0-278"><a id="__codelineno-0-278" name="__codelineno-0-278"></a> <span class="n">start</span> <span class="o">=</span> <span class="n">time</span><span class="o">.</span><span class="n">perf_counter</span><span class="p">()</span>
</span><span id="__span-0-279"><a id="__codelineno-0-279" name="__codelineno-0-279"></a>
</span><span id="__span-0-280"><a id="__codelineno-0-280" name="__codelineno-0-280"></a> <span class="k">try</span><span class="p">:</span>
</span><span id="__span-0-281"><a id="__codelineno-0-281" name="__codelineno-0-281"></a> <span class="n">result</span> <span class="o">=</span> <span class="k">await</span> <span class="n">asyncio</span><span class="o">.</span><span class="n">wait_for</span><span class="p">(</span>
</span><span id="__span-0-282"><a id="__codelineno-0-282" name="__codelineno-0-282"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_send_request</span><span class="p">(</span><span class="s2">"execute"</span><span class="p">,</span> <span class="p">{</span><span class="s2">"code"</span><span class="p">:</span> <span class="n">code</span><span class="p">}),</span>
</span><span id="__span-0-283"><a id="__codelineno-0-283" name="__codelineno-0-283"></a> <span class="n">timeout</span><span class="o">=</span><span class="n">timeout_ms</span> <span class="o">/</span> <span class="mi">1000</span><span class="p">,</span>
</span><span id="__span-0-284"><a id="__codelineno-0-284" name="__codelineno-0-284"></a> <span class="p">)</span>
</span><span id="__span-0-285"><a id="__codelineno-0-285" name="__codelineno-0-285"></a> <span class="n">elapsed</span> <span class="o">=</span> <span class="p">(</span><span class="n">time</span><span class="o">.</span><span class="n">perf_counter</span><span class="p">()</span> <span class="o">-</span> <span class="n">start</span><span class="p">)</span> <span class="o">*</span> <span class="mi">1000</span>
</span><span id="__span-0-286"><a id="__codelineno-0-286" name="__codelineno-0-286"></a>
</span><span id="__span-0-287"><a id="__codelineno-0-287" name="__codelineno-0-287"></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">result</span><span class="p">,</span> <span class="nb">dict</span><span class="p">):</span>
</span><span id="__span-0-288"><a id="__codelineno-0-288" name="__codelineno-0-288"></a> <span class="k">return</span> <span class="n">ExecutionResult</span><span class="p">(</span>
</span><span id="__span-0-289"><a id="__codelineno-0-289" name="__codelineno-0-289"></a> <span class="n">success</span><span class="o">=</span><span class="n">result</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"success"</span><span class="p">,</span> <span class="kc">False</span><span class="p">),</span>
</span><span id="__span-0-290"><a id="__codelineno-0-290" name="__codelineno-0-290"></a> <span class="n">result</span><span class="o">=</span><span class="n">result</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"result"</span><span class="p">),</span>
</span><span id="__span-0-291"><a id="__codelineno-0-291" name="__codelineno-0-291"></a> <span class="n">stdout</span><span class="o">=</span><span class="n">result</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"stdout"</span><span class="p">,</span> <span class="s2">""</span><span class="p">),</span>
</span><span id="__span-0-292"><a id="__codelineno-0-292" name="__codelineno-0-292"></a> <span class="n">stderr</span><span class="o">=</span><span class="n">result</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"stderr"</span><span class="p">,</span> <span class="s2">""</span><span class="p">),</span>
</span><span id="__span-0-293"><a id="__codelineno-0-293" name="__codelineno-0-293"></a> <span class="n">execution_time_ms</span><span class="o">=</span><span class="n">elapsed</span><span class="p">,</span>
</span><span id="__span-0-294"><a id="__codelineno-0-294" name="__codelineno-0-294"></a> <span class="n">error_type</span><span class="o">=</span><span class="n">result</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"error_type"</span><span class="p">),</span>
</span><span id="__span-0-295"><a id="__codelineno-0-295" name="__codelineno-0-295"></a> <span class="n">error_traceback</span><span class="o">=</span><span class="n">result</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"error_traceback"</span><span class="p">),</span>
</span><span id="__span-0-296"><a id="__codelineno-0-296" name="__codelineno-0-296"></a> <span class="p">)</span>
</span><span id="__span-0-297"><a id="__codelineno-0-297" name="__codelineno-0-297"></a> <span class="k">else</span><span class="p">:</span>
</span><span id="__span-0-298"><a id="__codelineno-0-298" name="__codelineno-0-298"></a> <span class="k">return</span> <span class="n">ExecutionResult</span><span class="p">(</span>
</span><span id="__span-0-299"><a id="__codelineno-0-299" name="__codelineno-0-299"></a> <span class="n">success</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span>
</span><span id="__span-0-300"><a id="__codelineno-0-300" name="__codelineno-0-300"></a> <span class="n">result</span><span class="o">=</span><span class="n">result</span><span class="p">,</span>
</span><span id="__span-0-301"><a id="__codelineno-0-301" name="__codelineno-0-301"></a> <span class="n">stdout</span><span class="o">=</span><span class="s2">""</span><span class="p">,</span>
</span><span id="__span-0-302"><a id="__codelineno-0-302" name="__codelineno-0-302"></a> <span class="n">stderr</span><span class="o">=</span><span class="s2">""</span><span class="p">,</span>
</span><span id="__span-0-303"><a id="__codelineno-0-303" name="__codelineno-0-303"></a> <span class="n">execution_time_ms</span><span class="o">=</span><span class="n">elapsed</span><span class="p">,</span>
</span><span id="__span-0-304"><a id="__codelineno-0-304" name="__codelineno-0-304"></a> <span class="p">)</span>
</span><span id="__span-0-305"><a id="__codelineno-0-305" name="__codelineno-0-305"></a>
</span><span id="__span-0-306"><a id="__codelineno-0-306" name="__codelineno-0-306"></a> <span class="k">except</span> <span class="ne">TimeoutError</span><span class="p">:</span>
</span><span id="__span-0-307"><a id="__codelineno-0-307" name="__codelineno-0-307"></a> <span class="k">return</span> <span class="n">ExecutionResult</span><span class="p">(</span>
</span><span id="__span-0-308"><a id="__codelineno-0-308" name="__codelineno-0-308"></a> <span class="n">success</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
</span><span id="__span-0-309"><a id="__codelineno-0-309" name="__codelineno-0-309"></a> <span class="n">result</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-310"><a id="__codelineno-0-310" name="__codelineno-0-310"></a> <span class="n">stdout</span><span class="o">=</span><span class="s2">""</span><span class="p">,</span>
</span><span id="__span-0-311"><a id="__codelineno-0-311" name="__codelineno-0-311"></a> <span class="n">stderr</span><span class="o">=</span><span class="sa">f</span><span class="s2">"Execution timed out after </span><span class="si">{</span><span class="n">timeout_ms</span><span class="si">}</span><span class="s2">ms"</span><span class="p">,</span>
</span><span id="__span-0-312"><a id="__codelineno-0-312" name="__codelineno-0-312"></a> <span class="n">execution_time_ms</span><span class="o">=</span><span class="nb">float</span><span class="p">(</span><span class="n">timeout_ms</span><span class="p">),</span>
</span><span id="__span-0-313"><a id="__codelineno-0-313" name="__codelineno-0-313"></a> <span class="n">error_type</span><span class="o">=</span><span class="s2">"TimeoutError"</span><span class="p">,</span>
</span><span id="__span-0-314"><a id="__codelineno-0-314" name="__codelineno-0-314"></a> <span class="p">)</span>
</span><span id="__span-0-315"><a id="__codelineno-0-315" name="__codelineno-0-315"></a> <span class="k">except</span> <span class="n">JsonRpcError</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
</span><span id="__span-0-316"><a id="__codelineno-0-316" name="__codelineno-0-316"></a> <span class="n">elapsed</span> <span class="o">=</span> <span class="p">(</span><span class="n">time</span><span class="o">.</span><span class="n">perf_counter</span><span class="p">()</span> <span class="o">-</span> <span class="n">start</span><span class="p">)</span> <span class="o">*</span> <span class="mi">1000</span>
</span><span id="__span-0-317"><a id="__codelineno-0-317" name="__codelineno-0-317"></a> <span class="k">return</span> <span class="n">ExecutionResult</span><span class="p">(</span>
</span><span id="__span-0-318"><a id="__codelineno-0-318" name="__codelineno-0-318"></a> <span class="n">success</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
</span><span id="__span-0-319"><a id="__codelineno-0-319" name="__codelineno-0-319"></a> <span class="n">result</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-320"><a id="__codelineno-0-320" name="__codelineno-0-320"></a> <span class="n">stdout</span><span class="o">=</span><span class="s2">""</span><span class="p">,</span>
</span><span id="__span-0-321"><a id="__codelineno-0-321" name="__codelineno-0-321"></a> <span class="n">stderr</span><span class="o">=</span><span class="n">e</span><span class="o">.</span><span class="n">message</span><span class="p">,</span>
</span><span id="__span-0-322"><a id="__codelineno-0-322" name="__codelineno-0-322"></a> <span class="n">execution_time_ms</span><span class="o">=</span><span class="n">elapsed</span><span class="p">,</span>
</span><span id="__span-0-323"><a id="__codelineno-0-323" name="__codelineno-0-323"></a> <span class="n">error_type</span><span class="o">=</span><span class="s2">"JsonRpcError"</span><span class="p">,</span>
</span><span id="__span-0-324"><a id="__codelineno-0-324" name="__codelineno-0-324"></a> <span class="p">)</span>
</span><span id="__span-0-325"><a id="__codelineno-0-325" name="__codelineno-0-325"></a> <span class="k">except</span> <span class="ne">ConnectionError</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
</span><span id="__span-0-326"><a id="__codelineno-0-326" name="__codelineno-0-326"></a> <span class="k">return</span> <span class="n">ExecutionResult</span><span class="p">(</span>
</span><span id="__span-0-327"><a id="__codelineno-0-327" name="__codelineno-0-327"></a> <span class="n">success</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
</span><span id="__span-0-328"><a id="__codelineno-0-328" name="__codelineno-0-328"></a> <span class="n">result</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-329"><a id="__codelineno-0-329" name="__codelineno-0-329"></a> <span class="n">stdout</span><span class="o">=</span><span class="s2">""</span><span class="p">,</span>
</span><span id="__span-0-330"><a id="__codelineno-0-330" name="__codelineno-0-330"></a> <span class="n">stderr</span><span class="o">=</span><span class="nb">str</span><span class="p">(</span><span class="n">e</span><span class="p">),</span>
</span><span id="__span-0-331"><a id="__codelineno-0-331" name="__codelineno-0-331"></a> <span class="n">execution_time_ms</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span>
</span><span id="__span-0-332"><a id="__codelineno-0-332" name="__codelineno-0-332"></a> <span class="n">error_type</span><span class="o">=</span><span class="s2">"ConnectionError"</span><span class="p">,</span>
</span><span id="__span-0-333"><a id="__codelineno-0-333" name="__codelineno-0-333"></a> <span class="p">)</span>
</span><span id="__span-0-334"><a id="__codelineno-0-334" name="__codelineno-0-334"></a>
</span><span id="__span-0-335"><a id="__codelineno-0-335" name="__codelineno-0-335"></a> <span class="c1"># =========================================================================</span>
</span><span id="__span-0-336"><a id="__codelineno-0-336" name="__codelineno-0-336"></a> <span class="c1"># Document Management</span>
</span><span id="__span-0-337"><a id="__codelineno-0-337" name="__codelineno-0-337"></a> <span class="c1"># =========================================================================</span>
</span><span id="__span-0-338"><a id="__codelineno-0-338" name="__codelineno-0-338"></a>
</span><span id="__span-0-339"><a id="__codelineno-0-339" name="__codelineno-0-339"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">get_documents</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">list</span><span class="p">[</span><span class="n">DocumentInfo</span><span class="p">]:</span>
</span><span id="__span-0-340"><a id="__codelineno-0-340" name="__codelineno-0-340"></a><span class="w"> </span><span class="sd">"""Get list of open documents."""</span>
</span><span id="__span-0-341"><a id="__codelineno-0-341" name="__codelineno-0-341"></a> <span class="n">result</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">execute_python</span><span class="p">(</span>
</span><span id="__span-0-342"><a id="__codelineno-0-342" name="__codelineno-0-342"></a><span class="w"> </span><span class="sd">"""</span>
</span><span id="__span-0-343"><a id="__codelineno-0-343" name="__codelineno-0-343"></a><span class="sd">_result_ = []</span>
</span><span id="__span-0-344"><a id="__codelineno-0-344" name="__codelineno-0-344"></a><span class="sd">for doc in FreeCAD.listDocuments().values():</span>
</span><span id="__span-0-345"><a id="__codelineno-0-345" name="__codelineno-0-345"></a><span class="sd"> _result_.append({</span>
</span><span id="__span-0-346"><a id="__codelineno-0-346" name="__codelineno-0-346"></a><span class="sd"> "name": doc.Name,</span>
</span><span id="__span-0-347"><a id="__codelineno-0-347" name="__codelineno-0-347"></a><span class="sd"> "label": doc.Label,</span>
</span><span id="__span-0-348"><a id="__codelineno-0-348" name="__codelineno-0-348"></a><span class="sd"> "path": doc.FileName or None,</span>
</span><span id="__span-0-349"><a id="__codelineno-0-349" name="__codelineno-0-349"></a><span class="sd"> "objects": [obj.Name for obj in doc.Objects],</span>
</span><span id="__span-0-350"><a id="__codelineno-0-350" name="__codelineno-0-350"></a><span class="sd"> "is_modified": doc.Modified if hasattr(doc, "Modified") else False,</span>
</span><span id="__span-0-351"><a id="__codelineno-0-351" name="__codelineno-0-351"></a><span class="sd"> "active_object": doc.ActiveObject.Name if doc.ActiveObject else None,</span>
</span><span id="__span-0-352"><a id="__codelineno-0-352" name="__codelineno-0-352"></a><span class="sd"> })</span>
</span><span id="__span-0-353"><a id="__codelineno-0-353" name="__codelineno-0-353"></a><span class="sd">"""</span>
</span><span id="__span-0-354"><a id="__codelineno-0-354" name="__codelineno-0-354"></a> <span class="p">)</span>
</span><span id="__span-0-355"><a id="__codelineno-0-355" name="__codelineno-0-355"></a>
</span><span id="__span-0-356"><a id="__codelineno-0-356" name="__codelineno-0-356"></a> <span class="k">if</span> <span class="n">result</span><span class="o">.</span><span class="n">success</span> <span class="ow">and</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">:</span>
</span><span id="__span-0-357"><a id="__codelineno-0-357" name="__codelineno-0-357"></a> <span class="k">return</span> <span class="p">[</span><span class="n">DocumentInfo</span><span class="p">(</span><span class="o">**</span><span class="n">doc</span><span class="p">)</span> <span class="k">for</span> <span class="n">doc</span> <span class="ow">in</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">]</span>
</span><span id="__span-0-358"><a id="__codelineno-0-358" name="__codelineno-0-358"></a> <span class="k">return</span> <span class="p">[]</span>
</span><span id="__span-0-359"><a id="__codelineno-0-359" name="__codelineno-0-359"></a>
</span><span id="__span-0-360"><a id="__codelineno-0-360" name="__codelineno-0-360"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">get_active_document</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">DocumentInfo</span> <span class="o">|</span> <span class="kc">None</span><span class="p">:</span>
</span><span id="__span-0-361"><a id="__codelineno-0-361" name="__codelineno-0-361"></a><span class="w"> </span><span class="sd">"""Get the active document."""</span>
</span><span id="__span-0-362"><a id="__codelineno-0-362" name="__codelineno-0-362"></a> <span class="n">result</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">execute_python</span><span class="p">(</span>
</span><span id="__span-0-363"><a id="__codelineno-0-363" name="__codelineno-0-363"></a><span class="w"> </span><span class="sd">"""</span>
</span><span id="__span-0-364"><a id="__codelineno-0-364" name="__codelineno-0-364"></a><span class="sd">doc = FreeCAD.ActiveDocument</span>
</span><span id="__span-0-365"><a id="__codelineno-0-365" name="__codelineno-0-365"></a><span class="sd">if doc:</span>
</span><span id="__span-0-366"><a id="__codelineno-0-366" name="__codelineno-0-366"></a><span class="sd"> _result_ = {</span>
</span><span id="__span-0-367"><a id="__codelineno-0-367" name="__codelineno-0-367"></a><span class="sd"> "name": doc.Name,</span>
</span><span id="__span-0-368"><a id="__codelineno-0-368" name="__codelineno-0-368"></a><span class="sd"> "label": doc.Label,</span>
</span><span id="__span-0-369"><a id="__codelineno-0-369" name="__codelineno-0-369"></a><span class="sd"> "path": doc.FileName or None,</span>
</span><span id="__span-0-370"><a id="__codelineno-0-370" name="__codelineno-0-370"></a><span class="sd"> "objects": [obj.Name for obj in doc.Objects],</span>
</span><span id="__span-0-371"><a id="__codelineno-0-371" name="__codelineno-0-371"></a><span class="sd"> "is_modified": doc.Modified if hasattr(doc, "Modified") else False,</span>
</span><span id="__span-0-372"><a id="__codelineno-0-372" name="__codelineno-0-372"></a><span class="sd"> "active_object": doc.ActiveObject.Name if doc.ActiveObject else None,</span>
</span><span id="__span-0-373"><a id="__codelineno-0-373" name="__codelineno-0-373"></a><span class="sd"> }</span>
</span><span id="__span-0-374"><a id="__codelineno-0-374" name="__codelineno-0-374"></a><span class="sd">else:</span>
</span><span id="__span-0-375"><a id="__codelineno-0-375" name="__codelineno-0-375"></a><span class="sd"> _result_ = None</span>
</span><span id="__span-0-376"><a id="__codelineno-0-376" name="__codelineno-0-376"></a><span class="sd">"""</span>
</span><span id="__span-0-377"><a id="__codelineno-0-377" name="__codelineno-0-377"></a> <span class="p">)</span>
</span><span id="__span-0-378"><a id="__codelineno-0-378" name="__codelineno-0-378"></a>
</span><span id="__span-0-379"><a id="__codelineno-0-379" name="__codelineno-0-379"></a> <span class="k">if</span> <span class="n">result</span><span class="o">.</span><span class="n">success</span> <span class="ow">and</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">:</span>
</span><span id="__span-0-380"><a id="__codelineno-0-380" name="__codelineno-0-380"></a> <span class="k">return</span> <span class="n">DocumentInfo</span><span class="p">(</span><span class="o">**</span><span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">)</span>
</span><span id="__span-0-381"><a id="__codelineno-0-381" name="__codelineno-0-381"></a> <span class="k">return</span> <span class="kc">None</span>
</span><span id="__span-0-382"><a id="__codelineno-0-382" name="__codelineno-0-382"></a>
</span><span id="__span-0-383"><a id="__codelineno-0-383" name="__codelineno-0-383"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">create_document</span><span class="p">(</span>
</span><span id="__span-0-384"><a id="__codelineno-0-384" name="__codelineno-0-384"></a> <span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">label</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span>
</span><span id="__span-0-385"><a id="__codelineno-0-385" name="__codelineno-0-385"></a> <span class="p">)</span> <span class="o">-&gt;</span> <span class="n">DocumentInfo</span><span class="p">:</span>
</span><span id="__span-0-386"><a id="__codelineno-0-386" name="__codelineno-0-386"></a><span class="w"> </span><span class="sd">"""Create a new document."""</span>
</span><span id="__span-0-387"><a id="__codelineno-0-387" name="__codelineno-0-387"></a> <span class="n">label</span> <span class="o">=</span> <span class="n">label</span> <span class="ow">or</span> <span class="n">name</span>
</span><span id="__span-0-388"><a id="__codelineno-0-388" name="__codelineno-0-388"></a> <span class="n">result</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">execute_python</span><span class="p">(</span>
</span><span id="__span-0-389"><a id="__codelineno-0-389" name="__codelineno-0-389"></a> <span class="sa">f</span><span class="s2">"""</span>
</span><span id="__span-0-390"><a id="__codelineno-0-390" name="__codelineno-0-390"></a><span class="s2">doc = FreeCAD.newDocument(</span><span class="si">{</span><span class="n">name</span><span class="si">!r}</span><span class="s2">)</span>
</span><span id="__span-0-391"><a id="__codelineno-0-391" name="__codelineno-0-391"></a><span class="s2">doc.Label = </span><span class="si">{</span><span class="n">label</span><span class="si">!r}</span>
</span><span id="__span-0-392"><a id="__codelineno-0-392" name="__codelineno-0-392"></a><span class="s2">_result_ = </span><span class="se">{{</span>
</span><span id="__span-0-393"><a id="__codelineno-0-393" name="__codelineno-0-393"></a><span class="s2"> "name": doc.Name,</span>
</span><span id="__span-0-394"><a id="__codelineno-0-394" name="__codelineno-0-394"></a><span class="s2"> "label": doc.Label,</span>
</span><span id="__span-0-395"><a id="__codelineno-0-395" name="__codelineno-0-395"></a><span class="s2"> "path": doc.FileName or None,</span>
</span><span id="__span-0-396"><a id="__codelineno-0-396" name="__codelineno-0-396"></a><span class="s2"> "objects": [],</span>
</span><span id="__span-0-397"><a id="__codelineno-0-397" name="__codelineno-0-397"></a><span class="s2"> "is_modified": False,</span>
</span><span id="__span-0-398"><a id="__codelineno-0-398" name="__codelineno-0-398"></a><span class="se">}}</span>
</span><span id="__span-0-399"><a id="__codelineno-0-399" name="__codelineno-0-399"></a><span class="s2">"""</span>
</span><span id="__span-0-400"><a id="__codelineno-0-400" name="__codelineno-0-400"></a> <span class="p">)</span>
</span><span id="__span-0-401"><a id="__codelineno-0-401" name="__codelineno-0-401"></a>
</span><span id="__span-0-402"><a id="__codelineno-0-402" name="__codelineno-0-402"></a> <span class="k">if</span> <span class="n">result</span><span class="o">.</span><span class="n">success</span> <span class="ow">and</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">:</span>
</span><span id="__span-0-403"><a id="__codelineno-0-403" name="__codelineno-0-403"></a> <span class="k">return</span> <span class="n">DocumentInfo</span><span class="p">(</span><span class="o">**</span><span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">)</span>
</span><span id="__span-0-404"><a id="__codelineno-0-404" name="__codelineno-0-404"></a>
</span><span id="__span-0-405"><a id="__codelineno-0-405" name="__codelineno-0-405"></a> <span class="n">error_msg</span> <span class="o">=</span> <span class="n">result</span><span class="o">.</span><span class="n">error_traceback</span> <span class="ow">or</span> <span class="s2">"Failed to create document"</span>
</span><span id="__span-0-406"><a id="__codelineno-0-406" name="__codelineno-0-406"></a> <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="n">error_msg</span><span class="p">)</span>
</span><span id="__span-0-407"><a id="__codelineno-0-407" name="__codelineno-0-407"></a>
</span><span id="__span-0-408"><a id="__codelineno-0-408" name="__codelineno-0-408"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">open_document</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">path</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">DocumentInfo</span><span class="p">:</span>
</span><span id="__span-0-409"><a id="__codelineno-0-409" name="__codelineno-0-409"></a><span class="w"> </span><span class="sd">"""Open an existing document."""</span>
</span><span id="__span-0-410"><a id="__codelineno-0-410" name="__codelineno-0-410"></a> <span class="n">result</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">execute_python</span><span class="p">(</span>
</span><span id="__span-0-411"><a id="__codelineno-0-411" name="__codelineno-0-411"></a> <span class="sa">f</span><span class="s2">"""</span>
</span><span id="__span-0-412"><a id="__codelineno-0-412" name="__codelineno-0-412"></a><span class="s2">import os</span>
</span><span id="__span-0-413"><a id="__codelineno-0-413" name="__codelineno-0-413"></a><span class="s2">if not os.path.exists(</span><span class="si">{</span><span class="n">path</span><span class="si">!r}</span><span class="s2">):</span>
</span><span id="__span-0-414"><a id="__codelineno-0-414" name="__codelineno-0-414"></a><span class="s2"> raise FileNotFoundError(f"File not found: </span><span class="si">{</span><span class="n">path</span><span class="si">!r}</span><span class="s2">")</span>
</span><span id="__span-0-415"><a id="__codelineno-0-415" name="__codelineno-0-415"></a>
</span><span id="__span-0-416"><a id="__codelineno-0-416" name="__codelineno-0-416"></a><span class="s2">doc = FreeCAD.openDocument(</span><span class="si">{</span><span class="n">path</span><span class="si">!r}</span><span class="s2">)</span>
</span><span id="__span-0-417"><a id="__codelineno-0-417" name="__codelineno-0-417"></a><span class="s2">_result_ = </span><span class="se">{{</span>
</span><span id="__span-0-418"><a id="__codelineno-0-418" name="__codelineno-0-418"></a><span class="s2"> "name": doc.Name,</span>
</span><span id="__span-0-419"><a id="__codelineno-0-419" name="__codelineno-0-419"></a><span class="s2"> "label": doc.Label,</span>
</span><span id="__span-0-420"><a id="__codelineno-0-420" name="__codelineno-0-420"></a><span class="s2"> "path": doc.FileName or None,</span>
</span><span id="__span-0-421"><a id="__codelineno-0-421" name="__codelineno-0-421"></a><span class="s2"> "objects": [obj.Name for obj in doc.Objects],</span>
</span><span id="__span-0-422"><a id="__codelineno-0-422" name="__codelineno-0-422"></a><span class="s2"> "is_modified": doc.Modified if hasattr(doc, "Modified") else False,</span>
</span><span id="__span-0-423"><a id="__codelineno-0-423" name="__codelineno-0-423"></a><span class="se">}}</span>
</span><span id="__span-0-424"><a id="__codelineno-0-424" name="__codelineno-0-424"></a><span class="s2">"""</span>
</span><span id="__span-0-425"><a id="__codelineno-0-425" name="__codelineno-0-425"></a> <span class="p">)</span>
</span><span id="__span-0-426"><a id="__codelineno-0-426" name="__codelineno-0-426"></a>
</span><span id="__span-0-427"><a id="__codelineno-0-427" name="__codelineno-0-427"></a> <span class="k">if</span> <span class="n">result</span><span class="o">.</span><span class="n">success</span> <span class="ow">and</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">:</span>
</span><span id="__span-0-428"><a id="__codelineno-0-428" name="__codelineno-0-428"></a> <span class="k">return</span> <span class="n">DocumentInfo</span><span class="p">(</span><span class="o">**</span><span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">)</span>
</span><span id="__span-0-429"><a id="__codelineno-0-429" name="__codelineno-0-429"></a>
</span><span id="__span-0-430"><a id="__codelineno-0-430" name="__codelineno-0-430"></a> <span class="k">if</span> <span class="s2">"FileNotFoundError"</span> <span class="ow">in</span> <span class="p">(</span><span class="n">result</span><span class="o">.</span><span class="n">error_type</span> <span class="ow">or</span> <span class="s2">""</span><span class="p">):</span>
</span><span id="__span-0-431"><a id="__codelineno-0-431" name="__codelineno-0-431"></a> <span class="k">raise</span> <span class="ne">FileNotFoundError</span><span class="p">(</span><span class="n">result</span><span class="o">.</span><span class="n">stderr</span><span class="p">)</span>
</span><span id="__span-0-432"><a id="__codelineno-0-432" name="__codelineno-0-432"></a>
</span><span id="__span-0-433"><a id="__codelineno-0-433" name="__codelineno-0-433"></a> <span class="n">error_msg</span> <span class="o">=</span> <span class="n">result</span><span class="o">.</span><span class="n">error_traceback</span> <span class="ow">or</span> <span class="s2">"Failed to open document"</span>
</span><span id="__span-0-434"><a id="__codelineno-0-434" name="__codelineno-0-434"></a> <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="n">error_msg</span><span class="p">)</span>
</span><span id="__span-0-435"><a id="__codelineno-0-435" name="__codelineno-0-435"></a>
</span><span id="__span-0-436"><a id="__codelineno-0-436" name="__codelineno-0-436"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">save_document</span><span class="p">(</span>
</span><span id="__span-0-437"><a id="__codelineno-0-437" name="__codelineno-0-437"></a> <span class="bp">self</span><span class="p">,</span>
</span><span id="__span-0-438"><a id="__codelineno-0-438" name="__codelineno-0-438"></a> <span class="n">doc_name</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-439"><a id="__codelineno-0-439" name="__codelineno-0-439"></a> <span class="n">path</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-440"><a id="__codelineno-0-440" name="__codelineno-0-440"></a> <span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">str</span><span class="p">:</span>
</span><span id="__span-0-441"><a id="__codelineno-0-441" name="__codelineno-0-441"></a><span class="w"> </span><span class="sd">"""Save a document."""</span>
</span><span id="__span-0-442"><a id="__codelineno-0-442" name="__codelineno-0-442"></a> <span class="n">code</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">"""</span>
</span><span id="__span-0-443"><a id="__codelineno-0-443" name="__codelineno-0-443"></a><span class="s2">doc = FreeCAD.ActiveDocument if </span><span class="si">{</span><span class="n">doc_name</span><span class="si">!r}</span><span class="s2"> is None else FreeCAD.getDocument(</span><span class="si">{</span><span class="n">doc_name</span><span class="si">!r}</span><span class="s2">)</span>
</span><span id="__span-0-444"><a id="__codelineno-0-444" name="__codelineno-0-444"></a><span class="s2">if doc is None:</span>
</span><span id="__span-0-445"><a id="__codelineno-0-445" name="__codelineno-0-445"></a><span class="s2"> raise ValueError("No active document" if </span><span class="si">{</span><span class="n">doc_name</span><span class="si">!r}</span><span class="s2"> is None else f"Document not found: </span><span class="si">{</span><span class="n">doc_name</span><span class="si">!r}</span><span class="s2">")</span>
</span><span id="__span-0-446"><a id="__codelineno-0-446" name="__codelineno-0-446"></a>
</span><span id="__span-0-447"><a id="__codelineno-0-447" name="__codelineno-0-447"></a><span class="s2">save_path = </span><span class="si">{</span><span class="n">path</span><span class="si">!r}</span><span class="s2"> or doc.FileName</span>
</span><span id="__span-0-448"><a id="__codelineno-0-448" name="__codelineno-0-448"></a><span class="s2">if not save_path:</span>
</span><span id="__span-0-449"><a id="__codelineno-0-449" name="__codelineno-0-449"></a><span class="s2"> raise ValueError("No path specified for new document")</span>
</span><span id="__span-0-450"><a id="__codelineno-0-450" name="__codelineno-0-450"></a>
</span><span id="__span-0-451"><a id="__codelineno-0-451" name="__codelineno-0-451"></a><span class="s2">doc.saveAs(save_path)</span>
</span><span id="__span-0-452"><a id="__codelineno-0-452" name="__codelineno-0-452"></a><span class="s2">_result_ = save_path</span>
</span><span id="__span-0-453"><a id="__codelineno-0-453" name="__codelineno-0-453"></a><span class="s2">"""</span>
</span><span id="__span-0-454"><a id="__codelineno-0-454" name="__codelineno-0-454"></a> <span class="n">result</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">execute_python</span><span class="p">(</span><span class="n">code</span><span class="p">)</span>
</span><span id="__span-0-455"><a id="__codelineno-0-455" name="__codelineno-0-455"></a>
</span><span id="__span-0-456"><a id="__codelineno-0-456" name="__codelineno-0-456"></a> <span class="k">if</span> <span class="n">result</span><span class="o">.</span><span class="n">success</span> <span class="ow">and</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">:</span>
</span><span id="__span-0-457"><a id="__codelineno-0-457" name="__codelineno-0-457"></a> <span class="k">return</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span>
</span><span id="__span-0-458"><a id="__codelineno-0-458" name="__codelineno-0-458"></a>
</span><span id="__span-0-459"><a id="__codelineno-0-459" name="__codelineno-0-459"></a> <span class="n">error_msg</span> <span class="o">=</span> <span class="n">result</span><span class="o">.</span><span class="n">error_traceback</span> <span class="ow">or</span> <span class="s2">"Failed to save document"</span>
</span><span id="__span-0-460"><a id="__codelineno-0-460" name="__codelineno-0-460"></a> <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="n">error_msg</span><span class="p">)</span>
</span><span id="__span-0-461"><a id="__codelineno-0-461" name="__codelineno-0-461"></a>
</span><span id="__span-0-462"><a id="__codelineno-0-462" name="__codelineno-0-462"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">close_document</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">doc_name</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kc">None</span><span class="p">:</span>
</span><span id="__span-0-463"><a id="__codelineno-0-463" name="__codelineno-0-463"></a><span class="w"> </span><span class="sd">"""Close a document."""</span>
</span><span id="__span-0-464"><a id="__codelineno-0-464" name="__codelineno-0-464"></a> <span class="n">code</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">"""</span>
</span><span id="__span-0-465"><a id="__codelineno-0-465" name="__codelineno-0-465"></a><span class="s2">doc_name = </span><span class="si">{</span><span class="n">doc_name</span><span class="si">!r}</span>
</span><span id="__span-0-466"><a id="__codelineno-0-466" name="__codelineno-0-466"></a><span class="s2">if doc_name is None:</span>
</span><span id="__span-0-467"><a id="__codelineno-0-467" name="__codelineno-0-467"></a><span class="s2"> doc = FreeCAD.ActiveDocument</span>
</span><span id="__span-0-468"><a id="__codelineno-0-468" name="__codelineno-0-468"></a><span class="s2"> if doc:</span>
</span><span id="__span-0-469"><a id="__codelineno-0-469" name="__codelineno-0-469"></a><span class="s2"> doc_name = doc.Name</span>
</span><span id="__span-0-470"><a id="__codelineno-0-470" name="__codelineno-0-470"></a><span class="s2"> else:</span>
</span><span id="__span-0-471"><a id="__codelineno-0-471" name="__codelineno-0-471"></a><span class="s2"> raise ValueError("No active document")</span>
</span><span id="__span-0-472"><a id="__codelineno-0-472" name="__codelineno-0-472"></a>
</span><span id="__span-0-473"><a id="__codelineno-0-473" name="__codelineno-0-473"></a><span class="s2">FreeCAD.closeDocument(doc_name)</span>
</span><span id="__span-0-474"><a id="__codelineno-0-474" name="__codelineno-0-474"></a><span class="s2">_result_ = True</span>
</span><span id="__span-0-475"><a id="__codelineno-0-475" name="__codelineno-0-475"></a><span class="s2">"""</span>
</span><span id="__span-0-476"><a id="__codelineno-0-476" name="__codelineno-0-476"></a> <span class="n">result</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">execute_python</span><span class="p">(</span><span class="n">code</span><span class="p">)</span>
</span><span id="__span-0-477"><a id="__codelineno-0-477" name="__codelineno-0-477"></a>
</span><span id="__span-0-478"><a id="__codelineno-0-478" name="__codelineno-0-478"></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">result</span><span class="o">.</span><span class="n">success</span><span class="p">:</span>
</span><span id="__span-0-479"><a id="__codelineno-0-479" name="__codelineno-0-479"></a> <span class="n">error_msg</span> <span class="o">=</span> <span class="n">result</span><span class="o">.</span><span class="n">error_traceback</span> <span class="ow">or</span> <span class="s2">"Failed to close document"</span>
</span><span id="__span-0-480"><a id="__codelineno-0-480" name="__codelineno-0-480"></a> <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="n">error_msg</span><span class="p">)</span>
</span><span id="__span-0-481"><a id="__codelineno-0-481" name="__codelineno-0-481"></a>
</span><span id="__span-0-482"><a id="__codelineno-0-482" name="__codelineno-0-482"></a> <span class="c1"># =========================================================================</span>
</span><span id="__span-0-483"><a id="__codelineno-0-483" name="__codelineno-0-483"></a> <span class="c1"># Object Management</span>
</span><span id="__span-0-484"><a id="__codelineno-0-484" name="__codelineno-0-484"></a> <span class="c1"># =========================================================================</span>
</span><span id="__span-0-485"><a id="__codelineno-0-485" name="__codelineno-0-485"></a>
</span><span id="__span-0-486"><a id="__codelineno-0-486" name="__codelineno-0-486"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">get_objects</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">doc_name</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">list</span><span class="p">[</span><span class="n">ObjectInfo</span><span class="p">]:</span>
</span><span id="__span-0-487"><a id="__codelineno-0-487" name="__codelineno-0-487"></a><span class="w"> </span><span class="sd">"""Get all objects in a document."""</span>
</span><span id="__span-0-488"><a id="__codelineno-0-488" name="__codelineno-0-488"></a> <span class="n">code</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">"""</span>
</span><span id="__span-0-489"><a id="__codelineno-0-489" name="__codelineno-0-489"></a><span class="s2">doc = FreeCAD.ActiveDocument if </span><span class="si">{</span><span class="n">doc_name</span><span class="si">!r}</span><span class="s2"> is None else FreeCAD.getDocument(</span><span class="si">{</span><span class="n">doc_name</span><span class="si">!r}</span><span class="s2">)</span>
</span><span id="__span-0-490"><a id="__codelineno-0-490" name="__codelineno-0-490"></a><span class="s2">if doc is None:</span>
</span><span id="__span-0-491"><a id="__codelineno-0-491" name="__codelineno-0-491"></a><span class="s2"> raise ValueError("No document found")</span>
</span><span id="__span-0-492"><a id="__codelineno-0-492" name="__codelineno-0-492"></a>
</span><span id="__span-0-493"><a id="__codelineno-0-493" name="__codelineno-0-493"></a><span class="s2">objects = []</span>
</span><span id="__span-0-494"><a id="__codelineno-0-494" name="__codelineno-0-494"></a><span class="s2">for obj in doc.Objects:</span>
</span><span id="__span-0-495"><a id="__codelineno-0-495" name="__codelineno-0-495"></a><span class="s2"> obj_info = </span><span class="se">{{</span>
</span><span id="__span-0-496"><a id="__codelineno-0-496" name="__codelineno-0-496"></a><span class="s2"> "name": obj.Name,</span>
</span><span id="__span-0-497"><a id="__codelineno-0-497" name="__codelineno-0-497"></a><span class="s2"> "label": obj.Label,</span>
</span><span id="__span-0-498"><a id="__codelineno-0-498" name="__codelineno-0-498"></a><span class="s2"> "type_id": obj.TypeId,</span>
</span><span id="__span-0-499"><a id="__codelineno-0-499" name="__codelineno-0-499"></a><span class="s2"> "visibility": obj.ViewObject.Visibility if hasattr(obj, "ViewObject") and obj.ViewObject else True,</span>
</span><span id="__span-0-500"><a id="__codelineno-0-500" name="__codelineno-0-500"></a><span class="s2"> "children": [c.Name for c in obj.OutList] if hasattr(obj, "OutList") else [],</span>
</span><span id="__span-0-501"><a id="__codelineno-0-501" name="__codelineno-0-501"></a><span class="s2"> "parents": [p.Name for p in obj.InList] if hasattr(obj, "InList") else [],</span>
</span><span id="__span-0-502"><a id="__codelineno-0-502" name="__codelineno-0-502"></a><span class="s2"> </span><span class="se">}}</span>
</span><span id="__span-0-503"><a id="__codelineno-0-503" name="__codelineno-0-503"></a><span class="s2"> objects.append(obj_info)</span>
</span><span id="__span-0-504"><a id="__codelineno-0-504" name="__codelineno-0-504"></a>
</span><span id="__span-0-505"><a id="__codelineno-0-505" name="__codelineno-0-505"></a><span class="s2">_result_ = objects</span>
</span><span id="__span-0-506"><a id="__codelineno-0-506" name="__codelineno-0-506"></a><span class="s2">"""</span>
</span><span id="__span-0-507"><a id="__codelineno-0-507" name="__codelineno-0-507"></a> <span class="n">result</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">execute_python</span><span class="p">(</span><span class="n">code</span><span class="p">)</span>
</span><span id="__span-0-508"><a id="__codelineno-0-508" name="__codelineno-0-508"></a>
</span><span id="__span-0-509"><a id="__codelineno-0-509" name="__codelineno-0-509"></a> <span class="k">if</span> <span class="n">result</span><span class="o">.</span><span class="n">success</span> <span class="ow">and</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">:</span>
</span><span id="__span-0-510"><a id="__codelineno-0-510" name="__codelineno-0-510"></a> <span class="k">return</span> <span class="p">[</span><span class="n">ObjectInfo</span><span class="p">(</span><span class="o">**</span><span class="n">obj</span><span class="p">)</span> <span class="k">for</span> <span class="n">obj</span> <span class="ow">in</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">]</span>
</span><span id="__span-0-511"><a id="__codelineno-0-511" name="__codelineno-0-511"></a> <span class="k">return</span> <span class="p">[]</span>
</span><span id="__span-0-512"><a id="__codelineno-0-512" name="__codelineno-0-512"></a>
</span><span id="__span-0-513"><a id="__codelineno-0-513" name="__codelineno-0-513"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">get_object</span><span class="p">(</span>
</span><span id="__span-0-514"><a id="__codelineno-0-514" name="__codelineno-0-514"></a> <span class="bp">self</span><span class="p">,</span>
</span><span id="__span-0-515"><a id="__codelineno-0-515" name="__codelineno-0-515"></a> <span class="n">obj_name</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span>
</span><span id="__span-0-516"><a id="__codelineno-0-516" name="__codelineno-0-516"></a> <span class="n">doc_name</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-517"><a id="__codelineno-0-517" name="__codelineno-0-517"></a> <span class="p">)</span> <span class="o">-&gt;</span> <span class="n">ObjectInfo</span><span class="p">:</span>
</span><span id="__span-0-518"><a id="__codelineno-0-518" name="__codelineno-0-518"></a><span class="w"> </span><span class="sd">"""Get detailed object information."""</span>
</span><span id="__span-0-519"><a id="__codelineno-0-519" name="__codelineno-0-519"></a> <span class="n">code</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">"""</span>
</span><span id="__span-0-520"><a id="__codelineno-0-520" name="__codelineno-0-520"></a><span class="s2">doc = FreeCAD.ActiveDocument if </span><span class="si">{</span><span class="n">doc_name</span><span class="si">!r}</span><span class="s2"> is None else FreeCAD.getDocument(</span><span class="si">{</span><span class="n">doc_name</span><span class="si">!r}</span><span class="s2">)</span>
</span><span id="__span-0-521"><a id="__codelineno-0-521" name="__codelineno-0-521"></a><span class="s2">if doc is None:</span>
</span><span id="__span-0-522"><a id="__codelineno-0-522" name="__codelineno-0-522"></a><span class="s2"> raise ValueError("No document found")</span>
</span><span id="__span-0-523"><a id="__codelineno-0-523" name="__codelineno-0-523"></a>
</span><span id="__span-0-524"><a id="__codelineno-0-524" name="__codelineno-0-524"></a><span class="s2">obj = doc.getObject(</span><span class="si">{</span><span class="n">obj_name</span><span class="si">!r}</span><span class="s2">)</span>
</span><span id="__span-0-525"><a id="__codelineno-0-525" name="__codelineno-0-525"></a><span class="s2">if obj is None:</span>
</span><span id="__span-0-526"><a id="__codelineno-0-526" name="__codelineno-0-526"></a><span class="s2"> raise ValueError(f"Object not found: </span><span class="si">{</span><span class="n">obj_name</span><span class="si">!r}</span><span class="s2">")</span>
</span><span id="__span-0-527"><a id="__codelineno-0-527" name="__codelineno-0-527"></a>
</span><span id="__span-0-528"><a id="__codelineno-0-528" name="__codelineno-0-528"></a><span class="s2">props = </span><span class="se">{{}}</span>
</span><span id="__span-0-529"><a id="__codelineno-0-529" name="__codelineno-0-529"></a><span class="s2">for prop in obj.PropertiesList:</span>
</span><span id="__span-0-530"><a id="__codelineno-0-530" name="__codelineno-0-530"></a><span class="s2"> try:</span>
</span><span id="__span-0-531"><a id="__codelineno-0-531" name="__codelineno-0-531"></a><span class="s2"> val = getattr(obj, prop)</span>
</span><span id="__span-0-532"><a id="__codelineno-0-532" name="__codelineno-0-532"></a><span class="s2"> if hasattr(val, '__class__') and val.__class__.__module__ != 'builtins':</span>
</span><span id="__span-0-533"><a id="__codelineno-0-533" name="__codelineno-0-533"></a><span class="s2"> val = str(val)</span>
</span><span id="__span-0-534"><a id="__codelineno-0-534" name="__codelineno-0-534"></a><span class="s2"> props[prop] = val</span>
</span><span id="__span-0-535"><a id="__codelineno-0-535" name="__codelineno-0-535"></a><span class="s2"> except Exception:</span>
</span><span id="__span-0-536"><a id="__codelineno-0-536" name="__codelineno-0-536"></a><span class="s2"> props[prop] = "&lt;unreadable&gt;"</span>
</span><span id="__span-0-537"><a id="__codelineno-0-537" name="__codelineno-0-537"></a>
</span><span id="__span-0-538"><a id="__codelineno-0-538" name="__codelineno-0-538"></a><span class="s2">shape_info = None</span>
</span><span id="__span-0-539"><a id="__codelineno-0-539" name="__codelineno-0-539"></a><span class="s2">if hasattr(obj, "Shape"):</span>
</span><span id="__span-0-540"><a id="__codelineno-0-540" name="__codelineno-0-540"></a><span class="s2"> shape = obj.Shape</span>
</span><span id="__span-0-541"><a id="__codelineno-0-541" name="__codelineno-0-541"></a><span class="s2"> shape_info = </span><span class="se">{{</span>
</span><span id="__span-0-542"><a id="__codelineno-0-542" name="__codelineno-0-542"></a><span class="s2"> "shape_type": shape.ShapeType,</span>
</span><span id="__span-0-543"><a id="__codelineno-0-543" name="__codelineno-0-543"></a><span class="s2"> "volume": shape.Volume if hasattr(shape, "Volume") else None,</span>
</span><span id="__span-0-544"><a id="__codelineno-0-544" name="__codelineno-0-544"></a><span class="s2"> "area": shape.Area if hasattr(shape, "Area") else None,</span>
</span><span id="__span-0-545"><a id="__codelineno-0-545" name="__codelineno-0-545"></a><span class="s2"> "is_valid": shape.isValid(),</span>
</span><span id="__span-0-546"><a id="__codelineno-0-546" name="__codelineno-0-546"></a><span class="s2"> "is_closed": shape.isClosed() if hasattr(shape, "isClosed") else False,</span>
</span><span id="__span-0-547"><a id="__codelineno-0-547" name="__codelineno-0-547"></a><span class="s2"> "vertex_count": len(shape.Vertexes) if hasattr(shape, "Vertexes") else 0,</span>
</span><span id="__span-0-548"><a id="__codelineno-0-548" name="__codelineno-0-548"></a><span class="s2"> "edge_count": len(shape.Edges) if hasattr(shape, "Edges") else 0,</span>
</span><span id="__span-0-549"><a id="__codelineno-0-549" name="__codelineno-0-549"></a><span class="s2"> "face_count": len(shape.Faces) if hasattr(shape, "Faces") else 0,</span>
</span><span id="__span-0-550"><a id="__codelineno-0-550" name="__codelineno-0-550"></a><span class="s2"> </span><span class="se">}}</span>
</span><span id="__span-0-551"><a id="__codelineno-0-551" name="__codelineno-0-551"></a>
</span><span id="__span-0-552"><a id="__codelineno-0-552" name="__codelineno-0-552"></a><span class="s2">_result_ = </span><span class="se">{{</span>
</span><span id="__span-0-553"><a id="__codelineno-0-553" name="__codelineno-0-553"></a><span class="s2"> "name": obj.Name,</span>
</span><span id="__span-0-554"><a id="__codelineno-0-554" name="__codelineno-0-554"></a><span class="s2"> "label": obj.Label,</span>
</span><span id="__span-0-555"><a id="__codelineno-0-555" name="__codelineno-0-555"></a><span class="s2"> "type_id": obj.TypeId,</span>
</span><span id="__span-0-556"><a id="__codelineno-0-556" name="__codelineno-0-556"></a><span class="s2"> "properties": props,</span>
</span><span id="__span-0-557"><a id="__codelineno-0-557" name="__codelineno-0-557"></a><span class="s2"> "shape_info": shape_info,</span>
</span><span id="__span-0-558"><a id="__codelineno-0-558" name="__codelineno-0-558"></a><span class="s2"> "children": [c.Name for c in obj.OutList] if hasattr(obj, "OutList") else [],</span>
</span><span id="__span-0-559"><a id="__codelineno-0-559" name="__codelineno-0-559"></a><span class="s2"> "parents": [p.Name for p in obj.InList] if hasattr(obj, "InList") else [],</span>
</span><span id="__span-0-560"><a id="__codelineno-0-560" name="__codelineno-0-560"></a><span class="s2"> "visibility": obj.ViewObject.Visibility if hasattr(obj, "ViewObject") and obj.ViewObject else True,</span>
</span><span id="__span-0-561"><a id="__codelineno-0-561" name="__codelineno-0-561"></a><span class="se">}}</span>
</span><span id="__span-0-562"><a id="__codelineno-0-562" name="__codelineno-0-562"></a><span class="s2">"""</span>
</span><span id="__span-0-563"><a id="__codelineno-0-563" name="__codelineno-0-563"></a> <span class="n">result</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">execute_python</span><span class="p">(</span><span class="n">code</span><span class="p">)</span>
</span><span id="__span-0-564"><a id="__codelineno-0-564" name="__codelineno-0-564"></a>
</span><span id="__span-0-565"><a id="__codelineno-0-565" name="__codelineno-0-565"></a> <span class="k">if</span> <span class="n">result</span><span class="o">.</span><span class="n">success</span> <span class="ow">and</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">:</span>
</span><span id="__span-0-566"><a id="__codelineno-0-566" name="__codelineno-0-566"></a> <span class="k">return</span> <span class="n">ObjectInfo</span><span class="p">(</span><span class="o">**</span><span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">)</span>
</span><span id="__span-0-567"><a id="__codelineno-0-567" name="__codelineno-0-567"></a>
</span><span id="__span-0-568"><a id="__codelineno-0-568" name="__codelineno-0-568"></a> <span class="n">error_msg</span> <span class="o">=</span> <span class="n">result</span><span class="o">.</span><span class="n">error_traceback</span> <span class="ow">or</span> <span class="s2">"Failed to get object"</span>
</span><span id="__span-0-569"><a id="__codelineno-0-569" name="__codelineno-0-569"></a> <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="n">error_msg</span><span class="p">)</span>
</span><span id="__span-0-570"><a id="__codelineno-0-570" name="__codelineno-0-570"></a>
</span><span id="__span-0-571"><a id="__codelineno-0-571" name="__codelineno-0-571"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">create_object</span><span class="p">(</span>
</span><span id="__span-0-572"><a id="__codelineno-0-572" name="__codelineno-0-572"></a> <span class="bp">self</span><span class="p">,</span>
</span><span id="__span-0-573"><a id="__codelineno-0-573" name="__codelineno-0-573"></a> <span class="n">type_id</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span>
</span><span id="__span-0-574"><a id="__codelineno-0-574" name="__codelineno-0-574"></a> <span class="n">name</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-575"><a id="__codelineno-0-575" name="__codelineno-0-575"></a> <span class="n">properties</span><span class="p">:</span> <span class="nb">dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Any</span><span class="p">]</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-576"><a id="__codelineno-0-576" name="__codelineno-0-576"></a> <span class="n">doc_name</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-577"><a id="__codelineno-0-577" name="__codelineno-0-577"></a> <span class="p">)</span> <span class="o">-&gt;</span> <span class="n">ObjectInfo</span><span class="p">:</span>
</span><span id="__span-0-578"><a id="__codelineno-0-578" name="__codelineno-0-578"></a><span class="w"> </span><span class="sd">"""Create a new object."""</span>
</span><span id="__span-0-579"><a id="__codelineno-0-579" name="__codelineno-0-579"></a> <span class="n">properties</span> <span class="o">=</span> <span class="n">properties</span> <span class="ow">or</span> <span class="p">{}</span>
</span><span id="__span-0-580"><a id="__codelineno-0-580" name="__codelineno-0-580"></a> <span class="n">code</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">"""</span>
</span><span id="__span-0-581"><a id="__codelineno-0-581" name="__codelineno-0-581"></a><span class="s2">doc = FreeCAD.ActiveDocument if </span><span class="si">{</span><span class="n">doc_name</span><span class="si">!r}</span><span class="s2"> is None else FreeCAD.getDocument(</span><span class="si">{</span><span class="n">doc_name</span><span class="si">!r}</span><span class="s2">)</span>
</span><span id="__span-0-582"><a id="__codelineno-0-582" name="__codelineno-0-582"></a><span class="s2">if doc is None:</span>
</span><span id="__span-0-583"><a id="__codelineno-0-583" name="__codelineno-0-583"></a><span class="s2"> raise ValueError("No document found")</span>
</span><span id="__span-0-584"><a id="__codelineno-0-584" name="__codelineno-0-584"></a>
</span><span id="__span-0-585"><a id="__codelineno-0-585" name="__codelineno-0-585"></a><span class="s2">obj = doc.addObject(</span><span class="si">{</span><span class="n">type_id</span><span class="si">!r}</span><span class="s2">, </span><span class="si">{</span><span class="n">name</span><span class="si">!r}</span><span class="s2"> or "")</span>
</span><span id="__span-0-586"><a id="__codelineno-0-586" name="__codelineno-0-586"></a>
</span><span id="__span-0-587"><a id="__codelineno-0-587" name="__codelineno-0-587"></a><span class="s2"># Set properties</span>
</span><span id="__span-0-588"><a id="__codelineno-0-588" name="__codelineno-0-588"></a><span class="s2">for prop_name, prop_val in </span><span class="si">{</span><span class="n">properties</span><span class="si">!r}</span><span class="s2">.items():</span>
</span><span id="__span-0-589"><a id="__codelineno-0-589" name="__codelineno-0-589"></a><span class="s2"> if hasattr(obj, prop_name):</span>
</span><span id="__span-0-590"><a id="__codelineno-0-590" name="__codelineno-0-590"></a><span class="s2"> setattr(obj, prop_name, prop_val)</span>
</span><span id="__span-0-591"><a id="__codelineno-0-591" name="__codelineno-0-591"></a>
</span><span id="__span-0-592"><a id="__codelineno-0-592" name="__codelineno-0-592"></a><span class="s2">doc.recompute()</span>
</span><span id="__span-0-593"><a id="__codelineno-0-593" name="__codelineno-0-593"></a>
</span><span id="__span-0-594"><a id="__codelineno-0-594" name="__codelineno-0-594"></a><span class="s2">_result_ = </span><span class="se">{{</span>
</span><span id="__span-0-595"><a id="__codelineno-0-595" name="__codelineno-0-595"></a><span class="s2"> "name": obj.Name,</span>
</span><span id="__span-0-596"><a id="__codelineno-0-596" name="__codelineno-0-596"></a><span class="s2"> "label": obj.Label,</span>
</span><span id="__span-0-597"><a id="__codelineno-0-597" name="__codelineno-0-597"></a><span class="s2"> "type_id": obj.TypeId,</span>
</span><span id="__span-0-598"><a id="__codelineno-0-598" name="__codelineno-0-598"></a><span class="s2"> "visibility": True,</span>
</span><span id="__span-0-599"><a id="__codelineno-0-599" name="__codelineno-0-599"></a><span class="s2"> "children": [c.Name for c in obj.OutList] if hasattr(obj, "OutList") else [],</span>
</span><span id="__span-0-600"><a id="__codelineno-0-600" name="__codelineno-0-600"></a><span class="s2"> "parents": [p.Name for p in obj.InList] if hasattr(obj, "InList") else [],</span>
</span><span id="__span-0-601"><a id="__codelineno-0-601" name="__codelineno-0-601"></a><span class="se">}}</span>
</span><span id="__span-0-602"><a id="__codelineno-0-602" name="__codelineno-0-602"></a><span class="s2">"""</span>
</span><span id="__span-0-603"><a id="__codelineno-0-603" name="__codelineno-0-603"></a> <span class="n">result</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">execute_python</span><span class="p">(</span><span class="n">code</span><span class="p">)</span>
</span><span id="__span-0-604"><a id="__codelineno-0-604" name="__codelineno-0-604"></a>
</span><span id="__span-0-605"><a id="__codelineno-0-605" name="__codelineno-0-605"></a> <span class="k">if</span> <span class="n">result</span><span class="o">.</span><span class="n">success</span> <span class="ow">and</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">:</span>
</span><span id="__span-0-606"><a id="__codelineno-0-606" name="__codelineno-0-606"></a> <span class="k">return</span> <span class="n">ObjectInfo</span><span class="p">(</span><span class="o">**</span><span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">)</span>
</span><span id="__span-0-607"><a id="__codelineno-0-607" name="__codelineno-0-607"></a>
</span><span id="__span-0-608"><a id="__codelineno-0-608" name="__codelineno-0-608"></a> <span class="n">error_msg</span> <span class="o">=</span> <span class="n">result</span><span class="o">.</span><span class="n">error_traceback</span> <span class="ow">or</span> <span class="s2">"Failed to create object"</span>
</span><span id="__span-0-609"><a id="__codelineno-0-609" name="__codelineno-0-609"></a> <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="n">error_msg</span><span class="p">)</span>
</span><span id="__span-0-610"><a id="__codelineno-0-610" name="__codelineno-0-610"></a>
</span><span id="__span-0-611"><a id="__codelineno-0-611" name="__codelineno-0-611"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">edit_object</span><span class="p">(</span>
</span><span id="__span-0-612"><a id="__codelineno-0-612" name="__codelineno-0-612"></a> <span class="bp">self</span><span class="p">,</span>
</span><span id="__span-0-613"><a id="__codelineno-0-613" name="__codelineno-0-613"></a> <span class="n">obj_name</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span>
</span><span id="__span-0-614"><a id="__codelineno-0-614" name="__codelineno-0-614"></a> <span class="n">properties</span><span class="p">:</span> <span class="nb">dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Any</span><span class="p">],</span>
</span><span id="__span-0-615"><a id="__codelineno-0-615" name="__codelineno-0-615"></a> <span class="n">doc_name</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-616"><a id="__codelineno-0-616" name="__codelineno-0-616"></a> <span class="p">)</span> <span class="o">-&gt;</span> <span class="n">ObjectInfo</span><span class="p">:</span>
</span><span id="__span-0-617"><a id="__codelineno-0-617" name="__codelineno-0-617"></a><span class="w"> </span><span class="sd">"""Edit object properties."""</span>
</span><span id="__span-0-618"><a id="__codelineno-0-618" name="__codelineno-0-618"></a> <span class="n">code</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">"""</span>
</span><span id="__span-0-619"><a id="__codelineno-0-619" name="__codelineno-0-619"></a><span class="s2">doc = FreeCAD.ActiveDocument if </span><span class="si">{</span><span class="n">doc_name</span><span class="si">!r}</span><span class="s2"> is None else FreeCAD.getDocument(</span><span class="si">{</span><span class="n">doc_name</span><span class="si">!r}</span><span class="s2">)</span>
</span><span id="__span-0-620"><a id="__codelineno-0-620" name="__codelineno-0-620"></a><span class="s2">if doc is None:</span>
</span><span id="__span-0-621"><a id="__codelineno-0-621" name="__codelineno-0-621"></a><span class="s2"> raise ValueError("No document found")</span>
</span><span id="__span-0-622"><a id="__codelineno-0-622" name="__codelineno-0-622"></a>
</span><span id="__span-0-623"><a id="__codelineno-0-623" name="__codelineno-0-623"></a><span class="s2">obj = doc.getObject(</span><span class="si">{</span><span class="n">obj_name</span><span class="si">!r}</span><span class="s2">)</span>
</span><span id="__span-0-624"><a id="__codelineno-0-624" name="__codelineno-0-624"></a><span class="s2">if obj is None:</span>
</span><span id="__span-0-625"><a id="__codelineno-0-625" name="__codelineno-0-625"></a><span class="s2"> raise ValueError(f"Object not found: </span><span class="si">{</span><span class="n">obj_name</span><span class="si">!r}</span><span class="s2">")</span>
</span><span id="__span-0-626"><a id="__codelineno-0-626" name="__codelineno-0-626"></a>
</span><span id="__span-0-627"><a id="__codelineno-0-627" name="__codelineno-0-627"></a><span class="s2"># Set properties</span>
</span><span id="__span-0-628"><a id="__codelineno-0-628" name="__codelineno-0-628"></a><span class="s2">for prop_name, prop_val in </span><span class="si">{</span><span class="n">properties</span><span class="si">!r}</span><span class="s2">.items():</span>
</span><span id="__span-0-629"><a id="__codelineno-0-629" name="__codelineno-0-629"></a><span class="s2"> if hasattr(obj, prop_name):</span>
</span><span id="__span-0-630"><a id="__codelineno-0-630" name="__codelineno-0-630"></a><span class="s2"> setattr(obj, prop_name, prop_val)</span>
</span><span id="__span-0-631"><a id="__codelineno-0-631" name="__codelineno-0-631"></a>
</span><span id="__span-0-632"><a id="__codelineno-0-632" name="__codelineno-0-632"></a><span class="s2">doc.recompute()</span>
</span><span id="__span-0-633"><a id="__codelineno-0-633" name="__codelineno-0-633"></a>
</span><span id="__span-0-634"><a id="__codelineno-0-634" name="__codelineno-0-634"></a><span class="s2">_result_ = </span><span class="se">{{</span>
</span><span id="__span-0-635"><a id="__codelineno-0-635" name="__codelineno-0-635"></a><span class="s2"> "name": obj.Name,</span>
</span><span id="__span-0-636"><a id="__codelineno-0-636" name="__codelineno-0-636"></a><span class="s2"> "label": obj.Label,</span>
</span><span id="__span-0-637"><a id="__codelineno-0-637" name="__codelineno-0-637"></a><span class="s2"> "type_id": obj.TypeId,</span>
</span><span id="__span-0-638"><a id="__codelineno-0-638" name="__codelineno-0-638"></a><span class="s2"> "visibility": obj.ViewObject.Visibility if hasattr(obj, "ViewObject") and obj.ViewObject else True,</span>
</span><span id="__span-0-639"><a id="__codelineno-0-639" name="__codelineno-0-639"></a><span class="s2"> "children": [c.Name for c in obj.OutList] if hasattr(obj, "OutList") else [],</span>
</span><span id="__span-0-640"><a id="__codelineno-0-640" name="__codelineno-0-640"></a><span class="s2"> "parents": [p.Name for p in obj.InList] if hasattr(obj, "InList") else [],</span>
</span><span id="__span-0-641"><a id="__codelineno-0-641" name="__codelineno-0-641"></a><span class="se">}}</span>
</span><span id="__span-0-642"><a id="__codelineno-0-642" name="__codelineno-0-642"></a><span class="s2">"""</span>
</span><span id="__span-0-643"><a id="__codelineno-0-643" name="__codelineno-0-643"></a> <span class="n">result</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">execute_python</span><span class="p">(</span><span class="n">code</span><span class="p">)</span>
</span><span id="__span-0-644"><a id="__codelineno-0-644" name="__codelineno-0-644"></a>
</span><span id="__span-0-645"><a id="__codelineno-0-645" name="__codelineno-0-645"></a> <span class="k">if</span> <span class="n">result</span><span class="o">.</span><span class="n">success</span> <span class="ow">and</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">:</span>
</span><span id="__span-0-646"><a id="__codelineno-0-646" name="__codelineno-0-646"></a> <span class="k">return</span> <span class="n">ObjectInfo</span><span class="p">(</span><span class="o">**</span><span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">)</span>
</span><span id="__span-0-647"><a id="__codelineno-0-647" name="__codelineno-0-647"></a>
</span><span id="__span-0-648"><a id="__codelineno-0-648" name="__codelineno-0-648"></a> <span class="n">error_msg</span> <span class="o">=</span> <span class="n">result</span><span class="o">.</span><span class="n">error_traceback</span> <span class="ow">or</span> <span class="s2">"Failed to edit object"</span>
</span><span id="__span-0-649"><a id="__codelineno-0-649" name="__codelineno-0-649"></a> <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="n">error_msg</span><span class="p">)</span>
</span><span id="__span-0-650"><a id="__codelineno-0-650" name="__codelineno-0-650"></a>
</span><span id="__span-0-651"><a id="__codelineno-0-651" name="__codelineno-0-651"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">delete_object</span><span class="p">(</span>
</span><span id="__span-0-652"><a id="__codelineno-0-652" name="__codelineno-0-652"></a> <span class="bp">self</span><span class="p">,</span>
</span><span id="__span-0-653"><a id="__codelineno-0-653" name="__codelineno-0-653"></a> <span class="n">obj_name</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span>
</span><span id="__span-0-654"><a id="__codelineno-0-654" name="__codelineno-0-654"></a> <span class="n">doc_name</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-655"><a id="__codelineno-0-655" name="__codelineno-0-655"></a> <span class="p">)</span> <span class="o">-&gt;</span> <span class="kc">None</span><span class="p">:</span>
</span><span id="__span-0-656"><a id="__codelineno-0-656" name="__codelineno-0-656"></a><span class="w"> </span><span class="sd">"""Delete an object."""</span>
</span><span id="__span-0-657"><a id="__codelineno-0-657" name="__codelineno-0-657"></a> <span class="n">code</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">"""</span>
</span><span id="__span-0-658"><a id="__codelineno-0-658" name="__codelineno-0-658"></a><span class="s2">doc = FreeCAD.ActiveDocument if </span><span class="si">{</span><span class="n">doc_name</span><span class="si">!r}</span><span class="s2"> is None else FreeCAD.getDocument(</span><span class="si">{</span><span class="n">doc_name</span><span class="si">!r}</span><span class="s2">)</span>
</span><span id="__span-0-659"><a id="__codelineno-0-659" name="__codelineno-0-659"></a><span class="s2">if doc is None:</span>
</span><span id="__span-0-660"><a id="__codelineno-0-660" name="__codelineno-0-660"></a><span class="s2"> raise ValueError("No document found")</span>
</span><span id="__span-0-661"><a id="__codelineno-0-661" name="__codelineno-0-661"></a>
</span><span id="__span-0-662"><a id="__codelineno-0-662" name="__codelineno-0-662"></a><span class="s2">obj = doc.getObject(</span><span class="si">{</span><span class="n">obj_name</span><span class="si">!r}</span><span class="s2">)</span>
</span><span id="__span-0-663"><a id="__codelineno-0-663" name="__codelineno-0-663"></a><span class="s2">if obj is None:</span>
</span><span id="__span-0-664"><a id="__codelineno-0-664" name="__codelineno-0-664"></a><span class="s2"> raise ValueError(f"Object not found: </span><span class="si">{</span><span class="n">obj_name</span><span class="si">!r}</span><span class="s2">")</span>
</span><span id="__span-0-665"><a id="__codelineno-0-665" name="__codelineno-0-665"></a>
</span><span id="__span-0-666"><a id="__codelineno-0-666" name="__codelineno-0-666"></a><span class="s2">doc.removeObject(</span><span class="si">{</span><span class="n">obj_name</span><span class="si">!r}</span><span class="s2">)</span>
</span><span id="__span-0-667"><a id="__codelineno-0-667" name="__codelineno-0-667"></a><span class="s2">_result_ = True</span>
</span><span id="__span-0-668"><a id="__codelineno-0-668" name="__codelineno-0-668"></a><span class="s2">"""</span>
</span><span id="__span-0-669"><a id="__codelineno-0-669" name="__codelineno-0-669"></a> <span class="n">result</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">execute_python</span><span class="p">(</span><span class="n">code</span><span class="p">)</span>
</span><span id="__span-0-670"><a id="__codelineno-0-670" name="__codelineno-0-670"></a>
</span><span id="__span-0-671"><a id="__codelineno-0-671" name="__codelineno-0-671"></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">result</span><span class="o">.</span><span class="n">success</span><span class="p">:</span>
</span><span id="__span-0-672"><a id="__codelineno-0-672" name="__codelineno-0-672"></a> <span class="n">error_msg</span> <span class="o">=</span> <span class="n">result</span><span class="o">.</span><span class="n">error_traceback</span> <span class="ow">or</span> <span class="s2">"Failed to delete object"</span>
</span><span id="__span-0-673"><a id="__codelineno-0-673" name="__codelineno-0-673"></a> <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="n">error_msg</span><span class="p">)</span>
</span><span id="__span-0-674"><a id="__codelineno-0-674" name="__codelineno-0-674"></a>
</span><span id="__span-0-675"><a id="__codelineno-0-675" name="__codelineno-0-675"></a> <span class="c1"># =========================================================================</span>
</span><span id="__span-0-676"><a id="__codelineno-0-676" name="__codelineno-0-676"></a> <span class="c1"># View and Screenshot</span>
</span><span id="__span-0-677"><a id="__codelineno-0-677" name="__codelineno-0-677"></a> <span class="c1"># =========================================================================</span>
</span><span id="__span-0-678"><a id="__codelineno-0-678" name="__codelineno-0-678"></a>
</span><span id="__span-0-679"><a id="__codelineno-0-679" name="__codelineno-0-679"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">get_screenshot</span><span class="p">(</span>
</span><span id="__span-0-680"><a id="__codelineno-0-680" name="__codelineno-0-680"></a> <span class="bp">self</span><span class="p">,</span>
</span><span id="__span-0-681"><a id="__codelineno-0-681" name="__codelineno-0-681"></a> <span class="n">view_angle</span><span class="p">:</span> <span class="n">ViewAngle</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-682"><a id="__codelineno-0-682" name="__codelineno-0-682"></a> <span class="n">width</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">800</span><span class="p">,</span>
</span><span id="__span-0-683"><a id="__codelineno-0-683" name="__codelineno-0-683"></a> <span class="n">height</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">600</span><span class="p">,</span>
</span><span id="__span-0-684"><a id="__codelineno-0-684" name="__codelineno-0-684"></a> <span class="n">doc_name</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-685"><a id="__codelineno-0-685" name="__codelineno-0-685"></a> <span class="p">)</span> <span class="o">-&gt;</span> <span class="n">ScreenshotResult</span><span class="p">:</span>
</span><span id="__span-0-686"><a id="__codelineno-0-686" name="__codelineno-0-686"></a><span class="w"> </span><span class="sd">"""Capture a screenshot of the 3D view via socket."""</span>
</span><span id="__span-0-687"><a id="__codelineno-0-687" name="__codelineno-0-687"></a> <span class="n">view_angle_str</span> <span class="o">=</span> <span class="n">view_angle</span><span class="o">.</span><span class="n">value</span> <span class="k">if</span> <span class="n">view_angle</span> <span class="k">else</span> <span class="s2">"Isometric"</span>
</span><span id="__span-0-688"><a id="__codelineno-0-688" name="__codelineno-0-688"></a> <span class="n">code</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">"""</span>
</span><span id="__span-0-689"><a id="__codelineno-0-689" name="__codelineno-0-689"></a><span class="s2">import base64</span>
</span><span id="__span-0-690"><a id="__codelineno-0-690" name="__codelineno-0-690"></a><span class="s2">import tempfile</span>
</span><span id="__span-0-691"><a id="__codelineno-0-691" name="__codelineno-0-691"></a><span class="s2">import os</span>
</span><span id="__span-0-692"><a id="__codelineno-0-692" name="__codelineno-0-692"></a>
</span><span id="__span-0-693"><a id="__codelineno-0-693" name="__codelineno-0-693"></a><span class="s2">doc = FreeCAD.ActiveDocument if </span><span class="si">{</span><span class="n">doc_name</span><span class="si">!r}</span><span class="s2"> is None else FreeCAD.getDocument(</span><span class="si">{</span><span class="n">doc_name</span><span class="si">!r}</span><span class="s2">)</span>
</span><span id="__span-0-694"><a id="__codelineno-0-694" name="__codelineno-0-694"></a><span class="s2">if doc is None:</span>
</span><span id="__span-0-695"><a id="__codelineno-0-695" name="__codelineno-0-695"></a><span class="s2"> raise ValueError("No document found")</span>
</span><span id="__span-0-696"><a id="__codelineno-0-696" name="__codelineno-0-696"></a>
</span><span id="__span-0-697"><a id="__codelineno-0-697" name="__codelineno-0-697"></a><span class="s2"># Check if GUI is available</span>
</span><span id="__span-0-698"><a id="__codelineno-0-698" name="__codelineno-0-698"></a><span class="s2">if not FreeCAD.GuiUp:</span>
</span><span id="__span-0-699"><a id="__codelineno-0-699" name="__codelineno-0-699"></a><span class="s2"> raise RuntimeError("GUI not available")</span>
</span><span id="__span-0-700"><a id="__codelineno-0-700" name="__codelineno-0-700"></a>
</span><span id="__span-0-701"><a id="__codelineno-0-701" name="__codelineno-0-701"></a><span class="s2">view = FreeCADGui.ActiveDocument.ActiveView</span>
</span><span id="__span-0-702"><a id="__codelineno-0-702" name="__codelineno-0-702"></a><span class="s2">if view is None:</span>
</span><span id="__span-0-703"><a id="__codelineno-0-703" name="__codelineno-0-703"></a><span class="s2"> raise ValueError("No active view")</span>
</span><span id="__span-0-704"><a id="__codelineno-0-704" name="__codelineno-0-704"></a>
</span><span id="__span-0-705"><a id="__codelineno-0-705" name="__codelineno-0-705"></a><span class="s2"># Check view type</span>
</span><span id="__span-0-706"><a id="__codelineno-0-706" name="__codelineno-0-706"></a><span class="s2">view_type = view.__class__.__name__</span>
</span><span id="__span-0-707"><a id="__codelineno-0-707" name="__codelineno-0-707"></a><span class="s2">if view_type not in ["View3DInventor", "View3DInventorPy"]:</span>
</span><span id="__span-0-708"><a id="__codelineno-0-708" name="__codelineno-0-708"></a><span class="s2"> raise ValueError(f"Cannot capture screenshot from </span><span class="se">{{</span><span class="s2">view_type</span><span class="se">}}</span><span class="s2"> view")</span>
</span><span id="__span-0-709"><a id="__codelineno-0-709" name="__codelineno-0-709"></a>
</span><span id="__span-0-710"><a id="__codelineno-0-710" name="__codelineno-0-710"></a><span class="s2"># Set view angle</span>
</span><span id="__span-0-711"><a id="__codelineno-0-711" name="__codelineno-0-711"></a><span class="s2">view_type_str = </span><span class="si">{</span><span class="n">view_angle_str</span><span class="si">!r}</span>
</span><span id="__span-0-712"><a id="__codelineno-0-712" name="__codelineno-0-712"></a><span class="s2">if view_type_str == "FitAll":</span>
</span><span id="__span-0-713"><a id="__codelineno-0-713" name="__codelineno-0-713"></a><span class="s2"> view.fitAll()</span>
</span><span id="__span-0-714"><a id="__codelineno-0-714" name="__codelineno-0-714"></a><span class="s2">elif view_type_str == "Isometric":</span>
</span><span id="__span-0-715"><a id="__codelineno-0-715" name="__codelineno-0-715"></a><span class="s2"> view.viewIsometric()</span>
</span><span id="__span-0-716"><a id="__codelineno-0-716" name="__codelineno-0-716"></a><span class="s2">elif view_type_str == "Front":</span>
</span><span id="__span-0-717"><a id="__codelineno-0-717" name="__codelineno-0-717"></a><span class="s2"> view.viewFront()</span>
</span><span id="__span-0-718"><a id="__codelineno-0-718" name="__codelineno-0-718"></a><span class="s2">elif view_type_str == "Back":</span>
</span><span id="__span-0-719"><a id="__codelineno-0-719" name="__codelineno-0-719"></a><span class="s2"> view.viewRear()</span>
</span><span id="__span-0-720"><a id="__codelineno-0-720" name="__codelineno-0-720"></a><span class="s2">elif view_type_str == "Top":</span>
</span><span id="__span-0-721"><a id="__codelineno-0-721" name="__codelineno-0-721"></a><span class="s2"> view.viewTop()</span>
</span><span id="__span-0-722"><a id="__codelineno-0-722" name="__codelineno-0-722"></a><span class="s2">elif view_type_str == "Bottom":</span>
</span><span id="__span-0-723"><a id="__codelineno-0-723" name="__codelineno-0-723"></a><span class="s2"> view.viewBottom()</span>
</span><span id="__span-0-724"><a id="__codelineno-0-724" name="__codelineno-0-724"></a><span class="s2">elif view_type_str == "Left":</span>
</span><span id="__span-0-725"><a id="__codelineno-0-725" name="__codelineno-0-725"></a><span class="s2"> view.viewLeft()</span>
</span><span id="__span-0-726"><a id="__codelineno-0-726" name="__codelineno-0-726"></a><span class="s2">elif view_type_str == "Right":</span>
</span><span id="__span-0-727"><a id="__codelineno-0-727" name="__codelineno-0-727"></a><span class="s2"> view.viewRight()</span>
</span><span id="__span-0-728"><a id="__codelineno-0-728" name="__codelineno-0-728"></a>
</span><span id="__span-0-729"><a id="__codelineno-0-729" name="__codelineno-0-729"></a><span class="s2"># Save to temp file and read</span>
</span><span id="__span-0-730"><a id="__codelineno-0-730" name="__codelineno-0-730"></a><span class="s2">with tempfile.NamedTemporaryFile(suffix=".png", delete=False) as f:</span>
</span><span id="__span-0-731"><a id="__codelineno-0-731" name="__codelineno-0-731"></a><span class="s2"> temp_path = f.name</span>
</span><span id="__span-0-732"><a id="__codelineno-0-732" name="__codelineno-0-732"></a>
</span><span id="__span-0-733"><a id="__codelineno-0-733" name="__codelineno-0-733"></a><span class="s2">view.saveImage(temp_path, </span><span class="si">{</span><span class="n">width</span><span class="si">}</span><span class="s2">, </span><span class="si">{</span><span class="n">height</span><span class="si">}</span><span class="s2">, "Current")</span>
</span><span id="__span-0-734"><a id="__codelineno-0-734" name="__codelineno-0-734"></a>
</span><span id="__span-0-735"><a id="__codelineno-0-735" name="__codelineno-0-735"></a><span class="s2">with open(temp_path, "rb") as f:</span>
</span><span id="__span-0-736"><a id="__codelineno-0-736" name="__codelineno-0-736"></a><span class="s2"> image_data = base64.b64encode(f.read()).decode("utf-8")</span>
</span><span id="__span-0-737"><a id="__codelineno-0-737" name="__codelineno-0-737"></a>
</span><span id="__span-0-738"><a id="__codelineno-0-738" name="__codelineno-0-738"></a><span class="s2">os.unlink(temp_path)</span>
</span><span id="__span-0-739"><a id="__codelineno-0-739" name="__codelineno-0-739"></a>
</span><span id="__span-0-740"><a id="__codelineno-0-740" name="__codelineno-0-740"></a><span class="s2">_result_ = </span><span class="se">{{</span>
</span><span id="__span-0-741"><a id="__codelineno-0-741" name="__codelineno-0-741"></a><span class="s2"> "success": True,</span>
</span><span id="__span-0-742"><a id="__codelineno-0-742" name="__codelineno-0-742"></a><span class="s2"> "data": image_data,</span>
</span><span id="__span-0-743"><a id="__codelineno-0-743" name="__codelineno-0-743"></a><span class="s2"> "format": "png",</span>
</span><span id="__span-0-744"><a id="__codelineno-0-744" name="__codelineno-0-744"></a><span class="s2"> "width": </span><span class="si">{</span><span class="n">width</span><span class="si">}</span><span class="s2">,</span>
</span><span id="__span-0-745"><a id="__codelineno-0-745" name="__codelineno-0-745"></a><span class="s2"> "height": </span><span class="si">{</span><span class="n">height</span><span class="si">}</span><span class="s2">,</span>
</span><span id="__span-0-746"><a id="__codelineno-0-746" name="__codelineno-0-746"></a><span class="se">}}</span>
</span><span id="__span-0-747"><a id="__codelineno-0-747" name="__codelineno-0-747"></a><span class="s2">"""</span>
</span><span id="__span-0-748"><a id="__codelineno-0-748" name="__codelineno-0-748"></a> <span class="n">result</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">execute_python</span><span class="p">(</span><span class="n">code</span><span class="p">)</span>
</span><span id="__span-0-749"><a id="__codelineno-0-749" name="__codelineno-0-749"></a>
</span><span id="__span-0-750"><a id="__codelineno-0-750" name="__codelineno-0-750"></a> <span class="k">if</span> <span class="n">result</span><span class="o">.</span><span class="n">success</span> <span class="ow">and</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">:</span>
</span><span id="__span-0-751"><a id="__codelineno-0-751" name="__codelineno-0-751"></a> <span class="k">return</span> <span class="n">ScreenshotResult</span><span class="p">(</span>
</span><span id="__span-0-752"><a id="__codelineno-0-752" name="__codelineno-0-752"></a> <span class="n">success</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span>
</span><span id="__span-0-753"><a id="__codelineno-0-753" name="__codelineno-0-753"></a> <span class="n">data</span><span class="o">=</span><span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">[</span><span class="s2">"data"</span><span class="p">],</span>
</span><span id="__span-0-754"><a id="__codelineno-0-754" name="__codelineno-0-754"></a> <span class="nb">format</span><span class="o">=</span><span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">[</span><span class="s2">"format"</span><span class="p">],</span>
</span><span id="__span-0-755"><a id="__codelineno-0-755" name="__codelineno-0-755"></a> <span class="n">width</span><span class="o">=</span><span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">[</span><span class="s2">"width"</span><span class="p">],</span>
</span><span id="__span-0-756"><a id="__codelineno-0-756" name="__codelineno-0-756"></a> <span class="n">height</span><span class="o">=</span><span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">[</span><span class="s2">"height"</span><span class="p">],</span>
</span><span id="__span-0-757"><a id="__codelineno-0-757" name="__codelineno-0-757"></a> <span class="n">view_angle</span><span class="o">=</span><span class="n">view_angle</span><span class="p">,</span>
</span><span id="__span-0-758"><a id="__codelineno-0-758" name="__codelineno-0-758"></a> <span class="p">)</span>
</span><span id="__span-0-759"><a id="__codelineno-0-759" name="__codelineno-0-759"></a>
</span><span id="__span-0-760"><a id="__codelineno-0-760" name="__codelineno-0-760"></a> <span class="k">return</span> <span class="n">ScreenshotResult</span><span class="p">(</span>
</span><span id="__span-0-761"><a id="__codelineno-0-761" name="__codelineno-0-761"></a> <span class="n">success</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
</span><span id="__span-0-762"><a id="__codelineno-0-762" name="__codelineno-0-762"></a> <span class="n">error</span><span class="o">=</span><span class="n">result</span><span class="o">.</span><span class="n">error_traceback</span>
</span><span id="__span-0-763"><a id="__codelineno-0-763" name="__codelineno-0-763"></a> <span class="ow">or</span> <span class="n">result</span><span class="o">.</span><span class="n">stderr</span>
</span><span id="__span-0-764"><a id="__codelineno-0-764" name="__codelineno-0-764"></a> <span class="ow">or</span> <span class="s2">"Failed to capture screenshot"</span><span class="p">,</span>
</span><span id="__span-0-765"><a id="__codelineno-0-765" name="__codelineno-0-765"></a> <span class="n">width</span><span class="o">=</span><span class="n">width</span><span class="p">,</span>
</span><span id="__span-0-766"><a id="__codelineno-0-766" name="__codelineno-0-766"></a> <span class="n">height</span><span class="o">=</span><span class="n">height</span><span class="p">,</span>
</span><span id="__span-0-767"><a id="__codelineno-0-767" name="__codelineno-0-767"></a> <span class="n">view_angle</span><span class="o">=</span><span class="n">view_angle</span><span class="p">,</span>
</span><span id="__span-0-768"><a id="__codelineno-0-768" name="__codelineno-0-768"></a> <span class="p">)</span>
</span><span id="__span-0-769"><a id="__codelineno-0-769" name="__codelineno-0-769"></a>
</span><span id="__span-0-770"><a id="__codelineno-0-770" name="__codelineno-0-770"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">set_view</span><span class="p">(</span>
</span><span id="__span-0-771"><a id="__codelineno-0-771" name="__codelineno-0-771"></a> <span class="bp">self</span><span class="p">,</span>
</span><span id="__span-0-772"><a id="__codelineno-0-772" name="__codelineno-0-772"></a> <span class="n">view_angle</span><span class="p">:</span> <span class="n">ViewAngle</span><span class="p">,</span>
</span><span id="__span-0-773"><a id="__codelineno-0-773" name="__codelineno-0-773"></a> <span class="n">doc_name</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-774"><a id="__codelineno-0-774" name="__codelineno-0-774"></a> <span class="p">)</span> <span class="o">-&gt;</span> <span class="kc">None</span><span class="p">:</span>
</span><span id="__span-0-775"><a id="__codelineno-0-775" name="__codelineno-0-775"></a><span class="w"> </span><span class="sd">"""Set the 3D view angle."""</span>
</span><span id="__span-0-776"><a id="__codelineno-0-776" name="__codelineno-0-776"></a> <span class="n">view_angle_str</span> <span class="o">=</span> <span class="n">view_angle</span><span class="o">.</span><span class="n">value</span>
</span><span id="__span-0-777"><a id="__codelineno-0-777" name="__codelineno-0-777"></a> <span class="n">code</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">"""</span>
</span><span id="__span-0-778"><a id="__codelineno-0-778" name="__codelineno-0-778"></a><span class="s2">doc = FreeCAD.ActiveDocument if </span><span class="si">{</span><span class="n">doc_name</span><span class="si">!r}</span><span class="s2"> is None else FreeCAD.getDocument(</span><span class="si">{</span><span class="n">doc_name</span><span class="si">!r}</span><span class="s2">)</span>
</span><span id="__span-0-779"><a id="__codelineno-0-779" name="__codelineno-0-779"></a><span class="s2">if doc is None:</span>
</span><span id="__span-0-780"><a id="__codelineno-0-780" name="__codelineno-0-780"></a><span class="s2"> raise ValueError("No document found")</span>
</span><span id="__span-0-781"><a id="__codelineno-0-781" name="__codelineno-0-781"></a>
</span><span id="__span-0-782"><a id="__codelineno-0-782" name="__codelineno-0-782"></a><span class="s2">if not FreeCAD.GuiUp:</span>
</span><span id="__span-0-783"><a id="__codelineno-0-783" name="__codelineno-0-783"></a><span class="s2"> _result_ = True</span>
</span><span id="__span-0-784"><a id="__codelineno-0-784" name="__codelineno-0-784"></a><span class="s2">else:</span>
</span><span id="__span-0-785"><a id="__codelineno-0-785" name="__codelineno-0-785"></a><span class="s2"> view = FreeCADGui.ActiveDocument.ActiveView</span>
</span><span id="__span-0-786"><a id="__codelineno-0-786" name="__codelineno-0-786"></a><span class="s2"> if view is None:</span>
</span><span id="__span-0-787"><a id="__codelineno-0-787" name="__codelineno-0-787"></a><span class="s2"> raise ValueError("No active view")</span>
</span><span id="__span-0-788"><a id="__codelineno-0-788" name="__codelineno-0-788"></a>
</span><span id="__span-0-789"><a id="__codelineno-0-789" name="__codelineno-0-789"></a><span class="s2"> view_type = </span><span class="si">{</span><span class="n">view_angle_str</span><span class="si">!r}</span>
</span><span id="__span-0-790"><a id="__codelineno-0-790" name="__codelineno-0-790"></a><span class="s2"> if view_type == "FitAll":</span>
</span><span id="__span-0-791"><a id="__codelineno-0-791" name="__codelineno-0-791"></a><span class="s2"> view.fitAll()</span>
</span><span id="__span-0-792"><a id="__codelineno-0-792" name="__codelineno-0-792"></a><span class="s2"> elif view_type == "Isometric":</span>
</span><span id="__span-0-793"><a id="__codelineno-0-793" name="__codelineno-0-793"></a><span class="s2"> view.viewIsometric()</span>
</span><span id="__span-0-794"><a id="__codelineno-0-794" name="__codelineno-0-794"></a><span class="s2"> elif view_type == "Front":</span>
</span><span id="__span-0-795"><a id="__codelineno-0-795" name="__codelineno-0-795"></a><span class="s2"> view.viewFront()</span>
</span><span id="__span-0-796"><a id="__codelineno-0-796" name="__codelineno-0-796"></a><span class="s2"> elif view_type == "Back":</span>
</span><span id="__span-0-797"><a id="__codelineno-0-797" name="__codelineno-0-797"></a><span class="s2"> view.viewRear()</span>
</span><span id="__span-0-798"><a id="__codelineno-0-798" name="__codelineno-0-798"></a><span class="s2"> elif view_type == "Top":</span>
</span><span id="__span-0-799"><a id="__codelineno-0-799" name="__codelineno-0-799"></a><span class="s2"> view.viewTop()</span>
</span><span id="__span-0-800"><a id="__codelineno-0-800" name="__codelineno-0-800"></a><span class="s2"> elif view_type == "Bottom":</span>
</span><span id="__span-0-801"><a id="__codelineno-0-801" name="__codelineno-0-801"></a><span class="s2"> view.viewBottom()</span>
</span><span id="__span-0-802"><a id="__codelineno-0-802" name="__codelineno-0-802"></a><span class="s2"> elif view_type == "Left":</span>
</span><span id="__span-0-803"><a id="__codelineno-0-803" name="__codelineno-0-803"></a><span class="s2"> view.viewLeft()</span>
</span><span id="__span-0-804"><a id="__codelineno-0-804" name="__codelineno-0-804"></a><span class="s2"> elif view_type == "Right":</span>
</span><span id="__span-0-805"><a id="__codelineno-0-805" name="__codelineno-0-805"></a><span class="s2"> view.viewRight()</span>
</span><span id="__span-0-806"><a id="__codelineno-0-806" name="__codelineno-0-806"></a>
</span><span id="__span-0-807"><a id="__codelineno-0-807" name="__codelineno-0-807"></a><span class="s2"> _result_ = True</span>
</span><span id="__span-0-808"><a id="__codelineno-0-808" name="__codelineno-0-808"></a><span class="s2">"""</span>
</span><span id="__span-0-809"><a id="__codelineno-0-809" name="__codelineno-0-809"></a> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">execute_python</span><span class="p">(</span><span class="n">code</span><span class="p">)</span>
</span><span id="__span-0-810"><a id="__codelineno-0-810" name="__codelineno-0-810"></a>
</span><span id="__span-0-811"><a id="__codelineno-0-811" name="__codelineno-0-811"></a> <span class="c1"># =========================================================================</span>
</span><span id="__span-0-812"><a id="__codelineno-0-812" name="__codelineno-0-812"></a> <span class="c1"># Macros</span>
</span><span id="__span-0-813"><a id="__codelineno-0-813" name="__codelineno-0-813"></a> <span class="c1"># =========================================================================</span>
</span><span id="__span-0-814"><a id="__codelineno-0-814" name="__codelineno-0-814"></a>
</span><span id="__span-0-815"><a id="__codelineno-0-815" name="__codelineno-0-815"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">get_macros</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">list</span><span class="p">[</span><span class="n">MacroInfo</span><span class="p">]:</span>
</span><span id="__span-0-816"><a id="__codelineno-0-816" name="__codelineno-0-816"></a><span class="w"> </span><span class="sd">"""Get list of available macros."""</span>
</span><span id="__span-0-817"><a id="__codelineno-0-817" name="__codelineno-0-817"></a> <span class="n">code</span> <span class="o">=</span> <span class="s2">"""</span>
</span><span id="__span-0-818"><a id="__codelineno-0-818" name="__codelineno-0-818"></a><span class="s2">import os</span>
</span><span id="__span-0-819"><a id="__codelineno-0-819" name="__codelineno-0-819"></a>
</span><span id="__span-0-820"><a id="__codelineno-0-820" name="__codelineno-0-820"></a><span class="s2">macro_paths = []</span>
</span><span id="__span-0-821"><a id="__codelineno-0-821" name="__codelineno-0-821"></a>
</span><span id="__span-0-822"><a id="__codelineno-0-822" name="__codelineno-0-822"></a><span class="s2">user_path = FreeCAD.getUserMacroDir(True)</span>
</span><span id="__span-0-823"><a id="__codelineno-0-823" name="__codelineno-0-823"></a><span class="s2">if os.path.exists(user_path):</span>
</span><span id="__span-0-824"><a id="__codelineno-0-824" name="__codelineno-0-824"></a><span class="s2"> macro_paths.append(("user", user_path))</span>
</span><span id="__span-0-825"><a id="__codelineno-0-825" name="__codelineno-0-825"></a>
</span><span id="__span-0-826"><a id="__codelineno-0-826" name="__codelineno-0-826"></a><span class="s2">system_path = FreeCAD.getResourceDir() + "Macro"</span>
</span><span id="__span-0-827"><a id="__codelineno-0-827" name="__codelineno-0-827"></a><span class="s2">if os.path.exists(system_path):</span>
</span><span id="__span-0-828"><a id="__codelineno-0-828" name="__codelineno-0-828"></a><span class="s2"> macro_paths.append(("system", system_path))</span>
</span><span id="__span-0-829"><a id="__codelineno-0-829" name="__codelineno-0-829"></a>
</span><span id="__span-0-830"><a id="__codelineno-0-830" name="__codelineno-0-830"></a><span class="s2">macros = []</span>
</span><span id="__span-0-831"><a id="__codelineno-0-831" name="__codelineno-0-831"></a><span class="s2">for source, path in macro_paths:</span>
</span><span id="__span-0-832"><a id="__codelineno-0-832" name="__codelineno-0-832"></a><span class="s2"> for filename in os.listdir(path):</span>
</span><span id="__span-0-833"><a id="__codelineno-0-833" name="__codelineno-0-833"></a><span class="s2"> if filename.endswith(".FCMacro"):</span>
</span><span id="__span-0-834"><a id="__codelineno-0-834" name="__codelineno-0-834"></a><span class="s2"> macro_file = os.path.join(path, filename)</span>
</span><span id="__span-0-835"><a id="__codelineno-0-835" name="__codelineno-0-835"></a><span class="s2"> description = ""</span>
</span><span id="__span-0-836"><a id="__codelineno-0-836" name="__codelineno-0-836"></a><span class="s2"> try:</span>
</span><span id="__span-0-837"><a id="__codelineno-0-837" name="__codelineno-0-837"></a><span class="s2"> with open(macro_file, "r") as f:</span>
</span><span id="__span-0-838"><a id="__codelineno-0-838" name="__codelineno-0-838"></a><span class="s2"> for line in f:</span>
</span><span id="__span-0-839"><a id="__codelineno-0-839" name="__codelineno-0-839"></a><span class="s2"> if line.startswith("#"):</span>
</span><span id="__span-0-840"><a id="__codelineno-0-840" name="__codelineno-0-840"></a><span class="s2"> desc = line.lstrip("#").strip()</span>
</span><span id="__span-0-841"><a id="__codelineno-0-841" name="__codelineno-0-841"></a><span class="s2"> if desc and not desc.startswith("!") and not desc.startswith("-*-"):</span>
</span><span id="__span-0-842"><a id="__codelineno-0-842" name="__codelineno-0-842"></a><span class="s2"> description = desc</span>
</span><span id="__span-0-843"><a id="__codelineno-0-843" name="__codelineno-0-843"></a><span class="s2"> break</span>
</span><span id="__span-0-844"><a id="__codelineno-0-844" name="__codelineno-0-844"></a><span class="s2"> except Exception:</span>
</span><span id="__span-0-845"><a id="__codelineno-0-845" name="__codelineno-0-845"></a><span class="s2"> pass</span>
</span><span id="__span-0-846"><a id="__codelineno-0-846" name="__codelineno-0-846"></a>
</span><span id="__span-0-847"><a id="__codelineno-0-847" name="__codelineno-0-847"></a><span class="s2"> macros.append({</span>
</span><span id="__span-0-848"><a id="__codelineno-0-848" name="__codelineno-0-848"></a><span class="s2"> "name": filename[:-8],</span>
</span><span id="__span-0-849"><a id="__codelineno-0-849" name="__codelineno-0-849"></a><span class="s2"> "path": macro_file,</span>
</span><span id="__span-0-850"><a id="__codelineno-0-850" name="__codelineno-0-850"></a><span class="s2"> "description": description,</span>
</span><span id="__span-0-851"><a id="__codelineno-0-851" name="__codelineno-0-851"></a><span class="s2"> "is_system": source == "system",</span>
</span><span id="__span-0-852"><a id="__codelineno-0-852" name="__codelineno-0-852"></a><span class="s2"> })</span>
</span><span id="__span-0-853"><a id="__codelineno-0-853" name="__codelineno-0-853"></a>
</span><span id="__span-0-854"><a id="__codelineno-0-854" name="__codelineno-0-854"></a><span class="s2">_result_ = macros</span>
</span><span id="__span-0-855"><a id="__codelineno-0-855" name="__codelineno-0-855"></a><span class="s2">"""</span>
</span><span id="__span-0-856"><a id="__codelineno-0-856" name="__codelineno-0-856"></a> <span class="n">result</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">execute_python</span><span class="p">(</span><span class="n">code</span><span class="p">)</span>
</span><span id="__span-0-857"><a id="__codelineno-0-857" name="__codelineno-0-857"></a>
</span><span id="__span-0-858"><a id="__codelineno-0-858" name="__codelineno-0-858"></a> <span class="k">if</span> <span class="n">result</span><span class="o">.</span><span class="n">success</span> <span class="ow">and</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">:</span>
</span><span id="__span-0-859"><a id="__codelineno-0-859" name="__codelineno-0-859"></a> <span class="k">return</span> <span class="p">[</span><span class="n">MacroInfo</span><span class="p">(</span><span class="o">**</span><span class="n">m</span><span class="p">)</span> <span class="k">for</span> <span class="n">m</span> <span class="ow">in</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">]</span>
</span><span id="__span-0-860"><a id="__codelineno-0-860" name="__codelineno-0-860"></a> <span class="k">return</span> <span class="p">[]</span>
</span><span id="__span-0-861"><a id="__codelineno-0-861" name="__codelineno-0-861"></a>
</span><span id="__span-0-862"><a id="__codelineno-0-862" name="__codelineno-0-862"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">run_macro</span><span class="p">(</span>
</span><span id="__span-0-863"><a id="__codelineno-0-863" name="__codelineno-0-863"></a> <span class="bp">self</span><span class="p">,</span>
</span><span id="__span-0-864"><a id="__codelineno-0-864" name="__codelineno-0-864"></a> <span class="n">macro_name</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span>
</span><span id="__span-0-865"><a id="__codelineno-0-865" name="__codelineno-0-865"></a> <span class="n">args</span><span class="p">:</span> <span class="nb">dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Any</span><span class="p">]</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-866"><a id="__codelineno-0-866" name="__codelineno-0-866"></a> <span class="p">)</span> <span class="o">-&gt;</span> <span class="n">ExecutionResult</span><span class="p">:</span>
</span><span id="__span-0-867"><a id="__codelineno-0-867" name="__codelineno-0-867"></a><span class="w"> </span><span class="sd">"""Run a macro by name."""</span>
</span><span id="__span-0-868"><a id="__codelineno-0-868" name="__codelineno-0-868"></a> <span class="n">args</span> <span class="o">=</span> <span class="n">args</span> <span class="ow">or</span> <span class="p">{}</span>
</span><span id="__span-0-869"><a id="__codelineno-0-869" name="__codelineno-0-869"></a> <span class="n">code</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">"""</span>
</span><span id="__span-0-870"><a id="__codelineno-0-870" name="__codelineno-0-870"></a><span class="s2">import os</span>
</span><span id="__span-0-871"><a id="__codelineno-0-871" name="__codelineno-0-871"></a>
</span><span id="__span-0-872"><a id="__codelineno-0-872" name="__codelineno-0-872"></a><span class="s2">macro_name = </span><span class="si">{</span><span class="n">macro_name</span><span class="si">!r}</span>
</span><span id="__span-0-873"><a id="__codelineno-0-873" name="__codelineno-0-873"></a><span class="s2">macro_file = None</span>
</span><span id="__span-0-874"><a id="__codelineno-0-874" name="__codelineno-0-874"></a>
</span><span id="__span-0-875"><a id="__codelineno-0-875" name="__codelineno-0-875"></a><span class="s2">user_path = FreeCAD.getUserMacroDir(True)</span>
</span><span id="__span-0-876"><a id="__codelineno-0-876" name="__codelineno-0-876"></a><span class="s2">user_macro = os.path.join(user_path, macro_name + ".FCMacro")</span>
</span><span id="__span-0-877"><a id="__codelineno-0-877" name="__codelineno-0-877"></a><span class="s2">if os.path.exists(user_macro):</span>
</span><span id="__span-0-878"><a id="__codelineno-0-878" name="__codelineno-0-878"></a><span class="s2"> macro_file = user_macro</span>
</span><span id="__span-0-879"><a id="__codelineno-0-879" name="__codelineno-0-879"></a>
</span><span id="__span-0-880"><a id="__codelineno-0-880" name="__codelineno-0-880"></a><span class="s2">if not macro_file:</span>
</span><span id="__span-0-881"><a id="__codelineno-0-881" name="__codelineno-0-881"></a><span class="s2"> system_path = FreeCAD.getResourceDir() + "Macro"</span>
</span><span id="__span-0-882"><a id="__codelineno-0-882" name="__codelineno-0-882"></a><span class="s2"> system_macro = os.path.join(system_path, macro_name + ".FCMacro")</span>
</span><span id="__span-0-883"><a id="__codelineno-0-883" name="__codelineno-0-883"></a><span class="s2"> if os.path.exists(system_macro):</span>
</span><span id="__span-0-884"><a id="__codelineno-0-884" name="__codelineno-0-884"></a><span class="s2"> macro_file = system_macro</span>
</span><span id="__span-0-885"><a id="__codelineno-0-885" name="__codelineno-0-885"></a>
</span><span id="__span-0-886"><a id="__codelineno-0-886" name="__codelineno-0-886"></a><span class="s2">if not macro_file:</span>
</span><span id="__span-0-887"><a id="__codelineno-0-887" name="__codelineno-0-887"></a><span class="s2"> raise FileNotFoundError(f"Macro not found: </span><span class="se">{{</span><span class="s2">macro_name</span><span class="se">}}</span><span class="s2">")</span>
</span><span id="__span-0-888"><a id="__codelineno-0-888" name="__codelineno-0-888"></a>
</span><span id="__span-0-889"><a id="__codelineno-0-889" name="__codelineno-0-889"></a><span class="s2">args = </span><span class="si">{</span><span class="n">args</span><span class="si">!r}</span>
</span><span id="__span-0-890"><a id="__codelineno-0-890" name="__codelineno-0-890"></a><span class="s2">for k, v in args.items():</span>
</span><span id="__span-0-891"><a id="__codelineno-0-891" name="__codelineno-0-891"></a><span class="s2"> exec(f"</span><span class="se">{{</span><span class="s2">k</span><span class="se">}}</span><span class="s2"> = </span><span class="se">{{</span><span class="s2">v!r</span><span class="se">}}</span><span class="s2">")</span>
</span><span id="__span-0-892"><a id="__codelineno-0-892" name="__codelineno-0-892"></a>
</span><span id="__span-0-893"><a id="__codelineno-0-893" name="__codelineno-0-893"></a><span class="s2">with open(macro_file, "r") as f:</span>
</span><span id="__span-0-894"><a id="__codelineno-0-894" name="__codelineno-0-894"></a><span class="s2"> macro_code = f.read()</span>
</span><span id="__span-0-895"><a id="__codelineno-0-895" name="__codelineno-0-895"></a>
</span><span id="__span-0-896"><a id="__codelineno-0-896" name="__codelineno-0-896"></a><span class="s2">exec(macro_code)</span>
</span><span id="__span-0-897"><a id="__codelineno-0-897" name="__codelineno-0-897"></a><span class="s2">_result_ = True</span>
</span><span id="__span-0-898"><a id="__codelineno-0-898" name="__codelineno-0-898"></a><span class="s2">"""</span>
</span><span id="__span-0-899"><a id="__codelineno-0-899" name="__codelineno-0-899"></a> <span class="k">return</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">execute_python</span><span class="p">(</span><span class="n">code</span><span class="p">)</span>
</span><span id="__span-0-900"><a id="__codelineno-0-900" name="__codelineno-0-900"></a>
</span><span id="__span-0-901"><a id="__codelineno-0-901" name="__codelineno-0-901"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">create_macro</span><span class="p">(</span>
</span><span id="__span-0-902"><a id="__codelineno-0-902" name="__codelineno-0-902"></a> <span class="bp">self</span><span class="p">,</span>
</span><span id="__span-0-903"><a id="__codelineno-0-903" name="__codelineno-0-903"></a> <span class="n">name</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span>
</span><span id="__span-0-904"><a id="__codelineno-0-904" name="__codelineno-0-904"></a> <span class="n">code</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span>
</span><span id="__span-0-905"><a id="__codelineno-0-905" name="__codelineno-0-905"></a> <span class="n">description</span><span class="p">:</span> <span class="nb">str</span> <span class="o">=</span> <span class="s2">""</span><span class="p">,</span>
</span><span id="__span-0-906"><a id="__codelineno-0-906" name="__codelineno-0-906"></a> <span class="p">)</span> <span class="o">-&gt;</span> <span class="n">MacroInfo</span><span class="p">:</span>
</span><span id="__span-0-907"><a id="__codelineno-0-907" name="__codelineno-0-907"></a><span class="w"> </span><span class="sd">"""Create a new macro."""</span>
</span><span id="__span-0-908"><a id="__codelineno-0-908" name="__codelineno-0-908"></a> <span class="n">create_code</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">"""</span>
</span><span id="__span-0-909"><a id="__codelineno-0-909" name="__codelineno-0-909"></a><span class="s2">import os</span>
</span><span id="__span-0-910"><a id="__codelineno-0-910" name="__codelineno-0-910"></a>
</span><span id="__span-0-911"><a id="__codelineno-0-911" name="__codelineno-0-911"></a><span class="s2">macro_path = FreeCAD.getUserMacroDir(True)</span>
</span><span id="__span-0-912"><a id="__codelineno-0-912" name="__codelineno-0-912"></a><span class="s2">os.makedirs(macro_path, exist_ok=True)</span>
</span><span id="__span-0-913"><a id="__codelineno-0-913" name="__codelineno-0-913"></a>
</span><span id="__span-0-914"><a id="__codelineno-0-914" name="__codelineno-0-914"></a><span class="s2">macro_file = os.path.join(macro_path, </span><span class="si">{</span><span class="n">name</span><span class="si">!r}</span><span class="s2"> + ".FCMacro")</span>
</span><span id="__span-0-915"><a id="__codelineno-0-915" name="__codelineno-0-915"></a>
</span><span id="__span-0-916"><a id="__codelineno-0-916" name="__codelineno-0-916"></a><span class="s2">header = ""</span>
</span><span id="__span-0-917"><a id="__codelineno-0-917" name="__codelineno-0-917"></a><span class="s2">if </span><span class="si">{</span><span class="n">description</span><span class="si">!r}</span><span class="s2">:</span>
</span><span id="__span-0-918"><a id="__codelineno-0-918" name="__codelineno-0-918"></a><span class="s2"> header = f"# </span><span class="si">{</span><span class="n">description</span><span class="si">!r}</span><span class="se">\\</span><span class="s2">n</span><span class="se">\\</span><span class="s2">n"</span>
</span><span id="__span-0-919"><a id="__codelineno-0-919" name="__codelineno-0-919"></a>
</span><span id="__span-0-920"><a id="__codelineno-0-920" name="__codelineno-0-920"></a><span class="s2">full_code = header + '''# -*- coding: utf-8 -*-</span>
</span><span id="__span-0-921"><a id="__codelineno-0-921" name="__codelineno-0-921"></a><span class="s2"># FreeCAD Macro: </span><span class="si">{</span><span class="n">name</span><span class="si">}</span>
</span><span id="__span-0-922"><a id="__codelineno-0-922" name="__codelineno-0-922"></a><span class="s2"># Created via MCP Bridge</span>
</span><span id="__span-0-923"><a id="__codelineno-0-923" name="__codelineno-0-923"></a>
</span><span id="__span-0-924"><a id="__codelineno-0-924" name="__codelineno-0-924"></a><span class="s2">import FreeCAD</span>
</span><span id="__span-0-925"><a id="__codelineno-0-925" name="__codelineno-0-925"></a><span class="s2">import FreeCADGui</span>
</span><span id="__span-0-926"><a id="__codelineno-0-926" name="__codelineno-0-926"></a>
</span><span id="__span-0-927"><a id="__codelineno-0-927" name="__codelineno-0-927"></a><span class="s2">''' + </span><span class="si">{</span><span class="n">code</span><span class="si">!r}</span>
</span><span id="__span-0-928"><a id="__codelineno-0-928" name="__codelineno-0-928"></a>
</span><span id="__span-0-929"><a id="__codelineno-0-929" name="__codelineno-0-929"></a><span class="s2">with open(macro_file, "w") as f:</span>
</span><span id="__span-0-930"><a id="__codelineno-0-930" name="__codelineno-0-930"></a><span class="s2"> f.write(full_code)</span>
</span><span id="__span-0-931"><a id="__codelineno-0-931" name="__codelineno-0-931"></a>
</span><span id="__span-0-932"><a id="__codelineno-0-932" name="__codelineno-0-932"></a><span class="s2">_result_ = </span><span class="se">{{</span>
</span><span id="__span-0-933"><a id="__codelineno-0-933" name="__codelineno-0-933"></a><span class="s2"> "name": </span><span class="si">{</span><span class="n">name</span><span class="si">!r}</span><span class="s2">,</span>
</span><span id="__span-0-934"><a id="__codelineno-0-934" name="__codelineno-0-934"></a><span class="s2"> "path": macro_file,</span>
</span><span id="__span-0-935"><a id="__codelineno-0-935" name="__codelineno-0-935"></a><span class="s2"> "description": </span><span class="si">{</span><span class="n">description</span><span class="si">!r}</span><span class="s2">,</span>
</span><span id="__span-0-936"><a id="__codelineno-0-936" name="__codelineno-0-936"></a><span class="s2"> "is_system": False,</span>
</span><span id="__span-0-937"><a id="__codelineno-0-937" name="__codelineno-0-937"></a><span class="se">}}</span>
</span><span id="__span-0-938"><a id="__codelineno-0-938" name="__codelineno-0-938"></a><span class="s2">"""</span>
</span><span id="__span-0-939"><a id="__codelineno-0-939" name="__codelineno-0-939"></a> <span class="n">result</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">execute_python</span><span class="p">(</span><span class="n">create_code</span><span class="p">)</span>
</span><span id="__span-0-940"><a id="__codelineno-0-940" name="__codelineno-0-940"></a>
</span><span id="__span-0-941"><a id="__codelineno-0-941" name="__codelineno-0-941"></a> <span class="k">if</span> <span class="n">result</span><span class="o">.</span><span class="n">success</span> <span class="ow">and</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">:</span>
</span><span id="__span-0-942"><a id="__codelineno-0-942" name="__codelineno-0-942"></a> <span class="k">return</span> <span class="n">MacroInfo</span><span class="p">(</span><span class="o">**</span><span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">)</span>
</span><span id="__span-0-943"><a id="__codelineno-0-943" name="__codelineno-0-943"></a>
</span><span id="__span-0-944"><a id="__codelineno-0-944" name="__codelineno-0-944"></a> <span class="n">error_msg</span> <span class="o">=</span> <span class="n">result</span><span class="o">.</span><span class="n">error_traceback</span> <span class="ow">or</span> <span class="s2">"Failed to create macro"</span>
</span><span id="__span-0-945"><a id="__codelineno-0-945" name="__codelineno-0-945"></a> <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="n">error_msg</span><span class="p">)</span>
</span><span id="__span-0-946"><a id="__codelineno-0-946" name="__codelineno-0-946"></a>
</span><span id="__span-0-947"><a id="__codelineno-0-947" name="__codelineno-0-947"></a> <span class="c1"># =========================================================================</span>
</span><span id="__span-0-948"><a id="__codelineno-0-948" name="__codelineno-0-948"></a> <span class="c1"># Workbenches</span>
</span><span id="__span-0-949"><a id="__codelineno-0-949" name="__codelineno-0-949"></a> <span class="c1"># =========================================================================</span>
</span><span id="__span-0-950"><a id="__codelineno-0-950" name="__codelineno-0-950"></a>
</span><span id="__span-0-951"><a id="__codelineno-0-951" name="__codelineno-0-951"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">get_workbenches</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">list</span><span class="p">[</span><span class="n">WorkbenchInfo</span><span class="p">]:</span>
</span><span id="__span-0-952"><a id="__codelineno-0-952" name="__codelineno-0-952"></a><span class="w"> </span><span class="sd">"""Get list of available workbenches."""</span>
</span><span id="__span-0-953"><a id="__codelineno-0-953" name="__codelineno-0-953"></a> <span class="n">code</span> <span class="o">=</span> <span class="s2">"""</span>
</span><span id="__span-0-954"><a id="__codelineno-0-954" name="__codelineno-0-954"></a><span class="s2">workbenches = []</span>
</span><span id="__span-0-955"><a id="__codelineno-0-955" name="__codelineno-0-955"></a><span class="s2">active_wb = FreeCADGui.activeWorkbench() if FreeCAD.GuiUp else None</span>
</span><span id="__span-0-956"><a id="__codelineno-0-956" name="__codelineno-0-956"></a><span class="s2">active_name = active_wb.__class__.__name__ if active_wb else None</span>
</span><span id="__span-0-957"><a id="__codelineno-0-957" name="__codelineno-0-957"></a>
</span><span id="__span-0-958"><a id="__codelineno-0-958" name="__codelineno-0-958"></a><span class="s2">if FreeCAD.GuiUp:</span>
</span><span id="__span-0-959"><a id="__codelineno-0-959" name="__codelineno-0-959"></a><span class="s2"> for name in FreeCADGui.listWorkbenches():</span>
</span><span id="__span-0-960"><a id="__codelineno-0-960" name="__codelineno-0-960"></a><span class="s2"> wb = FreeCADGui.getWorkbench(name)</span>
</span><span id="__span-0-961"><a id="__codelineno-0-961" name="__codelineno-0-961"></a><span class="s2"> workbenches.append({</span>
</span><span id="__span-0-962"><a id="__codelineno-0-962" name="__codelineno-0-962"></a><span class="s2"> "name": name,</span>
</span><span id="__span-0-963"><a id="__codelineno-0-963" name="__codelineno-0-963"></a><span class="s2"> "label": wb.MenuText if hasattr(wb, "MenuText") else name,</span>
</span><span id="__span-0-964"><a id="__codelineno-0-964" name="__codelineno-0-964"></a><span class="s2"> "icon": wb.Icon if hasattr(wb, "Icon") else "",</span>
</span><span id="__span-0-965"><a id="__codelineno-0-965" name="__codelineno-0-965"></a><span class="s2"> "is_active": name == active_name,</span>
</span><span id="__span-0-966"><a id="__codelineno-0-966" name="__codelineno-0-966"></a><span class="s2"> })</span>
</span><span id="__span-0-967"><a id="__codelineno-0-967" name="__codelineno-0-967"></a><span class="s2">else:</span>
</span><span id="__span-0-968"><a id="__codelineno-0-968" name="__codelineno-0-968"></a><span class="s2"> common = ["StartWorkbench", "PartWorkbench", "PartDesignWorkbench",</span>
</span><span id="__span-0-969"><a id="__codelineno-0-969" name="__codelineno-0-969"></a><span class="s2"> "DraftWorkbench", "SketcherWorkbench", "MeshWorkbench"]</span>
</span><span id="__span-0-970"><a id="__codelineno-0-970" name="__codelineno-0-970"></a><span class="s2"> for name in common:</span>
</span><span id="__span-0-971"><a id="__codelineno-0-971" name="__codelineno-0-971"></a><span class="s2"> workbenches.append({</span>
</span><span id="__span-0-972"><a id="__codelineno-0-972" name="__codelineno-0-972"></a><span class="s2"> "name": name,</span>
</span><span id="__span-0-973"><a id="__codelineno-0-973" name="__codelineno-0-973"></a><span class="s2"> "label": name.replace("Workbench", ""),</span>
</span><span id="__span-0-974"><a id="__codelineno-0-974" name="__codelineno-0-974"></a><span class="s2"> "icon": "",</span>
</span><span id="__span-0-975"><a id="__codelineno-0-975" name="__codelineno-0-975"></a><span class="s2"> "is_active": False,</span>
</span><span id="__span-0-976"><a id="__codelineno-0-976" name="__codelineno-0-976"></a><span class="s2"> })</span>
</span><span id="__span-0-977"><a id="__codelineno-0-977" name="__codelineno-0-977"></a>
</span><span id="__span-0-978"><a id="__codelineno-0-978" name="__codelineno-0-978"></a><span class="s2">_result_ = workbenches</span>
</span><span id="__span-0-979"><a id="__codelineno-0-979" name="__codelineno-0-979"></a><span class="s2">"""</span>
</span><span id="__span-0-980"><a id="__codelineno-0-980" name="__codelineno-0-980"></a> <span class="n">result</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">execute_python</span><span class="p">(</span><span class="n">code</span><span class="p">)</span>
</span><span id="__span-0-981"><a id="__codelineno-0-981" name="__codelineno-0-981"></a>
</span><span id="__span-0-982"><a id="__codelineno-0-982" name="__codelineno-0-982"></a> <span class="k">if</span> <span class="n">result</span><span class="o">.</span><span class="n">success</span> <span class="ow">and</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">:</span>
</span><span id="__span-0-983"><a id="__codelineno-0-983" name="__codelineno-0-983"></a> <span class="k">return</span> <span class="p">[</span><span class="n">WorkbenchInfo</span><span class="p">(</span><span class="o">**</span><span class="n">wb</span><span class="p">)</span> <span class="k">for</span> <span class="n">wb</span> <span class="ow">in</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">]</span>
</span><span id="__span-0-984"><a id="__codelineno-0-984" name="__codelineno-0-984"></a> <span class="k">return</span> <span class="p">[]</span>
</span><span id="__span-0-985"><a id="__codelineno-0-985" name="__codelineno-0-985"></a>
</span><span id="__span-0-986"><a id="__codelineno-0-986" name="__codelineno-0-986"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">activate_workbench</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">workbench_name</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kc">None</span><span class="p">:</span>
</span><span id="__span-0-987"><a id="__codelineno-0-987" name="__codelineno-0-987"></a><span class="w"> </span><span class="sd">"""Activate a workbench."""</span>
</span><span id="__span-0-988"><a id="__codelineno-0-988" name="__codelineno-0-988"></a> <span class="n">code</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">"""</span>
</span><span id="__span-0-989"><a id="__codelineno-0-989" name="__codelineno-0-989"></a><span class="s2">if FreeCAD.GuiUp:</span>
</span><span id="__span-0-990"><a id="__codelineno-0-990" name="__codelineno-0-990"></a><span class="s2"> try:</span>
</span><span id="__span-0-991"><a id="__codelineno-0-991" name="__codelineno-0-991"></a><span class="s2"> FreeCADGui.activateWorkbench(</span><span class="si">{</span><span class="n">workbench_name</span><span class="si">!r}</span><span class="s2">)</span>
</span><span id="__span-0-992"><a id="__codelineno-0-992" name="__codelineno-0-992"></a><span class="s2"> _result_ = True</span>
</span><span id="__span-0-993"><a id="__codelineno-0-993" name="__codelineno-0-993"></a><span class="s2"> except Exception as e:</span>
</span><span id="__span-0-994"><a id="__codelineno-0-994" name="__codelineno-0-994"></a><span class="s2"> raise ValueError(f"Failed to activate workbench: </span><span class="se">{{</span><span class="s2">e</span><span class="se">}}</span><span class="s2">")</span>
</span><span id="__span-0-995"><a id="__codelineno-0-995" name="__codelineno-0-995"></a><span class="s2">else:</span>
</span><span id="__span-0-996"><a id="__codelineno-0-996" name="__codelineno-0-996"></a><span class="s2"> _result_ = True</span>
</span><span id="__span-0-997"><a id="__codelineno-0-997" name="__codelineno-0-997"></a><span class="s2">"""</span>
</span><span id="__span-0-998"><a id="__codelineno-0-998" name="__codelineno-0-998"></a> <span class="n">result</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">execute_python</span><span class="p">(</span><span class="n">code</span><span class="p">)</span>
</span><span id="__span-0-999"><a id="__codelineno-0-999" name="__codelineno-0-999"></a>
</span><span id="__span-0-1000"><a id="__codelineno-0-1000" name="__codelineno-0-1000"></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">result</span><span class="o">.</span><span class="n">success</span><span class="p">:</span>
</span><span id="__span-0-1001"><a id="__codelineno-0-1001" name="__codelineno-0-1001"></a> <span class="n">error_msg</span> <span class="o">=</span> <span class="n">result</span><span class="o">.</span><span class="n">error_traceback</span> <span class="ow">or</span> <span class="s2">"Failed to activate workbench"</span>
</span><span id="__span-0-1002"><a id="__codelineno-0-1002" name="__codelineno-0-1002"></a> <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="n">error_msg</span><span class="p">)</span>
</span><span id="__span-0-1003"><a id="__codelineno-0-1003" name="__codelineno-0-1003"></a>
</span><span id="__span-0-1004"><a id="__codelineno-0-1004" name="__codelineno-0-1004"></a> <span class="c1"># =========================================================================</span>
</span><span id="__span-0-1005"><a id="__codelineno-0-1005" name="__codelineno-0-1005"></a> <span class="c1"># Version and Environment</span>
</span><span id="__span-0-1006"><a id="__codelineno-0-1006" name="__codelineno-0-1006"></a> <span class="c1"># =========================================================================</span>
</span><span id="__span-0-1007"><a id="__codelineno-0-1007" name="__codelineno-0-1007"></a>
</span><span id="__span-0-1008"><a id="__codelineno-0-1008" name="__codelineno-0-1008"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">get_freecad_version</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Any</span><span class="p">]:</span>
</span><span id="__span-0-1009"><a id="__codelineno-0-1009" name="__codelineno-0-1009"></a><span class="w"> </span><span class="sd">"""Get FreeCAD version information."""</span>
</span><span id="__span-0-1010"><a id="__codelineno-0-1010" name="__codelineno-0-1010"></a> <span class="n">code</span> <span class="o">=</span> <span class="s2">"""</span>
</span><span id="__span-0-1011"><a id="__codelineno-0-1011" name="__codelineno-0-1011"></a><span class="s2">import sys</span>
</span><span id="__span-0-1012"><a id="__codelineno-0-1012" name="__codelineno-0-1012"></a><span class="s2">_result_ = {</span>
</span><span id="__span-0-1013"><a id="__codelineno-0-1013" name="__codelineno-0-1013"></a><span class="s2"> "version": ".".join(str(x) for x in FreeCAD.Version()[:3]),</span>
</span><span id="__span-0-1014"><a id="__codelineno-0-1014" name="__codelineno-0-1014"></a><span class="s2"> "version_tuple": FreeCAD.Version()[:3],</span>
</span><span id="__span-0-1015"><a id="__codelineno-0-1015" name="__codelineno-0-1015"></a><span class="s2"> "build_date": FreeCAD.Version()[3] if len(FreeCAD.Version()) &gt; 3 else "unknown",</span>
</span><span id="__span-0-1016"><a id="__codelineno-0-1016" name="__codelineno-0-1016"></a><span class="s2"> "python_version": sys.version,</span>
</span><span id="__span-0-1017"><a id="__codelineno-0-1017" name="__codelineno-0-1017"></a><span class="s2"> "gui_available": FreeCAD.GuiUp,</span>
</span><span id="__span-0-1018"><a id="__codelineno-0-1018" name="__codelineno-0-1018"></a><span class="s2">}</span>
</span><span id="__span-0-1019"><a id="__codelineno-0-1019" name="__codelineno-0-1019"></a><span class="s2">"""</span>
</span><span id="__span-0-1020"><a id="__codelineno-0-1020" name="__codelineno-0-1020"></a> <span class="n">result</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">execute_python</span><span class="p">(</span><span class="n">code</span><span class="p">)</span>
</span><span id="__span-0-1021"><a id="__codelineno-0-1021" name="__codelineno-0-1021"></a>
</span><span id="__span-0-1022"><a id="__codelineno-0-1022" name="__codelineno-0-1022"></a> <span class="k">if</span> <span class="n">result</span><span class="o">.</span><span class="n">success</span> <span class="ow">and</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">:</span>
</span><span id="__span-0-1023"><a id="__codelineno-0-1023" name="__codelineno-0-1023"></a> <span class="k">return</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span>
</span><span id="__span-0-1024"><a id="__codelineno-0-1024" name="__codelineno-0-1024"></a>
</span><span id="__span-0-1025"><a id="__codelineno-0-1025" name="__codelineno-0-1025"></a> <span class="k">return</span> <span class="p">{</span>
</span><span id="__span-0-1026"><a id="__codelineno-0-1026" name="__codelineno-0-1026"></a> <span class="s2">"version"</span><span class="p">:</span> <span class="s2">"unknown"</span><span class="p">,</span>
</span><span id="__span-0-1027"><a id="__codelineno-0-1027" name="__codelineno-0-1027"></a> <span class="s2">"version_tuple"</span><span class="p">:</span> <span class="p">[],</span>
</span><span id="__span-0-1028"><a id="__codelineno-0-1028" name="__codelineno-0-1028"></a> <span class="s2">"build_date"</span><span class="p">:</span> <span class="s2">"unknown"</span><span class="p">,</span>
</span><span id="__span-0-1029"><a id="__codelineno-0-1029" name="__codelineno-0-1029"></a> <span class="s2">"python_version"</span><span class="p">:</span> <span class="s2">""</span><span class="p">,</span>
</span><span id="__span-0-1030"><a id="__codelineno-0-1030" name="__codelineno-0-1030"></a> <span class="s2">"gui_available"</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span>
</span><span id="__span-0-1031"><a id="__codelineno-0-1031" name="__codelineno-0-1031"></a> <span class="p">}</span>
</span><span id="__span-0-1032"><a id="__codelineno-0-1032" name="__codelineno-0-1032"></a>
</span><span id="__span-0-1033"><a id="__codelineno-0-1033" name="__codelineno-0-1033"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">is_gui_available</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">bool</span><span class="p">:</span>
</span><span id="__span-0-1034"><a id="__codelineno-0-1034" name="__codelineno-0-1034"></a><span class="w"> </span><span class="sd">"""Check if FreeCAD GUI is available."""</span>
</span><span id="__span-0-1035"><a id="__codelineno-0-1035" name="__codelineno-0-1035"></a> <span class="n">result</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">execute_python</span><span class="p">(</span><span class="s2">"_result_ = FreeCAD.GuiUp"</span><span class="p">)</span>
</span><span id="__span-0-1036"><a id="__codelineno-0-1036" name="__codelineno-0-1036"></a> <span class="k">return</span> <span class="nb">bool</span><span class="p">(</span><span class="n">result</span><span class="o">.</span><span class="n">success</span> <span class="ow">and</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">)</span>
</span><span id="__span-0-1037"><a id="__codelineno-0-1037" name="__codelineno-0-1037"></a>
</span><span id="__span-0-1038"><a id="__codelineno-0-1038" name="__codelineno-0-1038"></a> <span class="c1"># =========================================================================</span>
</span><span id="__span-0-1039"><a id="__codelineno-0-1039" name="__codelineno-0-1039"></a> <span class="c1"># Console</span>
</span><span id="__span-0-1040"><a id="__codelineno-0-1040" name="__codelineno-0-1040"></a> <span class="c1"># =========================================================================</span>
</span><span id="__span-0-1041"><a id="__codelineno-0-1041" name="__codelineno-0-1041"></a>
</span><span id="__span-0-1042"><a id="__codelineno-0-1042" name="__codelineno-0-1042"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">get_console_output</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">lines</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">100</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">list</span><span class="p">[</span><span class="nb">str</span><span class="p">]:</span>
</span><span id="__span-0-1043"><a id="__codelineno-0-1043" name="__codelineno-0-1043"></a><span class="w"> </span><span class="sd">"""Get recent console output."""</span>
</span><span id="__span-0-1044"><a id="__codelineno-0-1044" name="__codelineno-0-1044"></a> <span class="n">code</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">"""</span>
</span><span id="__span-0-1045"><a id="__codelineno-0-1045" name="__codelineno-0-1045"></a><span class="s2">output_lines = []</span>
</span><span id="__span-0-1046"><a id="__codelineno-0-1046" name="__codelineno-0-1046"></a>
</span><span id="__span-0-1047"><a id="__codelineno-0-1047" name="__codelineno-0-1047"></a><span class="s2">if hasattr(FreeCAD, 'Console'):</span>
</span><span id="__span-0-1048"><a id="__codelineno-0-1048" name="__codelineno-0-1048"></a><span class="s2"> console = FreeCAD.Console</span>
</span><span id="__span-0-1049"><a id="__codelineno-0-1049" name="__codelineno-0-1049"></a><span class="s2"> if hasattr(console, 'GetLog'):</span>
</span><span id="__span-0-1050"><a id="__codelineno-0-1050" name="__codelineno-0-1050"></a><span class="s2"> log = console.GetLog()</span>
</span><span id="__span-0-1051"><a id="__codelineno-0-1051" name="__codelineno-0-1051"></a><span class="s2"> if log:</span>
</span><span id="__span-0-1052"><a id="__codelineno-0-1052" name="__codelineno-0-1052"></a><span class="s2"> output_lines = log.split('</span><span class="se">\\</span><span class="s2">n')[-</span><span class="si">{</span><span class="n">lines</span><span class="si">}</span><span class="s2">:]</span>
</span><span id="__span-0-1053"><a id="__codelineno-0-1053" name="__codelineno-0-1053"></a>
</span><span id="__span-0-1054"><a id="__codelineno-0-1054" name="__codelineno-0-1054"></a><span class="s2">_result_ = output_lines</span>
</span><span id="__span-0-1055"><a id="__codelineno-0-1055" name="__codelineno-0-1055"></a><span class="s2">"""</span>
</span><span id="__span-0-1056"><a id="__codelineno-0-1056" name="__codelineno-0-1056"></a> <span class="n">result</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">execute_python</span><span class="p">(</span><span class="n">code</span><span class="p">)</span>
</span><span id="__span-0-1057"><a id="__codelineno-0-1057" name="__codelineno-0-1057"></a>
</span><span id="__span-0-1058"><a id="__codelineno-0-1058" name="__codelineno-0-1058"></a> <span class="k">if</span> <span class="n">result</span><span class="o">.</span><span class="n">success</span> <span class="ow">and</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">:</span>
</span><span id="__span-0-1059"><a id="__codelineno-0-1059" name="__codelineno-0-1059"></a> <span class="k">return</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span>
</span><span id="__span-0-1060"><a id="__codelineno-0-1060" name="__codelineno-0-1060"></a> <span class="k">return</span> <span class="p">[]</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> <div class="doc doc-children"> <h5 id="freecad_mcp.bridge.socket.SocketBridge-functions">Functions<a href="#freecad_mcp.bridge.socket.SocketBridge-functions" class="headerlink" title="Permanent link">¶</a></h5> <div class="doc doc-object doc-function"> <h6 id="freecad_mcp.bridge.socket.SocketBridge.__init__" class="doc doc-heading"> <code class="highlight language-python"><span class="fm">__init__</span><span class="p">(</span><span class="n">host</span><span class="o">=</span><span class="n">DEFAULT_SOCKET_HOST</span><span class="p">,</span> <span class="n">port</span><span class="o">=</span><span class="n">DEFAULT_SOCKET_PORT</span><span class="p">,</span> <span class="n">timeout</span><span class="o">=</span><span class="n">DEFAULT_TIMEOUT</span><span class="p">,</span> <span class="n">auto_reconnect</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span></code> <a href="#freecad_mcp.bridge.socket.SocketBridge.__init__" class="headerlink" title="Permanent link">¶</a></h6> <div class="doc doc-contents "> <p>Initialize the socket bridge.</p> <p><span class="doc-section-title">Parameters:</span></p> <table> <thead> <tr> <th>Name</th> <th>Type</th> <th>Description</th> <th>Default</th> </tr> </thead> <tbody> <tr class="doc-section-item"> <td> <code>host</code> </td> <td> <code><span title="str">str</span></code> </td> <td> <div class="doc-md-description"> <p>Socket server hostname.</p> </div> </td> <td> <code><span title="freecad_mcp.bridge.socket.DEFAULT_SOCKET_HOST">DEFAULT_SOCKET_HOST</span></code> </td> </tr> <tr class="doc-section-item"> <td> <code>port</code> </td> <td> <code><span title="int">int</span></code> </td> <td> <div class="doc-md-description"> <p>Socket server port.</p> </div> </td> <td> <code><span title="freecad_mcp.bridge.socket.DEFAULT_SOCKET_PORT">DEFAULT_SOCKET_PORT</span></code> </td> </tr> <tr class="doc-section-item"> <td> <code>timeout</code> </td> <td> <code><span title="float">float</span></code> </td> <td> <div class="doc-md-description"> <p>Connection and request timeout in seconds.</p> </div> </td> <td> <code><span title="freecad_mcp.bridge.socket.DEFAULT_TIMEOUT">DEFAULT_TIMEOUT</span></code> </td> </tr> <tr class="doc-section-item"> <td> <code>auto_reconnect</code> </td> <td> <code><span title="bool">bool</span></code> </td> <td> <div class="doc-md-description"> <p>Whether to automatically reconnect on connection loss.</p> </div> </td> <td> <code>True</code> </td> </tr> </tbody> </table> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/socket.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-66">66</a></span>
<span class="normal"><a href="#__codelineno-0-67">67</a></span>
<span class="normal"><a href="#__codelineno-0-68">68</a></span>
<span class="normal"><a href="#__codelineno-0-69">69</a></span>
<span class="normal"><a href="#__codelineno-0-70">70</a></span>
<span class="normal"><a href="#__codelineno-0-71">71</a></span>
<span class="normal"><a href="#__codelineno-0-72">72</a></span>
<span class="normal"><a href="#__codelineno-0-73">73</a></span>
<span class="normal"><a href="#__codelineno-0-74">74</a></span>
<span class="normal"><a href="#__codelineno-0-75">75</a></span>
<span class="normal"><a href="#__codelineno-0-76">76</a></span>
<span class="normal"><a href="#__codelineno-0-77">77</a></span>
<span class="normal"><a href="#__codelineno-0-78">78</a></span>
<span class="normal"><a href="#__codelineno-0-79">79</a></span>
<span class="normal"><a href="#__codelineno-0-80">80</a></span>
<span class="normal"><a href="#__codelineno-0-81">81</a></span>
<span class="normal"><a href="#__codelineno-0-82">82</a></span>
<span class="normal"><a href="#__codelineno-0-83">83</a></span>
<span class="normal"><a href="#__codelineno-0-84">84</a></span>
<span class="normal"><a href="#__codelineno-0-85">85</a></span>
<span class="normal"><a href="#__codelineno-0-86">86</a></span>
<span class="normal"><a href="#__codelineno-0-87">87</a></span>
<span class="normal"><a href="#__codelineno-0-88">88</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-66"><a id="__codelineno-0-66" name="__codelineno-0-66"></a><span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span>
</span><span id="__span-0-67"><a id="__codelineno-0-67" name="__codelineno-0-67"></a> <span class="bp">self</span><span class="p">,</span>
</span><span id="__span-0-68"><a id="__codelineno-0-68" name="__codelineno-0-68"></a> <span class="n">host</span><span class="p">:</span> <span class="nb">str</span> <span class="o">=</span> <span class="n">DEFAULT_SOCKET_HOST</span><span class="p">,</span>
</span><span id="__span-0-69"><a id="__codelineno-0-69" name="__codelineno-0-69"></a> <span class="n">port</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="n">DEFAULT_SOCKET_PORT</span><span class="p">,</span>
</span><span id="__span-0-70"><a id="__codelineno-0-70" name="__codelineno-0-70"></a> <span class="n">timeout</span><span class="p">:</span> <span class="nb">float</span> <span class="o">=</span> <span class="n">DEFAULT_TIMEOUT</span><span class="p">,</span>
</span><span id="__span-0-71"><a id="__codelineno-0-71" name="__codelineno-0-71"></a> <span class="n">auto_reconnect</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">True</span><span class="p">,</span>
</span><span id="__span-0-72"><a id="__codelineno-0-72" name="__codelineno-0-72"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="kc">None</span><span class="p">:</span>
</span><span id="__span-0-73"><a id="__codelineno-0-73" name="__codelineno-0-73"></a><span class="w"> </span><span class="sd">"""Initialize the socket bridge.</span>
</span><span id="__span-0-74"><a id="__codelineno-0-74" name="__codelineno-0-74"></a>
</span><span id="__span-0-75"><a id="__codelineno-0-75" name="__codelineno-0-75"></a><span class="sd"> Args:</span>
</span><span id="__span-0-76"><a id="__codelineno-0-76" name="__codelineno-0-76"></a><span class="sd"> host: Socket server hostname.</span>
</span><span id="__span-0-77"><a id="__codelineno-0-77" name="__codelineno-0-77"></a><span class="sd"> port: Socket server port.</span>
</span><span id="__span-0-78"><a id="__codelineno-0-78" name="__codelineno-0-78"></a><span class="sd"> timeout: Connection and request timeout in seconds.</span>
</span><span id="__span-0-79"><a id="__codelineno-0-79" name="__codelineno-0-79"></a><span class="sd"> auto_reconnect: Whether to automatically reconnect on connection loss.</span>
</span><span id="__span-0-80"><a id="__codelineno-0-80" name="__codelineno-0-80"></a><span class="sd"> """</span>
</span><span id="__span-0-81"><a id="__codelineno-0-81" name="__codelineno-0-81"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_host</span> <span class="o">=</span> <span class="n">host</span>
</span><span id="__span-0-82"><a id="__codelineno-0-82" name="__codelineno-0-82"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_port</span> <span class="o">=</span> <span class="n">port</span>
</span><span id="__span-0-83"><a id="__codelineno-0-83" name="__codelineno-0-83"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_timeout</span> <span class="o">=</span> <span class="n">timeout</span>
</span><span id="__span-0-84"><a id="__codelineno-0-84" name="__codelineno-0-84"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_auto_reconnect</span> <span class="o">=</span> <span class="n">auto_reconnect</span>
</span><span id="__span-0-85"><a id="__codelineno-0-85" name="__codelineno-0-85"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_reader</span><span class="p">:</span> <span class="n">asyncio</span><span class="o">.</span><span class="n">StreamReader</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span>
</span><span id="__span-0-86"><a id="__codelineno-0-86" name="__codelineno-0-86"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_writer</span><span class="p">:</span> <span class="n">asyncio</span><span class="o">.</span><span class="n">StreamWriter</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span>
</span><span id="__span-0-87"><a id="__codelineno-0-87" name="__codelineno-0-87"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_connected</span> <span class="o">=</span> <span class="kc">False</span>
</span><span id="__span-0-88"><a id="__codelineno-0-88" name="__codelineno-0-88"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_lock</span> <span class="o">=</span> <span class="n">asyncio</span><span class="o">.</span><span class="n">Lock</span><span class="p">()</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> </div> </div> <div class="doc doc-object doc-function"> <h6 id="freecad_mcp.bridge.socket.SocketBridge.activate_workbench" class="doc doc-heading"> <code class="highlight language-python"><span class="n">activate_workbench</span><span class="p">(</span><span class="n">workbench_name</span><span class="p">)</span></code> <span class="doc doc-labels"> <small class="doc doc-label doc-label-async"><code>async</code></small> </span> <a href="#freecad_mcp.bridge.socket.SocketBridge.activate_workbench" class="headerlink" title="Permanent link">¶</a></h6> <div class="doc doc-contents "> <p>Activate a workbench.</p> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/socket.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-986"> 986</a></span>
<span class="normal"><a href="#__codelineno-0-987"> 987</a></span>
<span class="normal"><a href="#__codelineno-0-988"> 988</a></span>
<span class="normal"><a href="#__codelineno-0-989"> 989</a></span>
<span class="normal"><a href="#__codelineno-0-990"> 990</a></span>
<span class="normal"><a href="#__codelineno-0-991"> 991</a></span>
<span class="normal"><a href="#__codelineno-0-992"> 992</a></span>
<span class="normal"><a href="#__codelineno-0-993"> 993</a></span>
<span class="normal"><a href="#__codelineno-0-994"> 994</a></span>
<span class="normal"><a href="#__codelineno-0-995"> 995</a></span>
<span class="normal"><a href="#__codelineno-0-996"> 996</a></span>
<span class="normal"><a href="#__codelineno-0-997"> 997</a></span>
<span class="normal"><a href="#__codelineno-0-998"> 998</a></span>
<span class="normal"><a href="#__codelineno-0-999"> 999</a></span>
<span class="normal"><a href="#__codelineno-0-1000">1000</a></span>
<span class="normal"><a href="#__codelineno-0-1001">1001</a></span>
<span class="normal"><a href="#__codelineno-0-1002">1002</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-986"><a id="__codelineno-0-986" name="__codelineno-0-986"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">activate_workbench</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">workbench_name</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kc">None</span><span class="p">:</span>
</span><span id="__span-0-987"><a id="__codelineno-0-987" name="__codelineno-0-987"></a><span class="w"> </span><span class="sd">"""Activate a workbench."""</span>
</span><span id="__span-0-988"><a id="__codelineno-0-988" name="__codelineno-0-988"></a> <span class="n">code</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">"""</span>
</span><span id="__span-0-989"><a id="__codelineno-0-989" name="__codelineno-0-989"></a><span class="s2">if FreeCAD.GuiUp:</span>
</span><span id="__span-0-990"><a id="__codelineno-0-990" name="__codelineno-0-990"></a><span class="s2"> try:</span>
</span><span id="__span-0-991"><a id="__codelineno-0-991" name="__codelineno-0-991"></a><span class="s2"> FreeCADGui.activateWorkbench(</span><span class="si">{</span><span class="n">workbench_name</span><span class="si">!r}</span><span class="s2">)</span>
</span><span id="__span-0-992"><a id="__codelineno-0-992" name="__codelineno-0-992"></a><span class="s2"> _result_ = True</span>
</span><span id="__span-0-993"><a id="__codelineno-0-993" name="__codelineno-0-993"></a><span class="s2"> except Exception as e:</span>
</span><span id="__span-0-994"><a id="__codelineno-0-994" name="__codelineno-0-994"></a><span class="s2"> raise ValueError(f"Failed to activate workbench: </span><span class="se">{{</span><span class="s2">e</span><span class="se">}}</span><span class="s2">")</span>
</span><span id="__span-0-995"><a id="__codelineno-0-995" name="__codelineno-0-995"></a><span class="s2">else:</span>
</span><span id="__span-0-996"><a id="__codelineno-0-996" name="__codelineno-0-996"></a><span class="s2"> _result_ = True</span>
</span><span id="__span-0-997"><a id="__codelineno-0-997" name="__codelineno-0-997"></a><span class="s2">"""</span>
</span><span id="__span-0-998"><a id="__codelineno-0-998" name="__codelineno-0-998"></a> <span class="n">result</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">execute_python</span><span class="p">(</span><span class="n">code</span><span class="p">)</span>
</span><span id="__span-0-999"><a id="__codelineno-0-999" name="__codelineno-0-999"></a>
</span><span id="__span-0-1000"><a id="__codelineno-0-1000" name="__codelineno-0-1000"></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">result</span><span class="o">.</span><span class="n">success</span><span class="p">:</span>
</span><span id="__span-0-1001"><a id="__codelineno-0-1001" name="__codelineno-0-1001"></a> <span class="n">error_msg</span> <span class="o">=</span> <span class="n">result</span><span class="o">.</span><span class="n">error_traceback</span> <span class="ow">or</span> <span class="s2">"Failed to activate workbench"</span>
</span><span id="__span-0-1002"><a id="__codelineno-0-1002" name="__codelineno-0-1002"></a> <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="n">error_msg</span><span class="p">)</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> </div> </div> <div class="doc doc-object doc-function"> <h6 id="freecad_mcp.bridge.socket.SocketBridge.close_document" class="doc doc-heading"> <code class="highlight language-python"><span class="n">close_document</span><span class="p">(</span><span class="n">doc_name</span><span class="o">=</span><span class="kc">None</span><span class="p">)</span></code> <span class="doc doc-labels"> <small class="doc doc-label doc-label-async"><code>async</code></small> </span> <a href="#freecad_mcp.bridge.socket.SocketBridge.close_document" class="headerlink" title="Permanent link">¶</a></h6> <div class="doc doc-contents "> <p>Close a document.</p> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/socket.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-462">462</a></span>
<span class="normal"><a href="#__codelineno-0-463">463</a></span>
<span class="normal"><a href="#__codelineno-0-464">464</a></span>
<span class="normal"><a href="#__codelineno-0-465">465</a></span>
<span class="normal"><a href="#__codelineno-0-466">466</a></span>
<span class="normal"><a href="#__codelineno-0-467">467</a></span>
<span class="normal"><a href="#__codelineno-0-468">468</a></span>
<span class="normal"><a href="#__codelineno-0-469">469</a></span>
<span class="normal"><a href="#__codelineno-0-470">470</a></span>
<span class="normal"><a href="#__codelineno-0-471">471</a></span>
<span class="normal"><a href="#__codelineno-0-472">472</a></span>
<span class="normal"><a href="#__codelineno-0-473">473</a></span>
<span class="normal"><a href="#__codelineno-0-474">474</a></span>
<span class="normal"><a href="#__codelineno-0-475">475</a></span>
<span class="normal"><a href="#__codelineno-0-476">476</a></span>
<span class="normal"><a href="#__codelineno-0-477">477</a></span>
<span class="normal"><a href="#__codelineno-0-478">478</a></span>
<span class="normal"><a href="#__codelineno-0-479">479</a></span>
<span class="normal"><a href="#__codelineno-0-480">480</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-462"><a id="__codelineno-0-462" name="__codelineno-0-462"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">close_document</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">doc_name</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kc">None</span><span class="p">:</span>
</span><span id="__span-0-463"><a id="__codelineno-0-463" name="__codelineno-0-463"></a><span class="w"> </span><span class="sd">"""Close a document."""</span>
</span><span id="__span-0-464"><a id="__codelineno-0-464" name="__codelineno-0-464"></a> <span class="n">code</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">"""</span>
</span><span id="__span-0-465"><a id="__codelineno-0-465" name="__codelineno-0-465"></a><span class="s2">doc_name = </span><span class="si">{</span><span class="n">doc_name</span><span class="si">!r}</span>
</span><span id="__span-0-466"><a id="__codelineno-0-466" name="__codelineno-0-466"></a><span class="s2">if doc_name is None:</span>
</span><span id="__span-0-467"><a id="__codelineno-0-467" name="__codelineno-0-467"></a><span class="s2"> doc = FreeCAD.ActiveDocument</span>
</span><span id="__span-0-468"><a id="__codelineno-0-468" name="__codelineno-0-468"></a><span class="s2"> if doc:</span>
</span><span id="__span-0-469"><a id="__codelineno-0-469" name="__codelineno-0-469"></a><span class="s2"> doc_name = doc.Name</span>
</span><span id="__span-0-470"><a id="__codelineno-0-470" name="__codelineno-0-470"></a><span class="s2"> else:</span>
</span><span id="__span-0-471"><a id="__codelineno-0-471" name="__codelineno-0-471"></a><span class="s2"> raise ValueError("No active document")</span>
</span><span id="__span-0-472"><a id="__codelineno-0-472" name="__codelineno-0-472"></a>
</span><span id="__span-0-473"><a id="__codelineno-0-473" name="__codelineno-0-473"></a><span class="s2">FreeCAD.closeDocument(doc_name)</span>
</span><span id="__span-0-474"><a id="__codelineno-0-474" name="__codelineno-0-474"></a><span class="s2">_result_ = True</span>
</span><span id="__span-0-475"><a id="__codelineno-0-475" name="__codelineno-0-475"></a><span class="s2">"""</span>
</span><span id="__span-0-476"><a id="__codelineno-0-476" name="__codelineno-0-476"></a> <span class="n">result</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">execute_python</span><span class="p">(</span><span class="n">code</span><span class="p">)</span>
</span><span id="__span-0-477"><a id="__codelineno-0-477" name="__codelineno-0-477"></a>
</span><span id="__span-0-478"><a id="__codelineno-0-478" name="__codelineno-0-478"></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">result</span><span class="o">.</span><span class="n">success</span><span class="p">:</span>
</span><span id="__span-0-479"><a id="__codelineno-0-479" name="__codelineno-0-479"></a> <span class="n">error_msg</span> <span class="o">=</span> <span class="n">result</span><span class="o">.</span><span class="n">error_traceback</span> <span class="ow">or</span> <span class="s2">"Failed to close document"</span>
</span><span id="__span-0-480"><a id="__codelineno-0-480" name="__codelineno-0-480"></a> <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="n">error_msg</span><span class="p">)</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> </div> </div> <div class="doc doc-object doc-function"> <h6 id="freecad_mcp.bridge.socket.SocketBridge.connect" class="doc doc-heading"> <code class="highlight language-python"><span class="n">connect</span><span class="p">()</span></code> <span class="doc doc-labels"> <small class="doc doc-label doc-label-async"><code>async</code></small> </span> <a href="#freecad_mcp.bridge.socket.SocketBridge.connect" class="headerlink" title="Permanent link">¶</a></h6> <div class="doc doc-contents "> <p>Establish connection to FreeCAD socket server.</p> <p><span class="doc-section-title">Raises:</span></p> <table> <thead> <tr> <th>Type</th> <th>Description</th> </tr> </thead> <tbody> <tr class="doc-section-item"> <td> <code><span title="ConnectionError">ConnectionError</span></code> </td> <td> <div class="doc-md-description"> <p>If connection cannot be established.</p> </div> </td> </tr> </tbody> </table> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/socket.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-90"> 90</a></span>
<span class="normal"><a href="#__codelineno-0-91"> 91</a></span>
<span class="normal"><a href="#__codelineno-0-92"> 92</a></span>
<span class="normal"><a href="#__codelineno-0-93"> 93</a></span>
<span class="normal"><a href="#__codelineno-0-94"> 94</a></span>
<span class="normal"><a href="#__codelineno-0-95"> 95</a></span>
<span class="normal"><a href="#__codelineno-0-96"> 96</a></span>
<span class="normal"><a href="#__codelineno-0-97"> 97</a></span>
<span class="normal"><a href="#__codelineno-0-98"> 98</a></span>
<span class="normal"><a href="#__codelineno-0-99"> 99</a></span>
<span class="normal"><a href="#__codelineno-0-100">100</a></span>
<span class="normal"><a href="#__codelineno-0-101">101</a></span>
<span class="normal"><a href="#__codelineno-0-102">102</a></span>
<span class="normal"><a href="#__codelineno-0-103">103</a></span>
<span class="normal"><a href="#__codelineno-0-104">104</a></span>
<span class="normal"><a href="#__codelineno-0-105">105</a></span>
<span class="normal"><a href="#__codelineno-0-106">106</a></span>
<span class="normal"><a href="#__codelineno-0-107">107</a></span>
<span class="normal"><a href="#__codelineno-0-108">108</a></span>
<span class="normal"><a href="#__codelineno-0-109">109</a></span>
<span class="normal"><a href="#__codelineno-0-110">110</a></span>
<span class="normal"><a href="#__codelineno-0-111">111</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-90"><a id="__codelineno-0-90" name="__codelineno-0-90"></a><span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">connect</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kc">None</span><span class="p">:</span>
</span><span id="__span-0-91"><a id="__codelineno-0-91" name="__codelineno-0-91"></a><span class="w"> </span><span class="sd">"""Establish connection to FreeCAD socket server.</span>
</span><span id="__span-0-92"><a id="__codelineno-0-92" name="__codelineno-0-92"></a>
</span><span id="__span-0-93"><a id="__codelineno-0-93" name="__codelineno-0-93"></a><span class="sd"> Raises:</span>
</span><span id="__span-0-94"><a id="__codelineno-0-94" name="__codelineno-0-94"></a><span class="sd"> ConnectionError: If connection cannot be established.</span>
</span><span id="__span-0-95"><a id="__codelineno-0-95" name="__codelineno-0-95"></a><span class="sd"> """</span>
</span><span id="__span-0-96"><a id="__codelineno-0-96" name="__codelineno-0-96"></a> <span class="k">try</span><span class="p">:</span>
</span><span id="__span-0-97"><a id="__codelineno-0-97" name="__codelineno-0-97"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_reader</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">_writer</span> <span class="o">=</span> <span class="k">await</span> <span class="n">asyncio</span><span class="o">.</span><span class="n">wait_for</span><span class="p">(</span>
</span><span id="__span-0-98"><a id="__codelineno-0-98" name="__codelineno-0-98"></a> <span class="n">asyncio</span><span class="o">.</span><span class="n">open_connection</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_host</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">_port</span><span class="p">),</span>
</span><span id="__span-0-99"><a id="__codelineno-0-99" name="__codelineno-0-99"></a> <span class="n">timeout</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">_timeout</span><span class="p">,</span>
</span><span id="__span-0-100"><a id="__codelineno-0-100" name="__codelineno-0-100"></a> <span class="p">)</span>
</span><span id="__span-0-101"><a id="__codelineno-0-101" name="__codelineno-0-101"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_connected</span> <span class="o">=</span> <span class="kc">True</span>
</span><span id="__span-0-102"><a id="__codelineno-0-102" name="__codelineno-0-102"></a>
</span><span id="__span-0-103"><a id="__codelineno-0-103" name="__codelineno-0-103"></a> <span class="c1"># Verify connection with a ping</span>
</span><span id="__span-0-104"><a id="__codelineno-0-104" name="__codelineno-0-104"></a> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">ping</span><span class="p">()</span>
</span><span id="__span-0-105"><a id="__codelineno-0-105" name="__codelineno-0-105"></a> <span class="k">except</span> <span class="ne">TimeoutError</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
</span><span id="__span-0-106"><a id="__codelineno-0-106" name="__codelineno-0-106"></a> <span class="n">msg</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">"Connection to </span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">_host</span><span class="si">}</span><span class="s2">:</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">_port</span><span class="si">}</span><span class="s2"> timed out"</span>
</span><span id="__span-0-107"><a id="__codelineno-0-107" name="__codelineno-0-107"></a> <span class="k">raise</span> <span class="ne">ConnectionError</span><span class="p">(</span><span class="n">msg</span><span class="p">)</span> <span class="kn">from</span><span class="w"> </span><span class="nn">e</span>
</span><span id="__span-0-108"><a id="__codelineno-0-108" name="__codelineno-0-108"></a> <span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
</span><span id="__span-0-109"><a id="__codelineno-0-109" name="__codelineno-0-109"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_connected</span> <span class="o">=</span> <span class="kc">False</span>
</span><span id="__span-0-110"><a id="__codelineno-0-110" name="__codelineno-0-110"></a> <span class="n">msg</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">"Failed to connect to </span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">_host</span><span class="si">}</span><span class="s2">:</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">_port</span><span class="si">}</span><span class="s2">: </span><span class="si">{</span><span class="n">e</span><span class="si">}</span><span class="s2">"</span>
</span><span id="__span-0-111"><a id="__codelineno-0-111" name="__codelineno-0-111"></a> <span class="k">raise</span> <span class="ne">ConnectionError</span><span class="p">(</span><span class="n">msg</span><span class="p">)</span> <span class="kn">from</span><span class="w"> </span><span class="nn">e</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> </div> </div> <div class="doc doc-object doc-function"> <h6 id="freecad_mcp.bridge.socket.SocketBridge.create_document" class="doc doc-heading"> <code class="highlight language-python"><span class="n">create_document</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">label</span><span class="o">=</span><span class="kc">None</span><span class="p">)</span></code> <span class="doc doc-labels"> <small class="doc doc-label doc-label-async"><code>async</code></small> </span> <a href="#freecad_mcp.bridge.socket.SocketBridge.create_document" class="headerlink" title="Permanent link">¶</a></h6> <div class="doc doc-contents "> <p>Create a new document.</p> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/socket.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-383">383</a></span>
<span class="normal"><a href="#__codelineno-0-384">384</a></span>
<span class="normal"><a href="#__codelineno-0-385">385</a></span>
<span class="normal"><a href="#__codelineno-0-386">386</a></span>
<span class="normal"><a href="#__codelineno-0-387">387</a></span>
<span class="normal"><a href="#__codelineno-0-388">388</a></span>
<span class="normal"><a href="#__codelineno-0-389">389</a></span>
<span class="normal"><a href="#__codelineno-0-390">390</a></span>
<span class="normal"><a href="#__codelineno-0-391">391</a></span>
<span class="normal"><a href="#__codelineno-0-392">392</a></span>
<span class="normal"><a href="#__codelineno-0-393">393</a></span>
<span class="normal"><a href="#__codelineno-0-394">394</a></span>
<span class="normal"><a href="#__codelineno-0-395">395</a></span>
<span class="normal"><a href="#__codelineno-0-396">396</a></span>
<span class="normal"><a href="#__codelineno-0-397">397</a></span>
<span class="normal"><a href="#__codelineno-0-398">398</a></span>
<span class="normal"><a href="#__codelineno-0-399">399</a></span>
<span class="normal"><a href="#__codelineno-0-400">400</a></span>
<span class="normal"><a href="#__codelineno-0-401">401</a></span>
<span class="normal"><a href="#__codelineno-0-402">402</a></span>
<span class="normal"><a href="#__codelineno-0-403">403</a></span>
<span class="normal"><a href="#__codelineno-0-404">404</a></span>
<span class="normal"><a href="#__codelineno-0-405">405</a></span>
<span class="normal"><a href="#__codelineno-0-406">406</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-383"><a id="__codelineno-0-383" name="__codelineno-0-383"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">create_document</span><span class="p">(</span>
</span><span id="__span-0-384"><a id="__codelineno-0-384" name="__codelineno-0-384"></a> <span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">label</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span>
</span><span id="__span-0-385"><a id="__codelineno-0-385" name="__codelineno-0-385"></a> <span class="p">)</span> <span class="o">-&gt;</span> <span class="n">DocumentInfo</span><span class="p">:</span>
</span><span id="__span-0-386"><a id="__codelineno-0-386" name="__codelineno-0-386"></a><span class="w"> </span><span class="sd">"""Create a new document."""</span>
</span><span id="__span-0-387"><a id="__codelineno-0-387" name="__codelineno-0-387"></a> <span class="n">label</span> <span class="o">=</span> <span class="n">label</span> <span class="ow">or</span> <span class="n">name</span>
</span><span id="__span-0-388"><a id="__codelineno-0-388" name="__codelineno-0-388"></a> <span class="n">result</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">execute_python</span><span class="p">(</span>
</span><span id="__span-0-389"><a id="__codelineno-0-389" name="__codelineno-0-389"></a> <span class="sa">f</span><span class="s2">"""</span>
</span><span id="__span-0-390"><a id="__codelineno-0-390" name="__codelineno-0-390"></a><span class="s2">doc = FreeCAD.newDocument(</span><span class="si">{</span><span class="n">name</span><span class="si">!r}</span><span class="s2">)</span>
</span><span id="__span-0-391"><a id="__codelineno-0-391" name="__codelineno-0-391"></a><span class="s2">doc.Label = </span><span class="si">{</span><span class="n">label</span><span class="si">!r}</span>
</span><span id="__span-0-392"><a id="__codelineno-0-392" name="__codelineno-0-392"></a><span class="s2">_result_ = </span><span class="se">{{</span>
</span><span id="__span-0-393"><a id="__codelineno-0-393" name="__codelineno-0-393"></a><span class="s2"> "name": doc.Name,</span>
</span><span id="__span-0-394"><a id="__codelineno-0-394" name="__codelineno-0-394"></a><span class="s2"> "label": doc.Label,</span>
</span><span id="__span-0-395"><a id="__codelineno-0-395" name="__codelineno-0-395"></a><span class="s2"> "path": doc.FileName or None,</span>
</span><span id="__span-0-396"><a id="__codelineno-0-396" name="__codelineno-0-396"></a><span class="s2"> "objects": [],</span>
</span><span id="__span-0-397"><a id="__codelineno-0-397" name="__codelineno-0-397"></a><span class="s2"> "is_modified": False,</span>
</span><span id="__span-0-398"><a id="__codelineno-0-398" name="__codelineno-0-398"></a><span class="se">}}</span>
</span><span id="__span-0-399"><a id="__codelineno-0-399" name="__codelineno-0-399"></a><span class="s2">"""</span>
</span><span id="__span-0-400"><a id="__codelineno-0-400" name="__codelineno-0-400"></a> <span class="p">)</span>
</span><span id="__span-0-401"><a id="__codelineno-0-401" name="__codelineno-0-401"></a>
</span><span id="__span-0-402"><a id="__codelineno-0-402" name="__codelineno-0-402"></a> <span class="k">if</span> <span class="n">result</span><span class="o">.</span><span class="n">success</span> <span class="ow">and</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">:</span>
</span><span id="__span-0-403"><a id="__codelineno-0-403" name="__codelineno-0-403"></a> <span class="k">return</span> <span class="n">DocumentInfo</span><span class="p">(</span><span class="o">**</span><span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">)</span>
</span><span id="__span-0-404"><a id="__codelineno-0-404" name="__codelineno-0-404"></a>
</span><span id="__span-0-405"><a id="__codelineno-0-405" name="__codelineno-0-405"></a> <span class="n">error_msg</span> <span class="o">=</span> <span class="n">result</span><span class="o">.</span><span class="n">error_traceback</span> <span class="ow">or</span> <span class="s2">"Failed to create document"</span>
</span><span id="__span-0-406"><a id="__codelineno-0-406" name="__codelineno-0-406"></a> <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="n">error_msg</span><span class="p">)</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> </div> </div> <div class="doc doc-object doc-function"> <h6 id="freecad_mcp.bridge.socket.SocketBridge.create_macro" class="doc doc-heading"> <code class="highlight language-python"><span class="n">create_macro</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">code</span><span class="p">,</span> <span class="n">description</span><span class="o">=</span><span class="s1">''</span><span class="p">)</span></code> <span class="doc doc-labels"> <small class="doc doc-label doc-label-async"><code>async</code></small> </span> <a href="#freecad_mcp.bridge.socket.SocketBridge.create_macro" class="headerlink" title="Permanent link">¶</a></h6> <div class="doc doc-contents "> <p>Create a new macro.</p> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/socket.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-901">901</a></span>
<span class="normal"><a href="#__codelineno-0-902">902</a></span>
<span class="normal"><a href="#__codelineno-0-903">903</a></span>
<span class="normal"><a href="#__codelineno-0-904">904</a></span>
<span class="normal"><a href="#__codelineno-0-905">905</a></span>
<span class="normal"><a href="#__codelineno-0-906">906</a></span>
<span class="normal"><a href="#__codelineno-0-907">907</a></span>
<span class="normal"><a href="#__codelineno-0-908">908</a></span>
<span class="normal"><a href="#__codelineno-0-909">909</a></span>
<span class="normal"><a href="#__codelineno-0-910">910</a></span>
<span class="normal"><a href="#__codelineno-0-911">911</a></span>
<span class="normal"><a href="#__codelineno-0-912">912</a></span>
<span class="normal"><a href="#__codelineno-0-913">913</a></span>
<span class="normal"><a href="#__codelineno-0-914">914</a></span>
<span class="normal"><a href="#__codelineno-0-915">915</a></span>
<span class="normal"><a href="#__codelineno-0-916">916</a></span>
<span class="normal"><a href="#__codelineno-0-917">917</a></span>
<span class="normal"><a href="#__codelineno-0-918">918</a></span>
<span class="normal"><a href="#__codelineno-0-919">919</a></span>
<span class="normal"><a href="#__codelineno-0-920">920</a></span>
<span class="normal"><a href="#__codelineno-0-921">921</a></span>
<span class="normal"><a href="#__codelineno-0-922">922</a></span>
<span class="normal"><a href="#__codelineno-0-923">923</a></span>
<span class="normal"><a href="#__codelineno-0-924">924</a></span>
<span class="normal"><a href="#__codelineno-0-925">925</a></span>
<span class="normal"><a href="#__codelineno-0-926">926</a></span>
<span class="normal"><a href="#__codelineno-0-927">927</a></span>
<span class="normal"><a href="#__codelineno-0-928">928</a></span>
<span class="normal"><a href="#__codelineno-0-929">929</a></span>
<span class="normal"><a href="#__codelineno-0-930">930</a></span>
<span class="normal"><a href="#__codelineno-0-931">931</a></span>
<span class="normal"><a href="#__codelineno-0-932">932</a></span>
<span class="normal"><a href="#__codelineno-0-933">933</a></span>
<span class="normal"><a href="#__codelineno-0-934">934</a></span>
<span class="normal"><a href="#__codelineno-0-935">935</a></span>
<span class="normal"><a href="#__codelineno-0-936">936</a></span>
<span class="normal"><a href="#__codelineno-0-937">937</a></span>
<span class="normal"><a href="#__codelineno-0-938">938</a></span>
<span class="normal"><a href="#__codelineno-0-939">939</a></span>
<span class="normal"><a href="#__codelineno-0-940">940</a></span>
<span class="normal"><a href="#__codelineno-0-941">941</a></span>
<span class="normal"><a href="#__codelineno-0-942">942</a></span>
<span class="normal"><a href="#__codelineno-0-943">943</a></span>
<span class="normal"><a href="#__codelineno-0-944">944</a></span>
<span class="normal"><a href="#__codelineno-0-945">945</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-901"><a id="__codelineno-0-901" name="__codelineno-0-901"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">create_macro</span><span class="p">(</span>
</span><span id="__span-0-902"><a id="__codelineno-0-902" name="__codelineno-0-902"></a> <span class="bp">self</span><span class="p">,</span>
</span><span id="__span-0-903"><a id="__codelineno-0-903" name="__codelineno-0-903"></a> <span class="n">name</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span>
</span><span id="__span-0-904"><a id="__codelineno-0-904" name="__codelineno-0-904"></a> <span class="n">code</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span>
</span><span id="__span-0-905"><a id="__codelineno-0-905" name="__codelineno-0-905"></a> <span class="n">description</span><span class="p">:</span> <span class="nb">str</span> <span class="o">=</span> <span class="s2">""</span><span class="p">,</span>
</span><span id="__span-0-906"><a id="__codelineno-0-906" name="__codelineno-0-906"></a> <span class="p">)</span> <span class="o">-&gt;</span> <span class="n">MacroInfo</span><span class="p">:</span>
</span><span id="__span-0-907"><a id="__codelineno-0-907" name="__codelineno-0-907"></a><span class="w"> </span><span class="sd">"""Create a new macro."""</span>
</span><span id="__span-0-908"><a id="__codelineno-0-908" name="__codelineno-0-908"></a> <span class="n">create_code</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">"""</span>
</span><span id="__span-0-909"><a id="__codelineno-0-909" name="__codelineno-0-909"></a><span class="s2">import os</span>
</span><span id="__span-0-910"><a id="__codelineno-0-910" name="__codelineno-0-910"></a>
</span><span id="__span-0-911"><a id="__codelineno-0-911" name="__codelineno-0-911"></a><span class="s2">macro_path = FreeCAD.getUserMacroDir(True)</span>
</span><span id="__span-0-912"><a id="__codelineno-0-912" name="__codelineno-0-912"></a><span class="s2">os.makedirs(macro_path, exist_ok=True)</span>
</span><span id="__span-0-913"><a id="__codelineno-0-913" name="__codelineno-0-913"></a>
</span><span id="__span-0-914"><a id="__codelineno-0-914" name="__codelineno-0-914"></a><span class="s2">macro_file = os.path.join(macro_path, </span><span class="si">{</span><span class="n">name</span><span class="si">!r}</span><span class="s2"> + ".FCMacro")</span>
</span><span id="__span-0-915"><a id="__codelineno-0-915" name="__codelineno-0-915"></a>
</span><span id="__span-0-916"><a id="__codelineno-0-916" name="__codelineno-0-916"></a><span class="s2">header = ""</span>
</span><span id="__span-0-917"><a id="__codelineno-0-917" name="__codelineno-0-917"></a><span class="s2">if </span><span class="si">{</span><span class="n">description</span><span class="si">!r}</span><span class="s2">:</span>
</span><span id="__span-0-918"><a id="__codelineno-0-918" name="__codelineno-0-918"></a><span class="s2"> header = f"# </span><span class="si">{</span><span class="n">description</span><span class="si">!r}</span><span class="se">\\</span><span class="s2">n</span><span class="se">\\</span><span class="s2">n"</span>
</span><span id="__span-0-919"><a id="__codelineno-0-919" name="__codelineno-0-919"></a>
</span><span id="__span-0-920"><a id="__codelineno-0-920" name="__codelineno-0-920"></a><span class="s2">full_code = header + '''# -*- coding: utf-8 -*-</span>
</span><span id="__span-0-921"><a id="__codelineno-0-921" name="__codelineno-0-921"></a><span class="s2"># FreeCAD Macro: </span><span class="si">{</span><span class="n">name</span><span class="si">}</span>
</span><span id="__span-0-922"><a id="__codelineno-0-922" name="__codelineno-0-922"></a><span class="s2"># Created via MCP Bridge</span>
</span><span id="__span-0-923"><a id="__codelineno-0-923" name="__codelineno-0-923"></a>
</span><span id="__span-0-924"><a id="__codelineno-0-924" name="__codelineno-0-924"></a><span class="s2">import FreeCAD</span>
</span><span id="__span-0-925"><a id="__codelineno-0-925" name="__codelineno-0-925"></a><span class="s2">import FreeCADGui</span>
</span><span id="__span-0-926"><a id="__codelineno-0-926" name="__codelineno-0-926"></a>
</span><span id="__span-0-927"><a id="__codelineno-0-927" name="__codelineno-0-927"></a><span class="s2">''' + </span><span class="si">{</span><span class="n">code</span><span class="si">!r}</span>
</span><span id="__span-0-928"><a id="__codelineno-0-928" name="__codelineno-0-928"></a>
</span><span id="__span-0-929"><a id="__codelineno-0-929" name="__codelineno-0-929"></a><span class="s2">with open(macro_file, "w") as f:</span>
</span><span id="__span-0-930"><a id="__codelineno-0-930" name="__codelineno-0-930"></a><span class="s2"> f.write(full_code)</span>
</span><span id="__span-0-931"><a id="__codelineno-0-931" name="__codelineno-0-931"></a>
</span><span id="__span-0-932"><a id="__codelineno-0-932" name="__codelineno-0-932"></a><span class="s2">_result_ = </span><span class="se">{{</span>
</span><span id="__span-0-933"><a id="__codelineno-0-933" name="__codelineno-0-933"></a><span class="s2"> "name": </span><span class="si">{</span><span class="n">name</span><span class="si">!r}</span><span class="s2">,</span>
</span><span id="__span-0-934"><a id="__codelineno-0-934" name="__codelineno-0-934"></a><span class="s2"> "path": macro_file,</span>
</span><span id="__span-0-935"><a id="__codelineno-0-935" name="__codelineno-0-935"></a><span class="s2"> "description": </span><span class="si">{</span><span class="n">description</span><span class="si">!r}</span><span class="s2">,</span>
</span><span id="__span-0-936"><a id="__codelineno-0-936" name="__codelineno-0-936"></a><span class="s2"> "is_system": False,</span>
</span><span id="__span-0-937"><a id="__codelineno-0-937" name="__codelineno-0-937"></a><span class="se">}}</span>
</span><span id="__span-0-938"><a id="__codelineno-0-938" name="__codelineno-0-938"></a><span class="s2">"""</span>
</span><span id="__span-0-939"><a id="__codelineno-0-939" name="__codelineno-0-939"></a> <span class="n">result</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">execute_python</span><span class="p">(</span><span class="n">create_code</span><span class="p">)</span>
</span><span id="__span-0-940"><a id="__codelineno-0-940" name="__codelineno-0-940"></a>
</span><span id="__span-0-941"><a id="__codelineno-0-941" name="__codelineno-0-941"></a> <span class="k">if</span> <span class="n">result</span><span class="o">.</span><span class="n">success</span> <span class="ow">and</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">:</span>
</span><span id="__span-0-942"><a id="__codelineno-0-942" name="__codelineno-0-942"></a> <span class="k">return</span> <span class="n">MacroInfo</span><span class="p">(</span><span class="o">**</span><span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">)</span>
</span><span id="__span-0-943"><a id="__codelineno-0-943" name="__codelineno-0-943"></a>
</span><span id="__span-0-944"><a id="__codelineno-0-944" name="__codelineno-0-944"></a> <span class="n">error_msg</span> <span class="o">=</span> <span class="n">result</span><span class="o">.</span><span class="n">error_traceback</span> <span class="ow">or</span> <span class="s2">"Failed to create macro"</span>
</span><span id="__span-0-945"><a id="__codelineno-0-945" name="__codelineno-0-945"></a> <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="n">error_msg</span><span class="p">)</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> </div> </div> <div class="doc doc-object doc-function"> <h6 id="freecad_mcp.bridge.socket.SocketBridge.create_object" class="doc doc-heading"> <code class="highlight language-python"><span class="n">create_object</span><span class="p">(</span><span class="n">type_id</span><span class="p">,</span> <span class="n">name</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">properties</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">doc_name</span><span class="o">=</span><span class="kc">None</span><span class="p">)</span></code> <span class="doc doc-labels"> <small class="doc doc-label doc-label-async"><code>async</code></small> </span> <a href="#freecad_mcp.bridge.socket.SocketBridge.create_object" class="headerlink" title="Permanent link">¶</a></h6> <div class="doc doc-contents "> <p>Create a new object.</p> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/socket.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-571">571</a></span>
<span class="normal"><a href="#__codelineno-0-572">572</a></span>
<span class="normal"><a href="#__codelineno-0-573">573</a></span>
<span class="normal"><a href="#__codelineno-0-574">574</a></span>
<span class="normal"><a href="#__codelineno-0-575">575</a></span>
<span class="normal"><a href="#__codelineno-0-576">576</a></span>
<span class="normal"><a href="#__codelineno-0-577">577</a></span>
<span class="normal"><a href="#__codelineno-0-578">578</a></span>
<span class="normal"><a href="#__codelineno-0-579">579</a></span>
<span class="normal"><a href="#__codelineno-0-580">580</a></span>
<span class="normal"><a href="#__codelineno-0-581">581</a></span>
<span class="normal"><a href="#__codelineno-0-582">582</a></span>
<span class="normal"><a href="#__codelineno-0-583">583</a></span>
<span class="normal"><a href="#__codelineno-0-584">584</a></span>
<span class="normal"><a href="#__codelineno-0-585">585</a></span>
<span class="normal"><a href="#__codelineno-0-586">586</a></span>
<span class="normal"><a href="#__codelineno-0-587">587</a></span>
<span class="normal"><a href="#__codelineno-0-588">588</a></span>
<span class="normal"><a href="#__codelineno-0-589">589</a></span>
<span class="normal"><a href="#__codelineno-0-590">590</a></span>
<span class="normal"><a href="#__codelineno-0-591">591</a></span>
<span class="normal"><a href="#__codelineno-0-592">592</a></span>
<span class="normal"><a href="#__codelineno-0-593">593</a></span>
<span class="normal"><a href="#__codelineno-0-594">594</a></span>
<span class="normal"><a href="#__codelineno-0-595">595</a></span>
<span class="normal"><a href="#__codelineno-0-596">596</a></span>
<span class="normal"><a href="#__codelineno-0-597">597</a></span>
<span class="normal"><a href="#__codelineno-0-598">598</a></span>
<span class="normal"><a href="#__codelineno-0-599">599</a></span>
<span class="normal"><a href="#__codelineno-0-600">600</a></span>
<span class="normal"><a href="#__codelineno-0-601">601</a></span>
<span class="normal"><a href="#__codelineno-0-602">602</a></span>
<span class="normal"><a href="#__codelineno-0-603">603</a></span>
<span class="normal"><a href="#__codelineno-0-604">604</a></span>
<span class="normal"><a href="#__codelineno-0-605">605</a></span>
<span class="normal"><a href="#__codelineno-0-606">606</a></span>
<span class="normal"><a href="#__codelineno-0-607">607</a></span>
<span class="normal"><a href="#__codelineno-0-608">608</a></span>
<span class="normal"><a href="#__codelineno-0-609">609</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-571"><a id="__codelineno-0-571" name="__codelineno-0-571"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">create_object</span><span class="p">(</span>
</span><span id="__span-0-572"><a id="__codelineno-0-572" name="__codelineno-0-572"></a> <span class="bp">self</span><span class="p">,</span>
</span><span id="__span-0-573"><a id="__codelineno-0-573" name="__codelineno-0-573"></a> <span class="n">type_id</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span>
</span><span id="__span-0-574"><a id="__codelineno-0-574" name="__codelineno-0-574"></a> <span class="n">name</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-575"><a id="__codelineno-0-575" name="__codelineno-0-575"></a> <span class="n">properties</span><span class="p">:</span> <span class="nb">dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Any</span><span class="p">]</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-576"><a id="__codelineno-0-576" name="__codelineno-0-576"></a> <span class="n">doc_name</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-577"><a id="__codelineno-0-577" name="__codelineno-0-577"></a> <span class="p">)</span> <span class="o">-&gt;</span> <span class="n">ObjectInfo</span><span class="p">:</span>
</span><span id="__span-0-578"><a id="__codelineno-0-578" name="__codelineno-0-578"></a><span class="w"> </span><span class="sd">"""Create a new object."""</span>
</span><span id="__span-0-579"><a id="__codelineno-0-579" name="__codelineno-0-579"></a> <span class="n">properties</span> <span class="o">=</span> <span class="n">properties</span> <span class="ow">or</span> <span class="p">{}</span>
</span><span id="__span-0-580"><a id="__codelineno-0-580" name="__codelineno-0-580"></a> <span class="n">code</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">"""</span>
</span><span id="__span-0-581"><a id="__codelineno-0-581" name="__codelineno-0-581"></a><span class="s2">doc = FreeCAD.ActiveDocument if </span><span class="si">{</span><span class="n">doc_name</span><span class="si">!r}</span><span class="s2"> is None else FreeCAD.getDocument(</span><span class="si">{</span><span class="n">doc_name</span><span class="si">!r}</span><span class="s2">)</span>
</span><span id="__span-0-582"><a id="__codelineno-0-582" name="__codelineno-0-582"></a><span class="s2">if doc is None:</span>
</span><span id="__span-0-583"><a id="__codelineno-0-583" name="__codelineno-0-583"></a><span class="s2"> raise ValueError("No document found")</span>
</span><span id="__span-0-584"><a id="__codelineno-0-584" name="__codelineno-0-584"></a>
</span><span id="__span-0-585"><a id="__codelineno-0-585" name="__codelineno-0-585"></a><span class="s2">obj = doc.addObject(</span><span class="si">{</span><span class="n">type_id</span><span class="si">!r}</span><span class="s2">, </span><span class="si">{</span><span class="n">name</span><span class="si">!r}</span><span class="s2"> or "")</span>
</span><span id="__span-0-586"><a id="__codelineno-0-586" name="__codelineno-0-586"></a>
</span><span id="__span-0-587"><a id="__codelineno-0-587" name="__codelineno-0-587"></a><span class="s2"># Set properties</span>
</span><span id="__span-0-588"><a id="__codelineno-0-588" name="__codelineno-0-588"></a><span class="s2">for prop_name, prop_val in </span><span class="si">{</span><span class="n">properties</span><span class="si">!r}</span><span class="s2">.items():</span>
</span><span id="__span-0-589"><a id="__codelineno-0-589" name="__codelineno-0-589"></a><span class="s2"> if hasattr(obj, prop_name):</span>
</span><span id="__span-0-590"><a id="__codelineno-0-590" name="__codelineno-0-590"></a><span class="s2"> setattr(obj, prop_name, prop_val)</span>
</span><span id="__span-0-591"><a id="__codelineno-0-591" name="__codelineno-0-591"></a>
</span><span id="__span-0-592"><a id="__codelineno-0-592" name="__codelineno-0-592"></a><span class="s2">doc.recompute()</span>
</span><span id="__span-0-593"><a id="__codelineno-0-593" name="__codelineno-0-593"></a>
</span><span id="__span-0-594"><a id="__codelineno-0-594" name="__codelineno-0-594"></a><span class="s2">_result_ = </span><span class="se">{{</span>
</span><span id="__span-0-595"><a id="__codelineno-0-595" name="__codelineno-0-595"></a><span class="s2"> "name": obj.Name,</span>
</span><span id="__span-0-596"><a id="__codelineno-0-596" name="__codelineno-0-596"></a><span class="s2"> "label": obj.Label,</span>
</span><span id="__span-0-597"><a id="__codelineno-0-597" name="__codelineno-0-597"></a><span class="s2"> "type_id": obj.TypeId,</span>
</span><span id="__span-0-598"><a id="__codelineno-0-598" name="__codelineno-0-598"></a><span class="s2"> "visibility": True,</span>
</span><span id="__span-0-599"><a id="__codelineno-0-599" name="__codelineno-0-599"></a><span class="s2"> "children": [c.Name for c in obj.OutList] if hasattr(obj, "OutList") else [],</span>
</span><span id="__span-0-600"><a id="__codelineno-0-600" name="__codelineno-0-600"></a><span class="s2"> "parents": [p.Name for p in obj.InList] if hasattr(obj, "InList") else [],</span>
</span><span id="__span-0-601"><a id="__codelineno-0-601" name="__codelineno-0-601"></a><span class="se">}}</span>
</span><span id="__span-0-602"><a id="__codelineno-0-602" name="__codelineno-0-602"></a><span class="s2">"""</span>
</span><span id="__span-0-603"><a id="__codelineno-0-603" name="__codelineno-0-603"></a> <span class="n">result</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">execute_python</span><span class="p">(</span><span class="n">code</span><span class="p">)</span>
</span><span id="__span-0-604"><a id="__codelineno-0-604" name="__codelineno-0-604"></a>
</span><span id="__span-0-605"><a id="__codelineno-0-605" name="__codelineno-0-605"></a> <span class="k">if</span> <span class="n">result</span><span class="o">.</span><span class="n">success</span> <span class="ow">and</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">:</span>
</span><span id="__span-0-606"><a id="__codelineno-0-606" name="__codelineno-0-606"></a> <span class="k">return</span> <span class="n">ObjectInfo</span><span class="p">(</span><span class="o">**</span><span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">)</span>
</span><span id="__span-0-607"><a id="__codelineno-0-607" name="__codelineno-0-607"></a>
</span><span id="__span-0-608"><a id="__codelineno-0-608" name="__codelineno-0-608"></a> <span class="n">error_msg</span> <span class="o">=</span> <span class="n">result</span><span class="o">.</span><span class="n">error_traceback</span> <span class="ow">or</span> <span class="s2">"Failed to create object"</span>
</span><span id="__span-0-609"><a id="__codelineno-0-609" name="__codelineno-0-609"></a> <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="n">error_msg</span><span class="p">)</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> </div> </div> <div class="doc doc-object doc-function"> <h6 id="freecad_mcp.bridge.socket.SocketBridge.delete_object" class="doc doc-heading"> <code class="highlight language-python"><span class="n">delete_object</span><span class="p">(</span><span class="n">obj_name</span><span class="p">,</span> <span class="n">doc_name</span><span class="o">=</span><span class="kc">None</span><span class="p">)</span></code> <span class="doc doc-labels"> <small class="doc doc-label doc-label-async"><code>async</code></small> </span> <a href="#freecad_mcp.bridge.socket.SocketBridge.delete_object" class="headerlink" title="Permanent link">¶</a></h6> <div class="doc doc-contents "> <p>Delete an object.</p> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/socket.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-651">651</a></span>
<span class="normal"><a href="#__codelineno-0-652">652</a></span>
<span class="normal"><a href="#__codelineno-0-653">653</a></span>
<span class="normal"><a href="#__codelineno-0-654">654</a></span>
<span class="normal"><a href="#__codelineno-0-655">655</a></span>
<span class="normal"><a href="#__codelineno-0-656">656</a></span>
<span class="normal"><a href="#__codelineno-0-657">657</a></span>
<span class="normal"><a href="#__codelineno-0-658">658</a></span>
<span class="normal"><a href="#__codelineno-0-659">659</a></span>
<span class="normal"><a href="#__codelineno-0-660">660</a></span>
<span class="normal"><a href="#__codelineno-0-661">661</a></span>
<span class="normal"><a href="#__codelineno-0-662">662</a></span>
<span class="normal"><a href="#__codelineno-0-663">663</a></span>
<span class="normal"><a href="#__codelineno-0-664">664</a></span>
<span class="normal"><a href="#__codelineno-0-665">665</a></span>
<span class="normal"><a href="#__codelineno-0-666">666</a></span>
<span class="normal"><a href="#__codelineno-0-667">667</a></span>
<span class="normal"><a href="#__codelineno-0-668">668</a></span>
<span class="normal"><a href="#__codelineno-0-669">669</a></span>
<span class="normal"><a href="#__codelineno-0-670">670</a></span>
<span class="normal"><a href="#__codelineno-0-671">671</a></span>
<span class="normal"><a href="#__codelineno-0-672">672</a></span>
<span class="normal"><a href="#__codelineno-0-673">673</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-651"><a id="__codelineno-0-651" name="__codelineno-0-651"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">delete_object</span><span class="p">(</span>
</span><span id="__span-0-652"><a id="__codelineno-0-652" name="__codelineno-0-652"></a> <span class="bp">self</span><span class="p">,</span>
</span><span id="__span-0-653"><a id="__codelineno-0-653" name="__codelineno-0-653"></a> <span class="n">obj_name</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span>
</span><span id="__span-0-654"><a id="__codelineno-0-654" name="__codelineno-0-654"></a> <span class="n">doc_name</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-655"><a id="__codelineno-0-655" name="__codelineno-0-655"></a> <span class="p">)</span> <span class="o">-&gt;</span> <span class="kc">None</span><span class="p">:</span>
</span><span id="__span-0-656"><a id="__codelineno-0-656" name="__codelineno-0-656"></a><span class="w"> </span><span class="sd">"""Delete an object."""</span>
</span><span id="__span-0-657"><a id="__codelineno-0-657" name="__codelineno-0-657"></a> <span class="n">code</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">"""</span>
</span><span id="__span-0-658"><a id="__codelineno-0-658" name="__codelineno-0-658"></a><span class="s2">doc = FreeCAD.ActiveDocument if </span><span class="si">{</span><span class="n">doc_name</span><span class="si">!r}</span><span class="s2"> is None else FreeCAD.getDocument(</span><span class="si">{</span><span class="n">doc_name</span><span class="si">!r}</span><span class="s2">)</span>
</span><span id="__span-0-659"><a id="__codelineno-0-659" name="__codelineno-0-659"></a><span class="s2">if doc is None:</span>
</span><span id="__span-0-660"><a id="__codelineno-0-660" name="__codelineno-0-660"></a><span class="s2"> raise ValueError("No document found")</span>
</span><span id="__span-0-661"><a id="__codelineno-0-661" name="__codelineno-0-661"></a>
</span><span id="__span-0-662"><a id="__codelineno-0-662" name="__codelineno-0-662"></a><span class="s2">obj = doc.getObject(</span><span class="si">{</span><span class="n">obj_name</span><span class="si">!r}</span><span class="s2">)</span>
</span><span id="__span-0-663"><a id="__codelineno-0-663" name="__codelineno-0-663"></a><span class="s2">if obj is None:</span>
</span><span id="__span-0-664"><a id="__codelineno-0-664" name="__codelineno-0-664"></a><span class="s2"> raise ValueError(f"Object not found: </span><span class="si">{</span><span class="n">obj_name</span><span class="si">!r}</span><span class="s2">")</span>
</span><span id="__span-0-665"><a id="__codelineno-0-665" name="__codelineno-0-665"></a>
</span><span id="__span-0-666"><a id="__codelineno-0-666" name="__codelineno-0-666"></a><span class="s2">doc.removeObject(</span><span class="si">{</span><span class="n">obj_name</span><span class="si">!r}</span><span class="s2">)</span>
</span><span id="__span-0-667"><a id="__codelineno-0-667" name="__codelineno-0-667"></a><span class="s2">_result_ = True</span>
</span><span id="__span-0-668"><a id="__codelineno-0-668" name="__codelineno-0-668"></a><span class="s2">"""</span>
</span><span id="__span-0-669"><a id="__codelineno-0-669" name="__codelineno-0-669"></a> <span class="n">result</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">execute_python</span><span class="p">(</span><span class="n">code</span><span class="p">)</span>
</span><span id="__span-0-670"><a id="__codelineno-0-670" name="__codelineno-0-670"></a>
</span><span id="__span-0-671"><a id="__codelineno-0-671" name="__codelineno-0-671"></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">result</span><span class="o">.</span><span class="n">success</span><span class="p">:</span>
</span><span id="__span-0-672"><a id="__codelineno-0-672" name="__codelineno-0-672"></a> <span class="n">error_msg</span> <span class="o">=</span> <span class="n">result</span><span class="o">.</span><span class="n">error_traceback</span> <span class="ow">or</span> <span class="s2">"Failed to delete object"</span>
</span><span id="__span-0-673"><a id="__codelineno-0-673" name="__codelineno-0-673"></a> <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="n">error_msg</span><span class="p">)</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> </div> </div> <div class="doc doc-object doc-function"> <h6 id="freecad_mcp.bridge.socket.SocketBridge.disconnect" class="doc doc-heading"> <code class="highlight language-python"><span class="n">disconnect</span><span class="p">()</span></code> <span class="doc doc-labels"> <small class="doc doc-label doc-label-async"><code>async</code></small> </span> <a href="#freecad_mcp.bridge.socket.SocketBridge.disconnect" class="headerlink" title="Permanent link">¶</a></h6> <div class="doc doc-contents "> <p>Close connection to FreeCAD socket server.</p> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/socket.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-113">113</a></span>
<span class="normal"><a href="#__codelineno-0-114">114</a></span>
<span class="normal"><a href="#__codelineno-0-115">115</a></span>
<span class="normal"><a href="#__codelineno-0-116">116</a></span>
<span class="normal"><a href="#__codelineno-0-117">117</a></span>
<span class="normal"><a href="#__codelineno-0-118">118</a></span>
<span class="normal"><a href="#__codelineno-0-119">119</a></span>
<span class="normal"><a href="#__codelineno-0-120">120</a></span>
<span class="normal"><a href="#__codelineno-0-121">121</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-113"><a id="__codelineno-0-113" name="__codelineno-0-113"></a><span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">disconnect</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kc">None</span><span class="p">:</span>
</span><span id="__span-0-114"><a id="__codelineno-0-114" name="__codelineno-0-114"></a><span class="w"> </span><span class="sd">"""Close connection to FreeCAD socket server."""</span>
</span><span id="__span-0-115"><a id="__codelineno-0-115" name="__codelineno-0-115"></a> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_writer</span><span class="p">:</span>
</span><span id="__span-0-116"><a id="__codelineno-0-116" name="__codelineno-0-116"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_writer</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
</span><span id="__span-0-117"><a id="__codelineno-0-117" name="__codelineno-0-117"></a> <span class="k">with</span> <span class="n">contextlib</span><span class="o">.</span><span class="n">suppress</span><span class="p">(</span><span class="ne">Exception</span><span class="p">):</span>
</span><span id="__span-0-118"><a id="__codelineno-0-118" name="__codelineno-0-118"></a> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">_writer</span><span class="o">.</span><span class="n">wait_closed</span><span class="p">()</span>
</span><span id="__span-0-119"><a id="__codelineno-0-119" name="__codelineno-0-119"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_reader</span> <span class="o">=</span> <span class="kc">None</span>
</span><span id="__span-0-120"><a id="__codelineno-0-120" name="__codelineno-0-120"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_writer</span> <span class="o">=</span> <span class="kc">None</span>
</span><span id="__span-0-121"><a id="__codelineno-0-121" name="__codelineno-0-121"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_connected</span> <span class="o">=</span> <span class="kc">False</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> </div> </div> <div class="doc doc-object doc-function"> <h6 id="freecad_mcp.bridge.socket.SocketBridge.edit_object" class="doc doc-heading"> <code class="highlight language-python"><span class="n">edit_object</span><span class="p">(</span><span class="n">obj_name</span><span class="p">,</span> <span class="n">properties</span><span class="p">,</span> <span class="n">doc_name</span><span class="o">=</span><span class="kc">None</span><span class="p">)</span></code> <span class="doc doc-labels"> <small class="doc doc-label doc-label-async"><code>async</code></small> </span> <a href="#freecad_mcp.bridge.socket.SocketBridge.edit_object" class="headerlink" title="Permanent link">¶</a></h6> <div class="doc doc-contents "> <p>Edit object properties.</p> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/socket.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-611">611</a></span>
<span class="normal"><a href="#__codelineno-0-612">612</a></span>
<span class="normal"><a href="#__codelineno-0-613">613</a></span>
<span class="normal"><a href="#__codelineno-0-614">614</a></span>
<span class="normal"><a href="#__codelineno-0-615">615</a></span>
<span class="normal"><a href="#__codelineno-0-616">616</a></span>
<span class="normal"><a href="#__codelineno-0-617">617</a></span>
<span class="normal"><a href="#__codelineno-0-618">618</a></span>
<span class="normal"><a href="#__codelineno-0-619">619</a></span>
<span class="normal"><a href="#__codelineno-0-620">620</a></span>
<span class="normal"><a href="#__codelineno-0-621">621</a></span>
<span class="normal"><a href="#__codelineno-0-622">622</a></span>
<span class="normal"><a href="#__codelineno-0-623">623</a></span>
<span class="normal"><a href="#__codelineno-0-624">624</a></span>
<span class="normal"><a href="#__codelineno-0-625">625</a></span>
<span class="normal"><a href="#__codelineno-0-626">626</a></span>
<span class="normal"><a href="#__codelineno-0-627">627</a></span>
<span class="normal"><a href="#__codelineno-0-628">628</a></span>
<span class="normal"><a href="#__codelineno-0-629">629</a></span>
<span class="normal"><a href="#__codelineno-0-630">630</a></span>
<span class="normal"><a href="#__codelineno-0-631">631</a></span>
<span class="normal"><a href="#__codelineno-0-632">632</a></span>
<span class="normal"><a href="#__codelineno-0-633">633</a></span>
<span class="normal"><a href="#__codelineno-0-634">634</a></span>
<span class="normal"><a href="#__codelineno-0-635">635</a></span>
<span class="normal"><a href="#__codelineno-0-636">636</a></span>
<span class="normal"><a href="#__codelineno-0-637">637</a></span>
<span class="normal"><a href="#__codelineno-0-638">638</a></span>
<span class="normal"><a href="#__codelineno-0-639">639</a></span>
<span class="normal"><a href="#__codelineno-0-640">640</a></span>
<span class="normal"><a href="#__codelineno-0-641">641</a></span>
<span class="normal"><a href="#__codelineno-0-642">642</a></span>
<span class="normal"><a href="#__codelineno-0-643">643</a></span>
<span class="normal"><a href="#__codelineno-0-644">644</a></span>
<span class="normal"><a href="#__codelineno-0-645">645</a></span>
<span class="normal"><a href="#__codelineno-0-646">646</a></span>
<span class="normal"><a href="#__codelineno-0-647">647</a></span>
<span class="normal"><a href="#__codelineno-0-648">648</a></span>
<span class="normal"><a href="#__codelineno-0-649">649</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-611"><a id="__codelineno-0-611" name="__codelineno-0-611"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">edit_object</span><span class="p">(</span>
</span><span id="__span-0-612"><a id="__codelineno-0-612" name="__codelineno-0-612"></a> <span class="bp">self</span><span class="p">,</span>
</span><span id="__span-0-613"><a id="__codelineno-0-613" name="__codelineno-0-613"></a> <span class="n">obj_name</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span>
</span><span id="__span-0-614"><a id="__codelineno-0-614" name="__codelineno-0-614"></a> <span class="n">properties</span><span class="p">:</span> <span class="nb">dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Any</span><span class="p">],</span>
</span><span id="__span-0-615"><a id="__codelineno-0-615" name="__codelineno-0-615"></a> <span class="n">doc_name</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-616"><a id="__codelineno-0-616" name="__codelineno-0-616"></a> <span class="p">)</span> <span class="o">-&gt;</span> <span class="n">ObjectInfo</span><span class="p">:</span>
</span><span id="__span-0-617"><a id="__codelineno-0-617" name="__codelineno-0-617"></a><span class="w"> </span><span class="sd">"""Edit object properties."""</span>
</span><span id="__span-0-618"><a id="__codelineno-0-618" name="__codelineno-0-618"></a> <span class="n">code</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">"""</span>
</span><span id="__span-0-619"><a id="__codelineno-0-619" name="__codelineno-0-619"></a><span class="s2">doc = FreeCAD.ActiveDocument if </span><span class="si">{</span><span class="n">doc_name</span><span class="si">!r}</span><span class="s2"> is None else FreeCAD.getDocument(</span><span class="si">{</span><span class="n">doc_name</span><span class="si">!r}</span><span class="s2">)</span>
</span><span id="__span-0-620"><a id="__codelineno-0-620" name="__codelineno-0-620"></a><span class="s2">if doc is None:</span>
</span><span id="__span-0-621"><a id="__codelineno-0-621" name="__codelineno-0-621"></a><span class="s2"> raise ValueError("No document found")</span>
</span><span id="__span-0-622"><a id="__codelineno-0-622" name="__codelineno-0-622"></a>
</span><span id="__span-0-623"><a id="__codelineno-0-623" name="__codelineno-0-623"></a><span class="s2">obj = doc.getObject(</span><span class="si">{</span><span class="n">obj_name</span><span class="si">!r}</span><span class="s2">)</span>
</span><span id="__span-0-624"><a id="__codelineno-0-624" name="__codelineno-0-624"></a><span class="s2">if obj is None:</span>
</span><span id="__span-0-625"><a id="__codelineno-0-625" name="__codelineno-0-625"></a><span class="s2"> raise ValueError(f"Object not found: </span><span class="si">{</span><span class="n">obj_name</span><span class="si">!r}</span><span class="s2">")</span>
</span><span id="__span-0-626"><a id="__codelineno-0-626" name="__codelineno-0-626"></a>
</span><span id="__span-0-627"><a id="__codelineno-0-627" name="__codelineno-0-627"></a><span class="s2"># Set properties</span>
</span><span id="__span-0-628"><a id="__codelineno-0-628" name="__codelineno-0-628"></a><span class="s2">for prop_name, prop_val in </span><span class="si">{</span><span class="n">properties</span><span class="si">!r}</span><span class="s2">.items():</span>
</span><span id="__span-0-629"><a id="__codelineno-0-629" name="__codelineno-0-629"></a><span class="s2"> if hasattr(obj, prop_name):</span>
</span><span id="__span-0-630"><a id="__codelineno-0-630" name="__codelineno-0-630"></a><span class="s2"> setattr(obj, prop_name, prop_val)</span>
</span><span id="__span-0-631"><a id="__codelineno-0-631" name="__codelineno-0-631"></a>
</span><span id="__span-0-632"><a id="__codelineno-0-632" name="__codelineno-0-632"></a><span class="s2">doc.recompute()</span>
</span><span id="__span-0-633"><a id="__codelineno-0-633" name="__codelineno-0-633"></a>
</span><span id="__span-0-634"><a id="__codelineno-0-634" name="__codelineno-0-634"></a><span class="s2">_result_ = </span><span class="se">{{</span>
</span><span id="__span-0-635"><a id="__codelineno-0-635" name="__codelineno-0-635"></a><span class="s2"> "name": obj.Name,</span>
</span><span id="__span-0-636"><a id="__codelineno-0-636" name="__codelineno-0-636"></a><span class="s2"> "label": obj.Label,</span>
</span><span id="__span-0-637"><a id="__codelineno-0-637" name="__codelineno-0-637"></a><span class="s2"> "type_id": obj.TypeId,</span>
</span><span id="__span-0-638"><a id="__codelineno-0-638" name="__codelineno-0-638"></a><span class="s2"> "visibility": obj.ViewObject.Visibility if hasattr(obj, "ViewObject") and obj.ViewObject else True,</span>
</span><span id="__span-0-639"><a id="__codelineno-0-639" name="__codelineno-0-639"></a><span class="s2"> "children": [c.Name for c in obj.OutList] if hasattr(obj, "OutList") else [],</span>
</span><span id="__span-0-640"><a id="__codelineno-0-640" name="__codelineno-0-640"></a><span class="s2"> "parents": [p.Name for p in obj.InList] if hasattr(obj, "InList") else [],</span>
</span><span id="__span-0-641"><a id="__codelineno-0-641" name="__codelineno-0-641"></a><span class="se">}}</span>
</span><span id="__span-0-642"><a id="__codelineno-0-642" name="__codelineno-0-642"></a><span class="s2">"""</span>
</span><span id="__span-0-643"><a id="__codelineno-0-643" name="__codelineno-0-643"></a> <span class="n">result</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">execute_python</span><span class="p">(</span><span class="n">code</span><span class="p">)</span>
</span><span id="__span-0-644"><a id="__codelineno-0-644" name="__codelineno-0-644"></a>
</span><span id="__span-0-645"><a id="__codelineno-0-645" name="__codelineno-0-645"></a> <span class="k">if</span> <span class="n">result</span><span class="o">.</span><span class="n">success</span> <span class="ow">and</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">:</span>
</span><span id="__span-0-646"><a id="__codelineno-0-646" name="__codelineno-0-646"></a> <span class="k">return</span> <span class="n">ObjectInfo</span><span class="p">(</span><span class="o">**</span><span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">)</span>
</span><span id="__span-0-647"><a id="__codelineno-0-647" name="__codelineno-0-647"></a>
</span><span id="__span-0-648"><a id="__codelineno-0-648" name="__codelineno-0-648"></a> <span class="n">error_msg</span> <span class="o">=</span> <span class="n">result</span><span class="o">.</span><span class="n">error_traceback</span> <span class="ow">or</span> <span class="s2">"Failed to edit object"</span>
</span><span id="__span-0-649"><a id="__codelineno-0-649" name="__codelineno-0-649"></a> <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="n">error_msg</span><span class="p">)</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> </div> </div> <div class="doc doc-object doc-function"> <h6 id="freecad_mcp.bridge.socket.SocketBridge.execute_python" class="doc doc-heading"> <code class="highlight language-python"><span class="n">execute_python</span><span class="p">(</span><span class="n">code</span><span class="p">,</span> <span class="n">timeout_ms</span><span class="o">=</span><span class="mi">30000</span><span class="p">)</span></code> <span class="doc doc-labels"> <small class="doc doc-label doc-label-async"><code>async</code></small> </span> <a href="#freecad_mcp.bridge.socket.SocketBridge.execute_python" class="headerlink" title="Permanent link">¶</a></h6> <div class="doc doc-contents "> <p>Execute Python code in FreeCAD context via socket.</p> <p><span class="doc-section-title">Parameters:</span></p> <table> <thead> <tr> <th>Name</th> <th>Type</th> <th>Description</th> <th>Default</th> </tr> </thead> <tbody> <tr class="doc-section-item"> <td> <code>code</code> </td> <td> <code><span title="str">str</span></code> </td> <td> <div class="doc-md-description"> <p>Python code to execute.</p> </div> </td> <td> <em>required</em> </td> </tr> <tr class="doc-section-item"> <td> <code>timeout_ms</code> </td> <td> <code><span title="int">int</span></code> </td> <td> <div class="doc-md-description"> <p>Maximum execution time in milliseconds.</p> </div> </td> <td> <code>30000</code> </td> </tr> </tbody> </table> <p><span class="doc-section-title">Returns:</span></p> <table> <thead> <tr> <th>Type</th> <th>Description</th> </tr> </thead> <tbody> <tr class="doc-section-item"> <td> <code><a class="autorefs autorefs-internal" title="ExecutionResult
dataclass
(freecad_mcp.bridge.base.ExecutionResult)" href="#freecad_mcp.bridge.base.ExecutionResult">ExecutionResult</a></code> </td> <td> <div class="doc-md-description"> <p>ExecutionResult with execution outcome.</p> </div> </td> </tr> </tbody> </table> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/socket.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-264">264</a></span>
<span class="normal"><a href="#__codelineno-0-265">265</a></span>
<span class="normal"><a href="#__codelineno-0-266">266</a></span>
<span class="normal"><a href="#__codelineno-0-267">267</a></span>
<span class="normal"><a href="#__codelineno-0-268">268</a></span>
<span class="normal"><a href="#__codelineno-0-269">269</a></span>
<span class="normal"><a href="#__codelineno-0-270">270</a></span>
<span class="normal"><a href="#__codelineno-0-271">271</a></span>
<span class="normal"><a href="#__codelineno-0-272">272</a></span>
<span class="normal"><a href="#__codelineno-0-273">273</a></span>
<span class="normal"><a href="#__codelineno-0-274">274</a></span>
<span class="normal"><a href="#__codelineno-0-275">275</a></span>
<span class="normal"><a href="#__codelineno-0-276">276</a></span>
<span class="normal"><a href="#__codelineno-0-277">277</a></span>
<span class="normal"><a href="#__codelineno-0-278">278</a></span>
<span class="normal"><a href="#__codelineno-0-279">279</a></span>
<span class="normal"><a href="#__codelineno-0-280">280</a></span>
<span class="normal"><a href="#__codelineno-0-281">281</a></span>
<span class="normal"><a href="#__codelineno-0-282">282</a></span>
<span class="normal"><a href="#__codelineno-0-283">283</a></span>
<span class="normal"><a href="#__codelineno-0-284">284</a></span>
<span class="normal"><a href="#__codelineno-0-285">285</a></span>
<span class="normal"><a href="#__codelineno-0-286">286</a></span>
<span class="normal"><a href="#__codelineno-0-287">287</a></span>
<span class="normal"><a href="#__codelineno-0-288">288</a></span>
<span class="normal"><a href="#__codelineno-0-289">289</a></span>
<span class="normal"><a href="#__codelineno-0-290">290</a></span>
<span class="normal"><a href="#__codelineno-0-291">291</a></span>
<span class="normal"><a href="#__codelineno-0-292">292</a></span>
<span class="normal"><a href="#__codelineno-0-293">293</a></span>
<span class="normal"><a href="#__codelineno-0-294">294</a></span>
<span class="normal"><a href="#__codelineno-0-295">295</a></span>
<span class="normal"><a href="#__codelineno-0-296">296</a></span>
<span class="normal"><a href="#__codelineno-0-297">297</a></span>
<span class="normal"><a href="#__codelineno-0-298">298</a></span>
<span class="normal"><a href="#__codelineno-0-299">299</a></span>
<span class="normal"><a href="#__codelineno-0-300">300</a></span>
<span class="normal"><a href="#__codelineno-0-301">301</a></span>
<span class="normal"><a href="#__codelineno-0-302">302</a></span>
<span class="normal"><a href="#__codelineno-0-303">303</a></span>
<span class="normal"><a href="#__codelineno-0-304">304</a></span>
<span class="normal"><a href="#__codelineno-0-305">305</a></span>
<span class="normal"><a href="#__codelineno-0-306">306</a></span>
<span class="normal"><a href="#__codelineno-0-307">307</a></span>
<span class="normal"><a href="#__codelineno-0-308">308</a></span>
<span class="normal"><a href="#__codelineno-0-309">309</a></span>
<span class="normal"><a href="#__codelineno-0-310">310</a></span>
<span class="normal"><a href="#__codelineno-0-311">311</a></span>
<span class="normal"><a href="#__codelineno-0-312">312</a></span>
<span class="normal"><a href="#__codelineno-0-313">313</a></span>
<span class="normal"><a href="#__codelineno-0-314">314</a></span>
<span class="normal"><a href="#__codelineno-0-315">315</a></span>
<span class="normal"><a href="#__codelineno-0-316">316</a></span>
<span class="normal"><a href="#__codelineno-0-317">317</a></span>
<span class="normal"><a href="#__codelineno-0-318">318</a></span>
<span class="normal"><a href="#__codelineno-0-319">319</a></span>
<span class="normal"><a href="#__codelineno-0-320">320</a></span>
<span class="normal"><a href="#__codelineno-0-321">321</a></span>
<span class="normal"><a href="#__codelineno-0-322">322</a></span>
<span class="normal"><a href="#__codelineno-0-323">323</a></span>
<span class="normal"><a href="#__codelineno-0-324">324</a></span>
<span class="normal"><a href="#__codelineno-0-325">325</a></span>
<span class="normal"><a href="#__codelineno-0-326">326</a></span>
<span class="normal"><a href="#__codelineno-0-327">327</a></span>
<span class="normal"><a href="#__codelineno-0-328">328</a></span>
<span class="normal"><a href="#__codelineno-0-329">329</a></span>
<span class="normal"><a href="#__codelineno-0-330">330</a></span>
<span class="normal"><a href="#__codelineno-0-331">331</a></span>
<span class="normal"><a href="#__codelineno-0-332">332</a></span>
<span class="normal"><a href="#__codelineno-0-333">333</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-264"><a id="__codelineno-0-264" name="__codelineno-0-264"></a><span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">execute_python</span><span class="p">(</span>
</span><span id="__span-0-265"><a id="__codelineno-0-265" name="__codelineno-0-265"></a> <span class="bp">self</span><span class="p">,</span>
</span><span id="__span-0-266"><a id="__codelineno-0-266" name="__codelineno-0-266"></a> <span class="n">code</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span>
</span><span id="__span-0-267"><a id="__codelineno-0-267" name="__codelineno-0-267"></a> <span class="n">timeout_ms</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">30000</span><span class="p">,</span>
</span><span id="__span-0-268"><a id="__codelineno-0-268" name="__codelineno-0-268"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">ExecutionResult</span><span class="p">:</span>
</span><span id="__span-0-269"><a id="__codelineno-0-269" name="__codelineno-0-269"></a><span class="w"> </span><span class="sd">"""Execute Python code in FreeCAD context via socket.</span>
</span><span id="__span-0-270"><a id="__codelineno-0-270" name="__codelineno-0-270"></a>
</span><span id="__span-0-271"><a id="__codelineno-0-271" name="__codelineno-0-271"></a><span class="sd"> Args:</span>
</span><span id="__span-0-272"><a id="__codelineno-0-272" name="__codelineno-0-272"></a><span class="sd"> code: Python code to execute.</span>
</span><span id="__span-0-273"><a id="__codelineno-0-273" name="__codelineno-0-273"></a><span class="sd"> timeout_ms: Maximum execution time in milliseconds.</span>
</span><span id="__span-0-274"><a id="__codelineno-0-274" name="__codelineno-0-274"></a>
</span><span id="__span-0-275"><a id="__codelineno-0-275" name="__codelineno-0-275"></a><span class="sd"> Returns:</span>
</span><span id="__span-0-276"><a id="__codelineno-0-276" name="__codelineno-0-276"></a><span class="sd"> ExecutionResult with execution outcome.</span>
</span><span id="__span-0-277"><a id="__codelineno-0-277" name="__codelineno-0-277"></a><span class="sd"> """</span>
</span><span id="__span-0-278"><a id="__codelineno-0-278" name="__codelineno-0-278"></a> <span class="n">start</span> <span class="o">=</span> <span class="n">time</span><span class="o">.</span><span class="n">perf_counter</span><span class="p">()</span>
</span><span id="__span-0-279"><a id="__codelineno-0-279" name="__codelineno-0-279"></a>
</span><span id="__span-0-280"><a id="__codelineno-0-280" name="__codelineno-0-280"></a> <span class="k">try</span><span class="p">:</span>
</span><span id="__span-0-281"><a id="__codelineno-0-281" name="__codelineno-0-281"></a> <span class="n">result</span> <span class="o">=</span> <span class="k">await</span> <span class="n">asyncio</span><span class="o">.</span><span class="n">wait_for</span><span class="p">(</span>
</span><span id="__span-0-282"><a id="__codelineno-0-282" name="__codelineno-0-282"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_send_request</span><span class="p">(</span><span class="s2">"execute"</span><span class="p">,</span> <span class="p">{</span><span class="s2">"code"</span><span class="p">:</span> <span class="n">code</span><span class="p">}),</span>
</span><span id="__span-0-283"><a id="__codelineno-0-283" name="__codelineno-0-283"></a> <span class="n">timeout</span><span class="o">=</span><span class="n">timeout_ms</span> <span class="o">/</span> <span class="mi">1000</span><span class="p">,</span>
</span><span id="__span-0-284"><a id="__codelineno-0-284" name="__codelineno-0-284"></a> <span class="p">)</span>
</span><span id="__span-0-285"><a id="__codelineno-0-285" name="__codelineno-0-285"></a> <span class="n">elapsed</span> <span class="o">=</span> <span class="p">(</span><span class="n">time</span><span class="o">.</span><span class="n">perf_counter</span><span class="p">()</span> <span class="o">-</span> <span class="n">start</span><span class="p">)</span> <span class="o">*</span> <span class="mi">1000</span>
</span><span id="__span-0-286"><a id="__codelineno-0-286" name="__codelineno-0-286"></a>
</span><span id="__span-0-287"><a id="__codelineno-0-287" name="__codelineno-0-287"></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">result</span><span class="p">,</span> <span class="nb">dict</span><span class="p">):</span>
</span><span id="__span-0-288"><a id="__codelineno-0-288" name="__codelineno-0-288"></a> <span class="k">return</span> <span class="n">ExecutionResult</span><span class="p">(</span>
</span><span id="__span-0-289"><a id="__codelineno-0-289" name="__codelineno-0-289"></a> <span class="n">success</span><span class="o">=</span><span class="n">result</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"success"</span><span class="p">,</span> <span class="kc">False</span><span class="p">),</span>
</span><span id="__span-0-290"><a id="__codelineno-0-290" name="__codelineno-0-290"></a> <span class="n">result</span><span class="o">=</span><span class="n">result</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"result"</span><span class="p">),</span>
</span><span id="__span-0-291"><a id="__codelineno-0-291" name="__codelineno-0-291"></a> <span class="n">stdout</span><span class="o">=</span><span class="n">result</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"stdout"</span><span class="p">,</span> <span class="s2">""</span><span class="p">),</span>
</span><span id="__span-0-292"><a id="__codelineno-0-292" name="__codelineno-0-292"></a> <span class="n">stderr</span><span class="o">=</span><span class="n">result</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"stderr"</span><span class="p">,</span> <span class="s2">""</span><span class="p">),</span>
</span><span id="__span-0-293"><a id="__codelineno-0-293" name="__codelineno-0-293"></a> <span class="n">execution_time_ms</span><span class="o">=</span><span class="n">elapsed</span><span class="p">,</span>
</span><span id="__span-0-294"><a id="__codelineno-0-294" name="__codelineno-0-294"></a> <span class="n">error_type</span><span class="o">=</span><span class="n">result</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"error_type"</span><span class="p">),</span>
</span><span id="__span-0-295"><a id="__codelineno-0-295" name="__codelineno-0-295"></a> <span class="n">error_traceback</span><span class="o">=</span><span class="n">result</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"error_traceback"</span><span class="p">),</span>
</span><span id="__span-0-296"><a id="__codelineno-0-296" name="__codelineno-0-296"></a> <span class="p">)</span>
</span><span id="__span-0-297"><a id="__codelineno-0-297" name="__codelineno-0-297"></a> <span class="k">else</span><span class="p">:</span>
</span><span id="__span-0-298"><a id="__codelineno-0-298" name="__codelineno-0-298"></a> <span class="k">return</span> <span class="n">ExecutionResult</span><span class="p">(</span>
</span><span id="__span-0-299"><a id="__codelineno-0-299" name="__codelineno-0-299"></a> <span class="n">success</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span>
</span><span id="__span-0-300"><a id="__codelineno-0-300" name="__codelineno-0-300"></a> <span class="n">result</span><span class="o">=</span><span class="n">result</span><span class="p">,</span>
</span><span id="__span-0-301"><a id="__codelineno-0-301" name="__codelineno-0-301"></a> <span class="n">stdout</span><span class="o">=</span><span class="s2">""</span><span class="p">,</span>
</span><span id="__span-0-302"><a id="__codelineno-0-302" name="__codelineno-0-302"></a> <span class="n">stderr</span><span class="o">=</span><span class="s2">""</span><span class="p">,</span>
</span><span id="__span-0-303"><a id="__codelineno-0-303" name="__codelineno-0-303"></a> <span class="n">execution_time_ms</span><span class="o">=</span><span class="n">elapsed</span><span class="p">,</span>
</span><span id="__span-0-304"><a id="__codelineno-0-304" name="__codelineno-0-304"></a> <span class="p">)</span>
</span><span id="__span-0-305"><a id="__codelineno-0-305" name="__codelineno-0-305"></a>
</span><span id="__span-0-306"><a id="__codelineno-0-306" name="__codelineno-0-306"></a> <span class="k">except</span> <span class="ne">TimeoutError</span><span class="p">:</span>
</span><span id="__span-0-307"><a id="__codelineno-0-307" name="__codelineno-0-307"></a> <span class="k">return</span> <span class="n">ExecutionResult</span><span class="p">(</span>
</span><span id="__span-0-308"><a id="__codelineno-0-308" name="__codelineno-0-308"></a> <span class="n">success</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
</span><span id="__span-0-309"><a id="__codelineno-0-309" name="__codelineno-0-309"></a> <span class="n">result</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-310"><a id="__codelineno-0-310" name="__codelineno-0-310"></a> <span class="n">stdout</span><span class="o">=</span><span class="s2">""</span><span class="p">,</span>
</span><span id="__span-0-311"><a id="__codelineno-0-311" name="__codelineno-0-311"></a> <span class="n">stderr</span><span class="o">=</span><span class="sa">f</span><span class="s2">"Execution timed out after </span><span class="si">{</span><span class="n">timeout_ms</span><span class="si">}</span><span class="s2">ms"</span><span class="p">,</span>
</span><span id="__span-0-312"><a id="__codelineno-0-312" name="__codelineno-0-312"></a> <span class="n">execution_time_ms</span><span class="o">=</span><span class="nb">float</span><span class="p">(</span><span class="n">timeout_ms</span><span class="p">),</span>
</span><span id="__span-0-313"><a id="__codelineno-0-313" name="__codelineno-0-313"></a> <span class="n">error_type</span><span class="o">=</span><span class="s2">"TimeoutError"</span><span class="p">,</span>
</span><span id="__span-0-314"><a id="__codelineno-0-314" name="__codelineno-0-314"></a> <span class="p">)</span>
</span><span id="__span-0-315"><a id="__codelineno-0-315" name="__codelineno-0-315"></a> <span class="k">except</span> <span class="n">JsonRpcError</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
</span><span id="__span-0-316"><a id="__codelineno-0-316" name="__codelineno-0-316"></a> <span class="n">elapsed</span> <span class="o">=</span> <span class="p">(</span><span class="n">time</span><span class="o">.</span><span class="n">perf_counter</span><span class="p">()</span> <span class="o">-</span> <span class="n">start</span><span class="p">)</span> <span class="o">*</span> <span class="mi">1000</span>
</span><span id="__span-0-317"><a id="__codelineno-0-317" name="__codelineno-0-317"></a> <span class="k">return</span> <span class="n">ExecutionResult</span><span class="p">(</span>
</span><span id="__span-0-318"><a id="__codelineno-0-318" name="__codelineno-0-318"></a> <span class="n">success</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
</span><span id="__span-0-319"><a id="__codelineno-0-319" name="__codelineno-0-319"></a> <span class="n">result</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-320"><a id="__codelineno-0-320" name="__codelineno-0-320"></a> <span class="n">stdout</span><span class="o">=</span><span class="s2">""</span><span class="p">,</span>
</span><span id="__span-0-321"><a id="__codelineno-0-321" name="__codelineno-0-321"></a> <span class="n">stderr</span><span class="o">=</span><span class="n">e</span><span class="o">.</span><span class="n">message</span><span class="p">,</span>
</span><span id="__span-0-322"><a id="__codelineno-0-322" name="__codelineno-0-322"></a> <span class="n">execution_time_ms</span><span class="o">=</span><span class="n">elapsed</span><span class="p">,</span>
</span><span id="__span-0-323"><a id="__codelineno-0-323" name="__codelineno-0-323"></a> <span class="n">error_type</span><span class="o">=</span><span class="s2">"JsonRpcError"</span><span class="p">,</span>
</span><span id="__span-0-324"><a id="__codelineno-0-324" name="__codelineno-0-324"></a> <span class="p">)</span>
</span><span id="__span-0-325"><a id="__codelineno-0-325" name="__codelineno-0-325"></a> <span class="k">except</span> <span class="ne">ConnectionError</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
</span><span id="__span-0-326"><a id="__codelineno-0-326" name="__codelineno-0-326"></a> <span class="k">return</span> <span class="n">ExecutionResult</span><span class="p">(</span>
</span><span id="__span-0-327"><a id="__codelineno-0-327" name="__codelineno-0-327"></a> <span class="n">success</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
</span><span id="__span-0-328"><a id="__codelineno-0-328" name="__codelineno-0-328"></a> <span class="n">result</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-329"><a id="__codelineno-0-329" name="__codelineno-0-329"></a> <span class="n">stdout</span><span class="o">=</span><span class="s2">""</span><span class="p">,</span>
</span><span id="__span-0-330"><a id="__codelineno-0-330" name="__codelineno-0-330"></a> <span class="n">stderr</span><span class="o">=</span><span class="nb">str</span><span class="p">(</span><span class="n">e</span><span class="p">),</span>
</span><span id="__span-0-331"><a id="__codelineno-0-331" name="__codelineno-0-331"></a> <span class="n">execution_time_ms</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span>
</span><span id="__span-0-332"><a id="__codelineno-0-332" name="__codelineno-0-332"></a> <span class="n">error_type</span><span class="o">=</span><span class="s2">"ConnectionError"</span><span class="p">,</span>
</span><span id="__span-0-333"><a id="__codelineno-0-333" name="__codelineno-0-333"></a> <span class="p">)</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> </div> </div> <div class="doc doc-object doc-function"> <h6 id="freecad_mcp.bridge.socket.SocketBridge.get_active_document" class="doc doc-heading"> <code class="highlight language-python"><span class="n">get_active_document</span><span class="p">()</span></code> <span class="doc doc-labels"> <small class="doc doc-label doc-label-async"><code>async</code></small> </span> <a href="#freecad_mcp.bridge.socket.SocketBridge.get_active_document" class="headerlink" title="Permanent link">¶</a></h6> <div class="doc doc-contents "> <p>Get the active document.</p> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/socket.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-360">360</a></span>
<span class="normal"><a href="#__codelineno-0-361">361</a></span>
<span class="normal"><a href="#__codelineno-0-362">362</a></span>
<span class="normal"><a href="#__codelineno-0-363">363</a></span>
<span class="normal"><a href="#__codelineno-0-364">364</a></span>
<span class="normal"><a href="#__codelineno-0-365">365</a></span>
<span class="normal"><a href="#__codelineno-0-366">366</a></span>
<span class="normal"><a href="#__codelineno-0-367">367</a></span>
<span class="normal"><a href="#__codelineno-0-368">368</a></span>
<span class="normal"><a href="#__codelineno-0-369">369</a></span>
<span class="normal"><a href="#__codelineno-0-370">370</a></span>
<span class="normal"><a href="#__codelineno-0-371">371</a></span>
<span class="normal"><a href="#__codelineno-0-372">372</a></span>
<span class="normal"><a href="#__codelineno-0-373">373</a></span>
<span class="normal"><a href="#__codelineno-0-374">374</a></span>
<span class="normal"><a href="#__codelineno-0-375">375</a></span>
<span class="normal"><a href="#__codelineno-0-376">376</a></span>
<span class="normal"><a href="#__codelineno-0-377">377</a></span>
<span class="normal"><a href="#__codelineno-0-378">378</a></span>
<span class="normal"><a href="#__codelineno-0-379">379</a></span>
<span class="normal"><a href="#__codelineno-0-380">380</a></span>
<span class="normal"><a href="#__codelineno-0-381">381</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-360"><a id="__codelineno-0-360" name="__codelineno-0-360"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">get_active_document</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">DocumentInfo</span> <span class="o">|</span> <span class="kc">None</span><span class="p">:</span>
</span><span id="__span-0-361"><a id="__codelineno-0-361" name="__codelineno-0-361"></a><span class="w"> </span><span class="sd">"""Get the active document."""</span>
</span><span id="__span-0-362"><a id="__codelineno-0-362" name="__codelineno-0-362"></a> <span class="n">result</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">execute_python</span><span class="p">(</span>
</span><span id="__span-0-363"><a id="__codelineno-0-363" name="__codelineno-0-363"></a><span class="w"> </span><span class="sd">"""</span>
</span><span id="__span-0-364"><a id="__codelineno-0-364" name="__codelineno-0-364"></a><span class="sd">doc = FreeCAD.ActiveDocument</span>
</span><span id="__span-0-365"><a id="__codelineno-0-365" name="__codelineno-0-365"></a><span class="sd">if doc:</span>
</span><span id="__span-0-366"><a id="__codelineno-0-366" name="__codelineno-0-366"></a><span class="sd"> _result_ = {</span>
</span><span id="__span-0-367"><a id="__codelineno-0-367" name="__codelineno-0-367"></a><span class="sd"> "name": doc.Name,</span>
</span><span id="__span-0-368"><a id="__codelineno-0-368" name="__codelineno-0-368"></a><span class="sd"> "label": doc.Label,</span>
</span><span id="__span-0-369"><a id="__codelineno-0-369" name="__codelineno-0-369"></a><span class="sd"> "path": doc.FileName or None,</span>
</span><span id="__span-0-370"><a id="__codelineno-0-370" name="__codelineno-0-370"></a><span class="sd"> "objects": [obj.Name for obj in doc.Objects],</span>
</span><span id="__span-0-371"><a id="__codelineno-0-371" name="__codelineno-0-371"></a><span class="sd"> "is_modified": doc.Modified if hasattr(doc, "Modified") else False,</span>
</span><span id="__span-0-372"><a id="__codelineno-0-372" name="__codelineno-0-372"></a><span class="sd"> "active_object": doc.ActiveObject.Name if doc.ActiveObject else None,</span>
</span><span id="__span-0-373"><a id="__codelineno-0-373" name="__codelineno-0-373"></a><span class="sd"> }</span>
</span><span id="__span-0-374"><a id="__codelineno-0-374" name="__codelineno-0-374"></a><span class="sd">else:</span>
</span><span id="__span-0-375"><a id="__codelineno-0-375" name="__codelineno-0-375"></a><span class="sd"> _result_ = None</span>
</span><span id="__span-0-376"><a id="__codelineno-0-376" name="__codelineno-0-376"></a><span class="sd">"""</span>
</span><span id="__span-0-377"><a id="__codelineno-0-377" name="__codelineno-0-377"></a> <span class="p">)</span>
</span><span id="__span-0-378"><a id="__codelineno-0-378" name="__codelineno-0-378"></a>
</span><span id="__span-0-379"><a id="__codelineno-0-379" name="__codelineno-0-379"></a> <span class="k">if</span> <span class="n">result</span><span class="o">.</span><span class="n">success</span> <span class="ow">and</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">:</span>
</span><span id="__span-0-380"><a id="__codelineno-0-380" name="__codelineno-0-380"></a> <span class="k">return</span> <span class="n">DocumentInfo</span><span class="p">(</span><span class="o">**</span><span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">)</span>
</span><span id="__span-0-381"><a id="__codelineno-0-381" name="__codelineno-0-381"></a> <span class="k">return</span> <span class="kc">None</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> </div> </div> <div class="doc doc-object doc-function"> <h6 id="freecad_mcp.bridge.socket.SocketBridge.get_console_output" class="doc doc-heading"> <code class="highlight language-python"><span class="n">get_console_output</span><span class="p">(</span><span class="n">lines</span><span class="o">=</span><span class="mi">100</span><span class="p">)</span></code> <span class="doc doc-labels"> <small class="doc doc-label doc-label-async"><code>async</code></small> </span> <a href="#freecad_mcp.bridge.socket.SocketBridge.get_console_output" class="headerlink" title="Permanent link">¶</a></h6> <div class="doc doc-contents "> <p>Get recent console output.</p> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/socket.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-1042">1042</a></span>
<span class="normal"><a href="#__codelineno-0-1043">1043</a></span>
<span class="normal"><a href="#__codelineno-0-1044">1044</a></span>
<span class="normal"><a href="#__codelineno-0-1045">1045</a></span>
<span class="normal"><a href="#__codelineno-0-1046">1046</a></span>
<span class="normal"><a href="#__codelineno-0-1047">1047</a></span>
<span class="normal"><a href="#__codelineno-0-1048">1048</a></span>
<span class="normal"><a href="#__codelineno-0-1049">1049</a></span>
<span class="normal"><a href="#__codelineno-0-1050">1050</a></span>
<span class="normal"><a href="#__codelineno-0-1051">1051</a></span>
<span class="normal"><a href="#__codelineno-0-1052">1052</a></span>
<span class="normal"><a href="#__codelineno-0-1053">1053</a></span>
<span class="normal"><a href="#__codelineno-0-1054">1054</a></span>
<span class="normal"><a href="#__codelineno-0-1055">1055</a></span>
<span class="normal"><a href="#__codelineno-0-1056">1056</a></span>
<span class="normal"><a href="#__codelineno-0-1057">1057</a></span>
<span class="normal"><a href="#__codelineno-0-1058">1058</a></span>
<span class="normal"><a href="#__codelineno-0-1059">1059</a></span>
<span class="normal"><a href="#__codelineno-0-1060">1060</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-1042"><a id="__codelineno-0-1042" name="__codelineno-0-1042"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">get_console_output</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">lines</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">100</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">list</span><span class="p">[</span><span class="nb">str</span><span class="p">]:</span>
</span><span id="__span-0-1043"><a id="__codelineno-0-1043" name="__codelineno-0-1043"></a><span class="w"> </span><span class="sd">"""Get recent console output."""</span>
</span><span id="__span-0-1044"><a id="__codelineno-0-1044" name="__codelineno-0-1044"></a> <span class="n">code</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">"""</span>
</span><span id="__span-0-1045"><a id="__codelineno-0-1045" name="__codelineno-0-1045"></a><span class="s2">output_lines = []</span>
</span><span id="__span-0-1046"><a id="__codelineno-0-1046" name="__codelineno-0-1046"></a>
</span><span id="__span-0-1047"><a id="__codelineno-0-1047" name="__codelineno-0-1047"></a><span class="s2">if hasattr(FreeCAD, 'Console'):</span>
</span><span id="__span-0-1048"><a id="__codelineno-0-1048" name="__codelineno-0-1048"></a><span class="s2"> console = FreeCAD.Console</span>
</span><span id="__span-0-1049"><a id="__codelineno-0-1049" name="__codelineno-0-1049"></a><span class="s2"> if hasattr(console, 'GetLog'):</span>
</span><span id="__span-0-1050"><a id="__codelineno-0-1050" name="__codelineno-0-1050"></a><span class="s2"> log = console.GetLog()</span>
</span><span id="__span-0-1051"><a id="__codelineno-0-1051" name="__codelineno-0-1051"></a><span class="s2"> if log:</span>
</span><span id="__span-0-1052"><a id="__codelineno-0-1052" name="__codelineno-0-1052"></a><span class="s2"> output_lines = log.split('</span><span class="se">\\</span><span class="s2">n')[-</span><span class="si">{</span><span class="n">lines</span><span class="si">}</span><span class="s2">:]</span>
</span><span id="__span-0-1053"><a id="__codelineno-0-1053" name="__codelineno-0-1053"></a>
</span><span id="__span-0-1054"><a id="__codelineno-0-1054" name="__codelineno-0-1054"></a><span class="s2">_result_ = output_lines</span>
</span><span id="__span-0-1055"><a id="__codelineno-0-1055" name="__codelineno-0-1055"></a><span class="s2">"""</span>
</span><span id="__span-0-1056"><a id="__codelineno-0-1056" name="__codelineno-0-1056"></a> <span class="n">result</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">execute_python</span><span class="p">(</span><span class="n">code</span><span class="p">)</span>
</span><span id="__span-0-1057"><a id="__codelineno-0-1057" name="__codelineno-0-1057"></a>
</span><span id="__span-0-1058"><a id="__codelineno-0-1058" name="__codelineno-0-1058"></a> <span class="k">if</span> <span class="n">result</span><span class="o">.</span><span class="n">success</span> <span class="ow">and</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">:</span>
</span><span id="__span-0-1059"><a id="__codelineno-0-1059" name="__codelineno-0-1059"></a> <span class="k">return</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span>
</span><span id="__span-0-1060"><a id="__codelineno-0-1060" name="__codelineno-0-1060"></a> <span class="k">return</span> <span class="p">[]</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> </div> </div> <div class="doc doc-object doc-function"> <h6 id="freecad_mcp.bridge.socket.SocketBridge.get_documents" class="doc doc-heading"> <code class="highlight language-python"><span class="n">get_documents</span><span class="p">()</span></code> <span class="doc doc-labels"> <small class="doc doc-label doc-label-async"><code>async</code></small> </span> <a href="#freecad_mcp.bridge.socket.SocketBridge.get_documents" class="headerlink" title="Permanent link">¶</a></h6> <div class="doc doc-contents "> <p>Get list of open documents.</p> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/socket.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-339">339</a></span>
<span class="normal"><a href="#__codelineno-0-340">340</a></span>
<span class="normal"><a href="#__codelineno-0-341">341</a></span>
<span class="normal"><a href="#__codelineno-0-342">342</a></span>
<span class="normal"><a href="#__codelineno-0-343">343</a></span>
<span class="normal"><a href="#__codelineno-0-344">344</a></span>
<span class="normal"><a href="#__codelineno-0-345">345</a></span>
<span class="normal"><a href="#__codelineno-0-346">346</a></span>
<span class="normal"><a href="#__codelineno-0-347">347</a></span>
<span class="normal"><a href="#__codelineno-0-348">348</a></span>
<span class="normal"><a href="#__codelineno-0-349">349</a></span>
<span class="normal"><a href="#__codelineno-0-350">350</a></span>
<span class="normal"><a href="#__codelineno-0-351">351</a></span>
<span class="normal"><a href="#__codelineno-0-352">352</a></span>
<span class="normal"><a href="#__codelineno-0-353">353</a></span>
<span class="normal"><a href="#__codelineno-0-354">354</a></span>
<span class="normal"><a href="#__codelineno-0-355">355</a></span>
<span class="normal"><a href="#__codelineno-0-356">356</a></span>
<span class="normal"><a href="#__codelineno-0-357">357</a></span>
<span class="normal"><a href="#__codelineno-0-358">358</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-339"><a id="__codelineno-0-339" name="__codelineno-0-339"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">get_documents</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">list</span><span class="p">[</span><span class="n">DocumentInfo</span><span class="p">]:</span>
</span><span id="__span-0-340"><a id="__codelineno-0-340" name="__codelineno-0-340"></a><span class="w"> </span><span class="sd">"""Get list of open documents."""</span>
</span><span id="__span-0-341"><a id="__codelineno-0-341" name="__codelineno-0-341"></a> <span class="n">result</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">execute_python</span><span class="p">(</span>
</span><span id="__span-0-342"><a id="__codelineno-0-342" name="__codelineno-0-342"></a><span class="w"> </span><span class="sd">"""</span>
</span><span id="__span-0-343"><a id="__codelineno-0-343" name="__codelineno-0-343"></a><span class="sd">_result_ = []</span>
</span><span id="__span-0-344"><a id="__codelineno-0-344" name="__codelineno-0-344"></a><span class="sd">for doc in FreeCAD.listDocuments().values():</span>
</span><span id="__span-0-345"><a id="__codelineno-0-345" name="__codelineno-0-345"></a><span class="sd"> _result_.append({</span>
</span><span id="__span-0-346"><a id="__codelineno-0-346" name="__codelineno-0-346"></a><span class="sd"> "name": doc.Name,</span>
</span><span id="__span-0-347"><a id="__codelineno-0-347" name="__codelineno-0-347"></a><span class="sd"> "label": doc.Label,</span>
</span><span id="__span-0-348"><a id="__codelineno-0-348" name="__codelineno-0-348"></a><span class="sd"> "path": doc.FileName or None,</span>
</span><span id="__span-0-349"><a id="__codelineno-0-349" name="__codelineno-0-349"></a><span class="sd"> "objects": [obj.Name for obj in doc.Objects],</span>
</span><span id="__span-0-350"><a id="__codelineno-0-350" name="__codelineno-0-350"></a><span class="sd"> "is_modified": doc.Modified if hasattr(doc, "Modified") else False,</span>
</span><span id="__span-0-351"><a id="__codelineno-0-351" name="__codelineno-0-351"></a><span class="sd"> "active_object": doc.ActiveObject.Name if doc.ActiveObject else None,</span>
</span><span id="__span-0-352"><a id="__codelineno-0-352" name="__codelineno-0-352"></a><span class="sd"> })</span>
</span><span id="__span-0-353"><a id="__codelineno-0-353" name="__codelineno-0-353"></a><span class="sd">"""</span>
</span><span id="__span-0-354"><a id="__codelineno-0-354" name="__codelineno-0-354"></a> <span class="p">)</span>
</span><span id="__span-0-355"><a id="__codelineno-0-355" name="__codelineno-0-355"></a>
</span><span id="__span-0-356"><a id="__codelineno-0-356" name="__codelineno-0-356"></a> <span class="k">if</span> <span class="n">result</span><span class="o">.</span><span class="n">success</span> <span class="ow">and</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">:</span>
</span><span id="__span-0-357"><a id="__codelineno-0-357" name="__codelineno-0-357"></a> <span class="k">return</span> <span class="p">[</span><span class="n">DocumentInfo</span><span class="p">(</span><span class="o">**</span><span class="n">doc</span><span class="p">)</span> <span class="k">for</span> <span class="n">doc</span> <span class="ow">in</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">]</span>
</span><span id="__span-0-358"><a id="__codelineno-0-358" name="__codelineno-0-358"></a> <span class="k">return</span> <span class="p">[]</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> </div> </div> <div class="doc doc-object doc-function"> <h6 id="freecad_mcp.bridge.socket.SocketBridge.get_freecad_version" class="doc doc-heading"> <code class="highlight language-python"><span class="n">get_freecad_version</span><span class="p">()</span></code> <span class="doc doc-labels"> <small class="doc doc-label doc-label-async"><code>async</code></small> </span> <a href="#freecad_mcp.bridge.socket.SocketBridge.get_freecad_version" class="headerlink" title="Permanent link">¶</a></h6> <div class="doc doc-contents "> <p>Get FreeCAD version information.</p> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/socket.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-1008">1008</a></span>
<span class="normal"><a href="#__codelineno-0-1009">1009</a></span>
<span class="normal"><a href="#__codelineno-0-1010">1010</a></span>
<span class="normal"><a href="#__codelineno-0-1011">1011</a></span>
<span class="normal"><a href="#__codelineno-0-1012">1012</a></span>
<span class="normal"><a href="#__codelineno-0-1013">1013</a></span>
<span class="normal"><a href="#__codelineno-0-1014">1014</a></span>
<span class="normal"><a href="#__codelineno-0-1015">1015</a></span>
<span class="normal"><a href="#__codelineno-0-1016">1016</a></span>
<span class="normal"><a href="#__codelineno-0-1017">1017</a></span>
<span class="normal"><a href="#__codelineno-0-1018">1018</a></span>
<span class="normal"><a href="#__codelineno-0-1019">1019</a></span>
<span class="normal"><a href="#__codelineno-0-1020">1020</a></span>
<span class="normal"><a href="#__codelineno-0-1021">1021</a></span>
<span class="normal"><a href="#__codelineno-0-1022">1022</a></span>
<span class="normal"><a href="#__codelineno-0-1023">1023</a></span>
<span class="normal"><a href="#__codelineno-0-1024">1024</a></span>
<span class="normal"><a href="#__codelineno-0-1025">1025</a></span>
<span class="normal"><a href="#__codelineno-0-1026">1026</a></span>
<span class="normal"><a href="#__codelineno-0-1027">1027</a></span>
<span class="normal"><a href="#__codelineno-0-1028">1028</a></span>
<span class="normal"><a href="#__codelineno-0-1029">1029</a></span>
<span class="normal"><a href="#__codelineno-0-1030">1030</a></span>
<span class="normal"><a href="#__codelineno-0-1031">1031</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-1008"><a id="__codelineno-0-1008" name="__codelineno-0-1008"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">get_freecad_version</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Any</span><span class="p">]:</span>
</span><span id="__span-0-1009"><a id="__codelineno-0-1009" name="__codelineno-0-1009"></a><span class="w"> </span><span class="sd">"""Get FreeCAD version information."""</span>
</span><span id="__span-0-1010"><a id="__codelineno-0-1010" name="__codelineno-0-1010"></a> <span class="n">code</span> <span class="o">=</span> <span class="s2">"""</span>
</span><span id="__span-0-1011"><a id="__codelineno-0-1011" name="__codelineno-0-1011"></a><span class="s2">import sys</span>
</span><span id="__span-0-1012"><a id="__codelineno-0-1012" name="__codelineno-0-1012"></a><span class="s2">_result_ = {</span>
</span><span id="__span-0-1013"><a id="__codelineno-0-1013" name="__codelineno-0-1013"></a><span class="s2"> "version": ".".join(str(x) for x in FreeCAD.Version()[:3]),</span>
</span><span id="__span-0-1014"><a id="__codelineno-0-1014" name="__codelineno-0-1014"></a><span class="s2"> "version_tuple": FreeCAD.Version()[:3],</span>
</span><span id="__span-0-1015"><a id="__codelineno-0-1015" name="__codelineno-0-1015"></a><span class="s2"> "build_date": FreeCAD.Version()[3] if len(FreeCAD.Version()) &gt; 3 else "unknown",</span>
</span><span id="__span-0-1016"><a id="__codelineno-0-1016" name="__codelineno-0-1016"></a><span class="s2"> "python_version": sys.version,</span>
</span><span id="__span-0-1017"><a id="__codelineno-0-1017" name="__codelineno-0-1017"></a><span class="s2"> "gui_available": FreeCAD.GuiUp,</span>
</span><span id="__span-0-1018"><a id="__codelineno-0-1018" name="__codelineno-0-1018"></a><span class="s2">}</span>
</span><span id="__span-0-1019"><a id="__codelineno-0-1019" name="__codelineno-0-1019"></a><span class="s2">"""</span>
</span><span id="__span-0-1020"><a id="__codelineno-0-1020" name="__codelineno-0-1020"></a> <span class="n">result</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">execute_python</span><span class="p">(</span><span class="n">code</span><span class="p">)</span>
</span><span id="__span-0-1021"><a id="__codelineno-0-1021" name="__codelineno-0-1021"></a>
</span><span id="__span-0-1022"><a id="__codelineno-0-1022" name="__codelineno-0-1022"></a> <span class="k">if</span> <span class="n">result</span><span class="o">.</span><span class="n">success</span> <span class="ow">and</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">:</span>
</span><span id="__span-0-1023"><a id="__codelineno-0-1023" name="__codelineno-0-1023"></a> <span class="k">return</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span>
</span><span id="__span-0-1024"><a id="__codelineno-0-1024" name="__codelineno-0-1024"></a>
</span><span id="__span-0-1025"><a id="__codelineno-0-1025" name="__codelineno-0-1025"></a> <span class="k">return</span> <span class="p">{</span>
</span><span id="__span-0-1026"><a id="__codelineno-0-1026" name="__codelineno-0-1026"></a> <span class="s2">"version"</span><span class="p">:</span> <span class="s2">"unknown"</span><span class="p">,</span>
</span><span id="__span-0-1027"><a id="__codelineno-0-1027" name="__codelineno-0-1027"></a> <span class="s2">"version_tuple"</span><span class="p">:</span> <span class="p">[],</span>
</span><span id="__span-0-1028"><a id="__codelineno-0-1028" name="__codelineno-0-1028"></a> <span class="s2">"build_date"</span><span class="p">:</span> <span class="s2">"unknown"</span><span class="p">,</span>
</span><span id="__span-0-1029"><a id="__codelineno-0-1029" name="__codelineno-0-1029"></a> <span class="s2">"python_version"</span><span class="p">:</span> <span class="s2">""</span><span class="p">,</span>
</span><span id="__span-0-1030"><a id="__codelineno-0-1030" name="__codelineno-0-1030"></a> <span class="s2">"gui_available"</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span>
</span><span id="__span-0-1031"><a id="__codelineno-0-1031" name="__codelineno-0-1031"></a> <span class="p">}</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> </div> </div> <div class="doc doc-object doc-function"> <h6 id="freecad_mcp.bridge.socket.SocketBridge.get_macros" class="doc doc-heading"> <code class="highlight language-python"><span class="n">get_macros</span><span class="p">()</span></code> <span class="doc doc-labels"> <small class="doc doc-label doc-label-async"><code>async</code></small> </span> <a href="#freecad_mcp.bridge.socket.SocketBridge.get_macros" class="headerlink" title="Permanent link">¶</a></h6> <div class="doc doc-contents "> <p>Get list of available macros.</p> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/socket.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-815">815</a></span>
<span class="normal"><a href="#__codelineno-0-816">816</a></span>
<span class="normal"><a href="#__codelineno-0-817">817</a></span>
<span class="normal"><a href="#__codelineno-0-818">818</a></span>
<span class="normal"><a href="#__codelineno-0-819">819</a></span>
<span class="normal"><a href="#__codelineno-0-820">820</a></span>
<span class="normal"><a href="#__codelineno-0-821">821</a></span>
<span class="normal"><a href="#__codelineno-0-822">822</a></span>
<span class="normal"><a href="#__codelineno-0-823">823</a></span>
<span class="normal"><a href="#__codelineno-0-824">824</a></span>
<span class="normal"><a href="#__codelineno-0-825">825</a></span>
<span class="normal"><a href="#__codelineno-0-826">826</a></span>
<span class="normal"><a href="#__codelineno-0-827">827</a></span>
<span class="normal"><a href="#__codelineno-0-828">828</a></span>
<span class="normal"><a href="#__codelineno-0-829">829</a></span>
<span class="normal"><a href="#__codelineno-0-830">830</a></span>
<span class="normal"><a href="#__codelineno-0-831">831</a></span>
<span class="normal"><a href="#__codelineno-0-832">832</a></span>
<span class="normal"><a href="#__codelineno-0-833">833</a></span>
<span class="normal"><a href="#__codelineno-0-834">834</a></span>
<span class="normal"><a href="#__codelineno-0-835">835</a></span>
<span class="normal"><a href="#__codelineno-0-836">836</a></span>
<span class="normal"><a href="#__codelineno-0-837">837</a></span>
<span class="normal"><a href="#__codelineno-0-838">838</a></span>
<span class="normal"><a href="#__codelineno-0-839">839</a></span>
<span class="normal"><a href="#__codelineno-0-840">840</a></span>
<span class="normal"><a href="#__codelineno-0-841">841</a></span>
<span class="normal"><a href="#__codelineno-0-842">842</a></span>
<span class="normal"><a href="#__codelineno-0-843">843</a></span>
<span class="normal"><a href="#__codelineno-0-844">844</a></span>
<span class="normal"><a href="#__codelineno-0-845">845</a></span>
<span class="normal"><a href="#__codelineno-0-846">846</a></span>
<span class="normal"><a href="#__codelineno-0-847">847</a></span>
<span class="normal"><a href="#__codelineno-0-848">848</a></span>
<span class="normal"><a href="#__codelineno-0-849">849</a></span>
<span class="normal"><a href="#__codelineno-0-850">850</a></span>
<span class="normal"><a href="#__codelineno-0-851">851</a></span>
<span class="normal"><a href="#__codelineno-0-852">852</a></span>
<span class="normal"><a href="#__codelineno-0-853">853</a></span>
<span class="normal"><a href="#__codelineno-0-854">854</a></span>
<span class="normal"><a href="#__codelineno-0-855">855</a></span>
<span class="normal"><a href="#__codelineno-0-856">856</a></span>
<span class="normal"><a href="#__codelineno-0-857">857</a></span>
<span class="normal"><a href="#__codelineno-0-858">858</a></span>
<span class="normal"><a href="#__codelineno-0-859">859</a></span>
<span class="normal"><a href="#__codelineno-0-860">860</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-815"><a id="__codelineno-0-815" name="__codelineno-0-815"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">get_macros</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">list</span><span class="p">[</span><span class="n">MacroInfo</span><span class="p">]:</span>
</span><span id="__span-0-816"><a id="__codelineno-0-816" name="__codelineno-0-816"></a><span class="w"> </span><span class="sd">"""Get list of available macros."""</span>
</span><span id="__span-0-817"><a id="__codelineno-0-817" name="__codelineno-0-817"></a> <span class="n">code</span> <span class="o">=</span> <span class="s2">"""</span>
</span><span id="__span-0-818"><a id="__codelineno-0-818" name="__codelineno-0-818"></a><span class="s2">import os</span>
</span><span id="__span-0-819"><a id="__codelineno-0-819" name="__codelineno-0-819"></a>
</span><span id="__span-0-820"><a id="__codelineno-0-820" name="__codelineno-0-820"></a><span class="s2">macro_paths = []</span>
</span><span id="__span-0-821"><a id="__codelineno-0-821" name="__codelineno-0-821"></a>
</span><span id="__span-0-822"><a id="__codelineno-0-822" name="__codelineno-0-822"></a><span class="s2">user_path = FreeCAD.getUserMacroDir(True)</span>
</span><span id="__span-0-823"><a id="__codelineno-0-823" name="__codelineno-0-823"></a><span class="s2">if os.path.exists(user_path):</span>
</span><span id="__span-0-824"><a id="__codelineno-0-824" name="__codelineno-0-824"></a><span class="s2"> macro_paths.append(("user", user_path))</span>
</span><span id="__span-0-825"><a id="__codelineno-0-825" name="__codelineno-0-825"></a>
</span><span id="__span-0-826"><a id="__codelineno-0-826" name="__codelineno-0-826"></a><span class="s2">system_path = FreeCAD.getResourceDir() + "Macro"</span>
</span><span id="__span-0-827"><a id="__codelineno-0-827" name="__codelineno-0-827"></a><span class="s2">if os.path.exists(system_path):</span>
</span><span id="__span-0-828"><a id="__codelineno-0-828" name="__codelineno-0-828"></a><span class="s2"> macro_paths.append(("system", system_path))</span>
</span><span id="__span-0-829"><a id="__codelineno-0-829" name="__codelineno-0-829"></a>
</span><span id="__span-0-830"><a id="__codelineno-0-830" name="__codelineno-0-830"></a><span class="s2">macros = []</span>
</span><span id="__span-0-831"><a id="__codelineno-0-831" name="__codelineno-0-831"></a><span class="s2">for source, path in macro_paths:</span>
</span><span id="__span-0-832"><a id="__codelineno-0-832" name="__codelineno-0-832"></a><span class="s2"> for filename in os.listdir(path):</span>
</span><span id="__span-0-833"><a id="__codelineno-0-833" name="__codelineno-0-833"></a><span class="s2"> if filename.endswith(".FCMacro"):</span>
</span><span id="__span-0-834"><a id="__codelineno-0-834" name="__codelineno-0-834"></a><span class="s2"> macro_file = os.path.join(path, filename)</span>
</span><span id="__span-0-835"><a id="__codelineno-0-835" name="__codelineno-0-835"></a><span class="s2"> description = ""</span>
</span><span id="__span-0-836"><a id="__codelineno-0-836" name="__codelineno-0-836"></a><span class="s2"> try:</span>
</span><span id="__span-0-837"><a id="__codelineno-0-837" name="__codelineno-0-837"></a><span class="s2"> with open(macro_file, "r") as f:</span>
</span><span id="__span-0-838"><a id="__codelineno-0-838" name="__codelineno-0-838"></a><span class="s2"> for line in f:</span>
</span><span id="__span-0-839"><a id="__codelineno-0-839" name="__codelineno-0-839"></a><span class="s2"> if line.startswith("#"):</span>
</span><span id="__span-0-840"><a id="__codelineno-0-840" name="__codelineno-0-840"></a><span class="s2"> desc = line.lstrip("#").strip()</span>
</span><span id="__span-0-841"><a id="__codelineno-0-841" name="__codelineno-0-841"></a><span class="s2"> if desc and not desc.startswith("!") and not desc.startswith("-*-"):</span>
</span><span id="__span-0-842"><a id="__codelineno-0-842" name="__codelineno-0-842"></a><span class="s2"> description = desc</span>
</span><span id="__span-0-843"><a id="__codelineno-0-843" name="__codelineno-0-843"></a><span class="s2"> break</span>
</span><span id="__span-0-844"><a id="__codelineno-0-844" name="__codelineno-0-844"></a><span class="s2"> except Exception:</span>
</span><span id="__span-0-845"><a id="__codelineno-0-845" name="__codelineno-0-845"></a><span class="s2"> pass</span>
</span><span id="__span-0-846"><a id="__codelineno-0-846" name="__codelineno-0-846"></a>
</span><span id="__span-0-847"><a id="__codelineno-0-847" name="__codelineno-0-847"></a><span class="s2"> macros.append({</span>
</span><span id="__span-0-848"><a id="__codelineno-0-848" name="__codelineno-0-848"></a><span class="s2"> "name": filename[:-8],</span>
</span><span id="__span-0-849"><a id="__codelineno-0-849" name="__codelineno-0-849"></a><span class="s2"> "path": macro_file,</span>
</span><span id="__span-0-850"><a id="__codelineno-0-850" name="__codelineno-0-850"></a><span class="s2"> "description": description,</span>
</span><span id="__span-0-851"><a id="__codelineno-0-851" name="__codelineno-0-851"></a><span class="s2"> "is_system": source == "system",</span>
</span><span id="__span-0-852"><a id="__codelineno-0-852" name="__codelineno-0-852"></a><span class="s2"> })</span>
</span><span id="__span-0-853"><a id="__codelineno-0-853" name="__codelineno-0-853"></a>
</span><span id="__span-0-854"><a id="__codelineno-0-854" name="__codelineno-0-854"></a><span class="s2">_result_ = macros</span>
</span><span id="__span-0-855"><a id="__codelineno-0-855" name="__codelineno-0-855"></a><span class="s2">"""</span>
</span><span id="__span-0-856"><a id="__codelineno-0-856" name="__codelineno-0-856"></a> <span class="n">result</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">execute_python</span><span class="p">(</span><span class="n">code</span><span class="p">)</span>
</span><span id="__span-0-857"><a id="__codelineno-0-857" name="__codelineno-0-857"></a>
</span><span id="__span-0-858"><a id="__codelineno-0-858" name="__codelineno-0-858"></a> <span class="k">if</span> <span class="n">result</span><span class="o">.</span><span class="n">success</span> <span class="ow">and</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">:</span>
</span><span id="__span-0-859"><a id="__codelineno-0-859" name="__codelineno-0-859"></a> <span class="k">return</span> <span class="p">[</span><span class="n">MacroInfo</span><span class="p">(</span><span class="o">**</span><span class="n">m</span><span class="p">)</span> <span class="k">for</span> <span class="n">m</span> <span class="ow">in</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">]</span>
</span><span id="__span-0-860"><a id="__codelineno-0-860" name="__codelineno-0-860"></a> <span class="k">return</span> <span class="p">[]</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> </div> </div> <div class="doc doc-object doc-function"> <h6 id="freecad_mcp.bridge.socket.SocketBridge.get_object" class="doc doc-heading"> <code class="highlight language-python"><span class="n">get_object</span><span class="p">(</span><span class="n">obj_name</span><span class="p">,</span> <span class="n">doc_name</span><span class="o">=</span><span class="kc">None</span><span class="p">)</span></code> <span class="doc doc-labels"> <small class="doc doc-label doc-label-async"><code>async</code></small> </span> <a href="#freecad_mcp.bridge.socket.SocketBridge.get_object" class="headerlink" title="Permanent link">¶</a></h6> <div class="doc doc-contents "> <p>Get detailed object information.</p> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/socket.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-513">513</a></span>
<span class="normal"><a href="#__codelineno-0-514">514</a></span>
<span class="normal"><a href="#__codelineno-0-515">515</a></span>
<span class="normal"><a href="#__codelineno-0-516">516</a></span>
<span class="normal"><a href="#__codelineno-0-517">517</a></span>
<span class="normal"><a href="#__codelineno-0-518">518</a></span>
<span class="normal"><a href="#__codelineno-0-519">519</a></span>
<span class="normal"><a href="#__codelineno-0-520">520</a></span>
<span class="normal"><a href="#__codelineno-0-521">521</a></span>
<span class="normal"><a href="#__codelineno-0-522">522</a></span>
<span class="normal"><a href="#__codelineno-0-523">523</a></span>
<span class="normal"><a href="#__codelineno-0-524">524</a></span>
<span class="normal"><a href="#__codelineno-0-525">525</a></span>
<span class="normal"><a href="#__codelineno-0-526">526</a></span>
<span class="normal"><a href="#__codelineno-0-527">527</a></span>
<span class="normal"><a href="#__codelineno-0-528">528</a></span>
<span class="normal"><a href="#__codelineno-0-529">529</a></span>
<span class="normal"><a href="#__codelineno-0-530">530</a></span>
<span class="normal"><a href="#__codelineno-0-531">531</a></span>
<span class="normal"><a href="#__codelineno-0-532">532</a></span>
<span class="normal"><a href="#__codelineno-0-533">533</a></span>
<span class="normal"><a href="#__codelineno-0-534">534</a></span>
<span class="normal"><a href="#__codelineno-0-535">535</a></span>
<span class="normal"><a href="#__codelineno-0-536">536</a></span>
<span class="normal"><a href="#__codelineno-0-537">537</a></span>
<span class="normal"><a href="#__codelineno-0-538">538</a></span>
<span class="normal"><a href="#__codelineno-0-539">539</a></span>
<span class="normal"><a href="#__codelineno-0-540">540</a></span>
<span class="normal"><a href="#__codelineno-0-541">541</a></span>
<span class="normal"><a href="#__codelineno-0-542">542</a></span>
<span class="normal"><a href="#__codelineno-0-543">543</a></span>
<span class="normal"><a href="#__codelineno-0-544">544</a></span>
<span class="normal"><a href="#__codelineno-0-545">545</a></span>
<span class="normal"><a href="#__codelineno-0-546">546</a></span>
<span class="normal"><a href="#__codelineno-0-547">547</a></span>
<span class="normal"><a href="#__codelineno-0-548">548</a></span>
<span class="normal"><a href="#__codelineno-0-549">549</a></span>
<span class="normal"><a href="#__codelineno-0-550">550</a></span>
<span class="normal"><a href="#__codelineno-0-551">551</a></span>
<span class="normal"><a href="#__codelineno-0-552">552</a></span>
<span class="normal"><a href="#__codelineno-0-553">553</a></span>
<span class="normal"><a href="#__codelineno-0-554">554</a></span>
<span class="normal"><a href="#__codelineno-0-555">555</a></span>
<span class="normal"><a href="#__codelineno-0-556">556</a></span>
<span class="normal"><a href="#__codelineno-0-557">557</a></span>
<span class="normal"><a href="#__codelineno-0-558">558</a></span>
<span class="normal"><a href="#__codelineno-0-559">559</a></span>
<span class="normal"><a href="#__codelineno-0-560">560</a></span>
<span class="normal"><a href="#__codelineno-0-561">561</a></span>
<span class="normal"><a href="#__codelineno-0-562">562</a></span>
<span class="normal"><a href="#__codelineno-0-563">563</a></span>
<span class="normal"><a href="#__codelineno-0-564">564</a></span>
<span class="normal"><a href="#__codelineno-0-565">565</a></span>
<span class="normal"><a href="#__codelineno-0-566">566</a></span>
<span class="normal"><a href="#__codelineno-0-567">567</a></span>
<span class="normal"><a href="#__codelineno-0-568">568</a></span>
<span class="normal"><a href="#__codelineno-0-569">569</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-513"><a id="__codelineno-0-513" name="__codelineno-0-513"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">get_object</span><span class="p">(</span>
</span><span id="__span-0-514"><a id="__codelineno-0-514" name="__codelineno-0-514"></a> <span class="bp">self</span><span class="p">,</span>
</span><span id="__span-0-515"><a id="__codelineno-0-515" name="__codelineno-0-515"></a> <span class="n">obj_name</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span>
</span><span id="__span-0-516"><a id="__codelineno-0-516" name="__codelineno-0-516"></a> <span class="n">doc_name</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-517"><a id="__codelineno-0-517" name="__codelineno-0-517"></a> <span class="p">)</span> <span class="o">-&gt;</span> <span class="n">ObjectInfo</span><span class="p">:</span>
</span><span id="__span-0-518"><a id="__codelineno-0-518" name="__codelineno-0-518"></a><span class="w"> </span><span class="sd">"""Get detailed object information."""</span>
</span><span id="__span-0-519"><a id="__codelineno-0-519" name="__codelineno-0-519"></a> <span class="n">code</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">"""</span>
</span><span id="__span-0-520"><a id="__codelineno-0-520" name="__codelineno-0-520"></a><span class="s2">doc = FreeCAD.ActiveDocument if </span><span class="si">{</span><span class="n">doc_name</span><span class="si">!r}</span><span class="s2"> is None else FreeCAD.getDocument(</span><span class="si">{</span><span class="n">doc_name</span><span class="si">!r}</span><span class="s2">)</span>
</span><span id="__span-0-521"><a id="__codelineno-0-521" name="__codelineno-0-521"></a><span class="s2">if doc is None:</span>
</span><span id="__span-0-522"><a id="__codelineno-0-522" name="__codelineno-0-522"></a><span class="s2"> raise ValueError("No document found")</span>
</span><span id="__span-0-523"><a id="__codelineno-0-523" name="__codelineno-0-523"></a>
</span><span id="__span-0-524"><a id="__codelineno-0-524" name="__codelineno-0-524"></a><span class="s2">obj = doc.getObject(</span><span class="si">{</span><span class="n">obj_name</span><span class="si">!r}</span><span class="s2">)</span>
</span><span id="__span-0-525"><a id="__codelineno-0-525" name="__codelineno-0-525"></a><span class="s2">if obj is None:</span>
</span><span id="__span-0-526"><a id="__codelineno-0-526" name="__codelineno-0-526"></a><span class="s2"> raise ValueError(f"Object not found: </span><span class="si">{</span><span class="n">obj_name</span><span class="si">!r}</span><span class="s2">")</span>
</span><span id="__span-0-527"><a id="__codelineno-0-527" name="__codelineno-0-527"></a>
</span><span id="__span-0-528"><a id="__codelineno-0-528" name="__codelineno-0-528"></a><span class="s2">props = </span><span class="se">{{}}</span>
</span><span id="__span-0-529"><a id="__codelineno-0-529" name="__codelineno-0-529"></a><span class="s2">for prop in obj.PropertiesList:</span>
</span><span id="__span-0-530"><a id="__codelineno-0-530" name="__codelineno-0-530"></a><span class="s2"> try:</span>
</span><span id="__span-0-531"><a id="__codelineno-0-531" name="__codelineno-0-531"></a><span class="s2"> val = getattr(obj, prop)</span>
</span><span id="__span-0-532"><a id="__codelineno-0-532" name="__codelineno-0-532"></a><span class="s2"> if hasattr(val, '__class__') and val.__class__.__module__ != 'builtins':</span>
</span><span id="__span-0-533"><a id="__codelineno-0-533" name="__codelineno-0-533"></a><span class="s2"> val = str(val)</span>
</span><span id="__span-0-534"><a id="__codelineno-0-534" name="__codelineno-0-534"></a><span class="s2"> props[prop] = val</span>
</span><span id="__span-0-535"><a id="__codelineno-0-535" name="__codelineno-0-535"></a><span class="s2"> except Exception:</span>
</span><span id="__span-0-536"><a id="__codelineno-0-536" name="__codelineno-0-536"></a><span class="s2"> props[prop] = "&lt;unreadable&gt;"</span>
</span><span id="__span-0-537"><a id="__codelineno-0-537" name="__codelineno-0-537"></a>
</span><span id="__span-0-538"><a id="__codelineno-0-538" name="__codelineno-0-538"></a><span class="s2">shape_info = None</span>
</span><span id="__span-0-539"><a id="__codelineno-0-539" name="__codelineno-0-539"></a><span class="s2">if hasattr(obj, "Shape"):</span>
</span><span id="__span-0-540"><a id="__codelineno-0-540" name="__codelineno-0-540"></a><span class="s2"> shape = obj.Shape</span>
</span><span id="__span-0-541"><a id="__codelineno-0-541" name="__codelineno-0-541"></a><span class="s2"> shape_info = </span><span class="se">{{</span>
</span><span id="__span-0-542"><a id="__codelineno-0-542" name="__codelineno-0-542"></a><span class="s2"> "shape_type": shape.ShapeType,</span>
</span><span id="__span-0-543"><a id="__codelineno-0-543" name="__codelineno-0-543"></a><span class="s2"> "volume": shape.Volume if hasattr(shape, "Volume") else None,</span>
</span><span id="__span-0-544"><a id="__codelineno-0-544" name="__codelineno-0-544"></a><span class="s2"> "area": shape.Area if hasattr(shape, "Area") else None,</span>
</span><span id="__span-0-545"><a id="__codelineno-0-545" name="__codelineno-0-545"></a><span class="s2"> "is_valid": shape.isValid(),</span>
</span><span id="__span-0-546"><a id="__codelineno-0-546" name="__codelineno-0-546"></a><span class="s2"> "is_closed": shape.isClosed() if hasattr(shape, "isClosed") else False,</span>
</span><span id="__span-0-547"><a id="__codelineno-0-547" name="__codelineno-0-547"></a><span class="s2"> "vertex_count": len(shape.Vertexes) if hasattr(shape, "Vertexes") else 0,</span>
</span><span id="__span-0-548"><a id="__codelineno-0-548" name="__codelineno-0-548"></a><span class="s2"> "edge_count": len(shape.Edges) if hasattr(shape, "Edges") else 0,</span>
</span><span id="__span-0-549"><a id="__codelineno-0-549" name="__codelineno-0-549"></a><span class="s2"> "face_count": len(shape.Faces) if hasattr(shape, "Faces") else 0,</span>
</span><span id="__span-0-550"><a id="__codelineno-0-550" name="__codelineno-0-550"></a><span class="s2"> </span><span class="se">}}</span>
</span><span id="__span-0-551"><a id="__codelineno-0-551" name="__codelineno-0-551"></a>
</span><span id="__span-0-552"><a id="__codelineno-0-552" name="__codelineno-0-552"></a><span class="s2">_result_ = </span><span class="se">{{</span>
</span><span id="__span-0-553"><a id="__codelineno-0-553" name="__codelineno-0-553"></a><span class="s2"> "name": obj.Name,</span>
</span><span id="__span-0-554"><a id="__codelineno-0-554" name="__codelineno-0-554"></a><span class="s2"> "label": obj.Label,</span>
</span><span id="__span-0-555"><a id="__codelineno-0-555" name="__codelineno-0-555"></a><span class="s2"> "type_id": obj.TypeId,</span>
</span><span id="__span-0-556"><a id="__codelineno-0-556" name="__codelineno-0-556"></a><span class="s2"> "properties": props,</span>
</span><span id="__span-0-557"><a id="__codelineno-0-557" name="__codelineno-0-557"></a><span class="s2"> "shape_info": shape_info,</span>
</span><span id="__span-0-558"><a id="__codelineno-0-558" name="__codelineno-0-558"></a><span class="s2"> "children": [c.Name for c in obj.OutList] if hasattr(obj, "OutList") else [],</span>
</span><span id="__span-0-559"><a id="__codelineno-0-559" name="__codelineno-0-559"></a><span class="s2"> "parents": [p.Name for p in obj.InList] if hasattr(obj, "InList") else [],</span>
</span><span id="__span-0-560"><a id="__codelineno-0-560" name="__codelineno-0-560"></a><span class="s2"> "visibility": obj.ViewObject.Visibility if hasattr(obj, "ViewObject") and obj.ViewObject else True,</span>
</span><span id="__span-0-561"><a id="__codelineno-0-561" name="__codelineno-0-561"></a><span class="se">}}</span>
</span><span id="__span-0-562"><a id="__codelineno-0-562" name="__codelineno-0-562"></a><span class="s2">"""</span>
</span><span id="__span-0-563"><a id="__codelineno-0-563" name="__codelineno-0-563"></a> <span class="n">result</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">execute_python</span><span class="p">(</span><span class="n">code</span><span class="p">)</span>
</span><span id="__span-0-564"><a id="__codelineno-0-564" name="__codelineno-0-564"></a>
</span><span id="__span-0-565"><a id="__codelineno-0-565" name="__codelineno-0-565"></a> <span class="k">if</span> <span class="n">result</span><span class="o">.</span><span class="n">success</span> <span class="ow">and</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">:</span>
</span><span id="__span-0-566"><a id="__codelineno-0-566" name="__codelineno-0-566"></a> <span class="k">return</span> <span class="n">ObjectInfo</span><span class="p">(</span><span class="o">**</span><span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">)</span>
</span><span id="__span-0-567"><a id="__codelineno-0-567" name="__codelineno-0-567"></a>
</span><span id="__span-0-568"><a id="__codelineno-0-568" name="__codelineno-0-568"></a> <span class="n">error_msg</span> <span class="o">=</span> <span class="n">result</span><span class="o">.</span><span class="n">error_traceback</span> <span class="ow">or</span> <span class="s2">"Failed to get object"</span>
</span><span id="__span-0-569"><a id="__codelineno-0-569" name="__codelineno-0-569"></a> <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="n">error_msg</span><span class="p">)</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> </div> </div> <div class="doc doc-object doc-function"> <h6 id="freecad_mcp.bridge.socket.SocketBridge.get_objects" class="doc doc-heading"> <code class="highlight language-python"><span class="n">get_objects</span><span class="p">(</span><span class="n">doc_name</span><span class="o">=</span><span class="kc">None</span><span class="p">)</span></code> <span class="doc doc-labels"> <small class="doc doc-label doc-label-async"><code>async</code></small> </span> <a href="#freecad_mcp.bridge.socket.SocketBridge.get_objects" class="headerlink" title="Permanent link">¶</a></h6> <div class="doc doc-contents "> <p>Get all objects in a document.</p> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/socket.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-486">486</a></span>
<span class="normal"><a href="#__codelineno-0-487">487</a></span>
<span class="normal"><a href="#__codelineno-0-488">488</a></span>
<span class="normal"><a href="#__codelineno-0-489">489</a></span>
<span class="normal"><a href="#__codelineno-0-490">490</a></span>
<span class="normal"><a href="#__codelineno-0-491">491</a></span>
<span class="normal"><a href="#__codelineno-0-492">492</a></span>
<span class="normal"><a href="#__codelineno-0-493">493</a></span>
<span class="normal"><a href="#__codelineno-0-494">494</a></span>
<span class="normal"><a href="#__codelineno-0-495">495</a></span>
<span class="normal"><a href="#__codelineno-0-496">496</a></span>
<span class="normal"><a href="#__codelineno-0-497">497</a></span>
<span class="normal"><a href="#__codelineno-0-498">498</a></span>
<span class="normal"><a href="#__codelineno-0-499">499</a></span>
<span class="normal"><a href="#__codelineno-0-500">500</a></span>
<span class="normal"><a href="#__codelineno-0-501">501</a></span>
<span class="normal"><a href="#__codelineno-0-502">502</a></span>
<span class="normal"><a href="#__codelineno-0-503">503</a></span>
<span class="normal"><a href="#__codelineno-0-504">504</a></span>
<span class="normal"><a href="#__codelineno-0-505">505</a></span>
<span class="normal"><a href="#__codelineno-0-506">506</a></span>
<span class="normal"><a href="#__codelineno-0-507">507</a></span>
<span class="normal"><a href="#__codelineno-0-508">508</a></span>
<span class="normal"><a href="#__codelineno-0-509">509</a></span>
<span class="normal"><a href="#__codelineno-0-510">510</a></span>
<span class="normal"><a href="#__codelineno-0-511">511</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-486"><a id="__codelineno-0-486" name="__codelineno-0-486"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">get_objects</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">doc_name</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">list</span><span class="p">[</span><span class="n">ObjectInfo</span><span class="p">]:</span>
</span><span id="__span-0-487"><a id="__codelineno-0-487" name="__codelineno-0-487"></a><span class="w"> </span><span class="sd">"""Get all objects in a document."""</span>
</span><span id="__span-0-488"><a id="__codelineno-0-488" name="__codelineno-0-488"></a> <span class="n">code</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">"""</span>
</span><span id="__span-0-489"><a id="__codelineno-0-489" name="__codelineno-0-489"></a><span class="s2">doc = FreeCAD.ActiveDocument if </span><span class="si">{</span><span class="n">doc_name</span><span class="si">!r}</span><span class="s2"> is None else FreeCAD.getDocument(</span><span class="si">{</span><span class="n">doc_name</span><span class="si">!r}</span><span class="s2">)</span>
</span><span id="__span-0-490"><a id="__codelineno-0-490" name="__codelineno-0-490"></a><span class="s2">if doc is None:</span>
</span><span id="__span-0-491"><a id="__codelineno-0-491" name="__codelineno-0-491"></a><span class="s2"> raise ValueError("No document found")</span>
</span><span id="__span-0-492"><a id="__codelineno-0-492" name="__codelineno-0-492"></a>
</span><span id="__span-0-493"><a id="__codelineno-0-493" name="__codelineno-0-493"></a><span class="s2">objects = []</span>
</span><span id="__span-0-494"><a id="__codelineno-0-494" name="__codelineno-0-494"></a><span class="s2">for obj in doc.Objects:</span>
</span><span id="__span-0-495"><a id="__codelineno-0-495" name="__codelineno-0-495"></a><span class="s2"> obj_info = </span><span class="se">{{</span>
</span><span id="__span-0-496"><a id="__codelineno-0-496" name="__codelineno-0-496"></a><span class="s2"> "name": obj.Name,</span>
</span><span id="__span-0-497"><a id="__codelineno-0-497" name="__codelineno-0-497"></a><span class="s2"> "label": obj.Label,</span>
</span><span id="__span-0-498"><a id="__codelineno-0-498" name="__codelineno-0-498"></a><span class="s2"> "type_id": obj.TypeId,</span>
</span><span id="__span-0-499"><a id="__codelineno-0-499" name="__codelineno-0-499"></a><span class="s2"> "visibility": obj.ViewObject.Visibility if hasattr(obj, "ViewObject") and obj.ViewObject else True,</span>
</span><span id="__span-0-500"><a id="__codelineno-0-500" name="__codelineno-0-500"></a><span class="s2"> "children": [c.Name for c in obj.OutList] if hasattr(obj, "OutList") else [],</span>
</span><span id="__span-0-501"><a id="__codelineno-0-501" name="__codelineno-0-501"></a><span class="s2"> "parents": [p.Name for p in obj.InList] if hasattr(obj, "InList") else [],</span>
</span><span id="__span-0-502"><a id="__codelineno-0-502" name="__codelineno-0-502"></a><span class="s2"> </span><span class="se">}}</span>
</span><span id="__span-0-503"><a id="__codelineno-0-503" name="__codelineno-0-503"></a><span class="s2"> objects.append(obj_info)</span>
</span><span id="__span-0-504"><a id="__codelineno-0-504" name="__codelineno-0-504"></a>
</span><span id="__span-0-505"><a id="__codelineno-0-505" name="__codelineno-0-505"></a><span class="s2">_result_ = objects</span>
</span><span id="__span-0-506"><a id="__codelineno-0-506" name="__codelineno-0-506"></a><span class="s2">"""</span>
</span><span id="__span-0-507"><a id="__codelineno-0-507" name="__codelineno-0-507"></a> <span class="n">result</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">execute_python</span><span class="p">(</span><span class="n">code</span><span class="p">)</span>
</span><span id="__span-0-508"><a id="__codelineno-0-508" name="__codelineno-0-508"></a>
</span><span id="__span-0-509"><a id="__codelineno-0-509" name="__codelineno-0-509"></a> <span class="k">if</span> <span class="n">result</span><span class="o">.</span><span class="n">success</span> <span class="ow">and</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">:</span>
</span><span id="__span-0-510"><a id="__codelineno-0-510" name="__codelineno-0-510"></a> <span class="k">return</span> <span class="p">[</span><span class="n">ObjectInfo</span><span class="p">(</span><span class="o">**</span><span class="n">obj</span><span class="p">)</span> <span class="k">for</span> <span class="n">obj</span> <span class="ow">in</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">]</span>
</span><span id="__span-0-511"><a id="__codelineno-0-511" name="__codelineno-0-511"></a> <span class="k">return</span> <span class="p">[]</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> </div> </div> <div class="doc doc-object doc-function"> <h6 id="freecad_mcp.bridge.socket.SocketBridge.get_screenshot" class="doc doc-heading"> <code class="highlight language-python"><span class="n">get_screenshot</span><span class="p">(</span><span class="n">view_angle</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">width</span><span class="o">=</span><span class="mi">800</span><span class="p">,</span> <span class="n">height</span><span class="o">=</span><span class="mi">600</span><span class="p">,</span> <span class="n">doc_name</span><span class="o">=</span><span class="kc">None</span><span class="p">)</span></code> <span class="doc doc-labels"> <small class="doc doc-label doc-label-async"><code>async</code></small> </span> <a href="#freecad_mcp.bridge.socket.SocketBridge.get_screenshot" class="headerlink" title="Permanent link">¶</a></h6> <div class="doc doc-contents "> <p>Capture a screenshot of the 3D view via socket.</p> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/socket.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-679">679</a></span>
<span class="normal"><a href="#__codelineno-0-680">680</a></span>
<span class="normal"><a href="#__codelineno-0-681">681</a></span>
<span class="normal"><a href="#__codelineno-0-682">682</a></span>
<span class="normal"><a href="#__codelineno-0-683">683</a></span>
<span class="normal"><a href="#__codelineno-0-684">684</a></span>
<span class="normal"><a href="#__codelineno-0-685">685</a></span>
<span class="normal"><a href="#__codelineno-0-686">686</a></span>
<span class="normal"><a href="#__codelineno-0-687">687</a></span>
<span class="normal"><a href="#__codelineno-0-688">688</a></span>
<span class="normal"><a href="#__codelineno-0-689">689</a></span>
<span class="normal"><a href="#__codelineno-0-690">690</a></span>
<span class="normal"><a href="#__codelineno-0-691">691</a></span>
<span class="normal"><a href="#__codelineno-0-692">692</a></span>
<span class="normal"><a href="#__codelineno-0-693">693</a></span>
<span class="normal"><a href="#__codelineno-0-694">694</a></span>
<span class="normal"><a href="#__codelineno-0-695">695</a></span>
<span class="normal"><a href="#__codelineno-0-696">696</a></span>
<span class="normal"><a href="#__codelineno-0-697">697</a></span>
<span class="normal"><a href="#__codelineno-0-698">698</a></span>
<span class="normal"><a href="#__codelineno-0-699">699</a></span>
<span class="normal"><a href="#__codelineno-0-700">700</a></span>
<span class="normal"><a href="#__codelineno-0-701">701</a></span>
<span class="normal"><a href="#__codelineno-0-702">702</a></span>
<span class="normal"><a href="#__codelineno-0-703">703</a></span>
<span class="normal"><a href="#__codelineno-0-704">704</a></span>
<span class="normal"><a href="#__codelineno-0-705">705</a></span>
<span class="normal"><a href="#__codelineno-0-706">706</a></span>
<span class="normal"><a href="#__codelineno-0-707">707</a></span>
<span class="normal"><a href="#__codelineno-0-708">708</a></span>
<span class="normal"><a href="#__codelineno-0-709">709</a></span>
<span class="normal"><a href="#__codelineno-0-710">710</a></span>
<span class="normal"><a href="#__codelineno-0-711">711</a></span>
<span class="normal"><a href="#__codelineno-0-712">712</a></span>
<span class="normal"><a href="#__codelineno-0-713">713</a></span>
<span class="normal"><a href="#__codelineno-0-714">714</a></span>
<span class="normal"><a href="#__codelineno-0-715">715</a></span>
<span class="normal"><a href="#__codelineno-0-716">716</a></span>
<span class="normal"><a href="#__codelineno-0-717">717</a></span>
<span class="normal"><a href="#__codelineno-0-718">718</a></span>
<span class="normal"><a href="#__codelineno-0-719">719</a></span>
<span class="normal"><a href="#__codelineno-0-720">720</a></span>
<span class="normal"><a href="#__codelineno-0-721">721</a></span>
<span class="normal"><a href="#__codelineno-0-722">722</a></span>
<span class="normal"><a href="#__codelineno-0-723">723</a></span>
<span class="normal"><a href="#__codelineno-0-724">724</a></span>
<span class="normal"><a href="#__codelineno-0-725">725</a></span>
<span class="normal"><a href="#__codelineno-0-726">726</a></span>
<span class="normal"><a href="#__codelineno-0-727">727</a></span>
<span class="normal"><a href="#__codelineno-0-728">728</a></span>
<span class="normal"><a href="#__codelineno-0-729">729</a></span>
<span class="normal"><a href="#__codelineno-0-730">730</a></span>
<span class="normal"><a href="#__codelineno-0-731">731</a></span>
<span class="normal"><a href="#__codelineno-0-732">732</a></span>
<span class="normal"><a href="#__codelineno-0-733">733</a></span>
<span class="normal"><a href="#__codelineno-0-734">734</a></span>
<span class="normal"><a href="#__codelineno-0-735">735</a></span>
<span class="normal"><a href="#__codelineno-0-736">736</a></span>
<span class="normal"><a href="#__codelineno-0-737">737</a></span>
<span class="normal"><a href="#__codelineno-0-738">738</a></span>
<span class="normal"><a href="#__codelineno-0-739">739</a></span>
<span class="normal"><a href="#__codelineno-0-740">740</a></span>
<span class="normal"><a href="#__codelineno-0-741">741</a></span>
<span class="normal"><a href="#__codelineno-0-742">742</a></span>
<span class="normal"><a href="#__codelineno-0-743">743</a></span>
<span class="normal"><a href="#__codelineno-0-744">744</a></span>
<span class="normal"><a href="#__codelineno-0-745">745</a></span>
<span class="normal"><a href="#__codelineno-0-746">746</a></span>
<span class="normal"><a href="#__codelineno-0-747">747</a></span>
<span class="normal"><a href="#__codelineno-0-748">748</a></span>
<span class="normal"><a href="#__codelineno-0-749">749</a></span>
<span class="normal"><a href="#__codelineno-0-750">750</a></span>
<span class="normal"><a href="#__codelineno-0-751">751</a></span>
<span class="normal"><a href="#__codelineno-0-752">752</a></span>
<span class="normal"><a href="#__codelineno-0-753">753</a></span>
<span class="normal"><a href="#__codelineno-0-754">754</a></span>
<span class="normal"><a href="#__codelineno-0-755">755</a></span>
<span class="normal"><a href="#__codelineno-0-756">756</a></span>
<span class="normal"><a href="#__codelineno-0-757">757</a></span>
<span class="normal"><a href="#__codelineno-0-758">758</a></span>
<span class="normal"><a href="#__codelineno-0-759">759</a></span>
<span class="normal"><a href="#__codelineno-0-760">760</a></span>
<span class="normal"><a href="#__codelineno-0-761">761</a></span>
<span class="normal"><a href="#__codelineno-0-762">762</a></span>
<span class="normal"><a href="#__codelineno-0-763">763</a></span>
<span class="normal"><a href="#__codelineno-0-764">764</a></span>
<span class="normal"><a href="#__codelineno-0-765">765</a></span>
<span class="normal"><a href="#__codelineno-0-766">766</a></span>
<span class="normal"><a href="#__codelineno-0-767">767</a></span>
<span class="normal"><a href="#__codelineno-0-768">768</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-679"><a id="__codelineno-0-679" name="__codelineno-0-679"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">get_screenshot</span><span class="p">(</span>
</span><span id="__span-0-680"><a id="__codelineno-0-680" name="__codelineno-0-680"></a> <span class="bp">self</span><span class="p">,</span>
</span><span id="__span-0-681"><a id="__codelineno-0-681" name="__codelineno-0-681"></a> <span class="n">view_angle</span><span class="p">:</span> <span class="n">ViewAngle</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-682"><a id="__codelineno-0-682" name="__codelineno-0-682"></a> <span class="n">width</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">800</span><span class="p">,</span>
</span><span id="__span-0-683"><a id="__codelineno-0-683" name="__codelineno-0-683"></a> <span class="n">height</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">600</span><span class="p">,</span>
</span><span id="__span-0-684"><a id="__codelineno-0-684" name="__codelineno-0-684"></a> <span class="n">doc_name</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-685"><a id="__codelineno-0-685" name="__codelineno-0-685"></a> <span class="p">)</span> <span class="o">-&gt;</span> <span class="n">ScreenshotResult</span><span class="p">:</span>
</span><span id="__span-0-686"><a id="__codelineno-0-686" name="__codelineno-0-686"></a><span class="w"> </span><span class="sd">"""Capture a screenshot of the 3D view via socket."""</span>
</span><span id="__span-0-687"><a id="__codelineno-0-687" name="__codelineno-0-687"></a> <span class="n">view_angle_str</span> <span class="o">=</span> <span class="n">view_angle</span><span class="o">.</span><span class="n">value</span> <span class="k">if</span> <span class="n">view_angle</span> <span class="k">else</span> <span class="s2">"Isometric"</span>
</span><span id="__span-0-688"><a id="__codelineno-0-688" name="__codelineno-0-688"></a> <span class="n">code</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">"""</span>
</span><span id="__span-0-689"><a id="__codelineno-0-689" name="__codelineno-0-689"></a><span class="s2">import base64</span>
</span><span id="__span-0-690"><a id="__codelineno-0-690" name="__codelineno-0-690"></a><span class="s2">import tempfile</span>
</span><span id="__span-0-691"><a id="__codelineno-0-691" name="__codelineno-0-691"></a><span class="s2">import os</span>
</span><span id="__span-0-692"><a id="__codelineno-0-692" name="__codelineno-0-692"></a>
</span><span id="__span-0-693"><a id="__codelineno-0-693" name="__codelineno-0-693"></a><span class="s2">doc = FreeCAD.ActiveDocument if </span><span class="si">{</span><span class="n">doc_name</span><span class="si">!r}</span><span class="s2"> is None else FreeCAD.getDocument(</span><span class="si">{</span><span class="n">doc_name</span><span class="si">!r}</span><span class="s2">)</span>
</span><span id="__span-0-694"><a id="__codelineno-0-694" name="__codelineno-0-694"></a><span class="s2">if doc is None:</span>
</span><span id="__span-0-695"><a id="__codelineno-0-695" name="__codelineno-0-695"></a><span class="s2"> raise ValueError("No document found")</span>
</span><span id="__span-0-696"><a id="__codelineno-0-696" name="__codelineno-0-696"></a>
</span><span id="__span-0-697"><a id="__codelineno-0-697" name="__codelineno-0-697"></a><span class="s2"># Check if GUI is available</span>
</span><span id="__span-0-698"><a id="__codelineno-0-698" name="__codelineno-0-698"></a><span class="s2">if not FreeCAD.GuiUp:</span>
</span><span id="__span-0-699"><a id="__codelineno-0-699" name="__codelineno-0-699"></a><span class="s2"> raise RuntimeError("GUI not available")</span>
</span><span id="__span-0-700"><a id="__codelineno-0-700" name="__codelineno-0-700"></a>
</span><span id="__span-0-701"><a id="__codelineno-0-701" name="__codelineno-0-701"></a><span class="s2">view = FreeCADGui.ActiveDocument.ActiveView</span>
</span><span id="__span-0-702"><a id="__codelineno-0-702" name="__codelineno-0-702"></a><span class="s2">if view is None:</span>
</span><span id="__span-0-703"><a id="__codelineno-0-703" name="__codelineno-0-703"></a><span class="s2"> raise ValueError("No active view")</span>
</span><span id="__span-0-704"><a id="__codelineno-0-704" name="__codelineno-0-704"></a>
</span><span id="__span-0-705"><a id="__codelineno-0-705" name="__codelineno-0-705"></a><span class="s2"># Check view type</span>
</span><span id="__span-0-706"><a id="__codelineno-0-706" name="__codelineno-0-706"></a><span class="s2">view_type = view.__class__.__name__</span>
</span><span id="__span-0-707"><a id="__codelineno-0-707" name="__codelineno-0-707"></a><span class="s2">if view_type not in ["View3DInventor", "View3DInventorPy"]:</span>
</span><span id="__span-0-708"><a id="__codelineno-0-708" name="__codelineno-0-708"></a><span class="s2"> raise ValueError(f"Cannot capture screenshot from </span><span class="se">{{</span><span class="s2">view_type</span><span class="se">}}</span><span class="s2"> view")</span>
</span><span id="__span-0-709"><a id="__codelineno-0-709" name="__codelineno-0-709"></a>
</span><span id="__span-0-710"><a id="__codelineno-0-710" name="__codelineno-0-710"></a><span class="s2"># Set view angle</span>
</span><span id="__span-0-711"><a id="__codelineno-0-711" name="__codelineno-0-711"></a><span class="s2">view_type_str = </span><span class="si">{</span><span class="n">view_angle_str</span><span class="si">!r}</span>
</span><span id="__span-0-712"><a id="__codelineno-0-712" name="__codelineno-0-712"></a><span class="s2">if view_type_str == "FitAll":</span>
</span><span id="__span-0-713"><a id="__codelineno-0-713" name="__codelineno-0-713"></a><span class="s2"> view.fitAll()</span>
</span><span id="__span-0-714"><a id="__codelineno-0-714" name="__codelineno-0-714"></a><span class="s2">elif view_type_str == "Isometric":</span>
</span><span id="__span-0-715"><a id="__codelineno-0-715" name="__codelineno-0-715"></a><span class="s2"> view.viewIsometric()</span>
</span><span id="__span-0-716"><a id="__codelineno-0-716" name="__codelineno-0-716"></a><span class="s2">elif view_type_str == "Front":</span>
</span><span id="__span-0-717"><a id="__codelineno-0-717" name="__codelineno-0-717"></a><span class="s2"> view.viewFront()</span>
</span><span id="__span-0-718"><a id="__codelineno-0-718" name="__codelineno-0-718"></a><span class="s2">elif view_type_str == "Back":</span>
</span><span id="__span-0-719"><a id="__codelineno-0-719" name="__codelineno-0-719"></a><span class="s2"> view.viewRear()</span>
</span><span id="__span-0-720"><a id="__codelineno-0-720" name="__codelineno-0-720"></a><span class="s2">elif view_type_str == "Top":</span>
</span><span id="__span-0-721"><a id="__codelineno-0-721" name="__codelineno-0-721"></a><span class="s2"> view.viewTop()</span>
</span><span id="__span-0-722"><a id="__codelineno-0-722" name="__codelineno-0-722"></a><span class="s2">elif view_type_str == "Bottom":</span>
</span><span id="__span-0-723"><a id="__codelineno-0-723" name="__codelineno-0-723"></a><span class="s2"> view.viewBottom()</span>
</span><span id="__span-0-724"><a id="__codelineno-0-724" name="__codelineno-0-724"></a><span class="s2">elif view_type_str == "Left":</span>
</span><span id="__span-0-725"><a id="__codelineno-0-725" name="__codelineno-0-725"></a><span class="s2"> view.viewLeft()</span>
</span><span id="__span-0-726"><a id="__codelineno-0-726" name="__codelineno-0-726"></a><span class="s2">elif view_type_str == "Right":</span>
</span><span id="__span-0-727"><a id="__codelineno-0-727" name="__codelineno-0-727"></a><span class="s2"> view.viewRight()</span>
</span><span id="__span-0-728"><a id="__codelineno-0-728" name="__codelineno-0-728"></a>
</span><span id="__span-0-729"><a id="__codelineno-0-729" name="__codelineno-0-729"></a><span class="s2"># Save to temp file and read</span>
</span><span id="__span-0-730"><a id="__codelineno-0-730" name="__codelineno-0-730"></a><span class="s2">with tempfile.NamedTemporaryFile(suffix=".png", delete=False) as f:</span>
</span><span id="__span-0-731"><a id="__codelineno-0-731" name="__codelineno-0-731"></a><span class="s2"> temp_path = f.name</span>
</span><span id="__span-0-732"><a id="__codelineno-0-732" name="__codelineno-0-732"></a>
</span><span id="__span-0-733"><a id="__codelineno-0-733" name="__codelineno-0-733"></a><span class="s2">view.saveImage(temp_path, </span><span class="si">{</span><span class="n">width</span><span class="si">}</span><span class="s2">, </span><span class="si">{</span><span class="n">height</span><span class="si">}</span><span class="s2">, "Current")</span>
</span><span id="__span-0-734"><a id="__codelineno-0-734" name="__codelineno-0-734"></a>
</span><span id="__span-0-735"><a id="__codelineno-0-735" name="__codelineno-0-735"></a><span class="s2">with open(temp_path, "rb") as f:</span>
</span><span id="__span-0-736"><a id="__codelineno-0-736" name="__codelineno-0-736"></a><span class="s2"> image_data = base64.b64encode(f.read()).decode("utf-8")</span>
</span><span id="__span-0-737"><a id="__codelineno-0-737" name="__codelineno-0-737"></a>
</span><span id="__span-0-738"><a id="__codelineno-0-738" name="__codelineno-0-738"></a><span class="s2">os.unlink(temp_path)</span>
</span><span id="__span-0-739"><a id="__codelineno-0-739" name="__codelineno-0-739"></a>
</span><span id="__span-0-740"><a id="__codelineno-0-740" name="__codelineno-0-740"></a><span class="s2">_result_ = </span><span class="se">{{</span>
</span><span id="__span-0-741"><a id="__codelineno-0-741" name="__codelineno-0-741"></a><span class="s2"> "success": True,</span>
</span><span id="__span-0-742"><a id="__codelineno-0-742" name="__codelineno-0-742"></a><span class="s2"> "data": image_data,</span>
</span><span id="__span-0-743"><a id="__codelineno-0-743" name="__codelineno-0-743"></a><span class="s2"> "format": "png",</span>
</span><span id="__span-0-744"><a id="__codelineno-0-744" name="__codelineno-0-744"></a><span class="s2"> "width": </span><span class="si">{</span><span class="n">width</span><span class="si">}</span><span class="s2">,</span>
</span><span id="__span-0-745"><a id="__codelineno-0-745" name="__codelineno-0-745"></a><span class="s2"> "height": </span><span class="si">{</span><span class="n">height</span><span class="si">}</span><span class="s2">,</span>
</span><span id="__span-0-746"><a id="__codelineno-0-746" name="__codelineno-0-746"></a><span class="se">}}</span>
</span><span id="__span-0-747"><a id="__codelineno-0-747" name="__codelineno-0-747"></a><span class="s2">"""</span>
</span><span id="__span-0-748"><a id="__codelineno-0-748" name="__codelineno-0-748"></a> <span class="n">result</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">execute_python</span><span class="p">(</span><span class="n">code</span><span class="p">)</span>
</span><span id="__span-0-749"><a id="__codelineno-0-749" name="__codelineno-0-749"></a>
</span><span id="__span-0-750"><a id="__codelineno-0-750" name="__codelineno-0-750"></a> <span class="k">if</span> <span class="n">result</span><span class="o">.</span><span class="n">success</span> <span class="ow">and</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">:</span>
</span><span id="__span-0-751"><a id="__codelineno-0-751" name="__codelineno-0-751"></a> <span class="k">return</span> <span class="n">ScreenshotResult</span><span class="p">(</span>
</span><span id="__span-0-752"><a id="__codelineno-0-752" name="__codelineno-0-752"></a> <span class="n">success</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span>
</span><span id="__span-0-753"><a id="__codelineno-0-753" name="__codelineno-0-753"></a> <span class="n">data</span><span class="o">=</span><span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">[</span><span class="s2">"data"</span><span class="p">],</span>
</span><span id="__span-0-754"><a id="__codelineno-0-754" name="__codelineno-0-754"></a> <span class="nb">format</span><span class="o">=</span><span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">[</span><span class="s2">"format"</span><span class="p">],</span>
</span><span id="__span-0-755"><a id="__codelineno-0-755" name="__codelineno-0-755"></a> <span class="n">width</span><span class="o">=</span><span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">[</span><span class="s2">"width"</span><span class="p">],</span>
</span><span id="__span-0-756"><a id="__codelineno-0-756" name="__codelineno-0-756"></a> <span class="n">height</span><span class="o">=</span><span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">[</span><span class="s2">"height"</span><span class="p">],</span>
</span><span id="__span-0-757"><a id="__codelineno-0-757" name="__codelineno-0-757"></a> <span class="n">view_angle</span><span class="o">=</span><span class="n">view_angle</span><span class="p">,</span>
</span><span id="__span-0-758"><a id="__codelineno-0-758" name="__codelineno-0-758"></a> <span class="p">)</span>
</span><span id="__span-0-759"><a id="__codelineno-0-759" name="__codelineno-0-759"></a>
</span><span id="__span-0-760"><a id="__codelineno-0-760" name="__codelineno-0-760"></a> <span class="k">return</span> <span class="n">ScreenshotResult</span><span class="p">(</span>
</span><span id="__span-0-761"><a id="__codelineno-0-761" name="__codelineno-0-761"></a> <span class="n">success</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
</span><span id="__span-0-762"><a id="__codelineno-0-762" name="__codelineno-0-762"></a> <span class="n">error</span><span class="o">=</span><span class="n">result</span><span class="o">.</span><span class="n">error_traceback</span>
</span><span id="__span-0-763"><a id="__codelineno-0-763" name="__codelineno-0-763"></a> <span class="ow">or</span> <span class="n">result</span><span class="o">.</span><span class="n">stderr</span>
</span><span id="__span-0-764"><a id="__codelineno-0-764" name="__codelineno-0-764"></a> <span class="ow">or</span> <span class="s2">"Failed to capture screenshot"</span><span class="p">,</span>
</span><span id="__span-0-765"><a id="__codelineno-0-765" name="__codelineno-0-765"></a> <span class="n">width</span><span class="o">=</span><span class="n">width</span><span class="p">,</span>
</span><span id="__span-0-766"><a id="__codelineno-0-766" name="__codelineno-0-766"></a> <span class="n">height</span><span class="o">=</span><span class="n">height</span><span class="p">,</span>
</span><span id="__span-0-767"><a id="__codelineno-0-767" name="__codelineno-0-767"></a> <span class="n">view_angle</span><span class="o">=</span><span class="n">view_angle</span><span class="p">,</span>
</span><span id="__span-0-768"><a id="__codelineno-0-768" name="__codelineno-0-768"></a> <span class="p">)</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> </div> </div> <div class="doc doc-object doc-function"> <h6 id="freecad_mcp.bridge.socket.SocketBridge.get_status" class="doc doc-heading"> <code class="highlight language-python"><span class="n">get_status</span><span class="p">()</span></code> <span class="doc doc-labels"> <small class="doc doc-label doc-label-async"><code>async</code></small> </span> <a href="#freecad_mcp.bridge.socket.SocketBridge.get_status" class="headerlink" title="Permanent link">¶</a></h6> <div class="doc doc-contents "> <p>Get detailed connection status.</p> <p><span class="doc-section-title">Returns:</span></p> <table> <thead> <tr> <th>Type</th> <th>Description</th> </tr> </thead> <tbody> <tr class="doc-section-item"> <td> <code><a class="autorefs autorefs-internal" title="ConnectionStatus
dataclass
(freecad_mcp.bridge.base.ConnectionStatus)" href="#freecad_mcp.bridge.base.ConnectionStatus">ConnectionStatus</a></code> </td> <td> <div class="doc-md-description"> <p>ConnectionStatus with full status information.</p> </div> </td> </tr> </tbody> </table> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/socket.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-228">228</a></span>
<span class="normal"><a href="#__codelineno-0-229">229</a></span>
<span class="normal"><a href="#__codelineno-0-230">230</a></span>
<span class="normal"><a href="#__codelineno-0-231">231</a></span>
<span class="normal"><a href="#__codelineno-0-232">232</a></span>
<span class="normal"><a href="#__codelineno-0-233">233</a></span>
<span class="normal"><a href="#__codelineno-0-234">234</a></span>
<span class="normal"><a href="#__codelineno-0-235">235</a></span>
<span class="normal"><a href="#__codelineno-0-236">236</a></span>
<span class="normal"><a href="#__codelineno-0-237">237</a></span>
<span class="normal"><a href="#__codelineno-0-238">238</a></span>
<span class="normal"><a href="#__codelineno-0-239">239</a></span>
<span class="normal"><a href="#__codelineno-0-240">240</a></span>
<span class="normal"><a href="#__codelineno-0-241">241</a></span>
<span class="normal"><a href="#__codelineno-0-242">242</a></span>
<span class="normal"><a href="#__codelineno-0-243">243</a></span>
<span class="normal"><a href="#__codelineno-0-244">244</a></span>
<span class="normal"><a href="#__codelineno-0-245">245</a></span>
<span class="normal"><a href="#__codelineno-0-246">246</a></span>
<span class="normal"><a href="#__codelineno-0-247">247</a></span>
<span class="normal"><a href="#__codelineno-0-248">248</a></span>
<span class="normal"><a href="#__codelineno-0-249">249</a></span>
<span class="normal"><a href="#__codelineno-0-250">250</a></span>
<span class="normal"><a href="#__codelineno-0-251">251</a></span>
<span class="normal"><a href="#__codelineno-0-252">252</a></span>
<span class="normal"><a href="#__codelineno-0-253">253</a></span>
<span class="normal"><a href="#__codelineno-0-254">254</a></span>
<span class="normal"><a href="#__codelineno-0-255">255</a></span>
<span class="normal"><a href="#__codelineno-0-256">256</a></span>
<span class="normal"><a href="#__codelineno-0-257">257</a></span>
<span class="normal"><a href="#__codelineno-0-258">258</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-228"><a id="__codelineno-0-228" name="__codelineno-0-228"></a><span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">get_status</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">ConnectionStatus</span><span class="p">:</span>
</span><span id="__span-0-229"><a id="__codelineno-0-229" name="__codelineno-0-229"></a><span class="w"> </span><span class="sd">"""Get detailed connection status.</span>
</span><span id="__span-0-230"><a id="__codelineno-0-230" name="__codelineno-0-230"></a>
</span><span id="__span-0-231"><a id="__codelineno-0-231" name="__codelineno-0-231"></a><span class="sd"> Returns:</span>
</span><span id="__span-0-232"><a id="__codelineno-0-232" name="__codelineno-0-232"></a><span class="sd"> ConnectionStatus with full status information.</span>
</span><span id="__span-0-233"><a id="__codelineno-0-233" name="__codelineno-0-233"></a><span class="sd"> """</span>
</span><span id="__span-0-234"><a id="__codelineno-0-234" name="__codelineno-0-234"></a> <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">_connected</span><span class="p">:</span>
</span><span id="__span-0-235"><a id="__codelineno-0-235" name="__codelineno-0-235"></a> <span class="k">return</span> <span class="n">ConnectionStatus</span><span class="p">(</span>
</span><span id="__span-0-236"><a id="__codelineno-0-236" name="__codelineno-0-236"></a> <span class="n">connected</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
</span><span id="__span-0-237"><a id="__codelineno-0-237" name="__codelineno-0-237"></a> <span class="n">mode</span><span class="o">=</span><span class="s2">"socket"</span><span class="p">,</span>
</span><span id="__span-0-238"><a id="__codelineno-0-238" name="__codelineno-0-238"></a> <span class="n">error</span><span class="o">=</span><span class="s2">"Not connected"</span><span class="p">,</span>
</span><span id="__span-0-239"><a id="__codelineno-0-239" name="__codelineno-0-239"></a> <span class="p">)</span>
</span><span id="__span-0-240"><a id="__codelineno-0-240" name="__codelineno-0-240"></a>
</span><span id="__span-0-241"><a id="__codelineno-0-241" name="__codelineno-0-241"></a> <span class="k">try</span><span class="p">:</span>
</span><span id="__span-0-242"><a id="__codelineno-0-242" name="__codelineno-0-242"></a> <span class="n">ping_ms</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">ping</span><span class="p">()</span>
</span><span id="__span-0-243"><a id="__codelineno-0-243" name="__codelineno-0-243"></a> <span class="n">version_info</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_freecad_version</span><span class="p">()</span>
</span><span id="__span-0-244"><a id="__codelineno-0-244" name="__codelineno-0-244"></a> <span class="n">gui_available</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">is_gui_available</span><span class="p">()</span>
</span><span id="__span-0-245"><a id="__codelineno-0-245" name="__codelineno-0-245"></a>
</span><span id="__span-0-246"><a id="__codelineno-0-246" name="__codelineno-0-246"></a> <span class="k">return</span> <span class="n">ConnectionStatus</span><span class="p">(</span>
</span><span id="__span-0-247"><a id="__codelineno-0-247" name="__codelineno-0-247"></a> <span class="n">connected</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span>
</span><span id="__span-0-248"><a id="__codelineno-0-248" name="__codelineno-0-248"></a> <span class="n">mode</span><span class="o">=</span><span class="s2">"socket"</span><span class="p">,</span>
</span><span id="__span-0-249"><a id="__codelineno-0-249" name="__codelineno-0-249"></a> <span class="n">freecad_version</span><span class="o">=</span><span class="n">version_info</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"version"</span><span class="p">,</span> <span class="s2">"unknown"</span><span class="p">),</span>
</span><span id="__span-0-250"><a id="__codelineno-0-250" name="__codelineno-0-250"></a> <span class="n">gui_available</span><span class="o">=</span><span class="n">gui_available</span><span class="p">,</span>
</span><span id="__span-0-251"><a id="__codelineno-0-251" name="__codelineno-0-251"></a> <span class="n">last_ping_ms</span><span class="o">=</span><span class="n">ping_ms</span><span class="p">,</span>
</span><span id="__span-0-252"><a id="__codelineno-0-252" name="__codelineno-0-252"></a> <span class="p">)</span>
</span><span id="__span-0-253"><a id="__codelineno-0-253" name="__codelineno-0-253"></a> <span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
</span><span id="__span-0-254"><a id="__codelineno-0-254" name="__codelineno-0-254"></a> <span class="k">return</span> <span class="n">ConnectionStatus</span><span class="p">(</span>
</span><span id="__span-0-255"><a id="__codelineno-0-255" name="__codelineno-0-255"></a> <span class="n">connected</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
</span><span id="__span-0-256"><a id="__codelineno-0-256" name="__codelineno-0-256"></a> <span class="n">mode</span><span class="o">=</span><span class="s2">"socket"</span><span class="p">,</span>
</span><span id="__span-0-257"><a id="__codelineno-0-257" name="__codelineno-0-257"></a> <span class="n">error</span><span class="o">=</span><span class="nb">str</span><span class="p">(</span><span class="n">e</span><span class="p">),</span>
</span><span id="__span-0-258"><a id="__codelineno-0-258" name="__codelineno-0-258"></a> <span class="p">)</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> </div> </div> <div class="doc doc-object doc-function"> <h6 id="freecad_mcp.bridge.socket.SocketBridge.get_workbenches" class="doc doc-heading"> <code class="highlight language-python"><span class="n">get_workbenches</span><span class="p">()</span></code> <span class="doc doc-labels"> <small class="doc doc-label doc-label-async"><code>async</code></small> </span> <a href="#freecad_mcp.bridge.socket.SocketBridge.get_workbenches" class="headerlink" title="Permanent link">¶</a></h6> <div class="doc doc-contents "> <p>Get list of available workbenches.</p> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/socket.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-951">951</a></span>
<span class="normal"><a href="#__codelineno-0-952">952</a></span>
<span class="normal"><a href="#__codelineno-0-953">953</a></span>
<span class="normal"><a href="#__codelineno-0-954">954</a></span>
<span class="normal"><a href="#__codelineno-0-955">955</a></span>
<span class="normal"><a href="#__codelineno-0-956">956</a></span>
<span class="normal"><a href="#__codelineno-0-957">957</a></span>
<span class="normal"><a href="#__codelineno-0-958">958</a></span>
<span class="normal"><a href="#__codelineno-0-959">959</a></span>
<span class="normal"><a href="#__codelineno-0-960">960</a></span>
<span class="normal"><a href="#__codelineno-0-961">961</a></span>
<span class="normal"><a href="#__codelineno-0-962">962</a></span>
<span class="normal"><a href="#__codelineno-0-963">963</a></span>
<span class="normal"><a href="#__codelineno-0-964">964</a></span>
<span class="normal"><a href="#__codelineno-0-965">965</a></span>
<span class="normal"><a href="#__codelineno-0-966">966</a></span>
<span class="normal"><a href="#__codelineno-0-967">967</a></span>
<span class="normal"><a href="#__codelineno-0-968">968</a></span>
<span class="normal"><a href="#__codelineno-0-969">969</a></span>
<span class="normal"><a href="#__codelineno-0-970">970</a></span>
<span class="normal"><a href="#__codelineno-0-971">971</a></span>
<span class="normal"><a href="#__codelineno-0-972">972</a></span>
<span class="normal"><a href="#__codelineno-0-973">973</a></span>
<span class="normal"><a href="#__codelineno-0-974">974</a></span>
<span class="normal"><a href="#__codelineno-0-975">975</a></span>
<span class="normal"><a href="#__codelineno-0-976">976</a></span>
<span class="normal"><a href="#__codelineno-0-977">977</a></span>
<span class="normal"><a href="#__codelineno-0-978">978</a></span>
<span class="normal"><a href="#__codelineno-0-979">979</a></span>
<span class="normal"><a href="#__codelineno-0-980">980</a></span>
<span class="normal"><a href="#__codelineno-0-981">981</a></span>
<span class="normal"><a href="#__codelineno-0-982">982</a></span>
<span class="normal"><a href="#__codelineno-0-983">983</a></span>
<span class="normal"><a href="#__codelineno-0-984">984</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-951"><a id="__codelineno-0-951" name="__codelineno-0-951"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">get_workbenches</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">list</span><span class="p">[</span><span class="n">WorkbenchInfo</span><span class="p">]:</span>
</span><span id="__span-0-952"><a id="__codelineno-0-952" name="__codelineno-0-952"></a><span class="w"> </span><span class="sd">"""Get list of available workbenches."""</span>
</span><span id="__span-0-953"><a id="__codelineno-0-953" name="__codelineno-0-953"></a> <span class="n">code</span> <span class="o">=</span> <span class="s2">"""</span>
</span><span id="__span-0-954"><a id="__codelineno-0-954" name="__codelineno-0-954"></a><span class="s2">workbenches = []</span>
</span><span id="__span-0-955"><a id="__codelineno-0-955" name="__codelineno-0-955"></a><span class="s2">active_wb = FreeCADGui.activeWorkbench() if FreeCAD.GuiUp else None</span>
</span><span id="__span-0-956"><a id="__codelineno-0-956" name="__codelineno-0-956"></a><span class="s2">active_name = active_wb.__class__.__name__ if active_wb else None</span>
</span><span id="__span-0-957"><a id="__codelineno-0-957" name="__codelineno-0-957"></a>
</span><span id="__span-0-958"><a id="__codelineno-0-958" name="__codelineno-0-958"></a><span class="s2">if FreeCAD.GuiUp:</span>
</span><span id="__span-0-959"><a id="__codelineno-0-959" name="__codelineno-0-959"></a><span class="s2"> for name in FreeCADGui.listWorkbenches():</span>
</span><span id="__span-0-960"><a id="__codelineno-0-960" name="__codelineno-0-960"></a><span class="s2"> wb = FreeCADGui.getWorkbench(name)</span>
</span><span id="__span-0-961"><a id="__codelineno-0-961" name="__codelineno-0-961"></a><span class="s2"> workbenches.append({</span>
</span><span id="__span-0-962"><a id="__codelineno-0-962" name="__codelineno-0-962"></a><span class="s2"> "name": name,</span>
</span><span id="__span-0-963"><a id="__codelineno-0-963" name="__codelineno-0-963"></a><span class="s2"> "label": wb.MenuText if hasattr(wb, "MenuText") else name,</span>
</span><span id="__span-0-964"><a id="__codelineno-0-964" name="__codelineno-0-964"></a><span class="s2"> "icon": wb.Icon if hasattr(wb, "Icon") else "",</span>
</span><span id="__span-0-965"><a id="__codelineno-0-965" name="__codelineno-0-965"></a><span class="s2"> "is_active": name == active_name,</span>
</span><span id="__span-0-966"><a id="__codelineno-0-966" name="__codelineno-0-966"></a><span class="s2"> })</span>
</span><span id="__span-0-967"><a id="__codelineno-0-967" name="__codelineno-0-967"></a><span class="s2">else:</span>
</span><span id="__span-0-968"><a id="__codelineno-0-968" name="__codelineno-0-968"></a><span class="s2"> common = ["StartWorkbench", "PartWorkbench", "PartDesignWorkbench",</span>
</span><span id="__span-0-969"><a id="__codelineno-0-969" name="__codelineno-0-969"></a><span class="s2"> "DraftWorkbench", "SketcherWorkbench", "MeshWorkbench"]</span>
</span><span id="__span-0-970"><a id="__codelineno-0-970" name="__codelineno-0-970"></a><span class="s2"> for name in common:</span>
</span><span id="__span-0-971"><a id="__codelineno-0-971" name="__codelineno-0-971"></a><span class="s2"> workbenches.append({</span>
</span><span id="__span-0-972"><a id="__codelineno-0-972" name="__codelineno-0-972"></a><span class="s2"> "name": name,</span>
</span><span id="__span-0-973"><a id="__codelineno-0-973" name="__codelineno-0-973"></a><span class="s2"> "label": name.replace("Workbench", ""),</span>
</span><span id="__span-0-974"><a id="__codelineno-0-974" name="__codelineno-0-974"></a><span class="s2"> "icon": "",</span>
</span><span id="__span-0-975"><a id="__codelineno-0-975" name="__codelineno-0-975"></a><span class="s2"> "is_active": False,</span>
</span><span id="__span-0-976"><a id="__codelineno-0-976" name="__codelineno-0-976"></a><span class="s2"> })</span>
</span><span id="__span-0-977"><a id="__codelineno-0-977" name="__codelineno-0-977"></a>
</span><span id="__span-0-978"><a id="__codelineno-0-978" name="__codelineno-0-978"></a><span class="s2">_result_ = workbenches</span>
</span><span id="__span-0-979"><a id="__codelineno-0-979" name="__codelineno-0-979"></a><span class="s2">"""</span>
</span><span id="__span-0-980"><a id="__codelineno-0-980" name="__codelineno-0-980"></a> <span class="n">result</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">execute_python</span><span class="p">(</span><span class="n">code</span><span class="p">)</span>
</span><span id="__span-0-981"><a id="__codelineno-0-981" name="__codelineno-0-981"></a>
</span><span id="__span-0-982"><a id="__codelineno-0-982" name="__codelineno-0-982"></a> <span class="k">if</span> <span class="n">result</span><span class="o">.</span><span class="n">success</span> <span class="ow">and</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">:</span>
</span><span id="__span-0-983"><a id="__codelineno-0-983" name="__codelineno-0-983"></a> <span class="k">return</span> <span class="p">[</span><span class="n">WorkbenchInfo</span><span class="p">(</span><span class="o">**</span><span class="n">wb</span><span class="p">)</span> <span class="k">for</span> <span class="n">wb</span> <span class="ow">in</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">]</span>
</span><span id="__span-0-984"><a id="__codelineno-0-984" name="__codelineno-0-984"></a> <span class="k">return</span> <span class="p">[]</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> </div> </div> <div class="doc doc-object doc-function"> <h6 id="freecad_mcp.bridge.socket.SocketBridge.is_connected" class="doc doc-heading"> <code class="highlight language-python"><span class="n">is_connected</span><span class="p">()</span></code> <span class="doc doc-labels"> <small class="doc doc-label doc-label-async"><code>async</code></small> </span> <a href="#freecad_mcp.bridge.socket.SocketBridge.is_connected" class="headerlink" title="Permanent link">¶</a></h6> <div class="doc doc-contents "> <p>Check if bridge is connected to FreeCAD.</p> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/socket.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-123">123</a></span>
<span class="normal"><a href="#__codelineno-0-124">124</a></span>
<span class="normal"><a href="#__codelineno-0-125">125</a></span>
<span class="normal"><a href="#__codelineno-0-126">126</a></span>
<span class="normal"><a href="#__codelineno-0-127">127</a></span>
<span class="normal"><a href="#__codelineno-0-128">128</a></span>
<span class="normal"><a href="#__codelineno-0-129">129</a></span>
<span class="normal"><a href="#__codelineno-0-130">130</a></span>
<span class="normal"><a href="#__codelineno-0-131">131</a></span>
<span class="normal"><a href="#__codelineno-0-132">132</a></span>
<span class="normal"><a href="#__codelineno-0-133">133</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-123"><a id="__codelineno-0-123" name="__codelineno-0-123"></a><span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">is_connected</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">bool</span><span class="p">:</span>
</span><span id="__span-0-124"><a id="__codelineno-0-124" name="__codelineno-0-124"></a><span class="w"> </span><span class="sd">"""Check if bridge is connected to FreeCAD."""</span>
</span><span id="__span-0-125"><a id="__codelineno-0-125" name="__codelineno-0-125"></a> <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">_connected</span> <span class="ow">or</span> <span class="bp">self</span><span class="o">.</span><span class="n">_writer</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
</span><span id="__span-0-126"><a id="__codelineno-0-126" name="__codelineno-0-126"></a> <span class="k">return</span> <span class="kc">False</span>
</span><span id="__span-0-127"><a id="__codelineno-0-127" name="__codelineno-0-127"></a>
</span><span id="__span-0-128"><a id="__codelineno-0-128" name="__codelineno-0-128"></a> <span class="k">try</span><span class="p">:</span>
</span><span id="__span-0-129"><a id="__codelineno-0-129" name="__codelineno-0-129"></a> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">ping</span><span class="p">()</span>
</span><span id="__span-0-130"><a id="__codelineno-0-130" name="__codelineno-0-130"></a> <span class="k">return</span> <span class="kc">True</span>
</span><span id="__span-0-131"><a id="__codelineno-0-131" name="__codelineno-0-131"></a> <span class="k">except</span> <span class="ne">Exception</span><span class="p">:</span>
</span><span id="__span-0-132"><a id="__codelineno-0-132" name="__codelineno-0-132"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_connected</span> <span class="o">=</span> <span class="kc">False</span>
</span><span id="__span-0-133"><a id="__codelineno-0-133" name="__codelineno-0-133"></a> <span class="k">return</span> <span class="kc">False</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> </div> </div> <div class="doc doc-object doc-function"> <h6 id="freecad_mcp.bridge.socket.SocketBridge.is_gui_available" class="doc doc-heading"> <code class="highlight language-python"><span class="n">is_gui_available</span><span class="p">()</span></code> <span class="doc doc-labels"> <small class="doc doc-label doc-label-async"><code>async</code></small> </span> <a href="#freecad_mcp.bridge.socket.SocketBridge.is_gui_available" class="headerlink" title="Permanent link">¶</a></h6> <div class="doc doc-contents "> <p>Check if FreeCAD GUI is available.</p> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/socket.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-1033">1033</a></span>
<span class="normal"><a href="#__codelineno-0-1034">1034</a></span>
<span class="normal"><a href="#__codelineno-0-1035">1035</a></span>
<span class="normal"><a href="#__codelineno-0-1036">1036</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-1033"><a id="__codelineno-0-1033" name="__codelineno-0-1033"></a><span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">is_gui_available</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">bool</span><span class="p">:</span>
</span><span id="__span-0-1034"><a id="__codelineno-0-1034" name="__codelineno-0-1034"></a><span class="w"> </span><span class="sd">"""Check if FreeCAD GUI is available."""</span>
</span><span id="__span-0-1035"><a id="__codelineno-0-1035" name="__codelineno-0-1035"></a> <span class="n">result</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">execute_python</span><span class="p">(</span><span class="s2">"_result_ = FreeCAD.GuiUp"</span><span class="p">)</span>
</span><span id="__span-0-1036"><a id="__codelineno-0-1036" name="__codelineno-0-1036"></a> <span class="k">return</span> <span class="nb">bool</span><span class="p">(</span><span class="n">result</span><span class="o">.</span><span class="n">success</span> <span class="ow">and</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">)</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> </div> </div> <div class="doc doc-object doc-function"> <h6 id="freecad_mcp.bridge.socket.SocketBridge.open_document" class="doc doc-heading"> <code class="highlight language-python"><span class="n">open_document</span><span class="p">(</span><span class="n">path</span><span class="p">)</span></code> <span class="doc doc-labels"> <small class="doc doc-label doc-label-async"><code>async</code></small> </span> <a href="#freecad_mcp.bridge.socket.SocketBridge.open_document" class="headerlink" title="Permanent link">¶</a></h6> <div class="doc doc-contents "> <p>Open an existing document.</p> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/socket.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-408">408</a></span>
<span class="normal"><a href="#__codelineno-0-409">409</a></span>
<span class="normal"><a href="#__codelineno-0-410">410</a></span>
<span class="normal"><a href="#__codelineno-0-411">411</a></span>
<span class="normal"><a href="#__codelineno-0-412">412</a></span>
<span class="normal"><a href="#__codelineno-0-413">413</a></span>
<span class="normal"><a href="#__codelineno-0-414">414</a></span>
<span class="normal"><a href="#__codelineno-0-415">415</a></span>
<span class="normal"><a href="#__codelineno-0-416">416</a></span>
<span class="normal"><a href="#__codelineno-0-417">417</a></span>
<span class="normal"><a href="#__codelineno-0-418">418</a></span>
<span class="normal"><a href="#__codelineno-0-419">419</a></span>
<span class="normal"><a href="#__codelineno-0-420">420</a></span>
<span class="normal"><a href="#__codelineno-0-421">421</a></span>
<span class="normal"><a href="#__codelineno-0-422">422</a></span>
<span class="normal"><a href="#__codelineno-0-423">423</a></span>
<span class="normal"><a href="#__codelineno-0-424">424</a></span>
<span class="normal"><a href="#__codelineno-0-425">425</a></span>
<span class="normal"><a href="#__codelineno-0-426">426</a></span>
<span class="normal"><a href="#__codelineno-0-427">427</a></span>
<span class="normal"><a href="#__codelineno-0-428">428</a></span>
<span class="normal"><a href="#__codelineno-0-429">429</a></span>
<span class="normal"><a href="#__codelineno-0-430">430</a></span>
<span class="normal"><a href="#__codelineno-0-431">431</a></span>
<span class="normal"><a href="#__codelineno-0-432">432</a></span>
<span class="normal"><a href="#__codelineno-0-433">433</a></span>
<span class="normal"><a href="#__codelineno-0-434">434</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-408"><a id="__codelineno-0-408" name="__codelineno-0-408"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">open_document</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">path</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">DocumentInfo</span><span class="p">:</span>
</span><span id="__span-0-409"><a id="__codelineno-0-409" name="__codelineno-0-409"></a><span class="w"> </span><span class="sd">"""Open an existing document."""</span>
</span><span id="__span-0-410"><a id="__codelineno-0-410" name="__codelineno-0-410"></a> <span class="n">result</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">execute_python</span><span class="p">(</span>
</span><span id="__span-0-411"><a id="__codelineno-0-411" name="__codelineno-0-411"></a> <span class="sa">f</span><span class="s2">"""</span>
</span><span id="__span-0-412"><a id="__codelineno-0-412" name="__codelineno-0-412"></a><span class="s2">import os</span>
</span><span id="__span-0-413"><a id="__codelineno-0-413" name="__codelineno-0-413"></a><span class="s2">if not os.path.exists(</span><span class="si">{</span><span class="n">path</span><span class="si">!r}</span><span class="s2">):</span>
</span><span id="__span-0-414"><a id="__codelineno-0-414" name="__codelineno-0-414"></a><span class="s2"> raise FileNotFoundError(f"File not found: </span><span class="si">{</span><span class="n">path</span><span class="si">!r}</span><span class="s2">")</span>
</span><span id="__span-0-415"><a id="__codelineno-0-415" name="__codelineno-0-415"></a>
</span><span id="__span-0-416"><a id="__codelineno-0-416" name="__codelineno-0-416"></a><span class="s2">doc = FreeCAD.openDocument(</span><span class="si">{</span><span class="n">path</span><span class="si">!r}</span><span class="s2">)</span>
</span><span id="__span-0-417"><a id="__codelineno-0-417" name="__codelineno-0-417"></a><span class="s2">_result_ = </span><span class="se">{{</span>
</span><span id="__span-0-418"><a id="__codelineno-0-418" name="__codelineno-0-418"></a><span class="s2"> "name": doc.Name,</span>
</span><span id="__span-0-419"><a id="__codelineno-0-419" name="__codelineno-0-419"></a><span class="s2"> "label": doc.Label,</span>
</span><span id="__span-0-420"><a id="__codelineno-0-420" name="__codelineno-0-420"></a><span class="s2"> "path": doc.FileName or None,</span>
</span><span id="__span-0-421"><a id="__codelineno-0-421" name="__codelineno-0-421"></a><span class="s2"> "objects": [obj.Name for obj in doc.Objects],</span>
</span><span id="__span-0-422"><a id="__codelineno-0-422" name="__codelineno-0-422"></a><span class="s2"> "is_modified": doc.Modified if hasattr(doc, "Modified") else False,</span>
</span><span id="__span-0-423"><a id="__codelineno-0-423" name="__codelineno-0-423"></a><span class="se">}}</span>
</span><span id="__span-0-424"><a id="__codelineno-0-424" name="__codelineno-0-424"></a><span class="s2">"""</span>
</span><span id="__span-0-425"><a id="__codelineno-0-425" name="__codelineno-0-425"></a> <span class="p">)</span>
</span><span id="__span-0-426"><a id="__codelineno-0-426" name="__codelineno-0-426"></a>
</span><span id="__span-0-427"><a id="__codelineno-0-427" name="__codelineno-0-427"></a> <span class="k">if</span> <span class="n">result</span><span class="o">.</span><span class="n">success</span> <span class="ow">and</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">:</span>
</span><span id="__span-0-428"><a id="__codelineno-0-428" name="__codelineno-0-428"></a> <span class="k">return</span> <span class="n">DocumentInfo</span><span class="p">(</span><span class="o">**</span><span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">)</span>
</span><span id="__span-0-429"><a id="__codelineno-0-429" name="__codelineno-0-429"></a>
</span><span id="__span-0-430"><a id="__codelineno-0-430" name="__codelineno-0-430"></a> <span class="k">if</span> <span class="s2">"FileNotFoundError"</span> <span class="ow">in</span> <span class="p">(</span><span class="n">result</span><span class="o">.</span><span class="n">error_type</span> <span class="ow">or</span> <span class="s2">""</span><span class="p">):</span>
</span><span id="__span-0-431"><a id="__codelineno-0-431" name="__codelineno-0-431"></a> <span class="k">raise</span> <span class="ne">FileNotFoundError</span><span class="p">(</span><span class="n">result</span><span class="o">.</span><span class="n">stderr</span><span class="p">)</span>
</span><span id="__span-0-432"><a id="__codelineno-0-432" name="__codelineno-0-432"></a>
</span><span id="__span-0-433"><a id="__codelineno-0-433" name="__codelineno-0-433"></a> <span class="n">error_msg</span> <span class="o">=</span> <span class="n">result</span><span class="o">.</span><span class="n">error_traceback</span> <span class="ow">or</span> <span class="s2">"Failed to open document"</span>
</span><span id="__span-0-434"><a id="__codelineno-0-434" name="__codelineno-0-434"></a> <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="n">error_msg</span><span class="p">)</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> </div> </div> <div class="doc doc-object doc-function"> <h6 id="freecad_mcp.bridge.socket.SocketBridge.ping" class="doc doc-heading"> <code class="highlight language-python"><span class="n">ping</span><span class="p">()</span></code> <span class="doc doc-labels"> <small class="doc doc-label doc-label-async"><code>async</code></small> </span> <a href="#freecad_mcp.bridge.socket.SocketBridge.ping" class="headerlink" title="Permanent link">¶</a></h6> <div class="doc doc-contents "> <p>Ping FreeCAD to check connection and measure latency.</p> <p><span class="doc-section-title">Returns:</span></p> <table> <thead> <tr> <th>Type</th> <th>Description</th> </tr> </thead> <tbody> <tr class="doc-section-item"> <td> <code><span title="float">float</span></code> </td> <td> <div class="doc-md-description"> <p>Round-trip time in milliseconds.</p> </div> </td> </tr> </tbody> </table> <p><span class="doc-section-title">Raises:</span></p> <table> <thead> <tr> <th>Type</th> <th>Description</th> </tr> </thead> <tbody> <tr class="doc-section-item"> <td> <code><span title="ConnectionError">ConnectionError</span></code> </td> <td> <div class="doc-md-description"> <p>If not connected.</p> </div> </td> </tr> </tbody> </table> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/socket.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-215">215</a></span>
<span class="normal"><a href="#__codelineno-0-216">216</a></span>
<span class="normal"><a href="#__codelineno-0-217">217</a></span>
<span class="normal"><a href="#__codelineno-0-218">218</a></span>
<span class="normal"><a href="#__codelineno-0-219">219</a></span>
<span class="normal"><a href="#__codelineno-0-220">220</a></span>
<span class="normal"><a href="#__codelineno-0-221">221</a></span>
<span class="normal"><a href="#__codelineno-0-222">222</a></span>
<span class="normal"><a href="#__codelineno-0-223">223</a></span>
<span class="normal"><a href="#__codelineno-0-224">224</a></span>
<span class="normal"><a href="#__codelineno-0-225">225</a></span>
<span class="normal"><a href="#__codelineno-0-226">226</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-215"><a id="__codelineno-0-215" name="__codelineno-0-215"></a><span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">ping</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">float</span><span class="p">:</span>
</span><span id="__span-0-216"><a id="__codelineno-0-216" name="__codelineno-0-216"></a><span class="w"> </span><span class="sd">"""Ping FreeCAD to check connection and measure latency.</span>
</span><span id="__span-0-217"><a id="__codelineno-0-217" name="__codelineno-0-217"></a>
</span><span id="__span-0-218"><a id="__codelineno-0-218" name="__codelineno-0-218"></a><span class="sd"> Returns:</span>
</span><span id="__span-0-219"><a id="__codelineno-0-219" name="__codelineno-0-219"></a><span class="sd"> Round-trip time in milliseconds.</span>
</span><span id="__span-0-220"><a id="__codelineno-0-220" name="__codelineno-0-220"></a>
</span><span id="__span-0-221"><a id="__codelineno-0-221" name="__codelineno-0-221"></a><span class="sd"> Raises:</span>
</span><span id="__span-0-222"><a id="__codelineno-0-222" name="__codelineno-0-222"></a><span class="sd"> ConnectionError: If not connected.</span>
</span><span id="__span-0-223"><a id="__codelineno-0-223" name="__codelineno-0-223"></a><span class="sd"> """</span>
</span><span id="__span-0-224"><a id="__codelineno-0-224" name="__codelineno-0-224"></a> <span class="n">start</span> <span class="o">=</span> <span class="n">time</span><span class="o">.</span><span class="n">perf_counter</span><span class="p">()</span>
</span><span id="__span-0-225"><a id="__codelineno-0-225" name="__codelineno-0-225"></a> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">_send_request</span><span class="p">(</span><span class="s2">"ping"</span><span class="p">)</span>
</span><span id="__span-0-226"><a id="__codelineno-0-226" name="__codelineno-0-226"></a> <span class="k">return</span> <span class="p">(</span><span class="n">time</span><span class="o">.</span><span class="n">perf_counter</span><span class="p">()</span> <span class="o">-</span> <span class="n">start</span><span class="p">)</span> <span class="o">*</span> <span class="mi">1000</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> </div> </div> <div class="doc doc-object doc-function"> <h6 id="freecad_mcp.bridge.socket.SocketBridge.run_macro" class="doc doc-heading"> <code class="highlight language-python"><span class="n">run_macro</span><span class="p">(</span><span class="n">macro_name</span><span class="p">,</span> <span class="n">args</span><span class="o">=</span><span class="kc">None</span><span class="p">)</span></code> <span class="doc doc-labels"> <small class="doc doc-label doc-label-async"><code>async</code></small> </span> <a href="#freecad_mcp.bridge.socket.SocketBridge.run_macro" class="headerlink" title="Permanent link">¶</a></h6> <div class="doc doc-contents "> <p>Run a macro by name.</p> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/socket.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-862">862</a></span>
<span class="normal"><a href="#__codelineno-0-863">863</a></span>
<span class="normal"><a href="#__codelineno-0-864">864</a></span>
<span class="normal"><a href="#__codelineno-0-865">865</a></span>
<span class="normal"><a href="#__codelineno-0-866">866</a></span>
<span class="normal"><a href="#__codelineno-0-867">867</a></span>
<span class="normal"><a href="#__codelineno-0-868">868</a></span>
<span class="normal"><a href="#__codelineno-0-869">869</a></span>
<span class="normal"><a href="#__codelineno-0-870">870</a></span>
<span class="normal"><a href="#__codelineno-0-871">871</a></span>
<span class="normal"><a href="#__codelineno-0-872">872</a></span>
<span class="normal"><a href="#__codelineno-0-873">873</a></span>
<span class="normal"><a href="#__codelineno-0-874">874</a></span>
<span class="normal"><a href="#__codelineno-0-875">875</a></span>
<span class="normal"><a href="#__codelineno-0-876">876</a></span>
<span class="normal"><a href="#__codelineno-0-877">877</a></span>
<span class="normal"><a href="#__codelineno-0-878">878</a></span>
<span class="normal"><a href="#__codelineno-0-879">879</a></span>
<span class="normal"><a href="#__codelineno-0-880">880</a></span>
<span class="normal"><a href="#__codelineno-0-881">881</a></span>
<span class="normal"><a href="#__codelineno-0-882">882</a></span>
<span class="normal"><a href="#__codelineno-0-883">883</a></span>
<span class="normal"><a href="#__codelineno-0-884">884</a></span>
<span class="normal"><a href="#__codelineno-0-885">885</a></span>
<span class="normal"><a href="#__codelineno-0-886">886</a></span>
<span class="normal"><a href="#__codelineno-0-887">887</a></span>
<span class="normal"><a href="#__codelineno-0-888">888</a></span>
<span class="normal"><a href="#__codelineno-0-889">889</a></span>
<span class="normal"><a href="#__codelineno-0-890">890</a></span>
<span class="normal"><a href="#__codelineno-0-891">891</a></span>
<span class="normal"><a href="#__codelineno-0-892">892</a></span>
<span class="normal"><a href="#__codelineno-0-893">893</a></span>
<span class="normal"><a href="#__codelineno-0-894">894</a></span>
<span class="normal"><a href="#__codelineno-0-895">895</a></span>
<span class="normal"><a href="#__codelineno-0-896">896</a></span>
<span class="normal"><a href="#__codelineno-0-897">897</a></span>
<span class="normal"><a href="#__codelineno-0-898">898</a></span>
<span class="normal"><a href="#__codelineno-0-899">899</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-862"><a id="__codelineno-0-862" name="__codelineno-0-862"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">run_macro</span><span class="p">(</span>
</span><span id="__span-0-863"><a id="__codelineno-0-863" name="__codelineno-0-863"></a> <span class="bp">self</span><span class="p">,</span>
</span><span id="__span-0-864"><a id="__codelineno-0-864" name="__codelineno-0-864"></a> <span class="n">macro_name</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span>
</span><span id="__span-0-865"><a id="__codelineno-0-865" name="__codelineno-0-865"></a> <span class="n">args</span><span class="p">:</span> <span class="nb">dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Any</span><span class="p">]</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-866"><a id="__codelineno-0-866" name="__codelineno-0-866"></a> <span class="p">)</span> <span class="o">-&gt;</span> <span class="n">ExecutionResult</span><span class="p">:</span>
</span><span id="__span-0-867"><a id="__codelineno-0-867" name="__codelineno-0-867"></a><span class="w"> </span><span class="sd">"""Run a macro by name."""</span>
</span><span id="__span-0-868"><a id="__codelineno-0-868" name="__codelineno-0-868"></a> <span class="n">args</span> <span class="o">=</span> <span class="n">args</span> <span class="ow">or</span> <span class="p">{}</span>
</span><span id="__span-0-869"><a id="__codelineno-0-869" name="__codelineno-0-869"></a> <span class="n">code</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">"""</span>
</span><span id="__span-0-870"><a id="__codelineno-0-870" name="__codelineno-0-870"></a><span class="s2">import os</span>
</span><span id="__span-0-871"><a id="__codelineno-0-871" name="__codelineno-0-871"></a>
</span><span id="__span-0-872"><a id="__codelineno-0-872" name="__codelineno-0-872"></a><span class="s2">macro_name = </span><span class="si">{</span><span class="n">macro_name</span><span class="si">!r}</span>
</span><span id="__span-0-873"><a id="__codelineno-0-873" name="__codelineno-0-873"></a><span class="s2">macro_file = None</span>
</span><span id="__span-0-874"><a id="__codelineno-0-874" name="__codelineno-0-874"></a>
</span><span id="__span-0-875"><a id="__codelineno-0-875" name="__codelineno-0-875"></a><span class="s2">user_path = FreeCAD.getUserMacroDir(True)</span>
</span><span id="__span-0-876"><a id="__codelineno-0-876" name="__codelineno-0-876"></a><span class="s2">user_macro = os.path.join(user_path, macro_name + ".FCMacro")</span>
</span><span id="__span-0-877"><a id="__codelineno-0-877" name="__codelineno-0-877"></a><span class="s2">if os.path.exists(user_macro):</span>
</span><span id="__span-0-878"><a id="__codelineno-0-878" name="__codelineno-0-878"></a><span class="s2"> macro_file = user_macro</span>
</span><span id="__span-0-879"><a id="__codelineno-0-879" name="__codelineno-0-879"></a>
</span><span id="__span-0-880"><a id="__codelineno-0-880" name="__codelineno-0-880"></a><span class="s2">if not macro_file:</span>
</span><span id="__span-0-881"><a id="__codelineno-0-881" name="__codelineno-0-881"></a><span class="s2"> system_path = FreeCAD.getResourceDir() + "Macro"</span>
</span><span id="__span-0-882"><a id="__codelineno-0-882" name="__codelineno-0-882"></a><span class="s2"> system_macro = os.path.join(system_path, macro_name + ".FCMacro")</span>
</span><span id="__span-0-883"><a id="__codelineno-0-883" name="__codelineno-0-883"></a><span class="s2"> if os.path.exists(system_macro):</span>
</span><span id="__span-0-884"><a id="__codelineno-0-884" name="__codelineno-0-884"></a><span class="s2"> macro_file = system_macro</span>
</span><span id="__span-0-885"><a id="__codelineno-0-885" name="__codelineno-0-885"></a>
</span><span id="__span-0-886"><a id="__codelineno-0-886" name="__codelineno-0-886"></a><span class="s2">if not macro_file:</span>
</span><span id="__span-0-887"><a id="__codelineno-0-887" name="__codelineno-0-887"></a><span class="s2"> raise FileNotFoundError(f"Macro not found: </span><span class="se">{{</span><span class="s2">macro_name</span><span class="se">}}</span><span class="s2">")</span>
</span><span id="__span-0-888"><a id="__codelineno-0-888" name="__codelineno-0-888"></a>
</span><span id="__span-0-889"><a id="__codelineno-0-889" name="__codelineno-0-889"></a><span class="s2">args = </span><span class="si">{</span><span class="n">args</span><span class="si">!r}</span>
</span><span id="__span-0-890"><a id="__codelineno-0-890" name="__codelineno-0-890"></a><span class="s2">for k, v in args.items():</span>
</span><span id="__span-0-891"><a id="__codelineno-0-891" name="__codelineno-0-891"></a><span class="s2"> exec(f"</span><span class="se">{{</span><span class="s2">k</span><span class="se">}}</span><span class="s2"> = </span><span class="se">{{</span><span class="s2">v!r</span><span class="se">}}</span><span class="s2">")</span>
</span><span id="__span-0-892"><a id="__codelineno-0-892" name="__codelineno-0-892"></a>
</span><span id="__span-0-893"><a id="__codelineno-0-893" name="__codelineno-0-893"></a><span class="s2">with open(macro_file, "r") as f:</span>
</span><span id="__span-0-894"><a id="__codelineno-0-894" name="__codelineno-0-894"></a><span class="s2"> macro_code = f.read()</span>
</span><span id="__span-0-895"><a id="__codelineno-0-895" name="__codelineno-0-895"></a>
</span><span id="__span-0-896"><a id="__codelineno-0-896" name="__codelineno-0-896"></a><span class="s2">exec(macro_code)</span>
</span><span id="__span-0-897"><a id="__codelineno-0-897" name="__codelineno-0-897"></a><span class="s2">_result_ = True</span>
</span><span id="__span-0-898"><a id="__codelineno-0-898" name="__codelineno-0-898"></a><span class="s2">"""</span>
</span><span id="__span-0-899"><a id="__codelineno-0-899" name="__codelineno-0-899"></a> <span class="k">return</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">execute_python</span><span class="p">(</span><span class="n">code</span><span class="p">)</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> </div> </div> <div class="doc doc-object doc-function"> <h6 id="freecad_mcp.bridge.socket.SocketBridge.save_document" class="doc doc-heading"> <code class="highlight language-python"><span class="n">save_document</span><span class="p">(</span><span class="n">doc_name</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">path</span><span class="o">=</span><span class="kc">None</span><span class="p">)</span></code> <span class="doc doc-labels"> <small class="doc doc-label doc-label-async"><code>async</code></small> </span> <a href="#freecad_mcp.bridge.socket.SocketBridge.save_document" class="headerlink" title="Permanent link">¶</a></h6> <div class="doc doc-contents "> <p>Save a document.</p> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/socket.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-436">436</a></span>
<span class="normal"><a href="#__codelineno-0-437">437</a></span>
<span class="normal"><a href="#__codelineno-0-438">438</a></span>
<span class="normal"><a href="#__codelineno-0-439">439</a></span>
<span class="normal"><a href="#__codelineno-0-440">440</a></span>
<span class="normal"><a href="#__codelineno-0-441">441</a></span>
<span class="normal"><a href="#__codelineno-0-442">442</a></span>
<span class="normal"><a href="#__codelineno-0-443">443</a></span>
<span class="normal"><a href="#__codelineno-0-444">444</a></span>
<span class="normal"><a href="#__codelineno-0-445">445</a></span>
<span class="normal"><a href="#__codelineno-0-446">446</a></span>
<span class="normal"><a href="#__codelineno-0-447">447</a></span>
<span class="normal"><a href="#__codelineno-0-448">448</a></span>
<span class="normal"><a href="#__codelineno-0-449">449</a></span>
<span class="normal"><a href="#__codelineno-0-450">450</a></span>
<span class="normal"><a href="#__codelineno-0-451">451</a></span>
<span class="normal"><a href="#__codelineno-0-452">452</a></span>
<span class="normal"><a href="#__codelineno-0-453">453</a></span>
<span class="normal"><a href="#__codelineno-0-454">454</a></span>
<span class="normal"><a href="#__codelineno-0-455">455</a></span>
<span class="normal"><a href="#__codelineno-0-456">456</a></span>
<span class="normal"><a href="#__codelineno-0-457">457</a></span>
<span class="normal"><a href="#__codelineno-0-458">458</a></span>
<span class="normal"><a href="#__codelineno-0-459">459</a></span>
<span class="normal"><a href="#__codelineno-0-460">460</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-436"><a id="__codelineno-0-436" name="__codelineno-0-436"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">save_document</span><span class="p">(</span>
</span><span id="__span-0-437"><a id="__codelineno-0-437" name="__codelineno-0-437"></a> <span class="bp">self</span><span class="p">,</span>
</span><span id="__span-0-438"><a id="__codelineno-0-438" name="__codelineno-0-438"></a> <span class="n">doc_name</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-439"><a id="__codelineno-0-439" name="__codelineno-0-439"></a> <span class="n">path</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-440"><a id="__codelineno-0-440" name="__codelineno-0-440"></a> <span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">str</span><span class="p">:</span>
</span><span id="__span-0-441"><a id="__codelineno-0-441" name="__codelineno-0-441"></a><span class="w"> </span><span class="sd">"""Save a document."""</span>
</span><span id="__span-0-442"><a id="__codelineno-0-442" name="__codelineno-0-442"></a> <span class="n">code</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">"""</span>
</span><span id="__span-0-443"><a id="__codelineno-0-443" name="__codelineno-0-443"></a><span class="s2">doc = FreeCAD.ActiveDocument if </span><span class="si">{</span><span class="n">doc_name</span><span class="si">!r}</span><span class="s2"> is None else FreeCAD.getDocument(</span><span class="si">{</span><span class="n">doc_name</span><span class="si">!r}</span><span class="s2">)</span>
</span><span id="__span-0-444"><a id="__codelineno-0-444" name="__codelineno-0-444"></a><span class="s2">if doc is None:</span>
</span><span id="__span-0-445"><a id="__codelineno-0-445" name="__codelineno-0-445"></a><span class="s2"> raise ValueError("No active document" if </span><span class="si">{</span><span class="n">doc_name</span><span class="si">!r}</span><span class="s2"> is None else f"Document not found: </span><span class="si">{</span><span class="n">doc_name</span><span class="si">!r}</span><span class="s2">")</span>
</span><span id="__span-0-446"><a id="__codelineno-0-446" name="__codelineno-0-446"></a>
</span><span id="__span-0-447"><a id="__codelineno-0-447" name="__codelineno-0-447"></a><span class="s2">save_path = </span><span class="si">{</span><span class="n">path</span><span class="si">!r}</span><span class="s2"> or doc.FileName</span>
</span><span id="__span-0-448"><a id="__codelineno-0-448" name="__codelineno-0-448"></a><span class="s2">if not save_path:</span>
</span><span id="__span-0-449"><a id="__codelineno-0-449" name="__codelineno-0-449"></a><span class="s2"> raise ValueError("No path specified for new document")</span>
</span><span id="__span-0-450"><a id="__codelineno-0-450" name="__codelineno-0-450"></a>
</span><span id="__span-0-451"><a id="__codelineno-0-451" name="__codelineno-0-451"></a><span class="s2">doc.saveAs(save_path)</span>
</span><span id="__span-0-452"><a id="__codelineno-0-452" name="__codelineno-0-452"></a><span class="s2">_result_ = save_path</span>
</span><span id="__span-0-453"><a id="__codelineno-0-453" name="__codelineno-0-453"></a><span class="s2">"""</span>
</span><span id="__span-0-454"><a id="__codelineno-0-454" name="__codelineno-0-454"></a> <span class="n">result</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">execute_python</span><span class="p">(</span><span class="n">code</span><span class="p">)</span>
</span><span id="__span-0-455"><a id="__codelineno-0-455" name="__codelineno-0-455"></a>
</span><span id="__span-0-456"><a id="__codelineno-0-456" name="__codelineno-0-456"></a> <span class="k">if</span> <span class="n">result</span><span class="o">.</span><span class="n">success</span> <span class="ow">and</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">:</span>
</span><span id="__span-0-457"><a id="__codelineno-0-457" name="__codelineno-0-457"></a> <span class="k">return</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span>
</span><span id="__span-0-458"><a id="__codelineno-0-458" name="__codelineno-0-458"></a>
</span><span id="__span-0-459"><a id="__codelineno-0-459" name="__codelineno-0-459"></a> <span class="n">error_msg</span> <span class="o">=</span> <span class="n">result</span><span class="o">.</span><span class="n">error_traceback</span> <span class="ow">or</span> <span class="s2">"Failed to save document"</span>
</span><span id="__span-0-460"><a id="__codelineno-0-460" name="__codelineno-0-460"></a> <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="n">error_msg</span><span class="p">)</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> </div> </div> <div class="doc doc-object doc-function"> <h6 id="freecad_mcp.bridge.socket.SocketBridge.set_view" class="doc doc-heading"> <code class="highlight language-python"><span class="n">set_view</span><span class="p">(</span><span class="n">view_angle</span><span class="p">,</span> <span class="n">doc_name</span><span class="o">=</span><span class="kc">None</span><span class="p">)</span></code> <span class="doc doc-labels"> <small class="doc doc-label doc-label-async"><code>async</code></small> </span> <a href="#freecad_mcp.bridge.socket.SocketBridge.set_view" class="headerlink" title="Permanent link">¶</a></h6> <div class="doc doc-contents "> <p>Set the 3D view angle.</p> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/socket.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-770">770</a></span>
<span class="normal"><a href="#__codelineno-0-771">771</a></span>
<span class="normal"><a href="#__codelineno-0-772">772</a></span>
<span class="normal"><a href="#__codelineno-0-773">773</a></span>
<span class="normal"><a href="#__codelineno-0-774">774</a></span>
<span class="normal"><a href="#__codelineno-0-775">775</a></span>
<span class="normal"><a href="#__codelineno-0-776">776</a></span>
<span class="normal"><a href="#__codelineno-0-777">777</a></span>
<span class="normal"><a href="#__codelineno-0-778">778</a></span>
<span class="normal"><a href="#__codelineno-0-779">779</a></span>
<span class="normal"><a href="#__codelineno-0-780">780</a></span>
<span class="normal"><a href="#__codelineno-0-781">781</a></span>
<span class="normal"><a href="#__codelineno-0-782">782</a></span>
<span class="normal"><a href="#__codelineno-0-783">783</a></span>
<span class="normal"><a href="#__codelineno-0-784">784</a></span>
<span class="normal"><a href="#__codelineno-0-785">785</a></span>
<span class="normal"><a href="#__codelineno-0-786">786</a></span>
<span class="normal"><a href="#__codelineno-0-787">787</a></span>
<span class="normal"><a href="#__codelineno-0-788">788</a></span>
<span class="normal"><a href="#__codelineno-0-789">789</a></span>
<span class="normal"><a href="#__codelineno-0-790">790</a></span>
<span class="normal"><a href="#__codelineno-0-791">791</a></span>
<span class="normal"><a href="#__codelineno-0-792">792</a></span>
<span class="normal"><a href="#__codelineno-0-793">793</a></span>
<span class="normal"><a href="#__codelineno-0-794">794</a></span>
<span class="normal"><a href="#__codelineno-0-795">795</a></span>
<span class="normal"><a href="#__codelineno-0-796">796</a></span>
<span class="normal"><a href="#__codelineno-0-797">797</a></span>
<span class="normal"><a href="#__codelineno-0-798">798</a></span>
<span class="normal"><a href="#__codelineno-0-799">799</a></span>
<span class="normal"><a href="#__codelineno-0-800">800</a></span>
<span class="normal"><a href="#__codelineno-0-801">801</a></span>
<span class="normal"><a href="#__codelineno-0-802">802</a></span>
<span class="normal"><a href="#__codelineno-0-803">803</a></span>
<span class="normal"><a href="#__codelineno-0-804">804</a></span>
<span class="normal"><a href="#__codelineno-0-805">805</a></span>
<span class="normal"><a href="#__codelineno-0-806">806</a></span>
<span class="normal"><a href="#__codelineno-0-807">807</a></span>
<span class="normal"><a href="#__codelineno-0-808">808</a></span>
<span class="normal"><a href="#__codelineno-0-809">809</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-770"><a id="__codelineno-0-770" name="__codelineno-0-770"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">set_view</span><span class="p">(</span>
</span><span id="__span-0-771"><a id="__codelineno-0-771" name="__codelineno-0-771"></a> <span class="bp">self</span><span class="p">,</span>
</span><span id="__span-0-772"><a id="__codelineno-0-772" name="__codelineno-0-772"></a> <span class="n">view_angle</span><span class="p">:</span> <span class="n">ViewAngle</span><span class="p">,</span>
</span><span id="__span-0-773"><a id="__codelineno-0-773" name="__codelineno-0-773"></a> <span class="n">doc_name</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-774"><a id="__codelineno-0-774" name="__codelineno-0-774"></a> <span class="p">)</span> <span class="o">-&gt;</span> <span class="kc">None</span><span class="p">:</span>
</span><span id="__span-0-775"><a id="__codelineno-0-775" name="__codelineno-0-775"></a><span class="w"> </span><span class="sd">"""Set the 3D view angle."""</span>
</span><span id="__span-0-776"><a id="__codelineno-0-776" name="__codelineno-0-776"></a> <span class="n">view_angle_str</span> <span class="o">=</span> <span class="n">view_angle</span><span class="o">.</span><span class="n">value</span>
</span><span id="__span-0-777"><a id="__codelineno-0-777" name="__codelineno-0-777"></a> <span class="n">code</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">"""</span>
</span><span id="__span-0-778"><a id="__codelineno-0-778" name="__codelineno-0-778"></a><span class="s2">doc = FreeCAD.ActiveDocument if </span><span class="si">{</span><span class="n">doc_name</span><span class="si">!r}</span><span class="s2"> is None else FreeCAD.getDocument(</span><span class="si">{</span><span class="n">doc_name</span><span class="si">!r}</span><span class="s2">)</span>
</span><span id="__span-0-779"><a id="__codelineno-0-779" name="__codelineno-0-779"></a><span class="s2">if doc is None:</span>
</span><span id="__span-0-780"><a id="__codelineno-0-780" name="__codelineno-0-780"></a><span class="s2"> raise ValueError("No document found")</span>
</span><span id="__span-0-781"><a id="__codelineno-0-781" name="__codelineno-0-781"></a>
</span><span id="__span-0-782"><a id="__codelineno-0-782" name="__codelineno-0-782"></a><span class="s2">if not FreeCAD.GuiUp:</span>
</span><span id="__span-0-783"><a id="__codelineno-0-783" name="__codelineno-0-783"></a><span class="s2"> _result_ = True</span>
</span><span id="__span-0-784"><a id="__codelineno-0-784" name="__codelineno-0-784"></a><span class="s2">else:</span>
</span><span id="__span-0-785"><a id="__codelineno-0-785" name="__codelineno-0-785"></a><span class="s2"> view = FreeCADGui.ActiveDocument.ActiveView</span>
</span><span id="__span-0-786"><a id="__codelineno-0-786" name="__codelineno-0-786"></a><span class="s2"> if view is None:</span>
</span><span id="__span-0-787"><a id="__codelineno-0-787" name="__codelineno-0-787"></a><span class="s2"> raise ValueError("No active view")</span>
</span><span id="__span-0-788"><a id="__codelineno-0-788" name="__codelineno-0-788"></a>
</span><span id="__span-0-789"><a id="__codelineno-0-789" name="__codelineno-0-789"></a><span class="s2"> view_type = </span><span class="si">{</span><span class="n">view_angle_str</span><span class="si">!r}</span>
</span><span id="__span-0-790"><a id="__codelineno-0-790" name="__codelineno-0-790"></a><span class="s2"> if view_type == "FitAll":</span>
</span><span id="__span-0-791"><a id="__codelineno-0-791" name="__codelineno-0-791"></a><span class="s2"> view.fitAll()</span>
</span><span id="__span-0-792"><a id="__codelineno-0-792" name="__codelineno-0-792"></a><span class="s2"> elif view_type == "Isometric":</span>
</span><span id="__span-0-793"><a id="__codelineno-0-793" name="__codelineno-0-793"></a><span class="s2"> view.viewIsometric()</span>
</span><span id="__span-0-794"><a id="__codelineno-0-794" name="__codelineno-0-794"></a><span class="s2"> elif view_type == "Front":</span>
</span><span id="__span-0-795"><a id="__codelineno-0-795" name="__codelineno-0-795"></a><span class="s2"> view.viewFront()</span>
</span><span id="__span-0-796"><a id="__codelineno-0-796" name="__codelineno-0-796"></a><span class="s2"> elif view_type == "Back":</span>
</span><span id="__span-0-797"><a id="__codelineno-0-797" name="__codelineno-0-797"></a><span class="s2"> view.viewRear()</span>
</span><span id="__span-0-798"><a id="__codelineno-0-798" name="__codelineno-0-798"></a><span class="s2"> elif view_type == "Top":</span>
</span><span id="__span-0-799"><a id="__codelineno-0-799" name="__codelineno-0-799"></a><span class="s2"> view.viewTop()</span>
</span><span id="__span-0-800"><a id="__codelineno-0-800" name="__codelineno-0-800"></a><span class="s2"> elif view_type == "Bottom":</span>
</span><span id="__span-0-801"><a id="__codelineno-0-801" name="__codelineno-0-801"></a><span class="s2"> view.viewBottom()</span>
</span><span id="__span-0-802"><a id="__codelineno-0-802" name="__codelineno-0-802"></a><span class="s2"> elif view_type == "Left":</span>
</span><span id="__span-0-803"><a id="__codelineno-0-803" name="__codelineno-0-803"></a><span class="s2"> view.viewLeft()</span>
</span><span id="__span-0-804"><a id="__codelineno-0-804" name="__codelineno-0-804"></a><span class="s2"> elif view_type == "Right":</span>
</span><span id="__span-0-805"><a id="__codelineno-0-805" name="__codelineno-0-805"></a><span class="s2"> view.viewRight()</span>
</span><span id="__span-0-806"><a id="__codelineno-0-806" name="__codelineno-0-806"></a>
</span><span id="__span-0-807"><a id="__codelineno-0-807" name="__codelineno-0-807"></a><span class="s2"> _result_ = True</span>
</span><span id="__span-0-808"><a id="__codelineno-0-808" name="__codelineno-0-808"></a><span class="s2">"""</span>
</span><span id="__span-0-809"><a id="__codelineno-0-809" name="__codelineno-0-809"></a> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">execute_python</span><span class="p">(</span><span class="n">code</span><span class="p">)</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> </div> </div> </div> </div> </div> </div> </div> </div><p>options: show_root_heading: true show_source: true</p> <h2 id="embedded-bridge">Embedded Bridge<a class="headerlink" href="#embedded-bridge" title="Permanent link">¶</a></h2> <div class="admonition warning"> <p class="admonition-title">Linux Only</p> </div> <p>The embedded bridge only works on Linux. See <a href="../../guide/connection-modes/">Connection Modes</a> for details.</p> <div class="doc doc-object doc-module"> <h2 id="freecad_mcp.bridge.embedded" class="doc doc-heading"> <code>freecad_mcp.bridge.embedded</code> <a href="#freecad_mcp.bridge.embedded" class="headerlink" title="Permanent link">¶</a></h2> <div class="doc doc-contents first"> <p>Embedded bridge - runs FreeCAD in-process.</p> <p>This bridge imports FreeCAD directly into the Robust MCP Server process, providing the fastest execution but limited to headless mode.</p> <p>Based on learnings from competitive analysis: - Thread-safe execution using ThreadPoolExecutor (from neka-nat) - Comprehensive object info including shape geometry - Macro support with templates and validation</p> <div class="doc doc-children"> <h3 id="freecad_mcp.bridge.embedded-classes">Classes<a href="#freecad_mcp.bridge.embedded-classes" class="headerlink" title="Permanent link">¶</a></h3> <div class="doc doc-object doc-class"> <h4 id="freecad_mcp.bridge.embedded.EmbeddedBridge" class="doc doc-heading"> <code>EmbeddedBridge</code> <a href="#freecad_mcp.bridge.embedded.EmbeddedBridge" class="headerlink" title="Permanent link">¶</a></h4> <div class="doc doc-contents "> <p class="doc doc-class-bases"> Bases: <code><a class="autorefs autorefs-internal" title="FreecadBridge (freecad_mcp.bridge.base.FreecadBridge)" href="#freecad_mcp.bridge.base.FreecadBridge">FreecadBridge</a></code></p> <p>Bridge that runs FreeCAD embedded in the Robust MCP Server process.</p> <p>This bridge imports FreeCAD directly, providing fast execution but only supports headless mode (no GUI).</p> <p><span class="doc-section-title">Attributes:</span></p> <table> <thead> <tr> <th>Name</th> <th>Type</th> <th>Description</th> </tr> </thead> <tbody> <tr class="doc-section-item"> <td><code><span title="freecad_mcp.bridge.embedded.EmbeddedBridge.freecad_path">freecad_path</span></code></td> <td> </td> <td> <div class="doc-md-description"> <p>Optional path to FreeCAD's lib directory.</p> </div> </td> </tr> </tbody> </table> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/embedded.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-35"> 35</a></span>
<span class="normal"><a href="#__codelineno-0-36"> 36</a></span>
<span class="normal"><a href="#__codelineno-0-37"> 37</a></span>
<span class="normal"><a href="#__codelineno-0-38"> 38</a></span>
<span class="normal"><a href="#__codelineno-0-39"> 39</a></span>
<span class="normal"><a href="#__codelineno-0-40"> 40</a></span>
<span class="normal"><a href="#__codelineno-0-41"> 41</a></span>
<span class="normal"><a href="#__codelineno-0-42"> 42</a></span>
<span class="normal"><a href="#__codelineno-0-43"> 43</a></span>
<span class="normal"><a href="#__codelineno-0-44"> 44</a></span>
<span class="normal"><a href="#__codelineno-0-45"> 45</a></span>
<span class="normal"><a href="#__codelineno-0-46"> 46</a></span>
<span class="normal"><a href="#__codelineno-0-47"> 47</a></span>
<span class="normal"><a href="#__codelineno-0-48"> 48</a></span>
<span class="normal"><a href="#__codelineno-0-49"> 49</a></span>
<span class="normal"><a href="#__codelineno-0-50"> 50</a></span>
<span class="normal"><a href="#__codelineno-0-51"> 51</a></span>
<span class="normal"><a href="#__codelineno-0-52"> 52</a></span>
<span class="normal"><a href="#__codelineno-0-53"> 53</a></span>
<span class="normal"><a href="#__codelineno-0-54"> 54</a></span>
<span class="normal"><a href="#__codelineno-0-55"> 55</a></span>
<span class="normal"><a href="#__codelineno-0-56"> 56</a></span>
<span class="normal"><a href="#__codelineno-0-57"> 57</a></span>
<span class="normal"><a href="#__codelineno-0-58"> 58</a></span>
<span class="normal"><a href="#__codelineno-0-59"> 59</a></span>
<span class="normal"><a href="#__codelineno-0-60"> 60</a></span>
<span class="normal"><a href="#__codelineno-0-61"> 61</a></span>
<span class="normal"><a href="#__codelineno-0-62"> 62</a></span>
<span class="normal"><a href="#__codelineno-0-63"> 63</a></span>
<span class="normal"><a href="#__codelineno-0-64"> 64</a></span>
<span class="normal"><a href="#__codelineno-0-65"> 65</a></span>
<span class="normal"><a href="#__codelineno-0-66"> 66</a></span>
<span class="normal"><a href="#__codelineno-0-67"> 67</a></span>
<span class="normal"><a href="#__codelineno-0-68"> 68</a></span>
<span class="normal"><a href="#__codelineno-0-69"> 69</a></span>
<span class="normal"><a href="#__codelineno-0-70"> 70</a></span>
<span class="normal"><a href="#__codelineno-0-71"> 71</a></span>
<span class="normal"><a href="#__codelineno-0-72"> 72</a></span>
<span class="normal"><a href="#__codelineno-0-73"> 73</a></span>
<span class="normal"><a href="#__codelineno-0-74"> 74</a></span>
<span class="normal"><a href="#__codelineno-0-75"> 75</a></span>
<span class="normal"><a href="#__codelineno-0-76"> 76</a></span>
<span class="normal"><a href="#__codelineno-0-77"> 77</a></span>
<span class="normal"><a href="#__codelineno-0-78"> 78</a></span>
<span class="normal"><a href="#__codelineno-0-79"> 79</a></span>
<span class="normal"><a href="#__codelineno-0-80"> 80</a></span>
<span class="normal"><a href="#__codelineno-0-81"> 81</a></span>
<span class="normal"><a href="#__codelineno-0-82"> 82</a></span>
<span class="normal"><a href="#__codelineno-0-83"> 83</a></span>
<span class="normal"><a href="#__codelineno-0-84"> 84</a></span>
<span class="normal"><a href="#__codelineno-0-85"> 85</a></span>
<span class="normal"><a href="#__codelineno-0-86"> 86</a></span>
<span class="normal"><a href="#__codelineno-0-87"> 87</a></span>
<span class="normal"><a href="#__codelineno-0-88"> 88</a></span>
<span class="normal"><a href="#__codelineno-0-89"> 89</a></span>
<span class="normal"><a href="#__codelineno-0-90"> 90</a></span>
<span class="normal"><a href="#__codelineno-0-91"> 91</a></span>
<span class="normal"><a href="#__codelineno-0-92"> 92</a></span>
<span class="normal"><a href="#__codelineno-0-93"> 93</a></span>
<span class="normal"><a href="#__codelineno-0-94"> 94</a></span>
<span class="normal"><a href="#__codelineno-0-95"> 95</a></span>
<span class="normal"><a href="#__codelineno-0-96"> 96</a></span>
<span class="normal"><a href="#__codelineno-0-97"> 97</a></span>
<span class="normal"><a href="#__codelineno-0-98"> 98</a></span>
<span class="normal"><a href="#__codelineno-0-99"> 99</a></span>
<span class="normal"><a href="#__codelineno-0-100"> 100</a></span>
<span class="normal"><a href="#__codelineno-0-101"> 101</a></span>
<span class="normal"><a href="#__codelineno-0-102"> 102</a></span>
<span class="normal"><a href="#__codelineno-0-103"> 103</a></span>
<span class="normal"><a href="#__codelineno-0-104"> 104</a></span>
<span class="normal"><a href="#__codelineno-0-105"> 105</a></span>
<span class="normal"><a href="#__codelineno-0-106"> 106</a></span>
<span class="normal"><a href="#__codelineno-0-107"> 107</a></span>
<span class="normal"><a href="#__codelineno-0-108"> 108</a></span>
<span class="normal"><a href="#__codelineno-0-109"> 109</a></span>
<span class="normal"><a href="#__codelineno-0-110"> 110</a></span>
<span class="normal"><a href="#__codelineno-0-111"> 111</a></span>
<span class="normal"><a href="#__codelineno-0-112"> 112</a></span>
<span class="normal"><a href="#__codelineno-0-113"> 113</a></span>
<span class="normal"><a href="#__codelineno-0-114"> 114</a></span>
<span class="normal"><a href="#__codelineno-0-115"> 115</a></span>
<span class="normal"><a href="#__codelineno-0-116"> 116</a></span>
<span class="normal"><a href="#__codelineno-0-117"> 117</a></span>
<span class="normal"><a href="#__codelineno-0-118"> 118</a></span>
<span class="normal"><a href="#__codelineno-0-119"> 119</a></span>
<span class="normal"><a href="#__codelineno-0-120"> 120</a></span>
<span class="normal"><a href="#__codelineno-0-121"> 121</a></span>
<span class="normal"><a href="#__codelineno-0-122"> 122</a></span>
<span class="normal"><a href="#__codelineno-0-123"> 123</a></span>
<span class="normal"><a href="#__codelineno-0-124"> 124</a></span>
<span class="normal"><a href="#__codelineno-0-125"> 125</a></span>
<span class="normal"><a href="#__codelineno-0-126"> 126</a></span>
<span class="normal"><a href="#__codelineno-0-127"> 127</a></span>
<span class="normal"><a href="#__codelineno-0-128"> 128</a></span>
<span class="normal"><a href="#__codelineno-0-129"> 129</a></span>
<span class="normal"><a href="#__codelineno-0-130"> 130</a></span>
<span class="normal"><a href="#__codelineno-0-131"> 131</a></span>
<span class="normal"><a href="#__codelineno-0-132"> 132</a></span>
<span class="normal"><a href="#__codelineno-0-133"> 133</a></span>
<span class="normal"><a href="#__codelineno-0-134"> 134</a></span>
<span class="normal"><a href="#__codelineno-0-135"> 135</a></span>
<span class="normal"><a href="#__codelineno-0-136"> 136</a></span>
<span class="normal"><a href="#__codelineno-0-137"> 137</a></span>
<span class="normal"><a href="#__codelineno-0-138"> 138</a></span>
<span class="normal"><a href="#__codelineno-0-139"> 139</a></span>
<span class="normal"><a href="#__codelineno-0-140"> 140</a></span>
<span class="normal"><a href="#__codelineno-0-141"> 141</a></span>
<span class="normal"><a href="#__codelineno-0-142"> 142</a></span>
<span class="normal"><a href="#__codelineno-0-143"> 143</a></span>
<span class="normal"><a href="#__codelineno-0-144"> 144</a></span>
<span class="normal"><a href="#__codelineno-0-145"> 145</a></span>
<span class="normal"><a href="#__codelineno-0-146"> 146</a></span>
<span class="normal"><a href="#__codelineno-0-147"> 147</a></span>
<span class="normal"><a href="#__codelineno-0-148"> 148</a></span>
<span class="normal"><a href="#__codelineno-0-149"> 149</a></span>
<span class="normal"><a href="#__codelineno-0-150"> 150</a></span>
<span class="normal"><a href="#__codelineno-0-151"> 151</a></span>
<span class="normal"><a href="#__codelineno-0-152"> 152</a></span>
<span class="normal"><a href="#__codelineno-0-153"> 153</a></span>
<span class="normal"><a href="#__codelineno-0-154"> 154</a></span>
<span class="normal"><a href="#__codelineno-0-155"> 155</a></span>
<span class="normal"><a href="#__codelineno-0-156"> 156</a></span>
<span class="normal"><a href="#__codelineno-0-157"> 157</a></span>
<span class="normal"><a href="#__codelineno-0-158"> 158</a></span>
<span class="normal"><a href="#__codelineno-0-159"> 159</a></span>
<span class="normal"><a href="#__codelineno-0-160"> 160</a></span>
<span class="normal"><a href="#__codelineno-0-161"> 161</a></span>
<span class="normal"><a href="#__codelineno-0-162"> 162</a></span>
<span class="normal"><a href="#__codelineno-0-163"> 163</a></span>
<span class="normal"><a href="#__codelineno-0-164"> 164</a></span>
<span class="normal"><a href="#__codelineno-0-165"> 165</a></span>
<span class="normal"><a href="#__codelineno-0-166"> 166</a></span>
<span class="normal"><a href="#__codelineno-0-167"> 167</a></span>
<span class="normal"><a href="#__codelineno-0-168"> 168</a></span>
<span class="normal"><a href="#__codelineno-0-169"> 169</a></span>
<span class="normal"><a href="#__codelineno-0-170"> 170</a></span>
<span class="normal"><a href="#__codelineno-0-171"> 171</a></span>
<span class="normal"><a href="#__codelineno-0-172"> 172</a></span>
<span class="normal"><a href="#__codelineno-0-173"> 173</a></span>
<span class="normal"><a href="#__codelineno-0-174"> 174</a></span>
<span class="normal"><a href="#__codelineno-0-175"> 175</a></span>
<span class="normal"><a href="#__codelineno-0-176"> 176</a></span>
<span class="normal"><a href="#__codelineno-0-177"> 177</a></span>
<span class="normal"><a href="#__codelineno-0-178"> 178</a></span>
<span class="normal"><a href="#__codelineno-0-179"> 179</a></span>
<span class="normal"><a href="#__codelineno-0-180"> 180</a></span>
<span class="normal"><a href="#__codelineno-0-181"> 181</a></span>
<span class="normal"><a href="#__codelineno-0-182"> 182</a></span>
<span class="normal"><a href="#__codelineno-0-183"> 183</a></span>
<span class="normal"><a href="#__codelineno-0-184"> 184</a></span>
<span class="normal"><a href="#__codelineno-0-185"> 185</a></span>
<span class="normal"><a href="#__codelineno-0-186"> 186</a></span>
<span class="normal"><a href="#__codelineno-0-187"> 187</a></span>
<span class="normal"><a href="#__codelineno-0-188"> 188</a></span>
<span class="normal"><a href="#__codelineno-0-189"> 189</a></span>
<span class="normal"><a href="#__codelineno-0-190"> 190</a></span>
<span class="normal"><a href="#__codelineno-0-191"> 191</a></span>
<span class="normal"><a href="#__codelineno-0-192"> 192</a></span>
<span class="normal"><a href="#__codelineno-0-193"> 193</a></span>
<span class="normal"><a href="#__codelineno-0-194"> 194</a></span>
<span class="normal"><a href="#__codelineno-0-195"> 195</a></span>
<span class="normal"><a href="#__codelineno-0-196"> 196</a></span>
<span class="normal"><a href="#__codelineno-0-197"> 197</a></span>
<span class="normal"><a href="#__codelineno-0-198"> 198</a></span>
<span class="normal"><a href="#__codelineno-0-199"> 199</a></span>
<span class="normal"><a href="#__codelineno-0-200"> 200</a></span>
<span class="normal"><a href="#__codelineno-0-201"> 201</a></span>
<span class="normal"><a href="#__codelineno-0-202"> 202</a></span>
<span class="normal"><a href="#__codelineno-0-203"> 203</a></span>
<span class="normal"><a href="#__codelineno-0-204"> 204</a></span>
<span class="normal"><a href="#__codelineno-0-205"> 205</a></span>
<span class="normal"><a href="#__codelineno-0-206"> 206</a></span>
<span class="normal"><a href="#__codelineno-0-207"> 207</a></span>
<span class="normal"><a href="#__codelineno-0-208"> 208</a></span>
<span class="normal"><a href="#__codelineno-0-209"> 209</a></span>
<span class="normal"><a href="#__codelineno-0-210"> 210</a></span>
<span class="normal"><a href="#__codelineno-0-211"> 211</a></span>
<span class="normal"><a href="#__codelineno-0-212"> 212</a></span>
<span class="normal"><a href="#__codelineno-0-213"> 213</a></span>
<span class="normal"><a href="#__codelineno-0-214"> 214</a></span>
<span class="normal"><a href="#__codelineno-0-215"> 215</a></span>
<span class="normal"><a href="#__codelineno-0-216"> 216</a></span>
<span class="normal"><a href="#__codelineno-0-217"> 217</a></span>
<span class="normal"><a href="#__codelineno-0-218"> 218</a></span>
<span class="normal"><a href="#__codelineno-0-219"> 219</a></span>
<span class="normal"><a href="#__codelineno-0-220"> 220</a></span>
<span class="normal"><a href="#__codelineno-0-221"> 221</a></span>
<span class="normal"><a href="#__codelineno-0-222"> 222</a></span>
<span class="normal"><a href="#__codelineno-0-223"> 223</a></span>
<span class="normal"><a href="#__codelineno-0-224"> 224</a></span>
<span class="normal"><a href="#__codelineno-0-225"> 225</a></span>
<span class="normal"><a href="#__codelineno-0-226"> 226</a></span>
<span class="normal"><a href="#__codelineno-0-227"> 227</a></span>
<span class="normal"><a href="#__codelineno-0-228"> 228</a></span>
<span class="normal"><a href="#__codelineno-0-229"> 229</a></span>
<span class="normal"><a href="#__codelineno-0-230"> 230</a></span>
<span class="normal"><a href="#__codelineno-0-231"> 231</a></span>
<span class="normal"><a href="#__codelineno-0-232"> 232</a></span>
<span class="normal"><a href="#__codelineno-0-233"> 233</a></span>
<span class="normal"><a href="#__codelineno-0-234"> 234</a></span>
<span class="normal"><a href="#__codelineno-0-235"> 235</a></span>
<span class="normal"><a href="#__codelineno-0-236"> 236</a></span>
<span class="normal"><a href="#__codelineno-0-237"> 237</a></span>
<span class="normal"><a href="#__codelineno-0-238"> 238</a></span>
<span class="normal"><a href="#__codelineno-0-239"> 239</a></span>
<span class="normal"><a href="#__codelineno-0-240"> 240</a></span>
<span class="normal"><a href="#__codelineno-0-241"> 241</a></span>
<span class="normal"><a href="#__codelineno-0-242"> 242</a></span>
<span class="normal"><a href="#__codelineno-0-243"> 243</a></span>
<span class="normal"><a href="#__codelineno-0-244"> 244</a></span>
<span class="normal"><a href="#__codelineno-0-245"> 245</a></span>
<span class="normal"><a href="#__codelineno-0-246"> 246</a></span>
<span class="normal"><a href="#__codelineno-0-247"> 247</a></span>
<span class="normal"><a href="#__codelineno-0-248"> 248</a></span>
<span class="normal"><a href="#__codelineno-0-249"> 249</a></span>
<span class="normal"><a href="#__codelineno-0-250"> 250</a></span>
<span class="normal"><a href="#__codelineno-0-251"> 251</a></span>
<span class="normal"><a href="#__codelineno-0-252"> 252</a></span>
<span class="normal"><a href="#__codelineno-0-253"> 253</a></span>
<span class="normal"><a href="#__codelineno-0-254"> 254</a></span>
<span class="normal"><a href="#__codelineno-0-255"> 255</a></span>
<span class="normal"><a href="#__codelineno-0-256"> 256</a></span>
<span class="normal"><a href="#__codelineno-0-257"> 257</a></span>
<span class="normal"><a href="#__codelineno-0-258"> 258</a></span>
<span class="normal"><a href="#__codelineno-0-259"> 259</a></span>
<span class="normal"><a href="#__codelineno-0-260"> 260</a></span>
<span class="normal"><a href="#__codelineno-0-261"> 261</a></span>
<span class="normal"><a href="#__codelineno-0-262"> 262</a></span>
<span class="normal"><a href="#__codelineno-0-263"> 263</a></span>
<span class="normal"><a href="#__codelineno-0-264"> 264</a></span>
<span class="normal"><a href="#__codelineno-0-265"> 265</a></span>
<span class="normal"><a href="#__codelineno-0-266"> 266</a></span>
<span class="normal"><a href="#__codelineno-0-267"> 267</a></span>
<span class="normal"><a href="#__codelineno-0-268"> 268</a></span>
<span class="normal"><a href="#__codelineno-0-269"> 269</a></span>
<span class="normal"><a href="#__codelineno-0-270"> 270</a></span>
<span class="normal"><a href="#__codelineno-0-271"> 271</a></span>
<span class="normal"><a href="#__codelineno-0-272"> 272</a></span>
<span class="normal"><a href="#__codelineno-0-273"> 273</a></span>
<span class="normal"><a href="#__codelineno-0-274"> 274</a></span>
<span class="normal"><a href="#__codelineno-0-275"> 275</a></span>
<span class="normal"><a href="#__codelineno-0-276"> 276</a></span>
<span class="normal"><a href="#__codelineno-0-277"> 277</a></span>
<span class="normal"><a href="#__codelineno-0-278"> 278</a></span>
<span class="normal"><a href="#__codelineno-0-279"> 279</a></span>
<span class="normal"><a href="#__codelineno-0-280"> 280</a></span>
<span class="normal"><a href="#__codelineno-0-281"> 281</a></span>
<span class="normal"><a href="#__codelineno-0-282"> 282</a></span>
<span class="normal"><a href="#__codelineno-0-283"> 283</a></span>
<span class="normal"><a href="#__codelineno-0-284"> 284</a></span>
<span class="normal"><a href="#__codelineno-0-285"> 285</a></span>
<span class="normal"><a href="#__codelineno-0-286"> 286</a></span>
<span class="normal"><a href="#__codelineno-0-287"> 287</a></span>
<span class="normal"><a href="#__codelineno-0-288"> 288</a></span>
<span class="normal"><a href="#__codelineno-0-289"> 289</a></span>
<span class="normal"><a href="#__codelineno-0-290"> 290</a></span>
<span class="normal"><a href="#__codelineno-0-291"> 291</a></span>
<span class="normal"><a href="#__codelineno-0-292"> 292</a></span>
<span class="normal"><a href="#__codelineno-0-293"> 293</a></span>
<span class="normal"><a href="#__codelineno-0-294"> 294</a></span>
<span class="normal"><a href="#__codelineno-0-295"> 295</a></span>
<span class="normal"><a href="#__codelineno-0-296"> 296</a></span>
<span class="normal"><a href="#__codelineno-0-297"> 297</a></span>
<span class="normal"><a href="#__codelineno-0-298"> 298</a></span>
<span class="normal"><a href="#__codelineno-0-299"> 299</a></span>
<span class="normal"><a href="#__codelineno-0-300"> 300</a></span>
<span class="normal"><a href="#__codelineno-0-301"> 301</a></span>
<span class="normal"><a href="#__codelineno-0-302"> 302</a></span>
<span class="normal"><a href="#__codelineno-0-303"> 303</a></span>
<span class="normal"><a href="#__codelineno-0-304"> 304</a></span>
<span class="normal"><a href="#__codelineno-0-305"> 305</a></span>
<span class="normal"><a href="#__codelineno-0-306"> 306</a></span>
<span class="normal"><a href="#__codelineno-0-307"> 307</a></span>
<span class="normal"><a href="#__codelineno-0-308"> 308</a></span>
<span class="normal"><a href="#__codelineno-0-309"> 309</a></span>
<span class="normal"><a href="#__codelineno-0-310"> 310</a></span>
<span class="normal"><a href="#__codelineno-0-311"> 311</a></span>
<span class="normal"><a href="#__codelineno-0-312"> 312</a></span>
<span class="normal"><a href="#__codelineno-0-313"> 313</a></span>
<span class="normal"><a href="#__codelineno-0-314"> 314</a></span>
<span class="normal"><a href="#__codelineno-0-315"> 315</a></span>
<span class="normal"><a href="#__codelineno-0-316"> 316</a></span>
<span class="normal"><a href="#__codelineno-0-317"> 317</a></span>
<span class="normal"><a href="#__codelineno-0-318"> 318</a></span>
<span class="normal"><a href="#__codelineno-0-319"> 319</a></span>
<span class="normal"><a href="#__codelineno-0-320"> 320</a></span>
<span class="normal"><a href="#__codelineno-0-321"> 321</a></span>
<span class="normal"><a href="#__codelineno-0-322"> 322</a></span>
<span class="normal"><a href="#__codelineno-0-323"> 323</a></span>
<span class="normal"><a href="#__codelineno-0-324"> 324</a></span>
<span class="normal"><a href="#__codelineno-0-325"> 325</a></span>
<span class="normal"><a href="#__codelineno-0-326"> 326</a></span>
<span class="normal"><a href="#__codelineno-0-327"> 327</a></span>
<span class="normal"><a href="#__codelineno-0-328"> 328</a></span>
<span class="normal"><a href="#__codelineno-0-329"> 329</a></span>
<span class="normal"><a href="#__codelineno-0-330"> 330</a></span>
<span class="normal"><a href="#__codelineno-0-331"> 331</a></span>
<span class="normal"><a href="#__codelineno-0-332"> 332</a></span>
<span class="normal"><a href="#__codelineno-0-333"> 333</a></span>
<span class="normal"><a href="#__codelineno-0-334"> 334</a></span>
<span class="normal"><a href="#__codelineno-0-335"> 335</a></span>
<span class="normal"><a href="#__codelineno-0-336"> 336</a></span>
<span class="normal"><a href="#__codelineno-0-337"> 337</a></span>
<span class="normal"><a href="#__codelineno-0-338"> 338</a></span>
<span class="normal"><a href="#__codelineno-0-339"> 339</a></span>
<span class="normal"><a href="#__codelineno-0-340"> 340</a></span>
<span class="normal"><a href="#__codelineno-0-341"> 341</a></span>
<span class="normal"><a href="#__codelineno-0-342"> 342</a></span>
<span class="normal"><a href="#__codelineno-0-343"> 343</a></span>
<span class="normal"><a href="#__codelineno-0-344"> 344</a></span>
<span class="normal"><a href="#__codelineno-0-345"> 345</a></span>
<span class="normal"><a href="#__codelineno-0-346"> 346</a></span>
<span class="normal"><a href="#__codelineno-0-347"> 347</a></span>
<span class="normal"><a href="#__codelineno-0-348"> 348</a></span>
<span class="normal"><a href="#__codelineno-0-349"> 349</a></span>
<span class="normal"><a href="#__codelineno-0-350"> 350</a></span>
<span class="normal"><a href="#__codelineno-0-351"> 351</a></span>
<span class="normal"><a href="#__codelineno-0-352"> 352</a></span>
<span class="normal"><a href="#__codelineno-0-353"> 353</a></span>
<span class="normal"><a href="#__codelineno-0-354"> 354</a></span>
<span class="normal"><a href="#__codelineno-0-355"> 355</a></span>
<span class="normal"><a href="#__codelineno-0-356"> 356</a></span>
<span class="normal"><a href="#__codelineno-0-357"> 357</a></span>
<span class="normal"><a href="#__codelineno-0-358"> 358</a></span>
<span class="normal"><a href="#__codelineno-0-359"> 359</a></span>
<span class="normal"><a href="#__codelineno-0-360"> 360</a></span>
<span class="normal"><a href="#__codelineno-0-361"> 361</a></span>
<span class="normal"><a href="#__codelineno-0-362"> 362</a></span>
<span class="normal"><a href="#__codelineno-0-363"> 363</a></span>
<span class="normal"><a href="#__codelineno-0-364"> 364</a></span>
<span class="normal"><a href="#__codelineno-0-365"> 365</a></span>
<span class="normal"><a href="#__codelineno-0-366"> 366</a></span>
<span class="normal"><a href="#__codelineno-0-367"> 367</a></span>
<span class="normal"><a href="#__codelineno-0-368"> 368</a></span>
<span class="normal"><a href="#__codelineno-0-369"> 369</a></span>
<span class="normal"><a href="#__codelineno-0-370"> 370</a></span>
<span class="normal"><a href="#__codelineno-0-371"> 371</a></span>
<span class="normal"><a href="#__codelineno-0-372"> 372</a></span>
<span class="normal"><a href="#__codelineno-0-373"> 373</a></span>
<span class="normal"><a href="#__codelineno-0-374"> 374</a></span>
<span class="normal"><a href="#__codelineno-0-375"> 375</a></span>
<span class="normal"><a href="#__codelineno-0-376"> 376</a></span>
<span class="normal"><a href="#__codelineno-0-377"> 377</a></span>
<span class="normal"><a href="#__codelineno-0-378"> 378</a></span>
<span class="normal"><a href="#__codelineno-0-379"> 379</a></span>
<span class="normal"><a href="#__codelineno-0-380"> 380</a></span>
<span class="normal"><a href="#__codelineno-0-381"> 381</a></span>
<span class="normal"><a href="#__codelineno-0-382"> 382</a></span>
<span class="normal"><a href="#__codelineno-0-383"> 383</a></span>
<span class="normal"><a href="#__codelineno-0-384"> 384</a></span>
<span class="normal"><a href="#__codelineno-0-385"> 385</a></span>
<span class="normal"><a href="#__codelineno-0-386"> 386</a></span>
<span class="normal"><a href="#__codelineno-0-387"> 387</a></span>
<span class="normal"><a href="#__codelineno-0-388"> 388</a></span>
<span class="normal"><a href="#__codelineno-0-389"> 389</a></span>
<span class="normal"><a href="#__codelineno-0-390"> 390</a></span>
<span class="normal"><a href="#__codelineno-0-391"> 391</a></span>
<span class="normal"><a href="#__codelineno-0-392"> 392</a></span>
<span class="normal"><a href="#__codelineno-0-393"> 393</a></span>
<span class="normal"><a href="#__codelineno-0-394"> 394</a></span>
<span class="normal"><a href="#__codelineno-0-395"> 395</a></span>
<span class="normal"><a href="#__codelineno-0-396"> 396</a></span>
<span class="normal"><a href="#__codelineno-0-397"> 397</a></span>
<span class="normal"><a href="#__codelineno-0-398"> 398</a></span>
<span class="normal"><a href="#__codelineno-0-399"> 399</a></span>
<span class="normal"><a href="#__codelineno-0-400"> 400</a></span>
<span class="normal"><a href="#__codelineno-0-401"> 401</a></span>
<span class="normal"><a href="#__codelineno-0-402"> 402</a></span>
<span class="normal"><a href="#__codelineno-0-403"> 403</a></span>
<span class="normal"><a href="#__codelineno-0-404"> 404</a></span>
<span class="normal"><a href="#__codelineno-0-405"> 405</a></span>
<span class="normal"><a href="#__codelineno-0-406"> 406</a></span>
<span class="normal"><a href="#__codelineno-0-407"> 407</a></span>
<span class="normal"><a href="#__codelineno-0-408"> 408</a></span>
<span class="normal"><a href="#__codelineno-0-409"> 409</a></span>
<span class="normal"><a href="#__codelineno-0-410"> 410</a></span>
<span class="normal"><a href="#__codelineno-0-411"> 411</a></span>
<span class="normal"><a href="#__codelineno-0-412"> 412</a></span>
<span class="normal"><a href="#__codelineno-0-413"> 413</a></span>
<span class="normal"><a href="#__codelineno-0-414"> 414</a></span>
<span class="normal"><a href="#__codelineno-0-415"> 415</a></span>
<span class="normal"><a href="#__codelineno-0-416"> 416</a></span>
<span class="normal"><a href="#__codelineno-0-417"> 417</a></span>
<span class="normal"><a href="#__codelineno-0-418"> 418</a></span>
<span class="normal"><a href="#__codelineno-0-419"> 419</a></span>
<span class="normal"><a href="#__codelineno-0-420"> 420</a></span>
<span class="normal"><a href="#__codelineno-0-421"> 421</a></span>
<span class="normal"><a href="#__codelineno-0-422"> 422</a></span>
<span class="normal"><a href="#__codelineno-0-423"> 423</a></span>
<span class="normal"><a href="#__codelineno-0-424"> 424</a></span>
<span class="normal"><a href="#__codelineno-0-425"> 425</a></span>
<span class="normal"><a href="#__codelineno-0-426"> 426</a></span>
<span class="normal"><a href="#__codelineno-0-427"> 427</a></span>
<span class="normal"><a href="#__codelineno-0-428"> 428</a></span>
<span class="normal"><a href="#__codelineno-0-429"> 429</a></span>
<span class="normal"><a href="#__codelineno-0-430"> 430</a></span>
<span class="normal"><a href="#__codelineno-0-431"> 431</a></span>
<span class="normal"><a href="#__codelineno-0-432"> 432</a></span>
<span class="normal"><a href="#__codelineno-0-433"> 433</a></span>
<span class="normal"><a href="#__codelineno-0-434"> 434</a></span>
<span class="normal"><a href="#__codelineno-0-435"> 435</a></span>
<span class="normal"><a href="#__codelineno-0-436"> 436</a></span>
<span class="normal"><a href="#__codelineno-0-437"> 437</a></span>
<span class="normal"><a href="#__codelineno-0-438"> 438</a></span>
<span class="normal"><a href="#__codelineno-0-439"> 439</a></span>
<span class="normal"><a href="#__codelineno-0-440"> 440</a></span>
<span class="normal"><a href="#__codelineno-0-441"> 441</a></span>
<span class="normal"><a href="#__codelineno-0-442"> 442</a></span>
<span class="normal"><a href="#__codelineno-0-443"> 443</a></span>
<span class="normal"><a href="#__codelineno-0-444"> 444</a></span>
<span class="normal"><a href="#__codelineno-0-445"> 445</a></span>
<span class="normal"><a href="#__codelineno-0-446"> 446</a></span>
<span class="normal"><a href="#__codelineno-0-447"> 447</a></span>
<span class="normal"><a href="#__codelineno-0-448"> 448</a></span>
<span class="normal"><a href="#__codelineno-0-449"> 449</a></span>
<span class="normal"><a href="#__codelineno-0-450"> 450</a></span>
<span class="normal"><a href="#__codelineno-0-451"> 451</a></span>
<span class="normal"><a href="#__codelineno-0-452"> 452</a></span>
<span class="normal"><a href="#__codelineno-0-453"> 453</a></span>
<span class="normal"><a href="#__codelineno-0-454"> 454</a></span>
<span class="normal"><a href="#__codelineno-0-455"> 455</a></span>
<span class="normal"><a href="#__codelineno-0-456"> 456</a></span>
<span class="normal"><a href="#__codelineno-0-457"> 457</a></span>
<span class="normal"><a href="#__codelineno-0-458"> 458</a></span>
<span class="normal"><a href="#__codelineno-0-459"> 459</a></span>
<span class="normal"><a href="#__codelineno-0-460"> 460</a></span>
<span class="normal"><a href="#__codelineno-0-461"> 461</a></span>
<span class="normal"><a href="#__codelineno-0-462"> 462</a></span>
<span class="normal"><a href="#__codelineno-0-463"> 463</a></span>
<span class="normal"><a href="#__codelineno-0-464"> 464</a></span>
<span class="normal"><a href="#__codelineno-0-465"> 465</a></span>
<span class="normal"><a href="#__codelineno-0-466"> 466</a></span>
<span class="normal"><a href="#__codelineno-0-467"> 467</a></span>
<span class="normal"><a href="#__codelineno-0-468"> 468</a></span>
<span class="normal"><a href="#__codelineno-0-469"> 469</a></span>
<span class="normal"><a href="#__codelineno-0-470"> 470</a></span>
<span class="normal"><a href="#__codelineno-0-471"> 471</a></span>
<span class="normal"><a href="#__codelineno-0-472"> 472</a></span>
<span class="normal"><a href="#__codelineno-0-473"> 473</a></span>
<span class="normal"><a href="#__codelineno-0-474"> 474</a></span>
<span class="normal"><a href="#__codelineno-0-475"> 475</a></span>
<span class="normal"><a href="#__codelineno-0-476"> 476</a></span>
<span class="normal"><a href="#__codelineno-0-477"> 477</a></span>
<span class="normal"><a href="#__codelineno-0-478"> 478</a></span>
<span class="normal"><a href="#__codelineno-0-479"> 479</a></span>
<span class="normal"><a href="#__codelineno-0-480"> 480</a></span>
<span class="normal"><a href="#__codelineno-0-481"> 481</a></span>
<span class="normal"><a href="#__codelineno-0-482"> 482</a></span>
<span class="normal"><a href="#__codelineno-0-483"> 483</a></span>
<span class="normal"><a href="#__codelineno-0-484"> 484</a></span>
<span class="normal"><a href="#__codelineno-0-485"> 485</a></span>
<span class="normal"><a href="#__codelineno-0-486"> 486</a></span>
<span class="normal"><a href="#__codelineno-0-487"> 487</a></span>
<span class="normal"><a href="#__codelineno-0-488"> 488</a></span>
<span class="normal"><a href="#__codelineno-0-489"> 489</a></span>
<span class="normal"><a href="#__codelineno-0-490"> 490</a></span>
<span class="normal"><a href="#__codelineno-0-491"> 491</a></span>
<span class="normal"><a href="#__codelineno-0-492"> 492</a></span>
<span class="normal"><a href="#__codelineno-0-493"> 493</a></span>
<span class="normal"><a href="#__codelineno-0-494"> 494</a></span>
<span class="normal"><a href="#__codelineno-0-495"> 495</a></span>
<span class="normal"><a href="#__codelineno-0-496"> 496</a></span>
<span class="normal"><a href="#__codelineno-0-497"> 497</a></span>
<span class="normal"><a href="#__codelineno-0-498"> 498</a></span>
<span class="normal"><a href="#__codelineno-0-499"> 499</a></span>
<span class="normal"><a href="#__codelineno-0-500"> 500</a></span>
<span class="normal"><a href="#__codelineno-0-501"> 501</a></span>
<span class="normal"><a href="#__codelineno-0-502"> 502</a></span>
<span class="normal"><a href="#__codelineno-0-503"> 503</a></span>
<span class="normal"><a href="#__codelineno-0-504"> 504</a></span>
<span class="normal"><a href="#__codelineno-0-505"> 505</a></span>
<span class="normal"><a href="#__codelineno-0-506"> 506</a></span>
<span class="normal"><a href="#__codelineno-0-507"> 507</a></span>
<span class="normal"><a href="#__codelineno-0-508"> 508</a></span>
<span class="normal"><a href="#__codelineno-0-509"> 509</a></span>
<span class="normal"><a href="#__codelineno-0-510"> 510</a></span>
<span class="normal"><a href="#__codelineno-0-511"> 511</a></span>
<span class="normal"><a href="#__codelineno-0-512"> 512</a></span>
<span class="normal"><a href="#__codelineno-0-513"> 513</a></span>
<span class="normal"><a href="#__codelineno-0-514"> 514</a></span>
<span class="normal"><a href="#__codelineno-0-515"> 515</a></span>
<span class="normal"><a href="#__codelineno-0-516"> 516</a></span>
<span class="normal"><a href="#__codelineno-0-517"> 517</a></span>
<span class="normal"><a href="#__codelineno-0-518"> 518</a></span>
<span class="normal"><a href="#__codelineno-0-519"> 519</a></span>
<span class="normal"><a href="#__codelineno-0-520"> 520</a></span>
<span class="normal"><a href="#__codelineno-0-521"> 521</a></span>
<span class="normal"><a href="#__codelineno-0-522"> 522</a></span>
<span class="normal"><a href="#__codelineno-0-523"> 523</a></span>
<span class="normal"><a href="#__codelineno-0-524"> 524</a></span>
<span class="normal"><a href="#__codelineno-0-525"> 525</a></span>
<span class="normal"><a href="#__codelineno-0-526"> 526</a></span>
<span class="normal"><a href="#__codelineno-0-527"> 527</a></span>
<span class="normal"><a href="#__codelineno-0-528"> 528</a></span>
<span class="normal"><a href="#__codelineno-0-529"> 529</a></span>
<span class="normal"><a href="#__codelineno-0-530"> 530</a></span>
<span class="normal"><a href="#__codelineno-0-531"> 531</a></span>
<span class="normal"><a href="#__codelineno-0-532"> 532</a></span>
<span class="normal"><a href="#__codelineno-0-533"> 533</a></span>
<span class="normal"><a href="#__codelineno-0-534"> 534</a></span>
<span class="normal"><a href="#__codelineno-0-535"> 535</a></span>
<span class="normal"><a href="#__codelineno-0-536"> 536</a></span>
<span class="normal"><a href="#__codelineno-0-537"> 537</a></span>
<span class="normal"><a href="#__codelineno-0-538"> 538</a></span>
<span class="normal"><a href="#__codelineno-0-539"> 539</a></span>
<span class="normal"><a href="#__codelineno-0-540"> 540</a></span>
<span class="normal"><a href="#__codelineno-0-541"> 541</a></span>
<span class="normal"><a href="#__codelineno-0-542"> 542</a></span>
<span class="normal"><a href="#__codelineno-0-543"> 543</a></span>
<span class="normal"><a href="#__codelineno-0-544"> 544</a></span>
<span class="normal"><a href="#__codelineno-0-545"> 545</a></span>
<span class="normal"><a href="#__codelineno-0-546"> 546</a></span>
<span class="normal"><a href="#__codelineno-0-547"> 547</a></span>
<span class="normal"><a href="#__codelineno-0-548"> 548</a></span>
<span class="normal"><a href="#__codelineno-0-549"> 549</a></span>
<span class="normal"><a href="#__codelineno-0-550"> 550</a></span>
<span class="normal"><a href="#__codelineno-0-551"> 551</a></span>
<span class="normal"><a href="#__codelineno-0-552"> 552</a></span>
<span class="normal"><a href="#__codelineno-0-553"> 553</a></span>
<span class="normal"><a href="#__codelineno-0-554"> 554</a></span>
<span class="normal"><a href="#__codelineno-0-555"> 555</a></span>
<span class="normal"><a href="#__codelineno-0-556"> 556</a></span>
<span class="normal"><a href="#__codelineno-0-557"> 557</a></span>
<span class="normal"><a href="#__codelineno-0-558"> 558</a></span>
<span class="normal"><a href="#__codelineno-0-559"> 559</a></span>
<span class="normal"><a href="#__codelineno-0-560"> 560</a></span>
<span class="normal"><a href="#__codelineno-0-561"> 561</a></span>
<span class="normal"><a href="#__codelineno-0-562"> 562</a></span>
<span class="normal"><a href="#__codelineno-0-563"> 563</a></span>
<span class="normal"><a href="#__codelineno-0-564"> 564</a></span>
<span class="normal"><a href="#__codelineno-0-565"> 565</a></span>
<span class="normal"><a href="#__codelineno-0-566"> 566</a></span>
<span class="normal"><a href="#__codelineno-0-567"> 567</a></span>
<span class="normal"><a href="#__codelineno-0-568"> 568</a></span>
<span class="normal"><a href="#__codelineno-0-569"> 569</a></span>
<span class="normal"><a href="#__codelineno-0-570"> 570</a></span>
<span class="normal"><a href="#__codelineno-0-571"> 571</a></span>
<span class="normal"><a href="#__codelineno-0-572"> 572</a></span>
<span class="normal"><a href="#__codelineno-0-573"> 573</a></span>
<span class="normal"><a href="#__codelineno-0-574"> 574</a></span>
<span class="normal"><a href="#__codelineno-0-575"> 575</a></span>
<span class="normal"><a href="#__codelineno-0-576"> 576</a></span>
<span class="normal"><a href="#__codelineno-0-577"> 577</a></span>
<span class="normal"><a href="#__codelineno-0-578"> 578</a></span>
<span class="normal"><a href="#__codelineno-0-579"> 579</a></span>
<span class="normal"><a href="#__codelineno-0-580"> 580</a></span>
<span class="normal"><a href="#__codelineno-0-581"> 581</a></span>
<span class="normal"><a href="#__codelineno-0-582"> 582</a></span>
<span class="normal"><a href="#__codelineno-0-583"> 583</a></span>
<span class="normal"><a href="#__codelineno-0-584"> 584</a></span>
<span class="normal"><a href="#__codelineno-0-585"> 585</a></span>
<span class="normal"><a href="#__codelineno-0-586"> 586</a></span>
<span class="normal"><a href="#__codelineno-0-587"> 587</a></span>
<span class="normal"><a href="#__codelineno-0-588"> 588</a></span>
<span class="normal"><a href="#__codelineno-0-589"> 589</a></span>
<span class="normal"><a href="#__codelineno-0-590"> 590</a></span>
<span class="normal"><a href="#__codelineno-0-591"> 591</a></span>
<span class="normal"><a href="#__codelineno-0-592"> 592</a></span>
<span class="normal"><a href="#__codelineno-0-593"> 593</a></span>
<span class="normal"><a href="#__codelineno-0-594"> 594</a></span>
<span class="normal"><a href="#__codelineno-0-595"> 595</a></span>
<span class="normal"><a href="#__codelineno-0-596"> 596</a></span>
<span class="normal"><a href="#__codelineno-0-597"> 597</a></span>
<span class="normal"><a href="#__codelineno-0-598"> 598</a></span>
<span class="normal"><a href="#__codelineno-0-599"> 599</a></span>
<span class="normal"><a href="#__codelineno-0-600"> 600</a></span>
<span class="normal"><a href="#__codelineno-0-601"> 601</a></span>
<span class="normal"><a href="#__codelineno-0-602"> 602</a></span>
<span class="normal"><a href="#__codelineno-0-603"> 603</a></span>
<span class="normal"><a href="#__codelineno-0-604"> 604</a></span>
<span class="normal"><a href="#__codelineno-0-605"> 605</a></span>
<span class="normal"><a href="#__codelineno-0-606"> 606</a></span>
<span class="normal"><a href="#__codelineno-0-607"> 607</a></span>
<span class="normal"><a href="#__codelineno-0-608"> 608</a></span>
<span class="normal"><a href="#__codelineno-0-609"> 609</a></span>
<span class="normal"><a href="#__codelineno-0-610"> 610</a></span>
<span class="normal"><a href="#__codelineno-0-611"> 611</a></span>
<span class="normal"><a href="#__codelineno-0-612"> 612</a></span>
<span class="normal"><a href="#__codelineno-0-613"> 613</a></span>
<span class="normal"><a href="#__codelineno-0-614"> 614</a></span>
<span class="normal"><a href="#__codelineno-0-615"> 615</a></span>
<span class="normal"><a href="#__codelineno-0-616"> 616</a></span>
<span class="normal"><a href="#__codelineno-0-617"> 617</a></span>
<span class="normal"><a href="#__codelineno-0-618"> 618</a></span>
<span class="normal"><a href="#__codelineno-0-619"> 619</a></span>
<span class="normal"><a href="#__codelineno-0-620"> 620</a></span>
<span class="normal"><a href="#__codelineno-0-621"> 621</a></span>
<span class="normal"><a href="#__codelineno-0-622"> 622</a></span>
<span class="normal"><a href="#__codelineno-0-623"> 623</a></span>
<span class="normal"><a href="#__codelineno-0-624"> 624</a></span>
<span class="normal"><a href="#__codelineno-0-625"> 625</a></span>
<span class="normal"><a href="#__codelineno-0-626"> 626</a></span>
<span class="normal"><a href="#__codelineno-0-627"> 627</a></span>
<span class="normal"><a href="#__codelineno-0-628"> 628</a></span>
<span class="normal"><a href="#__codelineno-0-629"> 629</a></span>
<span class="normal"><a href="#__codelineno-0-630"> 630</a></span>
<span class="normal"><a href="#__codelineno-0-631"> 631</a></span>
<span class="normal"><a href="#__codelineno-0-632"> 632</a></span>
<span class="normal"><a href="#__codelineno-0-633"> 633</a></span>
<span class="normal"><a href="#__codelineno-0-634"> 634</a></span>
<span class="normal"><a href="#__codelineno-0-635"> 635</a></span>
<span class="normal"><a href="#__codelineno-0-636"> 636</a></span>
<span class="normal"><a href="#__codelineno-0-637"> 637</a></span>
<span class="normal"><a href="#__codelineno-0-638"> 638</a></span>
<span class="normal"><a href="#__codelineno-0-639"> 639</a></span>
<span class="normal"><a href="#__codelineno-0-640"> 640</a></span>
<span class="normal"><a href="#__codelineno-0-641"> 641</a></span>
<span class="normal"><a href="#__codelineno-0-642"> 642</a></span>
<span class="normal"><a href="#__codelineno-0-643"> 643</a></span>
<span class="normal"><a href="#__codelineno-0-644"> 644</a></span>
<span class="normal"><a href="#__codelineno-0-645"> 645</a></span>
<span class="normal"><a href="#__codelineno-0-646"> 646</a></span>
<span class="normal"><a href="#__codelineno-0-647"> 647</a></span>
<span class="normal"><a href="#__codelineno-0-648"> 648</a></span>
<span class="normal"><a href="#__codelineno-0-649"> 649</a></span>
<span class="normal"><a href="#__codelineno-0-650"> 650</a></span>
<span class="normal"><a href="#__codelineno-0-651"> 651</a></span>
<span class="normal"><a href="#__codelineno-0-652"> 652</a></span>
<span class="normal"><a href="#__codelineno-0-653"> 653</a></span>
<span class="normal"><a href="#__codelineno-0-654"> 654</a></span>
<span class="normal"><a href="#__codelineno-0-655"> 655</a></span>
<span class="normal"><a href="#__codelineno-0-656"> 656</a></span>
<span class="normal"><a href="#__codelineno-0-657"> 657</a></span>
<span class="normal"><a href="#__codelineno-0-658"> 658</a></span>
<span class="normal"><a href="#__codelineno-0-659"> 659</a></span>
<span class="normal"><a href="#__codelineno-0-660"> 660</a></span>
<span class="normal"><a href="#__codelineno-0-661"> 661</a></span>
<span class="normal"><a href="#__codelineno-0-662"> 662</a></span>
<span class="normal"><a href="#__codelineno-0-663"> 663</a></span>
<span class="normal"><a href="#__codelineno-0-664"> 664</a></span>
<span class="normal"><a href="#__codelineno-0-665"> 665</a></span>
<span class="normal"><a href="#__codelineno-0-666"> 666</a></span>
<span class="normal"><a href="#__codelineno-0-667"> 667</a></span>
<span class="normal"><a href="#__codelineno-0-668"> 668</a></span>
<span class="normal"><a href="#__codelineno-0-669"> 669</a></span>
<span class="normal"><a href="#__codelineno-0-670"> 670</a></span>
<span class="normal"><a href="#__codelineno-0-671"> 671</a></span>
<span class="normal"><a href="#__codelineno-0-672"> 672</a></span>
<span class="normal"><a href="#__codelineno-0-673"> 673</a></span>
<span class="normal"><a href="#__codelineno-0-674"> 674</a></span>
<span class="normal"><a href="#__codelineno-0-675"> 675</a></span>
<span class="normal"><a href="#__codelineno-0-676"> 676</a></span>
<span class="normal"><a href="#__codelineno-0-677"> 677</a></span>
<span class="normal"><a href="#__codelineno-0-678"> 678</a></span>
<span class="normal"><a href="#__codelineno-0-679"> 679</a></span>
<span class="normal"><a href="#__codelineno-0-680"> 680</a></span>
<span class="normal"><a href="#__codelineno-0-681"> 681</a></span>
<span class="normal"><a href="#__codelineno-0-682"> 682</a></span>
<span class="normal"><a href="#__codelineno-0-683"> 683</a></span>
<span class="normal"><a href="#__codelineno-0-684"> 684</a></span>
<span class="normal"><a href="#__codelineno-0-685"> 685</a></span>
<span class="normal"><a href="#__codelineno-0-686"> 686</a></span>
<span class="normal"><a href="#__codelineno-0-687"> 687</a></span>
<span class="normal"><a href="#__codelineno-0-688"> 688</a></span>
<span class="normal"><a href="#__codelineno-0-689"> 689</a></span>
<span class="normal"><a href="#__codelineno-0-690"> 690</a></span>
<span class="normal"><a href="#__codelineno-0-691"> 691</a></span>
<span class="normal"><a href="#__codelineno-0-692"> 692</a></span>
<span class="normal"><a href="#__codelineno-0-693"> 693</a></span>
<span class="normal"><a href="#__codelineno-0-694"> 694</a></span>
<span class="normal"><a href="#__codelineno-0-695"> 695</a></span>
<span class="normal"><a href="#__codelineno-0-696"> 696</a></span>
<span class="normal"><a href="#__codelineno-0-697"> 697</a></span>
<span class="normal"><a href="#__codelineno-0-698"> 698</a></span>
<span class="normal"><a href="#__codelineno-0-699"> 699</a></span>
<span class="normal"><a href="#__codelineno-0-700"> 700</a></span>
<span class="normal"><a href="#__codelineno-0-701"> 701</a></span>
<span class="normal"><a href="#__codelineno-0-702"> 702</a></span>
<span class="normal"><a href="#__codelineno-0-703"> 703</a></span>
<span class="normal"><a href="#__codelineno-0-704"> 704</a></span>
<span class="normal"><a href="#__codelineno-0-705"> 705</a></span>
<span class="normal"><a href="#__codelineno-0-706"> 706</a></span>
<span class="normal"><a href="#__codelineno-0-707"> 707</a></span>
<span class="normal"><a href="#__codelineno-0-708"> 708</a></span>
<span class="normal"><a href="#__codelineno-0-709"> 709</a></span>
<span class="normal"><a href="#__codelineno-0-710"> 710</a></span>
<span class="normal"><a href="#__codelineno-0-711"> 711</a></span>
<span class="normal"><a href="#__codelineno-0-712"> 712</a></span>
<span class="normal"><a href="#__codelineno-0-713"> 713</a></span>
<span class="normal"><a href="#__codelineno-0-714"> 714</a></span>
<span class="normal"><a href="#__codelineno-0-715"> 715</a></span>
<span class="normal"><a href="#__codelineno-0-716"> 716</a></span>
<span class="normal"><a href="#__codelineno-0-717"> 717</a></span>
<span class="normal"><a href="#__codelineno-0-718"> 718</a></span>
<span class="normal"><a href="#__codelineno-0-719"> 719</a></span>
<span class="normal"><a href="#__codelineno-0-720"> 720</a></span>
<span class="normal"><a href="#__codelineno-0-721"> 721</a></span>
<span class="normal"><a href="#__codelineno-0-722"> 722</a></span>
<span class="normal"><a href="#__codelineno-0-723"> 723</a></span>
<span class="normal"><a href="#__codelineno-0-724"> 724</a></span>
<span class="normal"><a href="#__codelineno-0-725"> 725</a></span>
<span class="normal"><a href="#__codelineno-0-726"> 726</a></span>
<span class="normal"><a href="#__codelineno-0-727"> 727</a></span>
<span class="normal"><a href="#__codelineno-0-728"> 728</a></span>
<span class="normal"><a href="#__codelineno-0-729"> 729</a></span>
<span class="normal"><a href="#__codelineno-0-730"> 730</a></span>
<span class="normal"><a href="#__codelineno-0-731"> 731</a></span>
<span class="normal"><a href="#__codelineno-0-732"> 732</a></span>
<span class="normal"><a href="#__codelineno-0-733"> 733</a></span>
<span class="normal"><a href="#__codelineno-0-734"> 734</a></span>
<span class="normal"><a href="#__codelineno-0-735"> 735</a></span>
<span class="normal"><a href="#__codelineno-0-736"> 736</a></span>
<span class="normal"><a href="#__codelineno-0-737"> 737</a></span>
<span class="normal"><a href="#__codelineno-0-738"> 738</a></span>
<span class="normal"><a href="#__codelineno-0-739"> 739</a></span>
<span class="normal"><a href="#__codelineno-0-740"> 740</a></span>
<span class="normal"><a href="#__codelineno-0-741"> 741</a></span>
<span class="normal"><a href="#__codelineno-0-742"> 742</a></span>
<span class="normal"><a href="#__codelineno-0-743"> 743</a></span>
<span class="normal"><a href="#__codelineno-0-744"> 744</a></span>
<span class="normal"><a href="#__codelineno-0-745"> 745</a></span>
<span class="normal"><a href="#__codelineno-0-746"> 746</a></span>
<span class="normal"><a href="#__codelineno-0-747"> 747</a></span>
<span class="normal"><a href="#__codelineno-0-748"> 748</a></span>
<span class="normal"><a href="#__codelineno-0-749"> 749</a></span>
<span class="normal"><a href="#__codelineno-0-750"> 750</a></span>
<span class="normal"><a href="#__codelineno-0-751"> 751</a></span>
<span class="normal"><a href="#__codelineno-0-752"> 752</a></span>
<span class="normal"><a href="#__codelineno-0-753"> 753</a></span>
<span class="normal"><a href="#__codelineno-0-754"> 754</a></span>
<span class="normal"><a href="#__codelineno-0-755"> 755</a></span>
<span class="normal"><a href="#__codelineno-0-756"> 756</a></span>
<span class="normal"><a href="#__codelineno-0-757"> 757</a></span>
<span class="normal"><a href="#__codelineno-0-758"> 758</a></span>
<span class="normal"><a href="#__codelineno-0-759"> 759</a></span>
<span class="normal"><a href="#__codelineno-0-760"> 760</a></span>
<span class="normal"><a href="#__codelineno-0-761"> 761</a></span>
<span class="normal"><a href="#__codelineno-0-762"> 762</a></span>
<span class="normal"><a href="#__codelineno-0-763"> 763</a></span>
<span class="normal"><a href="#__codelineno-0-764"> 764</a></span>
<span class="normal"><a href="#__codelineno-0-765"> 765</a></span>
<span class="normal"><a href="#__codelineno-0-766"> 766</a></span>
<span class="normal"><a href="#__codelineno-0-767"> 767</a></span>
<span class="normal"><a href="#__codelineno-0-768"> 768</a></span>
<span class="normal"><a href="#__codelineno-0-769"> 769</a></span>
<span class="normal"><a href="#__codelineno-0-770"> 770</a></span>
<span class="normal"><a href="#__codelineno-0-771"> 771</a></span>
<span class="normal"><a href="#__codelineno-0-772"> 772</a></span>
<span class="normal"><a href="#__codelineno-0-773"> 773</a></span>
<span class="normal"><a href="#__codelineno-0-774"> 774</a></span>
<span class="normal"><a href="#__codelineno-0-775"> 775</a></span>
<span class="normal"><a href="#__codelineno-0-776"> 776</a></span>
<span class="normal"><a href="#__codelineno-0-777"> 777</a></span>
<span class="normal"><a href="#__codelineno-0-778"> 778</a></span>
<span class="normal"><a href="#__codelineno-0-779"> 779</a></span>
<span class="normal"><a href="#__codelineno-0-780"> 780</a></span>
<span class="normal"><a href="#__codelineno-0-781"> 781</a></span>
<span class="normal"><a href="#__codelineno-0-782"> 782</a></span>
<span class="normal"><a href="#__codelineno-0-783"> 783</a></span>
<span class="normal"><a href="#__codelineno-0-784"> 784</a></span>
<span class="normal"><a href="#__codelineno-0-785"> 785</a></span>
<span class="normal"><a href="#__codelineno-0-786"> 786</a></span>
<span class="normal"><a href="#__codelineno-0-787"> 787</a></span>
<span class="normal"><a href="#__codelineno-0-788"> 788</a></span>
<span class="normal"><a href="#__codelineno-0-789"> 789</a></span>
<span class="normal"><a href="#__codelineno-0-790"> 790</a></span>
<span class="normal"><a href="#__codelineno-0-791"> 791</a></span>
<span class="normal"><a href="#__codelineno-0-792"> 792</a></span>
<span class="normal"><a href="#__codelineno-0-793"> 793</a></span>
<span class="normal"><a href="#__codelineno-0-794"> 794</a></span>
<span class="normal"><a href="#__codelineno-0-795"> 795</a></span>
<span class="normal"><a href="#__codelineno-0-796"> 796</a></span>
<span class="normal"><a href="#__codelineno-0-797"> 797</a></span>
<span class="normal"><a href="#__codelineno-0-798"> 798</a></span>
<span class="normal"><a href="#__codelineno-0-799"> 799</a></span>
<span class="normal"><a href="#__codelineno-0-800"> 800</a></span>
<span class="normal"><a href="#__codelineno-0-801"> 801</a></span>
<span class="normal"><a href="#__codelineno-0-802"> 802</a></span>
<span class="normal"><a href="#__codelineno-0-803"> 803</a></span>
<span class="normal"><a href="#__codelineno-0-804"> 804</a></span>
<span class="normal"><a href="#__codelineno-0-805"> 805</a></span>
<span class="normal"><a href="#__codelineno-0-806"> 806</a></span>
<span class="normal"><a href="#__codelineno-0-807"> 807</a></span>
<span class="normal"><a href="#__codelineno-0-808"> 808</a></span>
<span class="normal"><a href="#__codelineno-0-809"> 809</a></span>
<span class="normal"><a href="#__codelineno-0-810"> 810</a></span>
<span class="normal"><a href="#__codelineno-0-811"> 811</a></span>
<span class="normal"><a href="#__codelineno-0-812"> 812</a></span>
<span class="normal"><a href="#__codelineno-0-813"> 813</a></span>
<span class="normal"><a href="#__codelineno-0-814"> 814</a></span>
<span class="normal"><a href="#__codelineno-0-815"> 815</a></span>
<span class="normal"><a href="#__codelineno-0-816"> 816</a></span>
<span class="normal"><a href="#__codelineno-0-817"> 817</a></span>
<span class="normal"><a href="#__codelineno-0-818"> 818</a></span>
<span class="normal"><a href="#__codelineno-0-819"> 819</a></span>
<span class="normal"><a href="#__codelineno-0-820"> 820</a></span>
<span class="normal"><a href="#__codelineno-0-821"> 821</a></span>
<span class="normal"><a href="#__codelineno-0-822"> 822</a></span>
<span class="normal"><a href="#__codelineno-0-823"> 823</a></span>
<span class="normal"><a href="#__codelineno-0-824"> 824</a></span>
<span class="normal"><a href="#__codelineno-0-825"> 825</a></span>
<span class="normal"><a href="#__codelineno-0-826"> 826</a></span>
<span class="normal"><a href="#__codelineno-0-827"> 827</a></span>
<span class="normal"><a href="#__codelineno-0-828"> 828</a></span>
<span class="normal"><a href="#__codelineno-0-829"> 829</a></span>
<span class="normal"><a href="#__codelineno-0-830"> 830</a></span>
<span class="normal"><a href="#__codelineno-0-831"> 831</a></span>
<span class="normal"><a href="#__codelineno-0-832"> 832</a></span>
<span class="normal"><a href="#__codelineno-0-833"> 833</a></span>
<span class="normal"><a href="#__codelineno-0-834"> 834</a></span>
<span class="normal"><a href="#__codelineno-0-835"> 835</a></span>
<span class="normal"><a href="#__codelineno-0-836"> 836</a></span>
<span class="normal"><a href="#__codelineno-0-837"> 837</a></span>
<span class="normal"><a href="#__codelineno-0-838"> 838</a></span>
<span class="normal"><a href="#__codelineno-0-839"> 839</a></span>
<span class="normal"><a href="#__codelineno-0-840"> 840</a></span>
<span class="normal"><a href="#__codelineno-0-841"> 841</a></span>
<span class="normal"><a href="#__codelineno-0-842"> 842</a></span>
<span class="normal"><a href="#__codelineno-0-843"> 843</a></span>
<span class="normal"><a href="#__codelineno-0-844"> 844</a></span>
<span class="normal"><a href="#__codelineno-0-845"> 845</a></span>
<span class="normal"><a href="#__codelineno-0-846"> 846</a></span>
<span class="normal"><a href="#__codelineno-0-847"> 847</a></span>
<span class="normal"><a href="#__codelineno-0-848"> 848</a></span>
<span class="normal"><a href="#__codelineno-0-849"> 849</a></span>
<span class="normal"><a href="#__codelineno-0-850"> 850</a></span>
<span class="normal"><a href="#__codelineno-0-851"> 851</a></span>
<span class="normal"><a href="#__codelineno-0-852"> 852</a></span>
<span class="normal"><a href="#__codelineno-0-853"> 853</a></span>
<span class="normal"><a href="#__codelineno-0-854"> 854</a></span>
<span class="normal"><a href="#__codelineno-0-855"> 855</a></span>
<span class="normal"><a href="#__codelineno-0-856"> 856</a></span>
<span class="normal"><a href="#__codelineno-0-857"> 857</a></span>
<span class="normal"><a href="#__codelineno-0-858"> 858</a></span>
<span class="normal"><a href="#__codelineno-0-859"> 859</a></span>
<span class="normal"><a href="#__codelineno-0-860"> 860</a></span>
<span class="normal"><a href="#__codelineno-0-861"> 861</a></span>
<span class="normal"><a href="#__codelineno-0-862"> 862</a></span>
<span class="normal"><a href="#__codelineno-0-863"> 863</a></span>
<span class="normal"><a href="#__codelineno-0-864"> 864</a></span>
<span class="normal"><a href="#__codelineno-0-865"> 865</a></span>
<span class="normal"><a href="#__codelineno-0-866"> 866</a></span>
<span class="normal"><a href="#__codelineno-0-867"> 867</a></span>
<span class="normal"><a href="#__codelineno-0-868"> 868</a></span>
<span class="normal"><a href="#__codelineno-0-869"> 869</a></span>
<span class="normal"><a href="#__codelineno-0-870"> 870</a></span>
<span class="normal"><a href="#__codelineno-0-871"> 871</a></span>
<span class="normal"><a href="#__codelineno-0-872"> 872</a></span>
<span class="normal"><a href="#__codelineno-0-873"> 873</a></span>
<span class="normal"><a href="#__codelineno-0-874"> 874</a></span>
<span class="normal"><a href="#__codelineno-0-875"> 875</a></span>
<span class="normal"><a href="#__codelineno-0-876"> 876</a></span>
<span class="normal"><a href="#__codelineno-0-877"> 877</a></span>
<span class="normal"><a href="#__codelineno-0-878"> 878</a></span>
<span class="normal"><a href="#__codelineno-0-879"> 879</a></span>
<span class="normal"><a href="#__codelineno-0-880"> 880</a></span>
<span class="normal"><a href="#__codelineno-0-881"> 881</a></span>
<span class="normal"><a href="#__codelineno-0-882"> 882</a></span>
<span class="normal"><a href="#__codelineno-0-883"> 883</a></span>
<span class="normal"><a href="#__codelineno-0-884"> 884</a></span>
<span class="normal"><a href="#__codelineno-0-885"> 885</a></span>
<span class="normal"><a href="#__codelineno-0-886"> 886</a></span>
<span class="normal"><a href="#__codelineno-0-887"> 887</a></span>
<span class="normal"><a href="#__codelineno-0-888"> 888</a></span>
<span class="normal"><a href="#__codelineno-0-889"> 889</a></span>
<span class="normal"><a href="#__codelineno-0-890"> 890</a></span>
<span class="normal"><a href="#__codelineno-0-891"> 891</a></span>
<span class="normal"><a href="#__codelineno-0-892"> 892</a></span>
<span class="normal"><a href="#__codelineno-0-893"> 893</a></span>
<span class="normal"><a href="#__codelineno-0-894"> 894</a></span>
<span class="normal"><a href="#__codelineno-0-895"> 895</a></span>
<span class="normal"><a href="#__codelineno-0-896"> 896</a></span>
<span class="normal"><a href="#__codelineno-0-897"> 897</a></span>
<span class="normal"><a href="#__codelineno-0-898"> 898</a></span>
<span class="normal"><a href="#__codelineno-0-899"> 899</a></span>
<span class="normal"><a href="#__codelineno-0-900"> 900</a></span>
<span class="normal"><a href="#__codelineno-0-901"> 901</a></span>
<span class="normal"><a href="#__codelineno-0-902"> 902</a></span>
<span class="normal"><a href="#__codelineno-0-903"> 903</a></span>
<span class="normal"><a href="#__codelineno-0-904"> 904</a></span>
<span class="normal"><a href="#__codelineno-0-905"> 905</a></span>
<span class="normal"><a href="#__codelineno-0-906"> 906</a></span>
<span class="normal"><a href="#__codelineno-0-907"> 907</a></span>
<span class="normal"><a href="#__codelineno-0-908"> 908</a></span>
<span class="normal"><a href="#__codelineno-0-909"> 909</a></span>
<span class="normal"><a href="#__codelineno-0-910"> 910</a></span>
<span class="normal"><a href="#__codelineno-0-911"> 911</a></span>
<span class="normal"><a href="#__codelineno-0-912"> 912</a></span>
<span class="normal"><a href="#__codelineno-0-913"> 913</a></span>
<span class="normal"><a href="#__codelineno-0-914"> 914</a></span>
<span class="normal"><a href="#__codelineno-0-915"> 915</a></span>
<span class="normal"><a href="#__codelineno-0-916"> 916</a></span>
<span class="normal"><a href="#__codelineno-0-917"> 917</a></span>
<span class="normal"><a href="#__codelineno-0-918"> 918</a></span>
<span class="normal"><a href="#__codelineno-0-919"> 919</a></span>
<span class="normal"><a href="#__codelineno-0-920"> 920</a></span>
<span class="normal"><a href="#__codelineno-0-921"> 921</a></span>
<span class="normal"><a href="#__codelineno-0-922"> 922</a></span>
<span class="normal"><a href="#__codelineno-0-923"> 923</a></span>
<span class="normal"><a href="#__codelineno-0-924"> 924</a></span>
<span class="normal"><a href="#__codelineno-0-925"> 925</a></span>
<span class="normal"><a href="#__codelineno-0-926"> 926</a></span>
<span class="normal"><a href="#__codelineno-0-927"> 927</a></span>
<span class="normal"><a href="#__codelineno-0-928"> 928</a></span>
<span class="normal"><a href="#__codelineno-0-929"> 929</a></span>
<span class="normal"><a href="#__codelineno-0-930"> 930</a></span>
<span class="normal"><a href="#__codelineno-0-931"> 931</a></span>
<span class="normal"><a href="#__codelineno-0-932"> 932</a></span>
<span class="normal"><a href="#__codelineno-0-933"> 933</a></span>
<span class="normal"><a href="#__codelineno-0-934"> 934</a></span>
<span class="normal"><a href="#__codelineno-0-935"> 935</a></span>
<span class="normal"><a href="#__codelineno-0-936"> 936</a></span>
<span class="normal"><a href="#__codelineno-0-937"> 937</a></span>
<span class="normal"><a href="#__codelineno-0-938"> 938</a></span>
<span class="normal"><a href="#__codelineno-0-939"> 939</a></span>
<span class="normal"><a href="#__codelineno-0-940"> 940</a></span>
<span class="normal"><a href="#__codelineno-0-941"> 941</a></span>
<span class="normal"><a href="#__codelineno-0-942"> 942</a></span>
<span class="normal"><a href="#__codelineno-0-943"> 943</a></span>
<span class="normal"><a href="#__codelineno-0-944"> 944</a></span>
<span class="normal"><a href="#__codelineno-0-945"> 945</a></span>
<span class="normal"><a href="#__codelineno-0-946"> 946</a></span>
<span class="normal"><a href="#__codelineno-0-947"> 947</a></span>
<span class="normal"><a href="#__codelineno-0-948"> 948</a></span>
<span class="normal"><a href="#__codelineno-0-949"> 949</a></span>
<span class="normal"><a href="#__codelineno-0-950"> 950</a></span>
<span class="normal"><a href="#__codelineno-0-951"> 951</a></span>
<span class="normal"><a href="#__codelineno-0-952"> 952</a></span>
<span class="normal"><a href="#__codelineno-0-953"> 953</a></span>
<span class="normal"><a href="#__codelineno-0-954"> 954</a></span>
<span class="normal"><a href="#__codelineno-0-955"> 955</a></span>
<span class="normal"><a href="#__codelineno-0-956"> 956</a></span>
<span class="normal"><a href="#__codelineno-0-957"> 957</a></span>
<span class="normal"><a href="#__codelineno-0-958"> 958</a></span>
<span class="normal"><a href="#__codelineno-0-959"> 959</a></span>
<span class="normal"><a href="#__codelineno-0-960"> 960</a></span>
<span class="normal"><a href="#__codelineno-0-961"> 961</a></span>
<span class="normal"><a href="#__codelineno-0-962"> 962</a></span>
<span class="normal"><a href="#__codelineno-0-963"> 963</a></span>
<span class="normal"><a href="#__codelineno-0-964"> 964</a></span>
<span class="normal"><a href="#__codelineno-0-965"> 965</a></span>
<span class="normal"><a href="#__codelineno-0-966"> 966</a></span>
<span class="normal"><a href="#__codelineno-0-967"> 967</a></span>
<span class="normal"><a href="#__codelineno-0-968"> 968</a></span>
<span class="normal"><a href="#__codelineno-0-969"> 969</a></span>
<span class="normal"><a href="#__codelineno-0-970"> 970</a></span>
<span class="normal"><a href="#__codelineno-0-971"> 971</a></span>
<span class="normal"><a href="#__codelineno-0-972"> 972</a></span>
<span class="normal"><a href="#__codelineno-0-973"> 973</a></span>
<span class="normal"><a href="#__codelineno-0-974"> 974</a></span>
<span class="normal"><a href="#__codelineno-0-975"> 975</a></span>
<span class="normal"><a href="#__codelineno-0-976"> 976</a></span>
<span class="normal"><a href="#__codelineno-0-977"> 977</a></span>
<span class="normal"><a href="#__codelineno-0-978"> 978</a></span>
<span class="normal"><a href="#__codelineno-0-979"> 979</a></span>
<span class="normal"><a href="#__codelineno-0-980"> 980</a></span>
<span class="normal"><a href="#__codelineno-0-981"> 981</a></span>
<span class="normal"><a href="#__codelineno-0-982"> 982</a></span>
<span class="normal"><a href="#__codelineno-0-983"> 983</a></span>
<span class="normal"><a href="#__codelineno-0-984"> 984</a></span>
<span class="normal"><a href="#__codelineno-0-985"> 985</a></span>
<span class="normal"><a href="#__codelineno-0-986"> 986</a></span>
<span class="normal"><a href="#__codelineno-0-987"> 987</a></span>
<span class="normal"><a href="#__codelineno-0-988"> 988</a></span>
<span class="normal"><a href="#__codelineno-0-989"> 989</a></span>
<span class="normal"><a href="#__codelineno-0-990"> 990</a></span>
<span class="normal"><a href="#__codelineno-0-991"> 991</a></span>
<span class="normal"><a href="#__codelineno-0-992"> 992</a></span>
<span class="normal"><a href="#__codelineno-0-993"> 993</a></span>
<span class="normal"><a href="#__codelineno-0-994"> 994</a></span>
<span class="normal"><a href="#__codelineno-0-995"> 995</a></span>
<span class="normal"><a href="#__codelineno-0-996"> 996</a></span>
<span class="normal"><a href="#__codelineno-0-997"> 997</a></span>
<span class="normal"><a href="#__codelineno-0-998"> 998</a></span>
<span class="normal"><a href="#__codelineno-0-999"> 999</a></span>
<span class="normal"><a href="#__codelineno-0-1000">1000</a></span>
<span class="normal"><a href="#__codelineno-0-1001">1001</a></span>
<span class="normal"><a href="#__codelineno-0-1002">1002</a></span>
<span class="normal"><a href="#__codelineno-0-1003">1003</a></span>
<span class="normal"><a href="#__codelineno-0-1004">1004</a></span>
<span class="normal"><a href="#__codelineno-0-1005">1005</a></span>
<span class="normal"><a href="#__codelineno-0-1006">1006</a></span>
<span class="normal"><a href="#__codelineno-0-1007">1007</a></span>
<span class="normal"><a href="#__codelineno-0-1008">1008</a></span>
<span class="normal"><a href="#__codelineno-0-1009">1009</a></span>
<span class="normal"><a href="#__codelineno-0-1010">1010</a></span>
<span class="normal"><a href="#__codelineno-0-1011">1011</a></span>
<span class="normal"><a href="#__codelineno-0-1012">1012</a></span>
<span class="normal"><a href="#__codelineno-0-1013">1013</a></span>
<span class="normal"><a href="#__codelineno-0-1014">1014</a></span>
<span class="normal"><a href="#__codelineno-0-1015">1015</a></span>
<span class="normal"><a href="#__codelineno-0-1016">1016</a></span>
<span class="normal"><a href="#__codelineno-0-1017">1017</a></span>
<span class="normal"><a href="#__codelineno-0-1018">1018</a></span>
<span class="normal"><a href="#__codelineno-0-1019">1019</a></span>
<span class="normal"><a href="#__codelineno-0-1020">1020</a></span>
<span class="normal"><a href="#__codelineno-0-1021">1021</a></span>
<span class="normal"><a href="#__codelineno-0-1022">1022</a></span>
<span class="normal"><a href="#__codelineno-0-1023">1023</a></span>
<span class="normal"><a href="#__codelineno-0-1024">1024</a></span>
<span class="normal"><a href="#__codelineno-0-1025">1025</a></span>
<span class="normal"><a href="#__codelineno-0-1026">1026</a></span>
<span class="normal"><a href="#__codelineno-0-1027">1027</a></span>
<span class="normal"><a href="#__codelineno-0-1028">1028</a></span>
<span class="normal"><a href="#__codelineno-0-1029">1029</a></span>
<span class="normal"><a href="#__codelineno-0-1030">1030</a></span>
<span class="normal"><a href="#__codelineno-0-1031">1031</a></span>
<span class="normal"><a href="#__codelineno-0-1032">1032</a></span>
<span class="normal"><a href="#__codelineno-0-1033">1033</a></span>
<span class="normal"><a href="#__codelineno-0-1034">1034</a></span>
<span class="normal"><a href="#__codelineno-0-1035">1035</a></span>
<span class="normal"><a href="#__codelineno-0-1036">1036</a></span>
<span class="normal"><a href="#__codelineno-0-1037">1037</a></span>
<span class="normal"><a href="#__codelineno-0-1038">1038</a></span>
<span class="normal"><a href="#__codelineno-0-1039">1039</a></span>
<span class="normal"><a href="#__codelineno-0-1040">1040</a></span>
<span class="normal"><a href="#__codelineno-0-1041">1041</a></span>
<span class="normal"><a href="#__codelineno-0-1042">1042</a></span>
<span class="normal"><a href="#__codelineno-0-1043">1043</a></span>
<span class="normal"><a href="#__codelineno-0-1044">1044</a></span>
<span class="normal"><a href="#__codelineno-0-1045">1045</a></span>
<span class="normal"><a href="#__codelineno-0-1046">1046</a></span>
<span class="normal"><a href="#__codelineno-0-1047">1047</a></span>
<span class="normal"><a href="#__codelineno-0-1048">1048</a></span>
<span class="normal"><a href="#__codelineno-0-1049">1049</a></span>
<span class="normal"><a href="#__codelineno-0-1050">1050</a></span>
<span class="normal"><a href="#__codelineno-0-1051">1051</a></span>
<span class="normal"><a href="#__codelineno-0-1052">1052</a></span>
<span class="normal"><a href="#__codelineno-0-1053">1053</a></span>
<span class="normal"><a href="#__codelineno-0-1054">1054</a></span>
<span class="normal"><a href="#__codelineno-0-1055">1055</a></span>
<span class="normal"><a href="#__codelineno-0-1056">1056</a></span>
<span class="normal"><a href="#__codelineno-0-1057">1057</a></span>
<span class="normal"><a href="#__codelineno-0-1058">1058</a></span>
<span class="normal"><a href="#__codelineno-0-1059">1059</a></span>
<span class="normal"><a href="#__codelineno-0-1060">1060</a></span>
<span class="normal"><a href="#__codelineno-0-1061">1061</a></span>
<span class="normal"><a href="#__codelineno-0-1062">1062</a></span>
<span class="normal"><a href="#__codelineno-0-1063">1063</a></span>
<span class="normal"><a href="#__codelineno-0-1064">1064</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-35"><a id="__codelineno-0-35" name="__codelineno-0-35"></a><span class="k">class</span><span class="w"> </span><span class="nc">EmbeddedBridge</span><span class="p">(</span><span class="n">FreecadBridge</span><span class="p">):</span>
</span><span id="__span-0-36"><a id="__codelineno-0-36" name="__codelineno-0-36"></a><span class="w"> </span><span class="sd">"""Bridge that runs FreeCAD embedded in the Robust MCP Server process.</span>
</span><span id="__span-0-37"><a id="__codelineno-0-37" name="__codelineno-0-37"></a>
</span><span id="__span-0-38"><a id="__codelineno-0-38" name="__codelineno-0-38"></a><span class="sd"> This bridge imports FreeCAD directly, providing fast execution</span>
</span><span id="__span-0-39"><a id="__codelineno-0-39" name="__codelineno-0-39"></a><span class="sd"> but only supports headless mode (no GUI).</span>
</span><span id="__span-0-40"><a id="__codelineno-0-40" name="__codelineno-0-40"></a>
</span><span id="__span-0-41"><a id="__codelineno-0-41" name="__codelineno-0-41"></a><span class="sd"> Attributes:</span>
</span><span id="__span-0-42"><a id="__codelineno-0-42" name="__codelineno-0-42"></a><span class="sd"> freecad_path: Optional path to FreeCAD's lib directory.</span>
</span><span id="__span-0-43"><a id="__codelineno-0-43" name="__codelineno-0-43"></a><span class="sd"> """</span>
</span><span id="__span-0-44"><a id="__codelineno-0-44" name="__codelineno-0-44"></a>
</span><span id="__span-0-45"><a id="__codelineno-0-45" name="__codelineno-0-45"></a> <span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">freecad_path</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kc">None</span><span class="p">:</span>
</span><span id="__span-0-46"><a id="__codelineno-0-46" name="__codelineno-0-46"></a><span class="w"> </span><span class="sd">"""Initialize the embedded bridge.</span>
</span><span id="__span-0-47"><a id="__codelineno-0-47" name="__codelineno-0-47"></a>
</span><span id="__span-0-48"><a id="__codelineno-0-48" name="__codelineno-0-48"></a><span class="sd"> Args:</span>
</span><span id="__span-0-49"><a id="__codelineno-0-49" name="__codelineno-0-49"></a><span class="sd"> freecad_path: Path to FreeCAD's lib directory. If provided,</span>
</span><span id="__span-0-50"><a id="__codelineno-0-50" name="__codelineno-0-50"></a><span class="sd"> this path will be added to sys.path before importing.</span>
</span><span id="__span-0-51"><a id="__codelineno-0-51" name="__codelineno-0-51"></a><span class="sd"> """</span>
</span><span id="__span-0-52"><a id="__codelineno-0-52" name="__codelineno-0-52"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_freecad_path</span> <span class="o">=</span> <span class="n">freecad_path</span>
</span><span id="__span-0-53"><a id="__codelineno-0-53" name="__codelineno-0-53"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_fc_module</span><span class="p">:</span> <span class="n">Any</span> <span class="o">=</span> <span class="kc">None</span>
</span><span id="__span-0-54"><a id="__codelineno-0-54" name="__codelineno-0-54"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_executor</span> <span class="o">=</span> <span class="n">ThreadPoolExecutor</span><span class="p">(</span><span class="n">max_workers</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span> <span class="n">thread_name_prefix</span><span class="o">=</span><span class="s2">"freecad"</span><span class="p">)</span>
</span><span id="__span-0-55"><a id="__codelineno-0-55" name="__codelineno-0-55"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_connected</span> <span class="o">=</span> <span class="kc">False</span>
</span><span id="__span-0-56"><a id="__codelineno-0-56" name="__codelineno-0-56"></a>
</span><span id="__span-0-57"><a id="__codelineno-0-57" name="__codelineno-0-57"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">connect</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kc">None</span><span class="p">:</span>
</span><span id="__span-0-58"><a id="__codelineno-0-58" name="__codelineno-0-58"></a><span class="w"> </span><span class="sd">"""Import and initialize FreeCAD.</span>
</span><span id="__span-0-59"><a id="__codelineno-0-59" name="__codelineno-0-59"></a>
</span><span id="__span-0-60"><a id="__codelineno-0-60" name="__codelineno-0-60"></a><span class="sd"> Raises:</span>
</span><span id="__span-0-61"><a id="__codelineno-0-61" name="__codelineno-0-61"></a><span class="sd"> ConnectionError: If FreeCAD cannot be imported.</span>
</span><span id="__span-0-62"><a id="__codelineno-0-62" name="__codelineno-0-62"></a><span class="sd"> """</span>
</span><span id="__span-0-63"><a id="__codelineno-0-63" name="__codelineno-0-63"></a> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_freecad_path</span><span class="p">:</span>
</span><span id="__span-0-64"><a id="__codelineno-0-64" name="__codelineno-0-64"></a> <span class="n">sys</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">insert</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">_freecad_path</span><span class="p">)</span>
</span><span id="__span-0-65"><a id="__codelineno-0-65" name="__codelineno-0-65"></a>
</span><span id="__span-0-66"><a id="__codelineno-0-66" name="__codelineno-0-66"></a> <span class="n">loop</span> <span class="o">=</span> <span class="n">asyncio</span><span class="o">.</span><span class="n">get_event_loop</span><span class="p">()</span>
</span><span id="__span-0-67"><a id="__codelineno-0-67" name="__codelineno-0-67"></a> <span class="k">try</span><span class="p">:</span>
</span><span id="__span-0-68"><a id="__codelineno-0-68" name="__codelineno-0-68"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_fc_module</span> <span class="o">=</span> <span class="k">await</span> <span class="n">loop</span><span class="o">.</span><span class="n">run_in_executor</span><span class="p">(</span>
</span><span id="__span-0-69"><a id="__codelineno-0-69" name="__codelineno-0-69"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_executor</span><span class="p">,</span>
</span><span id="__span-0-70"><a id="__codelineno-0-70" name="__codelineno-0-70"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_import_freecad</span><span class="p">,</span>
</span><span id="__span-0-71"><a id="__codelineno-0-71" name="__codelineno-0-71"></a> <span class="p">)</span>
</span><span id="__span-0-72"><a id="__codelineno-0-72" name="__codelineno-0-72"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_connected</span> <span class="o">=</span> <span class="kc">True</span>
</span><span id="__span-0-73"><a id="__codelineno-0-73" name="__codelineno-0-73"></a> <span class="k">except</span> <span class="ne">ImportError</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
</span><span id="__span-0-74"><a id="__codelineno-0-74" name="__codelineno-0-74"></a> <span class="n">msg</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">"Failed to import FreeCAD: </span><span class="si">{</span><span class="n">e</span><span class="si">}</span><span class="s2">"</span>
</span><span id="__span-0-75"><a id="__codelineno-0-75" name="__codelineno-0-75"></a> <span class="k">raise</span> <span class="ne">ConnectionError</span><span class="p">(</span><span class="n">msg</span><span class="p">)</span> <span class="kn">from</span><span class="w"> </span><span class="nn">e</span>
</span><span id="__span-0-76"><a id="__codelineno-0-76" name="__codelineno-0-76"></a>
</span><span id="__span-0-77"><a id="__codelineno-0-77" name="__codelineno-0-77"></a> <span class="k">def</span><span class="w"> </span><span class="nf">_import_freecad</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">Any</span><span class="p">:</span>
</span><span id="__span-0-78"><a id="__codelineno-0-78" name="__codelineno-0-78"></a><span class="w"> </span><span class="sd">"""Import FreeCAD module (runs in thread pool)."""</span>
</span><span id="__span-0-79"><a id="__codelineno-0-79" name="__codelineno-0-79"></a> <span class="kn">import</span><span class="w"> </span><span class="nn">FreeCAD</span>
</span><span id="__span-0-80"><a id="__codelineno-0-80" name="__codelineno-0-80"></a>
</span><span id="__span-0-81"><a id="__codelineno-0-81" name="__codelineno-0-81"></a> <span class="k">return</span> <span class="n">FreeCAD</span>
</span><span id="__span-0-82"><a id="__codelineno-0-82" name="__codelineno-0-82"></a>
</span><span id="__span-0-83"><a id="__codelineno-0-83" name="__codelineno-0-83"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">disconnect</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kc">None</span><span class="p">:</span>
</span><span id="__span-0-84"><a id="__codelineno-0-84" name="__codelineno-0-84"></a><span class="w"> </span><span class="sd">"""Clean up resources."""</span>
</span><span id="__span-0-85"><a id="__codelineno-0-85" name="__codelineno-0-85"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_connected</span> <span class="o">=</span> <span class="kc">False</span>
</span><span id="__span-0-86"><a id="__codelineno-0-86" name="__codelineno-0-86"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_executor</span><span class="o">.</span><span class="n">shutdown</span><span class="p">(</span><span class="n">wait</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
</span><span id="__span-0-87"><a id="__codelineno-0-87" name="__codelineno-0-87"></a>
</span><span id="__span-0-88"><a id="__codelineno-0-88" name="__codelineno-0-88"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">is_connected</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">bool</span><span class="p">:</span>
</span><span id="__span-0-89"><a id="__codelineno-0-89" name="__codelineno-0-89"></a><span class="w"> </span><span class="sd">"""Check if FreeCAD is imported and available."""</span>
</span><span id="__span-0-90"><a id="__codelineno-0-90" name="__codelineno-0-90"></a> <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_connected</span> <span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">_fc_module</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span>
</span><span id="__span-0-91"><a id="__codelineno-0-91" name="__codelineno-0-91"></a>
</span><span id="__span-0-92"><a id="__codelineno-0-92" name="__codelineno-0-92"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">execute_python</span><span class="p">(</span>
</span><span id="__span-0-93"><a id="__codelineno-0-93" name="__codelineno-0-93"></a> <span class="bp">self</span><span class="p">,</span>
</span><span id="__span-0-94"><a id="__codelineno-0-94" name="__codelineno-0-94"></a> <span class="n">code</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span>
</span><span id="__span-0-95"><a id="__codelineno-0-95" name="__codelineno-0-95"></a> <span class="n">timeout_ms</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">30000</span><span class="p">,</span>
</span><span id="__span-0-96"><a id="__codelineno-0-96" name="__codelineno-0-96"></a> <span class="p">)</span> <span class="o">-&gt;</span> <span class="n">ExecutionResult</span><span class="p">:</span>
</span><span id="__span-0-97"><a id="__codelineno-0-97" name="__codelineno-0-97"></a><span class="w"> </span><span class="sd">"""Execute Python code in FreeCAD context.</span>
</span><span id="__span-0-98"><a id="__codelineno-0-98" name="__codelineno-0-98"></a>
</span><span id="__span-0-99"><a id="__codelineno-0-99" name="__codelineno-0-99"></a><span class="sd"> Args:</span>
</span><span id="__span-0-100"><a id="__codelineno-0-100" name="__codelineno-0-100"></a><span class="sd"> code: Python code to execute.</span>
</span><span id="__span-0-101"><a id="__codelineno-0-101" name="__codelineno-0-101"></a><span class="sd"> timeout_ms: Maximum execution time in milliseconds.</span>
</span><span id="__span-0-102"><a id="__codelineno-0-102" name="__codelineno-0-102"></a>
</span><span id="__span-0-103"><a id="__codelineno-0-103" name="__codelineno-0-103"></a><span class="sd"> Returns:</span>
</span><span id="__span-0-104"><a id="__codelineno-0-104" name="__codelineno-0-104"></a><span class="sd"> ExecutionResult with execution outcome.</span>
</span><span id="__span-0-105"><a id="__codelineno-0-105" name="__codelineno-0-105"></a><span class="sd"> """</span>
</span><span id="__span-0-106"><a id="__codelineno-0-106" name="__codelineno-0-106"></a> <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">_connected</span><span class="p">:</span>
</span><span id="__span-0-107"><a id="__codelineno-0-107" name="__codelineno-0-107"></a> <span class="k">return</span> <span class="n">ExecutionResult</span><span class="p">(</span>
</span><span id="__span-0-108"><a id="__codelineno-0-108" name="__codelineno-0-108"></a> <span class="n">success</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
</span><span id="__span-0-109"><a id="__codelineno-0-109" name="__codelineno-0-109"></a> <span class="n">result</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-110"><a id="__codelineno-0-110" name="__codelineno-0-110"></a> <span class="n">stdout</span><span class="o">=</span><span class="s2">""</span><span class="p">,</span>
</span><span id="__span-0-111"><a id="__codelineno-0-111" name="__codelineno-0-111"></a> <span class="n">stderr</span><span class="o">=</span><span class="s2">"FreeCAD bridge not connected"</span><span class="p">,</span>
</span><span id="__span-0-112"><a id="__codelineno-0-112" name="__codelineno-0-112"></a> <span class="n">execution_time_ms</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span>
</span><span id="__span-0-113"><a id="__codelineno-0-113" name="__codelineno-0-113"></a> <span class="n">error_type</span><span class="o">=</span><span class="s2">"ConnectionError"</span><span class="p">,</span>
</span><span id="__span-0-114"><a id="__codelineno-0-114" name="__codelineno-0-114"></a> <span class="n">error_traceback</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-115"><a id="__codelineno-0-115" name="__codelineno-0-115"></a> <span class="p">)</span>
</span><span id="__span-0-116"><a id="__codelineno-0-116" name="__codelineno-0-116"></a>
</span><span id="__span-0-117"><a id="__codelineno-0-117" name="__codelineno-0-117"></a> <span class="n">loop</span> <span class="o">=</span> <span class="n">asyncio</span><span class="o">.</span><span class="n">get_event_loop</span><span class="p">()</span>
</span><span id="__span-0-118"><a id="__codelineno-0-118" name="__codelineno-0-118"></a>
</span><span id="__span-0-119"><a id="__codelineno-0-119" name="__codelineno-0-119"></a> <span class="k">try</span><span class="p">:</span>
</span><span id="__span-0-120"><a id="__codelineno-0-120" name="__codelineno-0-120"></a> <span class="n">result</span> <span class="o">=</span> <span class="k">await</span> <span class="n">asyncio</span><span class="o">.</span><span class="n">wait_for</span><span class="p">(</span>
</span><span id="__span-0-121"><a id="__codelineno-0-121" name="__codelineno-0-121"></a> <span class="n">loop</span><span class="o">.</span><span class="n">run_in_executor</span><span class="p">(</span>
</span><span id="__span-0-122"><a id="__codelineno-0-122" name="__codelineno-0-122"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_executor</span><span class="p">,</span>
</span><span id="__span-0-123"><a id="__codelineno-0-123" name="__codelineno-0-123"></a> <span class="k">lambda</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">_execute_code</span><span class="p">(</span><span class="n">code</span><span class="p">),</span>
</span><span id="__span-0-124"><a id="__codelineno-0-124" name="__codelineno-0-124"></a> <span class="p">),</span>
</span><span id="__span-0-125"><a id="__codelineno-0-125" name="__codelineno-0-125"></a> <span class="n">timeout</span><span class="o">=</span><span class="n">timeout_ms</span> <span class="o">/</span> <span class="mi">1000</span><span class="p">,</span>
</span><span id="__span-0-126"><a id="__codelineno-0-126" name="__codelineno-0-126"></a> <span class="p">)</span>
</span><span id="__span-0-127"><a id="__codelineno-0-127" name="__codelineno-0-127"></a> <span class="k">except</span> <span class="ne">TimeoutError</span><span class="p">:</span>
</span><span id="__span-0-128"><a id="__codelineno-0-128" name="__codelineno-0-128"></a> <span class="k">return</span> <span class="n">ExecutionResult</span><span class="p">(</span>
</span><span id="__span-0-129"><a id="__codelineno-0-129" name="__codelineno-0-129"></a> <span class="n">success</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
</span><span id="__span-0-130"><a id="__codelineno-0-130" name="__codelineno-0-130"></a> <span class="n">result</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-131"><a id="__codelineno-0-131" name="__codelineno-0-131"></a> <span class="n">stdout</span><span class="o">=</span><span class="s2">""</span><span class="p">,</span>
</span><span id="__span-0-132"><a id="__codelineno-0-132" name="__codelineno-0-132"></a> <span class="n">stderr</span><span class="o">=</span><span class="sa">f</span><span class="s2">"Execution timed out after </span><span class="si">{</span><span class="n">timeout_ms</span><span class="si">}</span><span class="s2">ms"</span><span class="p">,</span>
</span><span id="__span-0-133"><a id="__codelineno-0-133" name="__codelineno-0-133"></a> <span class="n">execution_time_ms</span><span class="o">=</span><span class="nb">float</span><span class="p">(</span><span class="n">timeout_ms</span><span class="p">),</span>
</span><span id="__span-0-134"><a id="__codelineno-0-134" name="__codelineno-0-134"></a> <span class="n">error_type</span><span class="o">=</span><span class="s2">"TimeoutError"</span><span class="p">,</span>
</span><span id="__span-0-135"><a id="__codelineno-0-135" name="__codelineno-0-135"></a> <span class="n">error_traceback</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-136"><a id="__codelineno-0-136" name="__codelineno-0-136"></a> <span class="p">)</span>
</span><span id="__span-0-137"><a id="__codelineno-0-137" name="__codelineno-0-137"></a>
</span><span id="__span-0-138"><a id="__codelineno-0-138" name="__codelineno-0-138"></a> <span class="k">return</span> <span class="n">result</span>
</span><span id="__span-0-139"><a id="__codelineno-0-139" name="__codelineno-0-139"></a>
</span><span id="__span-0-140"><a id="__codelineno-0-140" name="__codelineno-0-140"></a> <span class="k">def</span><span class="w"> </span><span class="nf">_execute_code</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">code</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">ExecutionResult</span><span class="p">:</span>
</span><span id="__span-0-141"><a id="__codelineno-0-141" name="__codelineno-0-141"></a><span class="w"> </span><span class="sd">"""Execute code synchronously (runs in thread pool)."""</span>
</span><span id="__span-0-142"><a id="__codelineno-0-142" name="__codelineno-0-142"></a> <span class="n">start</span> <span class="o">=</span> <span class="n">time</span><span class="o">.</span><span class="n">perf_counter</span><span class="p">()</span>
</span><span id="__span-0-143"><a id="__codelineno-0-143" name="__codelineno-0-143"></a> <span class="n">stdout_capture</span> <span class="o">=</span> <span class="n">io</span><span class="o">.</span><span class="n">StringIO</span><span class="p">()</span>
</span><span id="__span-0-144"><a id="__codelineno-0-144" name="__codelineno-0-144"></a> <span class="n">stderr_capture</span> <span class="o">=</span> <span class="n">io</span><span class="o">.</span><span class="n">StringIO</span><span class="p">()</span>
</span><span id="__span-0-145"><a id="__codelineno-0-145" name="__codelineno-0-145"></a>
</span><span id="__span-0-146"><a id="__codelineno-0-146" name="__codelineno-0-146"></a> <span class="c1"># Build execution context</span>
</span><span id="__span-0-147"><a id="__codelineno-0-147" name="__codelineno-0-147"></a> <span class="n">exec_globals</span><span class="p">:</span> <span class="nb">dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Any</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span>
</span><span id="__span-0-148"><a id="__codelineno-0-148" name="__codelineno-0-148"></a> <span class="s2">"FreeCAD"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">_fc_module</span><span class="p">,</span>
</span><span id="__span-0-149"><a id="__codelineno-0-149" name="__codelineno-0-149"></a> <span class="s2">"App"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">_fc_module</span><span class="p">,</span>
</span><span id="__span-0-150"><a id="__codelineno-0-150" name="__codelineno-0-150"></a> <span class="s2">"__builtins__"</span><span class="p">:</span> <span class="n">__builtins__</span><span class="p">,</span>
</span><span id="__span-0-151"><a id="__codelineno-0-151" name="__codelineno-0-151"></a> <span class="p">}</span>
</span><span id="__span-0-152"><a id="__codelineno-0-152" name="__codelineno-0-152"></a>
</span><span id="__span-0-153"><a id="__codelineno-0-153" name="__codelineno-0-153"></a> <span class="c1"># Try to add GUI module if available</span>
</span><span id="__span-0-154"><a id="__codelineno-0-154" name="__codelineno-0-154"></a> <span class="k">try</span><span class="p">:</span>
</span><span id="__span-0-155"><a id="__codelineno-0-155" name="__codelineno-0-155"></a> <span class="kn">import</span><span class="w"> </span><span class="nn">FreeCADGui</span>
</span><span id="__span-0-156"><a id="__codelineno-0-156" name="__codelineno-0-156"></a>
</span><span id="__span-0-157"><a id="__codelineno-0-157" name="__codelineno-0-157"></a> <span class="n">exec_globals</span><span class="p">[</span><span class="s2">"FreeCADGui"</span><span class="p">]</span> <span class="o">=</span> <span class="n">FreeCADGui</span>
</span><span id="__span-0-158"><a id="__codelineno-0-158" name="__codelineno-0-158"></a> <span class="n">exec_globals</span><span class="p">[</span><span class="s2">"Gui"</span><span class="p">]</span> <span class="o">=</span> <span class="n">FreeCADGui</span>
</span><span id="__span-0-159"><a id="__codelineno-0-159" name="__codelineno-0-159"></a> <span class="k">except</span> <span class="ne">ImportError</span><span class="p">:</span>
</span><span id="__span-0-160"><a id="__codelineno-0-160" name="__codelineno-0-160"></a> <span class="k">pass</span>
</span><span id="__span-0-161"><a id="__codelineno-0-161" name="__codelineno-0-161"></a>
</span><span id="__span-0-162"><a id="__codelineno-0-162" name="__codelineno-0-162"></a> <span class="k">try</span><span class="p">:</span>
</span><span id="__span-0-163"><a id="__codelineno-0-163" name="__codelineno-0-163"></a> <span class="k">with</span> <span class="n">redirect_stdout</span><span class="p">(</span><span class="n">stdout_capture</span><span class="p">),</span> <span class="n">redirect_stderr</span><span class="p">(</span><span class="n">stderr_capture</span><span class="p">):</span>
</span><span id="__span-0-164"><a id="__codelineno-0-164" name="__codelineno-0-164"></a> <span class="n">compiled</span> <span class="o">=</span> <span class="nb">compile</span><span class="p">(</span><span class="n">code</span><span class="p">,</span> <span class="s2">"&lt;mcp&gt;"</span><span class="p">,</span> <span class="s2">"exec"</span><span class="p">)</span>
</span><span id="__span-0-165"><a id="__codelineno-0-165" name="__codelineno-0-165"></a> <span class="n">exec</span><span class="p">(</span><span class="n">compiled</span><span class="p">,</span> <span class="n">exec_globals</span><span class="p">)</span> <span class="c1"># noqa: S102</span>
</span><span id="__span-0-166"><a id="__codelineno-0-166" name="__codelineno-0-166"></a>
</span><span id="__span-0-167"><a id="__codelineno-0-167" name="__codelineno-0-167"></a> <span class="n">elapsed</span> <span class="o">=</span> <span class="p">(</span><span class="n">time</span><span class="o">.</span><span class="n">perf_counter</span><span class="p">()</span> <span class="o">-</span> <span class="n">start</span><span class="p">)</span> <span class="o">*</span> <span class="mi">1000</span>
</span><span id="__span-0-168"><a id="__codelineno-0-168" name="__codelineno-0-168"></a>
</span><span id="__span-0-169"><a id="__codelineno-0-169" name="__codelineno-0-169"></a> <span class="k">return</span> <span class="n">ExecutionResult</span><span class="p">(</span>
</span><span id="__span-0-170"><a id="__codelineno-0-170" name="__codelineno-0-170"></a> <span class="n">success</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span>
</span><span id="__span-0-171"><a id="__codelineno-0-171" name="__codelineno-0-171"></a> <span class="n">result</span><span class="o">=</span><span class="n">exec_globals</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"_result_"</span><span class="p">),</span>
</span><span id="__span-0-172"><a id="__codelineno-0-172" name="__codelineno-0-172"></a> <span class="n">stdout</span><span class="o">=</span><span class="n">stdout_capture</span><span class="o">.</span><span class="n">getvalue</span><span class="p">(),</span>
</span><span id="__span-0-173"><a id="__codelineno-0-173" name="__codelineno-0-173"></a> <span class="n">stderr</span><span class="o">=</span><span class="n">stderr_capture</span><span class="o">.</span><span class="n">getvalue</span><span class="p">(),</span>
</span><span id="__span-0-174"><a id="__codelineno-0-174" name="__codelineno-0-174"></a> <span class="n">execution_time_ms</span><span class="o">=</span><span class="n">elapsed</span><span class="p">,</span>
</span><span id="__span-0-175"><a id="__codelineno-0-175" name="__codelineno-0-175"></a> <span class="p">)</span>
</span><span id="__span-0-176"><a id="__codelineno-0-176" name="__codelineno-0-176"></a>
</span><span id="__span-0-177"><a id="__codelineno-0-177" name="__codelineno-0-177"></a> <span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
</span><span id="__span-0-178"><a id="__codelineno-0-178" name="__codelineno-0-178"></a> <span class="kn">import</span><span class="w"> </span><span class="nn">traceback</span>
</span><span id="__span-0-179"><a id="__codelineno-0-179" name="__codelineno-0-179"></a>
</span><span id="__span-0-180"><a id="__codelineno-0-180" name="__codelineno-0-180"></a> <span class="n">elapsed</span> <span class="o">=</span> <span class="p">(</span><span class="n">time</span><span class="o">.</span><span class="n">perf_counter</span><span class="p">()</span> <span class="o">-</span> <span class="n">start</span><span class="p">)</span> <span class="o">*</span> <span class="mi">1000</span>
</span><span id="__span-0-181"><a id="__codelineno-0-181" name="__codelineno-0-181"></a>
</span><span id="__span-0-182"><a id="__codelineno-0-182" name="__codelineno-0-182"></a> <span class="k">return</span> <span class="n">ExecutionResult</span><span class="p">(</span>
</span><span id="__span-0-183"><a id="__codelineno-0-183" name="__codelineno-0-183"></a> <span class="n">success</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
</span><span id="__span-0-184"><a id="__codelineno-0-184" name="__codelineno-0-184"></a> <span class="n">result</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-185"><a id="__codelineno-0-185" name="__codelineno-0-185"></a> <span class="n">stdout</span><span class="o">=</span><span class="n">stdout_capture</span><span class="o">.</span><span class="n">getvalue</span><span class="p">(),</span>
</span><span id="__span-0-186"><a id="__codelineno-0-186" name="__codelineno-0-186"></a> <span class="n">stderr</span><span class="o">=</span><span class="n">stderr_capture</span><span class="o">.</span><span class="n">getvalue</span><span class="p">(),</span>
</span><span id="__span-0-187"><a id="__codelineno-0-187" name="__codelineno-0-187"></a> <span class="n">execution_time_ms</span><span class="o">=</span><span class="n">elapsed</span><span class="p">,</span>
</span><span id="__span-0-188"><a id="__codelineno-0-188" name="__codelineno-0-188"></a> <span class="n">error_type</span><span class="o">=</span><span class="nb">type</span><span class="p">(</span><span class="n">e</span><span class="p">)</span><span class="o">.</span><span class="vm">__name__</span><span class="p">,</span>
</span><span id="__span-0-189"><a id="__codelineno-0-189" name="__codelineno-0-189"></a> <span class="n">error_traceback</span><span class="o">=</span><span class="n">traceback</span><span class="o">.</span><span class="n">format_exc</span><span class="p">(),</span>
</span><span id="__span-0-190"><a id="__codelineno-0-190" name="__codelineno-0-190"></a> <span class="p">)</span>
</span><span id="__span-0-191"><a id="__codelineno-0-191" name="__codelineno-0-191"></a>
</span><span id="__span-0-192"><a id="__codelineno-0-192" name="__codelineno-0-192"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">get_documents</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">list</span><span class="p">[</span><span class="n">DocumentInfo</span><span class="p">]:</span>
</span><span id="__span-0-193"><a id="__codelineno-0-193" name="__codelineno-0-193"></a><span class="w"> </span><span class="sd">"""Get list of open documents."""</span>
</span><span id="__span-0-194"><a id="__codelineno-0-194" name="__codelineno-0-194"></a> <span class="n">result</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">execute_python</span><span class="p">(</span>
</span><span id="__span-0-195"><a id="__codelineno-0-195" name="__codelineno-0-195"></a><span class="w"> </span><span class="sd">"""</span>
</span><span id="__span-0-196"><a id="__codelineno-0-196" name="__codelineno-0-196"></a><span class="sd">_result_ = []</span>
</span><span id="__span-0-197"><a id="__codelineno-0-197" name="__codelineno-0-197"></a><span class="sd">for doc in FreeCAD.listDocuments().values():</span>
</span><span id="__span-0-198"><a id="__codelineno-0-198" name="__codelineno-0-198"></a><span class="sd"> _result_.append({</span>
</span><span id="__span-0-199"><a id="__codelineno-0-199" name="__codelineno-0-199"></a><span class="sd"> "name": doc.Name,</span>
</span><span id="__span-0-200"><a id="__codelineno-0-200" name="__codelineno-0-200"></a><span class="sd"> "path": doc.FileName or None,</span>
</span><span id="__span-0-201"><a id="__codelineno-0-201" name="__codelineno-0-201"></a><span class="sd"> "objects": [obj.Name for obj in doc.Objects],</span>
</span><span id="__span-0-202"><a id="__codelineno-0-202" name="__codelineno-0-202"></a><span class="sd"> "is_modified": doc.Modified if hasattr(doc, "Modified") else False,</span>
</span><span id="__span-0-203"><a id="__codelineno-0-203" name="__codelineno-0-203"></a><span class="sd"> "label": doc.Label,</span>
</span><span id="__span-0-204"><a id="__codelineno-0-204" name="__codelineno-0-204"></a><span class="sd"> })</span>
</span><span id="__span-0-205"><a id="__codelineno-0-205" name="__codelineno-0-205"></a><span class="sd">"""</span>
</span><span id="__span-0-206"><a id="__codelineno-0-206" name="__codelineno-0-206"></a> <span class="p">)</span>
</span><span id="__span-0-207"><a id="__codelineno-0-207" name="__codelineno-0-207"></a>
</span><span id="__span-0-208"><a id="__codelineno-0-208" name="__codelineno-0-208"></a> <span class="k">if</span> <span class="n">result</span><span class="o">.</span><span class="n">success</span> <span class="ow">and</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">:</span>
</span><span id="__span-0-209"><a id="__codelineno-0-209" name="__codelineno-0-209"></a> <span class="k">return</span> <span class="p">[</span><span class="n">DocumentInfo</span><span class="p">(</span><span class="o">**</span><span class="n">doc</span><span class="p">)</span> <span class="k">for</span> <span class="n">doc</span> <span class="ow">in</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">]</span>
</span><span id="__span-0-210"><a id="__codelineno-0-210" name="__codelineno-0-210"></a> <span class="k">return</span> <span class="p">[]</span>
</span><span id="__span-0-211"><a id="__codelineno-0-211" name="__codelineno-0-211"></a>
</span><span id="__span-0-212"><a id="__codelineno-0-212" name="__codelineno-0-212"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">get_active_document</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">DocumentInfo</span> <span class="o">|</span> <span class="kc">None</span><span class="p">:</span>
</span><span id="__span-0-213"><a id="__codelineno-0-213" name="__codelineno-0-213"></a><span class="w"> </span><span class="sd">"""Get the active document."""</span>
</span><span id="__span-0-214"><a id="__codelineno-0-214" name="__codelineno-0-214"></a> <span class="n">result</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">execute_python</span><span class="p">(</span>
</span><span id="__span-0-215"><a id="__codelineno-0-215" name="__codelineno-0-215"></a><span class="w"> </span><span class="sd">"""</span>
</span><span id="__span-0-216"><a id="__codelineno-0-216" name="__codelineno-0-216"></a><span class="sd">doc = FreeCAD.ActiveDocument</span>
</span><span id="__span-0-217"><a id="__codelineno-0-217" name="__codelineno-0-217"></a><span class="sd">if doc:</span>
</span><span id="__span-0-218"><a id="__codelineno-0-218" name="__codelineno-0-218"></a><span class="sd"> _result_ = {</span>
</span><span id="__span-0-219"><a id="__codelineno-0-219" name="__codelineno-0-219"></a><span class="sd"> "name": doc.Name,</span>
</span><span id="__span-0-220"><a id="__codelineno-0-220" name="__codelineno-0-220"></a><span class="sd"> "path": doc.FileName or None,</span>
</span><span id="__span-0-221"><a id="__codelineno-0-221" name="__codelineno-0-221"></a><span class="sd"> "objects": [obj.Name for obj in doc.Objects],</span>
</span><span id="__span-0-222"><a id="__codelineno-0-222" name="__codelineno-0-222"></a><span class="sd"> "is_modified": doc.Modified if hasattr(doc, "Modified") else False,</span>
</span><span id="__span-0-223"><a id="__codelineno-0-223" name="__codelineno-0-223"></a><span class="sd"> "label": doc.Label,</span>
</span><span id="__span-0-224"><a id="__codelineno-0-224" name="__codelineno-0-224"></a><span class="sd"> }</span>
</span><span id="__span-0-225"><a id="__codelineno-0-225" name="__codelineno-0-225"></a><span class="sd">else:</span>
</span><span id="__span-0-226"><a id="__codelineno-0-226" name="__codelineno-0-226"></a><span class="sd"> _result_ = None</span>
</span><span id="__span-0-227"><a id="__codelineno-0-227" name="__codelineno-0-227"></a><span class="sd">"""</span>
</span><span id="__span-0-228"><a id="__codelineno-0-228" name="__codelineno-0-228"></a> <span class="p">)</span>
</span><span id="__span-0-229"><a id="__codelineno-0-229" name="__codelineno-0-229"></a>
</span><span id="__span-0-230"><a id="__codelineno-0-230" name="__codelineno-0-230"></a> <span class="k">if</span> <span class="n">result</span><span class="o">.</span><span class="n">success</span> <span class="ow">and</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">:</span>
</span><span id="__span-0-231"><a id="__codelineno-0-231" name="__codelineno-0-231"></a> <span class="k">return</span> <span class="n">DocumentInfo</span><span class="p">(</span><span class="o">**</span><span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">)</span>
</span><span id="__span-0-232"><a id="__codelineno-0-232" name="__codelineno-0-232"></a> <span class="k">return</span> <span class="kc">None</span>
</span><span id="__span-0-233"><a id="__codelineno-0-233" name="__codelineno-0-233"></a>
</span><span id="__span-0-234"><a id="__codelineno-0-234" name="__codelineno-0-234"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">get_object</span><span class="p">(</span>
</span><span id="__span-0-235"><a id="__codelineno-0-235" name="__codelineno-0-235"></a> <span class="bp">self</span><span class="p">,</span>
</span><span id="__span-0-236"><a id="__codelineno-0-236" name="__codelineno-0-236"></a> <span class="n">obj_name</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span>
</span><span id="__span-0-237"><a id="__codelineno-0-237" name="__codelineno-0-237"></a> <span class="n">doc_name</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-238"><a id="__codelineno-0-238" name="__codelineno-0-238"></a> <span class="p">)</span> <span class="o">-&gt;</span> <span class="n">ObjectInfo</span><span class="p">:</span>
</span><span id="__span-0-239"><a id="__codelineno-0-239" name="__codelineno-0-239"></a><span class="w"> </span><span class="sd">"""Get detailed object information."""</span>
</span><span id="__span-0-240"><a id="__codelineno-0-240" name="__codelineno-0-240"></a> <span class="n">result</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">execute_python</span><span class="p">(</span>
</span><span id="__span-0-241"><a id="__codelineno-0-241" name="__codelineno-0-241"></a> <span class="sa">f</span><span class="s2">"""</span>
</span><span id="__span-0-242"><a id="__codelineno-0-242" name="__codelineno-0-242"></a><span class="s2">doc = FreeCAD.ActiveDocument if </span><span class="si">{</span><span class="n">doc_name</span><span class="si">!r}</span><span class="s2"> is None else FreeCAD.getDocument(</span><span class="si">{</span><span class="n">doc_name</span><span class="si">!r}</span><span class="s2">)</span>
</span><span id="__span-0-243"><a id="__codelineno-0-243" name="__codelineno-0-243"></a><span class="s2">if doc is None:</span>
</span><span id="__span-0-244"><a id="__codelineno-0-244" name="__codelineno-0-244"></a><span class="s2"> raise ValueError("No document found")</span>
</span><span id="__span-0-245"><a id="__codelineno-0-245" name="__codelineno-0-245"></a>
</span><span id="__span-0-246"><a id="__codelineno-0-246" name="__codelineno-0-246"></a><span class="s2">obj = doc.getObject(</span><span class="si">{</span><span class="n">obj_name</span><span class="si">!r}</span><span class="s2">)</span>
</span><span id="__span-0-247"><a id="__codelineno-0-247" name="__codelineno-0-247"></a><span class="s2">if obj is None:</span>
</span><span id="__span-0-248"><a id="__codelineno-0-248" name="__codelineno-0-248"></a><span class="s2"> raise ValueError(f"Object not found: </span><span class="si">{</span><span class="n">obj_name</span><span class="si">!r}</span><span class="s2">")</span>
</span><span id="__span-0-249"><a id="__codelineno-0-249" name="__codelineno-0-249"></a>
</span><span id="__span-0-250"><a id="__codelineno-0-250" name="__codelineno-0-250"></a><span class="s2">props = </span><span class="se">{{}}</span>
</span><span id="__span-0-251"><a id="__codelineno-0-251" name="__codelineno-0-251"></a><span class="s2">for prop in obj.PropertiesList:</span>
</span><span id="__span-0-252"><a id="__codelineno-0-252" name="__codelineno-0-252"></a><span class="s2"> try:</span>
</span><span id="__span-0-253"><a id="__codelineno-0-253" name="__codelineno-0-253"></a><span class="s2"> val = getattr(obj, prop)</span>
</span><span id="__span-0-254"><a id="__codelineno-0-254" name="__codelineno-0-254"></a><span class="s2"> if hasattr(val, '__class__') and val.__class__.__module__ != 'builtins':</span>
</span><span id="__span-0-255"><a id="__codelineno-0-255" name="__codelineno-0-255"></a><span class="s2"> val = str(val)</span>
</span><span id="__span-0-256"><a id="__codelineno-0-256" name="__codelineno-0-256"></a><span class="s2"> props[prop] = val</span>
</span><span id="__span-0-257"><a id="__codelineno-0-257" name="__codelineno-0-257"></a><span class="s2"> except Exception:</span>
</span><span id="__span-0-258"><a id="__codelineno-0-258" name="__codelineno-0-258"></a><span class="s2"> props[prop] = "&lt;unreadable&gt;"</span>
</span><span id="__span-0-259"><a id="__codelineno-0-259" name="__codelineno-0-259"></a>
</span><span id="__span-0-260"><a id="__codelineno-0-260" name="__codelineno-0-260"></a><span class="s2">shape_info = None</span>
</span><span id="__span-0-261"><a id="__codelineno-0-261" name="__codelineno-0-261"></a><span class="s2">if hasattr(obj, "Shape"):</span>
</span><span id="__span-0-262"><a id="__codelineno-0-262" name="__codelineno-0-262"></a><span class="s2"> shape = obj.Shape</span>
</span><span id="__span-0-263"><a id="__codelineno-0-263" name="__codelineno-0-263"></a><span class="s2"> shape_info = </span><span class="se">{{</span>
</span><span id="__span-0-264"><a id="__codelineno-0-264" name="__codelineno-0-264"></a><span class="s2"> "type": shape.ShapeType,</span>
</span><span id="__span-0-265"><a id="__codelineno-0-265" name="__codelineno-0-265"></a><span class="s2"> "volume": shape.Volume if hasattr(shape, "Volume") else None,</span>
</span><span id="__span-0-266"><a id="__codelineno-0-266" name="__codelineno-0-266"></a><span class="s2"> "area": shape.Area if hasattr(shape, "Area") else None,</span>
</span><span id="__span-0-267"><a id="__codelineno-0-267" name="__codelineno-0-267"></a><span class="s2"> "is_valid": shape.isValid(),</span>
</span><span id="__span-0-268"><a id="__codelineno-0-268" name="__codelineno-0-268"></a><span class="s2"> </span><span class="se">}}</span>
</span><span id="__span-0-269"><a id="__codelineno-0-269" name="__codelineno-0-269"></a>
</span><span id="__span-0-270"><a id="__codelineno-0-270" name="__codelineno-0-270"></a><span class="s2">_result_ = </span><span class="se">{{</span>
</span><span id="__span-0-271"><a id="__codelineno-0-271" name="__codelineno-0-271"></a><span class="s2"> "name": obj.Name,</span>
</span><span id="__span-0-272"><a id="__codelineno-0-272" name="__codelineno-0-272"></a><span class="s2"> "label": obj.Label,</span>
</span><span id="__span-0-273"><a id="__codelineno-0-273" name="__codelineno-0-273"></a><span class="s2"> "type_id": obj.TypeId,</span>
</span><span id="__span-0-274"><a id="__codelineno-0-274" name="__codelineno-0-274"></a><span class="s2"> "properties": props,</span>
</span><span id="__span-0-275"><a id="__codelineno-0-275" name="__codelineno-0-275"></a><span class="s2"> "shape_info": shape_info,</span>
</span><span id="__span-0-276"><a id="__codelineno-0-276" name="__codelineno-0-276"></a><span class="s2"> "children": [c.Name for c in obj.OutList] if hasattr(obj, "OutList") else [],</span>
</span><span id="__span-0-277"><a id="__codelineno-0-277" name="__codelineno-0-277"></a><span class="se">}}</span>
</span><span id="__span-0-278"><a id="__codelineno-0-278" name="__codelineno-0-278"></a><span class="s2">"""</span>
</span><span id="__span-0-279"><a id="__codelineno-0-279" name="__codelineno-0-279"></a> <span class="p">)</span>
</span><span id="__span-0-280"><a id="__codelineno-0-280" name="__codelineno-0-280"></a>
</span><span id="__span-0-281"><a id="__codelineno-0-281" name="__codelineno-0-281"></a> <span class="k">if</span> <span class="n">result</span><span class="o">.</span><span class="n">success</span> <span class="ow">and</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">:</span>
</span><span id="__span-0-282"><a id="__codelineno-0-282" name="__codelineno-0-282"></a> <span class="k">return</span> <span class="n">ObjectInfo</span><span class="p">(</span><span class="o">**</span><span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">)</span>
</span><span id="__span-0-283"><a id="__codelineno-0-283" name="__codelineno-0-283"></a>
</span><span id="__span-0-284"><a id="__codelineno-0-284" name="__codelineno-0-284"></a> <span class="n">error_msg</span> <span class="o">=</span> <span class="n">result</span><span class="o">.</span><span class="n">error_traceback</span> <span class="ow">or</span> <span class="s2">"Failed to get object"</span>
</span><span id="__span-0-285"><a id="__codelineno-0-285" name="__codelineno-0-285"></a> <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="n">error_msg</span><span class="p">)</span>
</span><span id="__span-0-286"><a id="__codelineno-0-286" name="__codelineno-0-286"></a>
</span><span id="__span-0-287"><a id="__codelineno-0-287" name="__codelineno-0-287"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">get_console_output</span><span class="p">(</span>
</span><span id="__span-0-288"><a id="__codelineno-0-288" name="__codelineno-0-288"></a> <span class="bp">self</span><span class="p">,</span>
</span><span id="__span-0-289"><a id="__codelineno-0-289" name="__codelineno-0-289"></a> <span class="n">lines</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">100</span><span class="p">,</span>
</span><span id="__span-0-290"><a id="__codelineno-0-290" name="__codelineno-0-290"></a> <span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">list</span><span class="p">[</span><span class="nb">str</span><span class="p">]:</span>
</span><span id="__span-0-291"><a id="__codelineno-0-291" name="__codelineno-0-291"></a><span class="w"> </span><span class="sd">"""Get recent console output.</span>
</span><span id="__span-0-292"><a id="__codelineno-0-292" name="__codelineno-0-292"></a>
</span><span id="__span-0-293"><a id="__codelineno-0-293" name="__codelineno-0-293"></a><span class="sd"> Note: In embedded mode, we don't have direct access to FreeCAD's</span>
</span><span id="__span-0-294"><a id="__codelineno-0-294" name="__codelineno-0-294"></a><span class="sd"> console history, so we return an empty list or captured output.</span>
</span><span id="__span-0-295"><a id="__codelineno-0-295" name="__codelineno-0-295"></a><span class="sd"> """</span>
</span><span id="__span-0-296"><a id="__codelineno-0-296" name="__codelineno-0-296"></a> <span class="k">return</span> <span class="p">[]</span>
</span><span id="__span-0-297"><a id="__codelineno-0-297" name="__codelineno-0-297"></a>
</span><span id="__span-0-298"><a id="__codelineno-0-298" name="__codelineno-0-298"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">get_freecad_version</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Any</span><span class="p">]:</span>
</span><span id="__span-0-299"><a id="__codelineno-0-299" name="__codelineno-0-299"></a><span class="w"> </span><span class="sd">"""Get FreeCAD version information."""</span>
</span><span id="__span-0-300"><a id="__codelineno-0-300" name="__codelineno-0-300"></a> <span class="n">result</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">execute_python</span><span class="p">(</span>
</span><span id="__span-0-301"><a id="__codelineno-0-301" name="__codelineno-0-301"></a><span class="w"> </span><span class="sd">"""</span>
</span><span id="__span-0-302"><a id="__codelineno-0-302" name="__codelineno-0-302"></a><span class="sd">import sys</span>
</span><span id="__span-0-303"><a id="__codelineno-0-303" name="__codelineno-0-303"></a><span class="sd">_result_ = {</span>
</span><span id="__span-0-304"><a id="__codelineno-0-304" name="__codelineno-0-304"></a><span class="sd"> "version": ".".join(str(x) for x in FreeCAD.Version()[:3]),</span>
</span><span id="__span-0-305"><a id="__codelineno-0-305" name="__codelineno-0-305"></a><span class="sd"> "version_tuple": FreeCAD.Version()[:3],</span>
</span><span id="__span-0-306"><a id="__codelineno-0-306" name="__codelineno-0-306"></a><span class="sd"> "build_date": FreeCAD.Version()[3] if len(FreeCAD.Version()) &gt; 3 else "unknown",</span>
</span><span id="__span-0-307"><a id="__codelineno-0-307" name="__codelineno-0-307"></a><span class="sd"> "python_version": sys.version,</span>
</span><span id="__span-0-308"><a id="__codelineno-0-308" name="__codelineno-0-308"></a><span class="sd"> "gui_available": hasattr(FreeCAD, "GuiUp") and FreeCAD.GuiUp,</span>
</span><span id="__span-0-309"><a id="__codelineno-0-309" name="__codelineno-0-309"></a><span class="sd">}</span>
</span><span id="__span-0-310"><a id="__codelineno-0-310" name="__codelineno-0-310"></a><span class="sd">"""</span>
</span><span id="__span-0-311"><a id="__codelineno-0-311" name="__codelineno-0-311"></a> <span class="p">)</span>
</span><span id="__span-0-312"><a id="__codelineno-0-312" name="__codelineno-0-312"></a>
</span><span id="__span-0-313"><a id="__codelineno-0-313" name="__codelineno-0-313"></a> <span class="k">if</span> <span class="n">result</span><span class="o">.</span><span class="n">success</span> <span class="ow">and</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">:</span>
</span><span id="__span-0-314"><a id="__codelineno-0-314" name="__codelineno-0-314"></a> <span class="k">return</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span>
</span><span id="__span-0-315"><a id="__codelineno-0-315" name="__codelineno-0-315"></a>
</span><span id="__span-0-316"><a id="__codelineno-0-316" name="__codelineno-0-316"></a> <span class="k">return</span> <span class="p">{</span>
</span><span id="__span-0-317"><a id="__codelineno-0-317" name="__codelineno-0-317"></a> <span class="s2">"version"</span><span class="p">:</span> <span class="s2">"unknown"</span><span class="p">,</span>
</span><span id="__span-0-318"><a id="__codelineno-0-318" name="__codelineno-0-318"></a> <span class="s2">"version_tuple"</span><span class="p">:</span> <span class="p">[],</span>
</span><span id="__span-0-319"><a id="__codelineno-0-319" name="__codelineno-0-319"></a> <span class="s2">"build_date"</span><span class="p">:</span> <span class="s2">"unknown"</span><span class="p">,</span>
</span><span id="__span-0-320"><a id="__codelineno-0-320" name="__codelineno-0-320"></a> <span class="s2">"python_version"</span><span class="p">:</span> <span class="n">sys</span><span class="o">.</span><span class="n">version</span><span class="p">,</span>
</span><span id="__span-0-321"><a id="__codelineno-0-321" name="__codelineno-0-321"></a> <span class="s2">"gui_available"</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span>
</span><span id="__span-0-322"><a id="__codelineno-0-322" name="__codelineno-0-322"></a> <span class="p">}</span>
</span><span id="__span-0-323"><a id="__codelineno-0-323" name="__codelineno-0-323"></a>
</span><span id="__span-0-324"><a id="__codelineno-0-324" name="__codelineno-0-324"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">is_gui_available</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">bool</span><span class="p">:</span>
</span><span id="__span-0-325"><a id="__codelineno-0-325" name="__codelineno-0-325"></a><span class="w"> </span><span class="sd">"""Check if GUI is available."""</span>
</span><span id="__span-0-326"><a id="__codelineno-0-326" name="__codelineno-0-326"></a> <span class="n">result</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">execute_python</span><span class="p">(</span>
</span><span id="__span-0-327"><a id="__codelineno-0-327" name="__codelineno-0-327"></a> <span class="s2">"_result_ = hasattr(FreeCAD, 'GuiUp') and FreeCAD.GuiUp"</span>
</span><span id="__span-0-328"><a id="__codelineno-0-328" name="__codelineno-0-328"></a> <span class="p">)</span>
</span><span id="__span-0-329"><a id="__codelineno-0-329" name="__codelineno-0-329"></a> <span class="k">return</span> <span class="nb">bool</span><span class="p">(</span><span class="n">result</span><span class="o">.</span><span class="n">success</span> <span class="ow">and</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">)</span>
</span><span id="__span-0-330"><a id="__codelineno-0-330" name="__codelineno-0-330"></a>
</span><span id="__span-0-331"><a id="__codelineno-0-331" name="__codelineno-0-331"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">ping</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">float</span><span class="p">:</span>
</span><span id="__span-0-332"><a id="__codelineno-0-332" name="__codelineno-0-332"></a><span class="w"> </span><span class="sd">"""Ping FreeCAD to check connection and measure latency.</span>
</span><span id="__span-0-333"><a id="__codelineno-0-333" name="__codelineno-0-333"></a>
</span><span id="__span-0-334"><a id="__codelineno-0-334" name="__codelineno-0-334"></a><span class="sd"> Returns:</span>
</span><span id="__span-0-335"><a id="__codelineno-0-335" name="__codelineno-0-335"></a><span class="sd"> Round-trip time in milliseconds.</span>
</span><span id="__span-0-336"><a id="__codelineno-0-336" name="__codelineno-0-336"></a>
</span><span id="__span-0-337"><a id="__codelineno-0-337" name="__codelineno-0-337"></a><span class="sd"> Raises:</span>
</span><span id="__span-0-338"><a id="__codelineno-0-338" name="__codelineno-0-338"></a><span class="sd"> ConnectionError: If not connected.</span>
</span><span id="__span-0-339"><a id="__codelineno-0-339" name="__codelineno-0-339"></a><span class="sd"> """</span>
</span><span id="__span-0-340"><a id="__codelineno-0-340" name="__codelineno-0-340"></a> <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">_connected</span><span class="p">:</span>
</span><span id="__span-0-341"><a id="__codelineno-0-341" name="__codelineno-0-341"></a> <span class="n">msg</span> <span class="o">=</span> <span class="s2">"Not connected to FreeCAD"</span>
</span><span id="__span-0-342"><a id="__codelineno-0-342" name="__codelineno-0-342"></a> <span class="k">raise</span> <span class="ne">ConnectionError</span><span class="p">(</span><span class="n">msg</span><span class="p">)</span>
</span><span id="__span-0-343"><a id="__codelineno-0-343" name="__codelineno-0-343"></a>
</span><span id="__span-0-344"><a id="__codelineno-0-344" name="__codelineno-0-344"></a> <span class="n">start</span> <span class="o">=</span> <span class="n">time</span><span class="o">.</span><span class="n">perf_counter</span><span class="p">()</span>
</span><span id="__span-0-345"><a id="__codelineno-0-345" name="__codelineno-0-345"></a> <span class="n">result</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">execute_python</span><span class="p">(</span><span class="s2">"_result_ = True"</span><span class="p">)</span>
</span><span id="__span-0-346"><a id="__codelineno-0-346" name="__codelineno-0-346"></a> <span class="n">elapsed</span> <span class="o">=</span> <span class="p">(</span><span class="n">time</span><span class="o">.</span><span class="n">perf_counter</span><span class="p">()</span> <span class="o">-</span> <span class="n">start</span><span class="p">)</span> <span class="o">*</span> <span class="mi">1000</span>
</span><span id="__span-0-347"><a id="__codelineno-0-347" name="__codelineno-0-347"></a>
</span><span id="__span-0-348"><a id="__codelineno-0-348" name="__codelineno-0-348"></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">result</span><span class="o">.</span><span class="n">success</span><span class="p">:</span>
</span><span id="__span-0-349"><a id="__codelineno-0-349" name="__codelineno-0-349"></a> <span class="n">msg</span> <span class="o">=</span> <span class="s2">"Ping failed"</span>
</span><span id="__span-0-350"><a id="__codelineno-0-350" name="__codelineno-0-350"></a> <span class="k">raise</span> <span class="ne">ConnectionError</span><span class="p">(</span><span class="n">msg</span><span class="p">)</span>
</span><span id="__span-0-351"><a id="__codelineno-0-351" name="__codelineno-0-351"></a>
</span><span id="__span-0-352"><a id="__codelineno-0-352" name="__codelineno-0-352"></a> <span class="k">return</span> <span class="n">elapsed</span>
</span><span id="__span-0-353"><a id="__codelineno-0-353" name="__codelineno-0-353"></a>
</span><span id="__span-0-354"><a id="__codelineno-0-354" name="__codelineno-0-354"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">get_status</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">ConnectionStatus</span><span class="p">:</span>
</span><span id="__span-0-355"><a id="__codelineno-0-355" name="__codelineno-0-355"></a><span class="w"> </span><span class="sd">"""Get detailed connection status.</span>
</span><span id="__span-0-356"><a id="__codelineno-0-356" name="__codelineno-0-356"></a>
</span><span id="__span-0-357"><a id="__codelineno-0-357" name="__codelineno-0-357"></a><span class="sd"> Returns:</span>
</span><span id="__span-0-358"><a id="__codelineno-0-358" name="__codelineno-0-358"></a><span class="sd"> ConnectionStatus with full status information.</span>
</span><span id="__span-0-359"><a id="__codelineno-0-359" name="__codelineno-0-359"></a><span class="sd"> """</span>
</span><span id="__span-0-360"><a id="__codelineno-0-360" name="__codelineno-0-360"></a> <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">_connected</span><span class="p">:</span>
</span><span id="__span-0-361"><a id="__codelineno-0-361" name="__codelineno-0-361"></a> <span class="k">return</span> <span class="n">ConnectionStatus</span><span class="p">(</span>
</span><span id="__span-0-362"><a id="__codelineno-0-362" name="__codelineno-0-362"></a> <span class="n">connected</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
</span><span id="__span-0-363"><a id="__codelineno-0-363" name="__codelineno-0-363"></a> <span class="n">mode</span><span class="o">=</span><span class="s2">"embedded"</span><span class="p">,</span>
</span><span id="__span-0-364"><a id="__codelineno-0-364" name="__codelineno-0-364"></a> <span class="n">error</span><span class="o">=</span><span class="s2">"Not connected"</span><span class="p">,</span>
</span><span id="__span-0-365"><a id="__codelineno-0-365" name="__codelineno-0-365"></a> <span class="p">)</span>
</span><span id="__span-0-366"><a id="__codelineno-0-366" name="__codelineno-0-366"></a>
</span><span id="__span-0-367"><a id="__codelineno-0-367" name="__codelineno-0-367"></a> <span class="k">try</span><span class="p">:</span>
</span><span id="__span-0-368"><a id="__codelineno-0-368" name="__codelineno-0-368"></a> <span class="n">ping_ms</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">ping</span><span class="p">()</span>
</span><span id="__span-0-369"><a id="__codelineno-0-369" name="__codelineno-0-369"></a> <span class="n">version_info</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_freecad_version</span><span class="p">()</span>
</span><span id="__span-0-370"><a id="__codelineno-0-370" name="__codelineno-0-370"></a> <span class="n">gui_available</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">is_gui_available</span><span class="p">()</span>
</span><span id="__span-0-371"><a id="__codelineno-0-371" name="__codelineno-0-371"></a>
</span><span id="__span-0-372"><a id="__codelineno-0-372" name="__codelineno-0-372"></a> <span class="k">return</span> <span class="n">ConnectionStatus</span><span class="p">(</span>
</span><span id="__span-0-373"><a id="__codelineno-0-373" name="__codelineno-0-373"></a> <span class="n">connected</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span>
</span><span id="__span-0-374"><a id="__codelineno-0-374" name="__codelineno-0-374"></a> <span class="n">mode</span><span class="o">=</span><span class="s2">"embedded"</span><span class="p">,</span>
</span><span id="__span-0-375"><a id="__codelineno-0-375" name="__codelineno-0-375"></a> <span class="n">freecad_version</span><span class="o">=</span><span class="n">version_info</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"version"</span><span class="p">,</span> <span class="s2">"unknown"</span><span class="p">),</span>
</span><span id="__span-0-376"><a id="__codelineno-0-376" name="__codelineno-0-376"></a> <span class="n">gui_available</span><span class="o">=</span><span class="n">gui_available</span><span class="p">,</span>
</span><span id="__span-0-377"><a id="__codelineno-0-377" name="__codelineno-0-377"></a> <span class="n">last_ping_ms</span><span class="o">=</span><span class="n">ping_ms</span><span class="p">,</span>
</span><span id="__span-0-378"><a id="__codelineno-0-378" name="__codelineno-0-378"></a> <span class="p">)</span>
</span><span id="__span-0-379"><a id="__codelineno-0-379" name="__codelineno-0-379"></a> <span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
</span><span id="__span-0-380"><a id="__codelineno-0-380" name="__codelineno-0-380"></a> <span class="k">return</span> <span class="n">ConnectionStatus</span><span class="p">(</span>
</span><span id="__span-0-381"><a id="__codelineno-0-381" name="__codelineno-0-381"></a> <span class="n">connected</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
</span><span id="__span-0-382"><a id="__codelineno-0-382" name="__codelineno-0-382"></a> <span class="n">mode</span><span class="o">=</span><span class="s2">"embedded"</span><span class="p">,</span>
</span><span id="__span-0-383"><a id="__codelineno-0-383" name="__codelineno-0-383"></a> <span class="n">error</span><span class="o">=</span><span class="nb">str</span><span class="p">(</span><span class="n">e</span><span class="p">),</span>
</span><span id="__span-0-384"><a id="__codelineno-0-384" name="__codelineno-0-384"></a> <span class="p">)</span>
</span><span id="__span-0-385"><a id="__codelineno-0-385" name="__codelineno-0-385"></a>
</span><span id="__span-0-386"><a id="__codelineno-0-386" name="__codelineno-0-386"></a> <span class="c1"># =========================================================================</span>
</span><span id="__span-0-387"><a id="__codelineno-0-387" name="__codelineno-0-387"></a> <span class="c1"># Document Management</span>
</span><span id="__span-0-388"><a id="__codelineno-0-388" name="__codelineno-0-388"></a> <span class="c1"># =========================================================================</span>
</span><span id="__span-0-389"><a id="__codelineno-0-389" name="__codelineno-0-389"></a>
</span><span id="__span-0-390"><a id="__codelineno-0-390" name="__codelineno-0-390"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">create_document</span><span class="p">(</span>
</span><span id="__span-0-391"><a id="__codelineno-0-391" name="__codelineno-0-391"></a> <span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">label</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span>
</span><span id="__span-0-392"><a id="__codelineno-0-392" name="__codelineno-0-392"></a> <span class="p">)</span> <span class="o">-&gt;</span> <span class="n">DocumentInfo</span><span class="p">:</span>
</span><span id="__span-0-393"><a id="__codelineno-0-393" name="__codelineno-0-393"></a><span class="w"> </span><span class="sd">"""Create a new document.</span>
</span><span id="__span-0-394"><a id="__codelineno-0-394" name="__codelineno-0-394"></a>
</span><span id="__span-0-395"><a id="__codelineno-0-395" name="__codelineno-0-395"></a><span class="sd"> Args:</span>
</span><span id="__span-0-396"><a id="__codelineno-0-396" name="__codelineno-0-396"></a><span class="sd"> name: Internal document name (no spaces).</span>
</span><span id="__span-0-397"><a id="__codelineno-0-397" name="__codelineno-0-397"></a><span class="sd"> label: Display label (optional, defaults to name).</span>
</span><span id="__span-0-398"><a id="__codelineno-0-398" name="__codelineno-0-398"></a>
</span><span id="__span-0-399"><a id="__codelineno-0-399" name="__codelineno-0-399"></a><span class="sd"> Returns:</span>
</span><span id="__span-0-400"><a id="__codelineno-0-400" name="__codelineno-0-400"></a><span class="sd"> DocumentInfo for the created document.</span>
</span><span id="__span-0-401"><a id="__codelineno-0-401" name="__codelineno-0-401"></a><span class="sd"> """</span>
</span><span id="__span-0-402"><a id="__codelineno-0-402" name="__codelineno-0-402"></a> <span class="n">label</span> <span class="o">=</span> <span class="n">label</span> <span class="ow">or</span> <span class="n">name</span>
</span><span id="__span-0-403"><a id="__codelineno-0-403" name="__codelineno-0-403"></a> <span class="n">result</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">execute_python</span><span class="p">(</span>
</span><span id="__span-0-404"><a id="__codelineno-0-404" name="__codelineno-0-404"></a> <span class="sa">f</span><span class="s2">"""</span>
</span><span id="__span-0-405"><a id="__codelineno-0-405" name="__codelineno-0-405"></a><span class="s2">doc = FreeCAD.newDocument(</span><span class="si">{</span><span class="n">name</span><span class="si">!r}</span><span class="s2">)</span>
</span><span id="__span-0-406"><a id="__codelineno-0-406" name="__codelineno-0-406"></a><span class="s2">doc.Label = </span><span class="si">{</span><span class="n">label</span><span class="si">!r}</span>
</span><span id="__span-0-407"><a id="__codelineno-0-407" name="__codelineno-0-407"></a><span class="s2">_result_ = </span><span class="se">{{</span>
</span><span id="__span-0-408"><a id="__codelineno-0-408" name="__codelineno-0-408"></a><span class="s2"> "name": doc.Name,</span>
</span><span id="__span-0-409"><a id="__codelineno-0-409" name="__codelineno-0-409"></a><span class="s2"> "label": doc.Label,</span>
</span><span id="__span-0-410"><a id="__codelineno-0-410" name="__codelineno-0-410"></a><span class="s2"> "path": doc.FileName or None,</span>
</span><span id="__span-0-411"><a id="__codelineno-0-411" name="__codelineno-0-411"></a><span class="s2"> "objects": [],</span>
</span><span id="__span-0-412"><a id="__codelineno-0-412" name="__codelineno-0-412"></a><span class="s2"> "is_modified": False,</span>
</span><span id="__span-0-413"><a id="__codelineno-0-413" name="__codelineno-0-413"></a><span class="se">}}</span>
</span><span id="__span-0-414"><a id="__codelineno-0-414" name="__codelineno-0-414"></a><span class="s2">"""</span>
</span><span id="__span-0-415"><a id="__codelineno-0-415" name="__codelineno-0-415"></a> <span class="p">)</span>
</span><span id="__span-0-416"><a id="__codelineno-0-416" name="__codelineno-0-416"></a>
</span><span id="__span-0-417"><a id="__codelineno-0-417" name="__codelineno-0-417"></a> <span class="k">if</span> <span class="n">result</span><span class="o">.</span><span class="n">success</span> <span class="ow">and</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">:</span>
</span><span id="__span-0-418"><a id="__codelineno-0-418" name="__codelineno-0-418"></a> <span class="k">return</span> <span class="n">DocumentInfo</span><span class="p">(</span><span class="o">**</span><span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">)</span>
</span><span id="__span-0-419"><a id="__codelineno-0-419" name="__codelineno-0-419"></a>
</span><span id="__span-0-420"><a id="__codelineno-0-420" name="__codelineno-0-420"></a> <span class="n">error_msg</span> <span class="o">=</span> <span class="n">result</span><span class="o">.</span><span class="n">error_traceback</span> <span class="ow">or</span> <span class="s2">"Failed to create document"</span>
</span><span id="__span-0-421"><a id="__codelineno-0-421" name="__codelineno-0-421"></a> <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="n">error_msg</span><span class="p">)</span>
</span><span id="__span-0-422"><a id="__codelineno-0-422" name="__codelineno-0-422"></a>
</span><span id="__span-0-423"><a id="__codelineno-0-423" name="__codelineno-0-423"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">open_document</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">path</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">DocumentInfo</span><span class="p">:</span>
</span><span id="__span-0-424"><a id="__codelineno-0-424" name="__codelineno-0-424"></a><span class="w"> </span><span class="sd">"""Open an existing document.</span>
</span><span id="__span-0-425"><a id="__codelineno-0-425" name="__codelineno-0-425"></a>
</span><span id="__span-0-426"><a id="__codelineno-0-426" name="__codelineno-0-426"></a><span class="sd"> Args:</span>
</span><span id="__span-0-427"><a id="__codelineno-0-427" name="__codelineno-0-427"></a><span class="sd"> path: Path to the .FCStd file.</span>
</span><span id="__span-0-428"><a id="__codelineno-0-428" name="__codelineno-0-428"></a>
</span><span id="__span-0-429"><a id="__codelineno-0-429" name="__codelineno-0-429"></a><span class="sd"> Returns:</span>
</span><span id="__span-0-430"><a id="__codelineno-0-430" name="__codelineno-0-430"></a><span class="sd"> DocumentInfo for the opened document.</span>
</span><span id="__span-0-431"><a id="__codelineno-0-431" name="__codelineno-0-431"></a>
</span><span id="__span-0-432"><a id="__codelineno-0-432" name="__codelineno-0-432"></a><span class="sd"> Raises:</span>
</span><span id="__span-0-433"><a id="__codelineno-0-433" name="__codelineno-0-433"></a><span class="sd"> FileNotFoundError: If file doesn't exist.</span>
</span><span id="__span-0-434"><a id="__codelineno-0-434" name="__codelineno-0-434"></a><span class="sd"> ValueError: If file is not a valid FreeCAD document.</span>
</span><span id="__span-0-435"><a id="__codelineno-0-435" name="__codelineno-0-435"></a><span class="sd"> """</span>
</span><span id="__span-0-436"><a id="__codelineno-0-436" name="__codelineno-0-436"></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">Path</span><span class="p">(</span><span class="n">path</span><span class="p">)</span><span class="o">.</span><span class="n">exists</span><span class="p">():</span>
</span><span id="__span-0-437"><a id="__codelineno-0-437" name="__codelineno-0-437"></a> <span class="n">msg</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">"File not found: </span><span class="si">{</span><span class="n">path</span><span class="si">}</span><span class="s2">"</span>
</span><span id="__span-0-438"><a id="__codelineno-0-438" name="__codelineno-0-438"></a> <span class="k">raise</span> <span class="ne">FileNotFoundError</span><span class="p">(</span><span class="n">msg</span><span class="p">)</span>
</span><span id="__span-0-439"><a id="__codelineno-0-439" name="__codelineno-0-439"></a>
</span><span id="__span-0-440"><a id="__codelineno-0-440" name="__codelineno-0-440"></a> <span class="n">result</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">execute_python</span><span class="p">(</span>
</span><span id="__span-0-441"><a id="__codelineno-0-441" name="__codelineno-0-441"></a> <span class="sa">f</span><span class="s2">"""</span>
</span><span id="__span-0-442"><a id="__codelineno-0-442" name="__codelineno-0-442"></a><span class="s2">doc = FreeCAD.openDocument(</span><span class="si">{</span><span class="n">path</span><span class="si">!r}</span><span class="s2">)</span>
</span><span id="__span-0-443"><a id="__codelineno-0-443" name="__codelineno-0-443"></a><span class="s2">_result_ = </span><span class="se">{{</span>
</span><span id="__span-0-444"><a id="__codelineno-0-444" name="__codelineno-0-444"></a><span class="s2"> "name": doc.Name,</span>
</span><span id="__span-0-445"><a id="__codelineno-0-445" name="__codelineno-0-445"></a><span class="s2"> "label": doc.Label,</span>
</span><span id="__span-0-446"><a id="__codelineno-0-446" name="__codelineno-0-446"></a><span class="s2"> "path": doc.FileName or None,</span>
</span><span id="__span-0-447"><a id="__codelineno-0-447" name="__codelineno-0-447"></a><span class="s2"> "objects": [obj.Name for obj in doc.Objects],</span>
</span><span id="__span-0-448"><a id="__codelineno-0-448" name="__codelineno-0-448"></a><span class="s2"> "is_modified": doc.Modified if hasattr(doc, "Modified") else False,</span>
</span><span id="__span-0-449"><a id="__codelineno-0-449" name="__codelineno-0-449"></a><span class="se">}}</span>
</span><span id="__span-0-450"><a id="__codelineno-0-450" name="__codelineno-0-450"></a><span class="s2">"""</span>
</span><span id="__span-0-451"><a id="__codelineno-0-451" name="__codelineno-0-451"></a> <span class="p">)</span>
</span><span id="__span-0-452"><a id="__codelineno-0-452" name="__codelineno-0-452"></a>
</span><span id="__span-0-453"><a id="__codelineno-0-453" name="__codelineno-0-453"></a> <span class="k">if</span> <span class="n">result</span><span class="o">.</span><span class="n">success</span> <span class="ow">and</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">:</span>
</span><span id="__span-0-454"><a id="__codelineno-0-454" name="__codelineno-0-454"></a> <span class="k">return</span> <span class="n">DocumentInfo</span><span class="p">(</span><span class="o">**</span><span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">)</span>
</span><span id="__span-0-455"><a id="__codelineno-0-455" name="__codelineno-0-455"></a>
</span><span id="__span-0-456"><a id="__codelineno-0-456" name="__codelineno-0-456"></a> <span class="n">error_msg</span> <span class="o">=</span> <span class="n">result</span><span class="o">.</span><span class="n">error_traceback</span> <span class="ow">or</span> <span class="s2">"Failed to open document"</span>
</span><span id="__span-0-457"><a id="__codelineno-0-457" name="__codelineno-0-457"></a> <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="n">error_msg</span><span class="p">)</span>
</span><span id="__span-0-458"><a id="__codelineno-0-458" name="__codelineno-0-458"></a>
</span><span id="__span-0-459"><a id="__codelineno-0-459" name="__codelineno-0-459"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">save_document</span><span class="p">(</span>
</span><span id="__span-0-460"><a id="__codelineno-0-460" name="__codelineno-0-460"></a> <span class="bp">self</span><span class="p">,</span>
</span><span id="__span-0-461"><a id="__codelineno-0-461" name="__codelineno-0-461"></a> <span class="n">doc_name</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-462"><a id="__codelineno-0-462" name="__codelineno-0-462"></a> <span class="n">path</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-463"><a id="__codelineno-0-463" name="__codelineno-0-463"></a> <span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">str</span><span class="p">:</span>
</span><span id="__span-0-464"><a id="__codelineno-0-464" name="__codelineno-0-464"></a><span class="w"> </span><span class="sd">"""Save a document.</span>
</span><span id="__span-0-465"><a id="__codelineno-0-465" name="__codelineno-0-465"></a>
</span><span id="__span-0-466"><a id="__codelineno-0-466" name="__codelineno-0-466"></a><span class="sd"> Args:</span>
</span><span id="__span-0-467"><a id="__codelineno-0-467" name="__codelineno-0-467"></a><span class="sd"> doc_name: Document name (uses active if None).</span>
</span><span id="__span-0-468"><a id="__codelineno-0-468" name="__codelineno-0-468"></a><span class="sd"> path: Save path (uses existing path if None).</span>
</span><span id="__span-0-469"><a id="__codelineno-0-469" name="__codelineno-0-469"></a>
</span><span id="__span-0-470"><a id="__codelineno-0-470" name="__codelineno-0-470"></a><span class="sd"> Returns:</span>
</span><span id="__span-0-471"><a id="__codelineno-0-471" name="__codelineno-0-471"></a><span class="sd"> Path where document was saved.</span>
</span><span id="__span-0-472"><a id="__codelineno-0-472" name="__codelineno-0-472"></a>
</span><span id="__span-0-473"><a id="__codelineno-0-473" name="__codelineno-0-473"></a><span class="sd"> Raises:</span>
</span><span id="__span-0-474"><a id="__codelineno-0-474" name="__codelineno-0-474"></a><span class="sd"> ValueError: If document not found or no path specified for new doc.</span>
</span><span id="__span-0-475"><a id="__codelineno-0-475" name="__codelineno-0-475"></a><span class="sd"> """</span>
</span><span id="__span-0-476"><a id="__codelineno-0-476" name="__codelineno-0-476"></a> <span class="n">code</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">"""</span>
</span><span id="__span-0-477"><a id="__codelineno-0-477" name="__codelineno-0-477"></a><span class="s2">doc = FreeCAD.ActiveDocument if </span><span class="si">{</span><span class="n">doc_name</span><span class="si">!r}</span><span class="s2"> is None else FreeCAD.getDocument(</span><span class="si">{</span><span class="n">doc_name</span><span class="si">!r}</span><span class="s2">)</span>
</span><span id="__span-0-478"><a id="__codelineno-0-478" name="__codelineno-0-478"></a><span class="s2">if doc is None:</span>
</span><span id="__span-0-479"><a id="__codelineno-0-479" name="__codelineno-0-479"></a><span class="s2"> raise ValueError("No active document" if </span><span class="si">{</span><span class="n">doc_name</span><span class="si">!r}</span><span class="s2"> is None else f"Document not found: </span><span class="si">{</span><span class="n">doc_name</span><span class="si">!r}</span><span class="s2">")</span>
</span><span id="__span-0-480"><a id="__codelineno-0-480" name="__codelineno-0-480"></a>
</span><span id="__span-0-481"><a id="__codelineno-0-481" name="__codelineno-0-481"></a><span class="s2">save_path = </span><span class="si">{</span><span class="n">path</span><span class="si">!r}</span><span class="s2"> or doc.FileName</span>
</span><span id="__span-0-482"><a id="__codelineno-0-482" name="__codelineno-0-482"></a><span class="s2">if not save_path:</span>
</span><span id="__span-0-483"><a id="__codelineno-0-483" name="__codelineno-0-483"></a><span class="s2"> raise ValueError("No path specified for new document")</span>
</span><span id="__span-0-484"><a id="__codelineno-0-484" name="__codelineno-0-484"></a>
</span><span id="__span-0-485"><a id="__codelineno-0-485" name="__codelineno-0-485"></a><span class="s2">doc.saveAs(save_path)</span>
</span><span id="__span-0-486"><a id="__codelineno-0-486" name="__codelineno-0-486"></a><span class="s2">_result_ = save_path</span>
</span><span id="__span-0-487"><a id="__codelineno-0-487" name="__codelineno-0-487"></a><span class="s2">"""</span>
</span><span id="__span-0-488"><a id="__codelineno-0-488" name="__codelineno-0-488"></a>
</span><span id="__span-0-489"><a id="__codelineno-0-489" name="__codelineno-0-489"></a> <span class="n">result</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">execute_python</span><span class="p">(</span><span class="n">code</span><span class="p">)</span>
</span><span id="__span-0-490"><a id="__codelineno-0-490" name="__codelineno-0-490"></a>
</span><span id="__span-0-491"><a id="__codelineno-0-491" name="__codelineno-0-491"></a> <span class="k">if</span> <span class="n">result</span><span class="o">.</span><span class="n">success</span> <span class="ow">and</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">:</span>
</span><span id="__span-0-492"><a id="__codelineno-0-492" name="__codelineno-0-492"></a> <span class="k">return</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span>
</span><span id="__span-0-493"><a id="__codelineno-0-493" name="__codelineno-0-493"></a>
</span><span id="__span-0-494"><a id="__codelineno-0-494" name="__codelineno-0-494"></a> <span class="n">error_msg</span> <span class="o">=</span> <span class="n">result</span><span class="o">.</span><span class="n">error_traceback</span> <span class="ow">or</span> <span class="s2">"Failed to save document"</span>
</span><span id="__span-0-495"><a id="__codelineno-0-495" name="__codelineno-0-495"></a> <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="n">error_msg</span><span class="p">)</span>
</span><span id="__span-0-496"><a id="__codelineno-0-496" name="__codelineno-0-496"></a>
</span><span id="__span-0-497"><a id="__codelineno-0-497" name="__codelineno-0-497"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">close_document</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">doc_name</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kc">None</span><span class="p">:</span>
</span><span id="__span-0-498"><a id="__codelineno-0-498" name="__codelineno-0-498"></a><span class="w"> </span><span class="sd">"""Close a document.</span>
</span><span id="__span-0-499"><a id="__codelineno-0-499" name="__codelineno-0-499"></a>
</span><span id="__span-0-500"><a id="__codelineno-0-500" name="__codelineno-0-500"></a><span class="sd"> Args:</span>
</span><span id="__span-0-501"><a id="__codelineno-0-501" name="__codelineno-0-501"></a><span class="sd"> doc_name: Document name (uses active if None).</span>
</span><span id="__span-0-502"><a id="__codelineno-0-502" name="__codelineno-0-502"></a><span class="sd"> """</span>
</span><span id="__span-0-503"><a id="__codelineno-0-503" name="__codelineno-0-503"></a> <span class="n">code</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">"""</span>
</span><span id="__span-0-504"><a id="__codelineno-0-504" name="__codelineno-0-504"></a><span class="s2">doc_name = </span><span class="si">{</span><span class="n">doc_name</span><span class="si">!r}</span>
</span><span id="__span-0-505"><a id="__codelineno-0-505" name="__codelineno-0-505"></a><span class="s2">if doc_name is None:</span>
</span><span id="__span-0-506"><a id="__codelineno-0-506" name="__codelineno-0-506"></a><span class="s2"> doc = FreeCAD.ActiveDocument</span>
</span><span id="__span-0-507"><a id="__codelineno-0-507" name="__codelineno-0-507"></a><span class="s2"> if doc:</span>
</span><span id="__span-0-508"><a id="__codelineno-0-508" name="__codelineno-0-508"></a><span class="s2"> doc_name = doc.Name</span>
</span><span id="__span-0-509"><a id="__codelineno-0-509" name="__codelineno-0-509"></a><span class="s2"> else:</span>
</span><span id="__span-0-510"><a id="__codelineno-0-510" name="__codelineno-0-510"></a><span class="s2"> raise ValueError("No active document")</span>
</span><span id="__span-0-511"><a id="__codelineno-0-511" name="__codelineno-0-511"></a>
</span><span id="__span-0-512"><a id="__codelineno-0-512" name="__codelineno-0-512"></a><span class="s2">FreeCAD.closeDocument(doc_name)</span>
</span><span id="__span-0-513"><a id="__codelineno-0-513" name="__codelineno-0-513"></a><span class="s2">_result_ = True</span>
</span><span id="__span-0-514"><a id="__codelineno-0-514" name="__codelineno-0-514"></a><span class="s2">"""</span>
</span><span id="__span-0-515"><a id="__codelineno-0-515" name="__codelineno-0-515"></a> <span class="n">result</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">execute_python</span><span class="p">(</span><span class="n">code</span><span class="p">)</span>
</span><span id="__span-0-516"><a id="__codelineno-0-516" name="__codelineno-0-516"></a>
</span><span id="__span-0-517"><a id="__codelineno-0-517" name="__codelineno-0-517"></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">result</span><span class="o">.</span><span class="n">success</span><span class="p">:</span>
</span><span id="__span-0-518"><a id="__codelineno-0-518" name="__codelineno-0-518"></a> <span class="n">error_msg</span> <span class="o">=</span> <span class="n">result</span><span class="o">.</span><span class="n">error_traceback</span> <span class="ow">or</span> <span class="s2">"Failed to close document"</span>
</span><span id="__span-0-519"><a id="__codelineno-0-519" name="__codelineno-0-519"></a> <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="n">error_msg</span><span class="p">)</span>
</span><span id="__span-0-520"><a id="__codelineno-0-520" name="__codelineno-0-520"></a>
</span><span id="__span-0-521"><a id="__codelineno-0-521" name="__codelineno-0-521"></a> <span class="c1"># =========================================================================</span>
</span><span id="__span-0-522"><a id="__codelineno-0-522" name="__codelineno-0-522"></a> <span class="c1"># Object Management</span>
</span><span id="__span-0-523"><a id="__codelineno-0-523" name="__codelineno-0-523"></a> <span class="c1"># =========================================================================</span>
</span><span id="__span-0-524"><a id="__codelineno-0-524" name="__codelineno-0-524"></a>
</span><span id="__span-0-525"><a id="__codelineno-0-525" name="__codelineno-0-525"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">get_objects</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">doc_name</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">list</span><span class="p">[</span><span class="n">ObjectInfo</span><span class="p">]:</span>
</span><span id="__span-0-526"><a id="__codelineno-0-526" name="__codelineno-0-526"></a><span class="w"> </span><span class="sd">"""Get all objects in a document.</span>
</span><span id="__span-0-527"><a id="__codelineno-0-527" name="__codelineno-0-527"></a>
</span><span id="__span-0-528"><a id="__codelineno-0-528" name="__codelineno-0-528"></a><span class="sd"> Args:</span>
</span><span id="__span-0-529"><a id="__codelineno-0-529" name="__codelineno-0-529"></a><span class="sd"> doc_name: Document name (uses active if None).</span>
</span><span id="__span-0-530"><a id="__codelineno-0-530" name="__codelineno-0-530"></a>
</span><span id="__span-0-531"><a id="__codelineno-0-531" name="__codelineno-0-531"></a><span class="sd"> Returns:</span>
</span><span id="__span-0-532"><a id="__codelineno-0-532" name="__codelineno-0-532"></a><span class="sd"> List of ObjectInfo for each object.</span>
</span><span id="__span-0-533"><a id="__codelineno-0-533" name="__codelineno-0-533"></a><span class="sd"> """</span>
</span><span id="__span-0-534"><a id="__codelineno-0-534" name="__codelineno-0-534"></a> <span class="n">code</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">"""</span>
</span><span id="__span-0-535"><a id="__codelineno-0-535" name="__codelineno-0-535"></a><span class="s2">doc = FreeCAD.ActiveDocument if </span><span class="si">{</span><span class="n">doc_name</span><span class="si">!r}</span><span class="s2"> is None else FreeCAD.getDocument(</span><span class="si">{</span><span class="n">doc_name</span><span class="si">!r}</span><span class="s2">)</span>
</span><span id="__span-0-536"><a id="__codelineno-0-536" name="__codelineno-0-536"></a><span class="s2">if doc is None:</span>
</span><span id="__span-0-537"><a id="__codelineno-0-537" name="__codelineno-0-537"></a><span class="s2"> raise ValueError("No document found")</span>
</span><span id="__span-0-538"><a id="__codelineno-0-538" name="__codelineno-0-538"></a>
</span><span id="__span-0-539"><a id="__codelineno-0-539" name="__codelineno-0-539"></a><span class="s2">objects = []</span>
</span><span id="__span-0-540"><a id="__codelineno-0-540" name="__codelineno-0-540"></a><span class="s2">for obj in doc.Objects:</span>
</span><span id="__span-0-541"><a id="__codelineno-0-541" name="__codelineno-0-541"></a><span class="s2"> obj_info = </span><span class="se">{{</span>
</span><span id="__span-0-542"><a id="__codelineno-0-542" name="__codelineno-0-542"></a><span class="s2"> "name": obj.Name,</span>
</span><span id="__span-0-543"><a id="__codelineno-0-543" name="__codelineno-0-543"></a><span class="s2"> "label": obj.Label,</span>
</span><span id="__span-0-544"><a id="__codelineno-0-544" name="__codelineno-0-544"></a><span class="s2"> "type_id": obj.TypeId,</span>
</span><span id="__span-0-545"><a id="__codelineno-0-545" name="__codelineno-0-545"></a><span class="s2"> "visibility": obj.ViewObject.Visibility if hasattr(obj, "ViewObject") and obj.ViewObject else True,</span>
</span><span id="__span-0-546"><a id="__codelineno-0-546" name="__codelineno-0-546"></a><span class="s2"> "children": [c.Name for c in obj.OutList] if hasattr(obj, "OutList") else [],</span>
</span><span id="__span-0-547"><a id="__codelineno-0-547" name="__codelineno-0-547"></a><span class="s2"> "parents": [p.Name for p in obj.InList] if hasattr(obj, "InList") else [],</span>
</span><span id="__span-0-548"><a id="__codelineno-0-548" name="__codelineno-0-548"></a><span class="s2"> </span><span class="se">}}</span>
</span><span id="__span-0-549"><a id="__codelineno-0-549" name="__codelineno-0-549"></a><span class="s2"> objects.append(obj_info)</span>
</span><span id="__span-0-550"><a id="__codelineno-0-550" name="__codelineno-0-550"></a>
</span><span id="__span-0-551"><a id="__codelineno-0-551" name="__codelineno-0-551"></a><span class="s2">_result_ = objects</span>
</span><span id="__span-0-552"><a id="__codelineno-0-552" name="__codelineno-0-552"></a><span class="s2">"""</span>
</span><span id="__span-0-553"><a id="__codelineno-0-553" name="__codelineno-0-553"></a> <span class="n">result</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">execute_python</span><span class="p">(</span><span class="n">code</span><span class="p">)</span>
</span><span id="__span-0-554"><a id="__codelineno-0-554" name="__codelineno-0-554"></a>
</span><span id="__span-0-555"><a id="__codelineno-0-555" name="__codelineno-0-555"></a> <span class="k">if</span> <span class="n">result</span><span class="o">.</span><span class="n">success</span> <span class="ow">and</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">:</span>
</span><span id="__span-0-556"><a id="__codelineno-0-556" name="__codelineno-0-556"></a> <span class="k">return</span> <span class="p">[</span><span class="n">ObjectInfo</span><span class="p">(</span><span class="o">**</span><span class="n">obj</span><span class="p">)</span> <span class="k">for</span> <span class="n">obj</span> <span class="ow">in</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">]</span>
</span><span id="__span-0-557"><a id="__codelineno-0-557" name="__codelineno-0-557"></a> <span class="k">return</span> <span class="p">[]</span>
</span><span id="__span-0-558"><a id="__codelineno-0-558" name="__codelineno-0-558"></a>
</span><span id="__span-0-559"><a id="__codelineno-0-559" name="__codelineno-0-559"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">create_object</span><span class="p">(</span>
</span><span id="__span-0-560"><a id="__codelineno-0-560" name="__codelineno-0-560"></a> <span class="bp">self</span><span class="p">,</span>
</span><span id="__span-0-561"><a id="__codelineno-0-561" name="__codelineno-0-561"></a> <span class="n">type_id</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span>
</span><span id="__span-0-562"><a id="__codelineno-0-562" name="__codelineno-0-562"></a> <span class="n">name</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-563"><a id="__codelineno-0-563" name="__codelineno-0-563"></a> <span class="n">properties</span><span class="p">:</span> <span class="nb">dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Any</span><span class="p">]</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-564"><a id="__codelineno-0-564" name="__codelineno-0-564"></a> <span class="n">doc_name</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-565"><a id="__codelineno-0-565" name="__codelineno-0-565"></a> <span class="p">)</span> <span class="o">-&gt;</span> <span class="n">ObjectInfo</span><span class="p">:</span>
</span><span id="__span-0-566"><a id="__codelineno-0-566" name="__codelineno-0-566"></a><span class="w"> </span><span class="sd">"""Create a new object.</span>
</span><span id="__span-0-567"><a id="__codelineno-0-567" name="__codelineno-0-567"></a>
</span><span id="__span-0-568"><a id="__codelineno-0-568" name="__codelineno-0-568"></a><span class="sd"> Args:</span>
</span><span id="__span-0-569"><a id="__codelineno-0-569" name="__codelineno-0-569"></a><span class="sd"> type_id: FreeCAD type ID (e.g., "Part::Box", "Part::Cylinder").</span>
</span><span id="__span-0-570"><a id="__codelineno-0-570" name="__codelineno-0-570"></a><span class="sd"> name: Object name (auto-generated if None).</span>
</span><span id="__span-0-571"><a id="__codelineno-0-571" name="__codelineno-0-571"></a><span class="sd"> properties: Initial property values.</span>
</span><span id="__span-0-572"><a id="__codelineno-0-572" name="__codelineno-0-572"></a><span class="sd"> doc_name: Target document (uses active if None).</span>
</span><span id="__span-0-573"><a id="__codelineno-0-573" name="__codelineno-0-573"></a>
</span><span id="__span-0-574"><a id="__codelineno-0-574" name="__codelineno-0-574"></a><span class="sd"> Returns:</span>
</span><span id="__span-0-575"><a id="__codelineno-0-575" name="__codelineno-0-575"></a><span class="sd"> ObjectInfo for the created object.</span>
</span><span id="__span-0-576"><a id="__codelineno-0-576" name="__codelineno-0-576"></a><span class="sd"> """</span>
</span><span id="__span-0-577"><a id="__codelineno-0-577" name="__codelineno-0-577"></a> <span class="n">properties</span> <span class="o">=</span> <span class="n">properties</span> <span class="ow">or</span> <span class="p">{}</span>
</span><span id="__span-0-578"><a id="__codelineno-0-578" name="__codelineno-0-578"></a> <span class="n">code</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">"""</span>
</span><span id="__span-0-579"><a id="__codelineno-0-579" name="__codelineno-0-579"></a><span class="s2">doc = FreeCAD.ActiveDocument if </span><span class="si">{</span><span class="n">doc_name</span><span class="si">!r}</span><span class="s2"> is None else FreeCAD.getDocument(</span><span class="si">{</span><span class="n">doc_name</span><span class="si">!r}</span><span class="s2">)</span>
</span><span id="__span-0-580"><a id="__codelineno-0-580" name="__codelineno-0-580"></a><span class="s2">if doc is None:</span>
</span><span id="__span-0-581"><a id="__codelineno-0-581" name="__codelineno-0-581"></a><span class="s2"> raise ValueError("No document found")</span>
</span><span id="__span-0-582"><a id="__codelineno-0-582" name="__codelineno-0-582"></a>
</span><span id="__span-0-583"><a id="__codelineno-0-583" name="__codelineno-0-583"></a><span class="s2">obj = doc.addObject(</span><span class="si">{</span><span class="n">type_id</span><span class="si">!r}</span><span class="s2">, </span><span class="si">{</span><span class="n">name</span><span class="si">!r}</span><span class="s2"> or "")</span>
</span><span id="__span-0-584"><a id="__codelineno-0-584" name="__codelineno-0-584"></a>
</span><span id="__span-0-585"><a id="__codelineno-0-585" name="__codelineno-0-585"></a><span class="s2"># Set properties</span>
</span><span id="__span-0-586"><a id="__codelineno-0-586" name="__codelineno-0-586"></a><span class="s2">for prop_name, prop_val in </span><span class="si">{</span><span class="n">properties</span><span class="si">!r}</span><span class="s2">.items():</span>
</span><span id="__span-0-587"><a id="__codelineno-0-587" name="__codelineno-0-587"></a><span class="s2"> if hasattr(obj, prop_name):</span>
</span><span id="__span-0-588"><a id="__codelineno-0-588" name="__codelineno-0-588"></a><span class="s2"> setattr(obj, prop_name, prop_val)</span>
</span><span id="__span-0-589"><a id="__codelineno-0-589" name="__codelineno-0-589"></a>
</span><span id="__span-0-590"><a id="__codelineno-0-590" name="__codelineno-0-590"></a><span class="s2">doc.recompute()</span>
</span><span id="__span-0-591"><a id="__codelineno-0-591" name="__codelineno-0-591"></a>
</span><span id="__span-0-592"><a id="__codelineno-0-592" name="__codelineno-0-592"></a><span class="s2">_result_ = </span><span class="se">{{</span>
</span><span id="__span-0-593"><a id="__codelineno-0-593" name="__codelineno-0-593"></a><span class="s2"> "name": obj.Name,</span>
</span><span id="__span-0-594"><a id="__codelineno-0-594" name="__codelineno-0-594"></a><span class="s2"> "label": obj.Label,</span>
</span><span id="__span-0-595"><a id="__codelineno-0-595" name="__codelineno-0-595"></a><span class="s2"> "type_id": obj.TypeId,</span>
</span><span id="__span-0-596"><a id="__codelineno-0-596" name="__codelineno-0-596"></a><span class="s2"> "visibility": True,</span>
</span><span id="__span-0-597"><a id="__codelineno-0-597" name="__codelineno-0-597"></a><span class="s2"> "children": [c.Name for c in obj.OutList] if hasattr(obj, "OutList") else [],</span>
</span><span id="__span-0-598"><a id="__codelineno-0-598" name="__codelineno-0-598"></a><span class="s2"> "parents": [p.Name for p in obj.InList] if hasattr(obj, "InList") else [],</span>
</span><span id="__span-0-599"><a id="__codelineno-0-599" name="__codelineno-0-599"></a><span class="se">}}</span>
</span><span id="__span-0-600"><a id="__codelineno-0-600" name="__codelineno-0-600"></a><span class="s2">"""</span>
</span><span id="__span-0-601"><a id="__codelineno-0-601" name="__codelineno-0-601"></a> <span class="n">result</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">execute_python</span><span class="p">(</span><span class="n">code</span><span class="p">)</span>
</span><span id="__span-0-602"><a id="__codelineno-0-602" name="__codelineno-0-602"></a>
</span><span id="__span-0-603"><a id="__codelineno-0-603" name="__codelineno-0-603"></a> <span class="k">if</span> <span class="n">result</span><span class="o">.</span><span class="n">success</span> <span class="ow">and</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">:</span>
</span><span id="__span-0-604"><a id="__codelineno-0-604" name="__codelineno-0-604"></a> <span class="k">return</span> <span class="n">ObjectInfo</span><span class="p">(</span><span class="o">**</span><span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">)</span>
</span><span id="__span-0-605"><a id="__codelineno-0-605" name="__codelineno-0-605"></a>
</span><span id="__span-0-606"><a id="__codelineno-0-606" name="__codelineno-0-606"></a> <span class="n">error_msg</span> <span class="o">=</span> <span class="n">result</span><span class="o">.</span><span class="n">error_traceback</span> <span class="ow">or</span> <span class="s2">"Failed to create object"</span>
</span><span id="__span-0-607"><a id="__codelineno-0-607" name="__codelineno-0-607"></a> <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="n">error_msg</span><span class="p">)</span>
</span><span id="__span-0-608"><a id="__codelineno-0-608" name="__codelineno-0-608"></a>
</span><span id="__span-0-609"><a id="__codelineno-0-609" name="__codelineno-0-609"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">edit_object</span><span class="p">(</span>
</span><span id="__span-0-610"><a id="__codelineno-0-610" name="__codelineno-0-610"></a> <span class="bp">self</span><span class="p">,</span>
</span><span id="__span-0-611"><a id="__codelineno-0-611" name="__codelineno-0-611"></a> <span class="n">obj_name</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span>
</span><span id="__span-0-612"><a id="__codelineno-0-612" name="__codelineno-0-612"></a> <span class="n">properties</span><span class="p">:</span> <span class="nb">dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Any</span><span class="p">],</span>
</span><span id="__span-0-613"><a id="__codelineno-0-613" name="__codelineno-0-613"></a> <span class="n">doc_name</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-614"><a id="__codelineno-0-614" name="__codelineno-0-614"></a> <span class="p">)</span> <span class="o">-&gt;</span> <span class="n">ObjectInfo</span><span class="p">:</span>
</span><span id="__span-0-615"><a id="__codelineno-0-615" name="__codelineno-0-615"></a><span class="w"> </span><span class="sd">"""Edit object properties.</span>
</span><span id="__span-0-616"><a id="__codelineno-0-616" name="__codelineno-0-616"></a>
</span><span id="__span-0-617"><a id="__codelineno-0-617" name="__codelineno-0-617"></a><span class="sd"> Args:</span>
</span><span id="__span-0-618"><a id="__codelineno-0-618" name="__codelineno-0-618"></a><span class="sd"> obj_name: Name of the object to edit.</span>
</span><span id="__span-0-619"><a id="__codelineno-0-619" name="__codelineno-0-619"></a><span class="sd"> properties: Property values to set.</span>
</span><span id="__span-0-620"><a id="__codelineno-0-620" name="__codelineno-0-620"></a><span class="sd"> doc_name: Document name (uses active if None).</span>
</span><span id="__span-0-621"><a id="__codelineno-0-621" name="__codelineno-0-621"></a>
</span><span id="__span-0-622"><a id="__codelineno-0-622" name="__codelineno-0-622"></a><span class="sd"> Returns:</span>
</span><span id="__span-0-623"><a id="__codelineno-0-623" name="__codelineno-0-623"></a><span class="sd"> Updated ObjectInfo.</span>
</span><span id="__span-0-624"><a id="__codelineno-0-624" name="__codelineno-0-624"></a>
</span><span id="__span-0-625"><a id="__codelineno-0-625" name="__codelineno-0-625"></a><span class="sd"> Raises:</span>
</span><span id="__span-0-626"><a id="__codelineno-0-626" name="__codelineno-0-626"></a><span class="sd"> ValueError: If object not found.</span>
</span><span id="__span-0-627"><a id="__codelineno-0-627" name="__codelineno-0-627"></a><span class="sd"> """</span>
</span><span id="__span-0-628"><a id="__codelineno-0-628" name="__codelineno-0-628"></a> <span class="n">code</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">"""</span>
</span><span id="__span-0-629"><a id="__codelineno-0-629" name="__codelineno-0-629"></a><span class="s2">doc = FreeCAD.ActiveDocument if </span><span class="si">{</span><span class="n">doc_name</span><span class="si">!r}</span><span class="s2"> is None else FreeCAD.getDocument(</span><span class="si">{</span><span class="n">doc_name</span><span class="si">!r}</span><span class="s2">)</span>
</span><span id="__span-0-630"><a id="__codelineno-0-630" name="__codelineno-0-630"></a><span class="s2">if doc is None:</span>
</span><span id="__span-0-631"><a id="__codelineno-0-631" name="__codelineno-0-631"></a><span class="s2"> raise ValueError("No document found")</span>
</span><span id="__span-0-632"><a id="__codelineno-0-632" name="__codelineno-0-632"></a>
</span><span id="__span-0-633"><a id="__codelineno-0-633" name="__codelineno-0-633"></a><span class="s2">obj = doc.getObject(</span><span class="si">{</span><span class="n">obj_name</span><span class="si">!r}</span><span class="s2">)</span>
</span><span id="__span-0-634"><a id="__codelineno-0-634" name="__codelineno-0-634"></a><span class="s2">if obj is None:</span>
</span><span id="__span-0-635"><a id="__codelineno-0-635" name="__codelineno-0-635"></a><span class="s2"> raise ValueError(f"Object not found: </span><span class="si">{</span><span class="n">obj_name</span><span class="si">!r}</span><span class="s2">")</span>
</span><span id="__span-0-636"><a id="__codelineno-0-636" name="__codelineno-0-636"></a>
</span><span id="__span-0-637"><a id="__codelineno-0-637" name="__codelineno-0-637"></a><span class="s2"># Set properties</span>
</span><span id="__span-0-638"><a id="__codelineno-0-638" name="__codelineno-0-638"></a><span class="s2">for prop_name, prop_val in </span><span class="si">{</span><span class="n">properties</span><span class="si">!r}</span><span class="s2">.items():</span>
</span><span id="__span-0-639"><a id="__codelineno-0-639" name="__codelineno-0-639"></a><span class="s2"> if hasattr(obj, prop_name):</span>
</span><span id="__span-0-640"><a id="__codelineno-0-640" name="__codelineno-0-640"></a><span class="s2"> setattr(obj, prop_name, prop_val)</span>
</span><span id="__span-0-641"><a id="__codelineno-0-641" name="__codelineno-0-641"></a>
</span><span id="__span-0-642"><a id="__codelineno-0-642" name="__codelineno-0-642"></a><span class="s2">doc.recompute()</span>
</span><span id="__span-0-643"><a id="__codelineno-0-643" name="__codelineno-0-643"></a>
</span><span id="__span-0-644"><a id="__codelineno-0-644" name="__codelineno-0-644"></a><span class="s2">_result_ = </span><span class="se">{{</span>
</span><span id="__span-0-645"><a id="__codelineno-0-645" name="__codelineno-0-645"></a><span class="s2"> "name": obj.Name,</span>
</span><span id="__span-0-646"><a id="__codelineno-0-646" name="__codelineno-0-646"></a><span class="s2"> "label": obj.Label,</span>
</span><span id="__span-0-647"><a id="__codelineno-0-647" name="__codelineno-0-647"></a><span class="s2"> "type_id": obj.TypeId,</span>
</span><span id="__span-0-648"><a id="__codelineno-0-648" name="__codelineno-0-648"></a><span class="s2"> "visibility": obj.ViewObject.Visibility if hasattr(obj, "ViewObject") and obj.ViewObject else True,</span>
</span><span id="__span-0-649"><a id="__codelineno-0-649" name="__codelineno-0-649"></a><span class="s2"> "children": [c.Name for c in obj.OutList] if hasattr(obj, "OutList") else [],</span>
</span><span id="__span-0-650"><a id="__codelineno-0-650" name="__codelineno-0-650"></a><span class="s2"> "parents": [p.Name for p in obj.InList] if hasattr(obj, "InList") else [],</span>
</span><span id="__span-0-651"><a id="__codelineno-0-651" name="__codelineno-0-651"></a><span class="se">}}</span>
</span><span id="__span-0-652"><a id="__codelineno-0-652" name="__codelineno-0-652"></a><span class="s2">"""</span>
</span><span id="__span-0-653"><a id="__codelineno-0-653" name="__codelineno-0-653"></a> <span class="n">result</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">execute_python</span><span class="p">(</span><span class="n">code</span><span class="p">)</span>
</span><span id="__span-0-654"><a id="__codelineno-0-654" name="__codelineno-0-654"></a>
</span><span id="__span-0-655"><a id="__codelineno-0-655" name="__codelineno-0-655"></a> <span class="k">if</span> <span class="n">result</span><span class="o">.</span><span class="n">success</span> <span class="ow">and</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">:</span>
</span><span id="__span-0-656"><a id="__codelineno-0-656" name="__codelineno-0-656"></a> <span class="k">return</span> <span class="n">ObjectInfo</span><span class="p">(</span><span class="o">**</span><span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">)</span>
</span><span id="__span-0-657"><a id="__codelineno-0-657" name="__codelineno-0-657"></a>
</span><span id="__span-0-658"><a id="__codelineno-0-658" name="__codelineno-0-658"></a> <span class="n">error_msg</span> <span class="o">=</span> <span class="n">result</span><span class="o">.</span><span class="n">error_traceback</span> <span class="ow">or</span> <span class="s2">"Failed to edit object"</span>
</span><span id="__span-0-659"><a id="__codelineno-0-659" name="__codelineno-0-659"></a> <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="n">error_msg</span><span class="p">)</span>
</span><span id="__span-0-660"><a id="__codelineno-0-660" name="__codelineno-0-660"></a>
</span><span id="__span-0-661"><a id="__codelineno-0-661" name="__codelineno-0-661"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">delete_object</span><span class="p">(</span>
</span><span id="__span-0-662"><a id="__codelineno-0-662" name="__codelineno-0-662"></a> <span class="bp">self</span><span class="p">,</span>
</span><span id="__span-0-663"><a id="__codelineno-0-663" name="__codelineno-0-663"></a> <span class="n">obj_name</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span>
</span><span id="__span-0-664"><a id="__codelineno-0-664" name="__codelineno-0-664"></a> <span class="n">doc_name</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-665"><a id="__codelineno-0-665" name="__codelineno-0-665"></a> <span class="p">)</span> <span class="o">-&gt;</span> <span class="kc">None</span><span class="p">:</span>
</span><span id="__span-0-666"><a id="__codelineno-0-666" name="__codelineno-0-666"></a><span class="w"> </span><span class="sd">"""Delete an object.</span>
</span><span id="__span-0-667"><a id="__codelineno-0-667" name="__codelineno-0-667"></a>
</span><span id="__span-0-668"><a id="__codelineno-0-668" name="__codelineno-0-668"></a><span class="sd"> Args:</span>
</span><span id="__span-0-669"><a id="__codelineno-0-669" name="__codelineno-0-669"></a><span class="sd"> obj_name: Name of the object to delete.</span>
</span><span id="__span-0-670"><a id="__codelineno-0-670" name="__codelineno-0-670"></a><span class="sd"> doc_name: Document name (uses active if None).</span>
</span><span id="__span-0-671"><a id="__codelineno-0-671" name="__codelineno-0-671"></a>
</span><span id="__span-0-672"><a id="__codelineno-0-672" name="__codelineno-0-672"></a><span class="sd"> Raises:</span>
</span><span id="__span-0-673"><a id="__codelineno-0-673" name="__codelineno-0-673"></a><span class="sd"> ValueError: If object not found.</span>
</span><span id="__span-0-674"><a id="__codelineno-0-674" name="__codelineno-0-674"></a><span class="sd"> """</span>
</span><span id="__span-0-675"><a id="__codelineno-0-675" name="__codelineno-0-675"></a> <span class="n">code</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">"""</span>
</span><span id="__span-0-676"><a id="__codelineno-0-676" name="__codelineno-0-676"></a><span class="s2">doc = FreeCAD.ActiveDocument if </span><span class="si">{</span><span class="n">doc_name</span><span class="si">!r}</span><span class="s2"> is None else FreeCAD.getDocument(</span><span class="si">{</span><span class="n">doc_name</span><span class="si">!r}</span><span class="s2">)</span>
</span><span id="__span-0-677"><a id="__codelineno-0-677" name="__codelineno-0-677"></a><span class="s2">if doc is None:</span>
</span><span id="__span-0-678"><a id="__codelineno-0-678" name="__codelineno-0-678"></a><span class="s2"> raise ValueError("No document found")</span>
</span><span id="__span-0-679"><a id="__codelineno-0-679" name="__codelineno-0-679"></a>
</span><span id="__span-0-680"><a id="__codelineno-0-680" name="__codelineno-0-680"></a><span class="s2">obj = doc.getObject(</span><span class="si">{</span><span class="n">obj_name</span><span class="si">!r}</span><span class="s2">)</span>
</span><span id="__span-0-681"><a id="__codelineno-0-681" name="__codelineno-0-681"></a><span class="s2">if obj is None:</span>
</span><span id="__span-0-682"><a id="__codelineno-0-682" name="__codelineno-0-682"></a><span class="s2"> raise ValueError(f"Object not found: </span><span class="si">{</span><span class="n">obj_name</span><span class="si">!r}</span><span class="s2">")</span>
</span><span id="__span-0-683"><a id="__codelineno-0-683" name="__codelineno-0-683"></a>
</span><span id="__span-0-684"><a id="__codelineno-0-684" name="__codelineno-0-684"></a><span class="s2">doc.removeObject(</span><span class="si">{</span><span class="n">obj_name</span><span class="si">!r}</span><span class="s2">)</span>
</span><span id="__span-0-685"><a id="__codelineno-0-685" name="__codelineno-0-685"></a><span class="s2">_result_ = True</span>
</span><span id="__span-0-686"><a id="__codelineno-0-686" name="__codelineno-0-686"></a><span class="s2">"""</span>
</span><span id="__span-0-687"><a id="__codelineno-0-687" name="__codelineno-0-687"></a> <span class="n">result</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">execute_python</span><span class="p">(</span><span class="n">code</span><span class="p">)</span>
</span><span id="__span-0-688"><a id="__codelineno-0-688" name="__codelineno-0-688"></a>
</span><span id="__span-0-689"><a id="__codelineno-0-689" name="__codelineno-0-689"></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">result</span><span class="o">.</span><span class="n">success</span><span class="p">:</span>
</span><span id="__span-0-690"><a id="__codelineno-0-690" name="__codelineno-0-690"></a> <span class="n">error_msg</span> <span class="o">=</span> <span class="n">result</span><span class="o">.</span><span class="n">error_traceback</span> <span class="ow">or</span> <span class="s2">"Failed to delete object"</span>
</span><span id="__span-0-691"><a id="__codelineno-0-691" name="__codelineno-0-691"></a> <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="n">error_msg</span><span class="p">)</span>
</span><span id="__span-0-692"><a id="__codelineno-0-692" name="__codelineno-0-692"></a>
</span><span id="__span-0-693"><a id="__codelineno-0-693" name="__codelineno-0-693"></a> <span class="c1"># =========================================================================</span>
</span><span id="__span-0-694"><a id="__codelineno-0-694" name="__codelineno-0-694"></a> <span class="c1"># View and Screenshot</span>
</span><span id="__span-0-695"><a id="__codelineno-0-695" name="__codelineno-0-695"></a> <span class="c1"># =========================================================================</span>
</span><span id="__span-0-696"><a id="__codelineno-0-696" name="__codelineno-0-696"></a>
</span><span id="__span-0-697"><a id="__codelineno-0-697" name="__codelineno-0-697"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">get_screenshot</span><span class="p">(</span>
</span><span id="__span-0-698"><a id="__codelineno-0-698" name="__codelineno-0-698"></a> <span class="bp">self</span><span class="p">,</span>
</span><span id="__span-0-699"><a id="__codelineno-0-699" name="__codelineno-0-699"></a> <span class="n">view_angle</span><span class="p">:</span> <span class="n">ViewAngle</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-700"><a id="__codelineno-0-700" name="__codelineno-0-700"></a> <span class="n">width</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">800</span><span class="p">,</span>
</span><span id="__span-0-701"><a id="__codelineno-0-701" name="__codelineno-0-701"></a> <span class="n">height</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">600</span><span class="p">,</span>
</span><span id="__span-0-702"><a id="__codelineno-0-702" name="__codelineno-0-702"></a> <span class="n">doc_name</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-703"><a id="__codelineno-0-703" name="__codelineno-0-703"></a> <span class="p">)</span> <span class="o">-&gt;</span> <span class="n">ScreenshotResult</span><span class="p">:</span>
</span><span id="__span-0-704"><a id="__codelineno-0-704" name="__codelineno-0-704"></a><span class="w"> </span><span class="sd">"""Capture a screenshot of the 3D view.</span>
</span><span id="__span-0-705"><a id="__codelineno-0-705" name="__codelineno-0-705"></a>
</span><span id="__span-0-706"><a id="__codelineno-0-706" name="__codelineno-0-706"></a><span class="sd"> Note: In embedded headless mode, screenshots are typically not available.</span>
</span><span id="__span-0-707"><a id="__codelineno-0-707" name="__codelineno-0-707"></a>
</span><span id="__span-0-708"><a id="__codelineno-0-708" name="__codelineno-0-708"></a><span class="sd"> Args:</span>
</span><span id="__span-0-709"><a id="__codelineno-0-709" name="__codelineno-0-709"></a><span class="sd"> view_angle: View angle to set before capture.</span>
</span><span id="__span-0-710"><a id="__codelineno-0-710" name="__codelineno-0-710"></a><span class="sd"> width: Image width in pixels.</span>
</span><span id="__span-0-711"><a id="__codelineno-0-711" name="__codelineno-0-711"></a><span class="sd"> height: Image height in pixels.</span>
</span><span id="__span-0-712"><a id="__codelineno-0-712" name="__codelineno-0-712"></a><span class="sd"> doc_name: Document name (uses active if None).</span>
</span><span id="__span-0-713"><a id="__codelineno-0-713" name="__codelineno-0-713"></a>
</span><span id="__span-0-714"><a id="__codelineno-0-714" name="__codelineno-0-714"></a><span class="sd"> Returns:</span>
</span><span id="__span-0-715"><a id="__codelineno-0-715" name="__codelineno-0-715"></a><span class="sd"> ScreenshotResult with image data or error.</span>
</span><span id="__span-0-716"><a id="__codelineno-0-716" name="__codelineno-0-716"></a><span class="sd"> """</span>
</span><span id="__span-0-717"><a id="__codelineno-0-717" name="__codelineno-0-717"></a> <span class="c1"># Check if GUI is available</span>
</span><span id="__span-0-718"><a id="__codelineno-0-718" name="__codelineno-0-718"></a> <span class="n">gui_available</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">is_gui_available</span><span class="p">()</span>
</span><span id="__span-0-719"><a id="__codelineno-0-719" name="__codelineno-0-719"></a>
</span><span id="__span-0-720"><a id="__codelineno-0-720" name="__codelineno-0-720"></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">gui_available</span><span class="p">:</span>
</span><span id="__span-0-721"><a id="__codelineno-0-721" name="__codelineno-0-721"></a> <span class="k">return</span> <span class="n">ScreenshotResult</span><span class="p">(</span>
</span><span id="__span-0-722"><a id="__codelineno-0-722" name="__codelineno-0-722"></a> <span class="n">success</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
</span><span id="__span-0-723"><a id="__codelineno-0-723" name="__codelineno-0-723"></a> <span class="n">error</span><span class="o">=</span><span class="s2">"Screenshots not available in headless mode"</span><span class="p">,</span>
</span><span id="__span-0-724"><a id="__codelineno-0-724" name="__codelineno-0-724"></a> <span class="n">width</span><span class="o">=</span><span class="n">width</span><span class="p">,</span>
</span><span id="__span-0-725"><a id="__codelineno-0-725" name="__codelineno-0-725"></a> <span class="n">height</span><span class="o">=</span><span class="n">height</span><span class="p">,</span>
</span><span id="__span-0-726"><a id="__codelineno-0-726" name="__codelineno-0-726"></a> <span class="n">view_angle</span><span class="o">=</span><span class="n">view_angle</span><span class="p">,</span>
</span><span id="__span-0-727"><a id="__codelineno-0-727" name="__codelineno-0-727"></a> <span class="p">)</span>
</span><span id="__span-0-728"><a id="__codelineno-0-728" name="__codelineno-0-728"></a>
</span><span id="__span-0-729"><a id="__codelineno-0-729" name="__codelineno-0-729"></a> <span class="c1"># If GUI is available, attempt screenshot</span>
</span><span id="__span-0-730"><a id="__codelineno-0-730" name="__codelineno-0-730"></a> <span class="n">view_angle_str</span> <span class="o">=</span> <span class="n">view_angle</span><span class="o">.</span><span class="n">value</span> <span class="k">if</span> <span class="n">view_angle</span> <span class="k">else</span> <span class="s2">"Isometric"</span>
</span><span id="__span-0-731"><a id="__codelineno-0-731" name="__codelineno-0-731"></a> <span class="n">code</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">"""</span>
</span><span id="__span-0-732"><a id="__codelineno-0-732" name="__codelineno-0-732"></a><span class="s2">import base64</span>
</span><span id="__span-0-733"><a id="__codelineno-0-733" name="__codelineno-0-733"></a><span class="s2">import tempfile</span>
</span><span id="__span-0-734"><a id="__codelineno-0-734" name="__codelineno-0-734"></a><span class="s2">import os</span>
</span><span id="__span-0-735"><a id="__codelineno-0-735" name="__codelineno-0-735"></a>
</span><span id="__span-0-736"><a id="__codelineno-0-736" name="__codelineno-0-736"></a><span class="s2">doc = FreeCAD.ActiveDocument if </span><span class="si">{</span><span class="n">doc_name</span><span class="si">!r}</span><span class="s2"> is None else FreeCAD.getDocument(</span><span class="si">{</span><span class="n">doc_name</span><span class="si">!r}</span><span class="s2">)</span>
</span><span id="__span-0-737"><a id="__codelineno-0-737" name="__codelineno-0-737"></a><span class="s2">if doc is None:</span>
</span><span id="__span-0-738"><a id="__codelineno-0-738" name="__codelineno-0-738"></a><span class="s2"> raise ValueError("No document found")</span>
</span><span id="__span-0-739"><a id="__codelineno-0-739" name="__codelineno-0-739"></a>
</span><span id="__span-0-740"><a id="__codelineno-0-740" name="__codelineno-0-740"></a><span class="s2">view = FreeCADGui.ActiveDocument.ActiveView</span>
</span><span id="__span-0-741"><a id="__codelineno-0-741" name="__codelineno-0-741"></a><span class="s2">if view is None:</span>
</span><span id="__span-0-742"><a id="__codelineno-0-742" name="__codelineno-0-742"></a><span class="s2"> raise ValueError("No active view")</span>
</span><span id="__span-0-743"><a id="__codelineno-0-743" name="__codelineno-0-743"></a>
</span><span id="__span-0-744"><a id="__codelineno-0-744" name="__codelineno-0-744"></a><span class="s2"># Set view angle</span>
</span><span id="__span-0-745"><a id="__codelineno-0-745" name="__codelineno-0-745"></a><span class="s2">view_type = </span><span class="si">{</span><span class="n">view_angle_str</span><span class="si">!r}</span>
</span><span id="__span-0-746"><a id="__codelineno-0-746" name="__codelineno-0-746"></a><span class="s2">if view_type == "FitAll":</span>
</span><span id="__span-0-747"><a id="__codelineno-0-747" name="__codelineno-0-747"></a><span class="s2"> view.fitAll()</span>
</span><span id="__span-0-748"><a id="__codelineno-0-748" name="__codelineno-0-748"></a><span class="s2">elif view_type == "Isometric":</span>
</span><span id="__span-0-749"><a id="__codelineno-0-749" name="__codelineno-0-749"></a><span class="s2"> view.viewIsometric()</span>
</span><span id="__span-0-750"><a id="__codelineno-0-750" name="__codelineno-0-750"></a><span class="s2">elif view_type == "Front":</span>
</span><span id="__span-0-751"><a id="__codelineno-0-751" name="__codelineno-0-751"></a><span class="s2"> view.viewFront()</span>
</span><span id="__span-0-752"><a id="__codelineno-0-752" name="__codelineno-0-752"></a><span class="s2">elif view_type == "Back":</span>
</span><span id="__span-0-753"><a id="__codelineno-0-753" name="__codelineno-0-753"></a><span class="s2"> view.viewRear()</span>
</span><span id="__span-0-754"><a id="__codelineno-0-754" name="__codelineno-0-754"></a><span class="s2">elif view_type == "Top":</span>
</span><span id="__span-0-755"><a id="__codelineno-0-755" name="__codelineno-0-755"></a><span class="s2"> view.viewTop()</span>
</span><span id="__span-0-756"><a id="__codelineno-0-756" name="__codelineno-0-756"></a><span class="s2">elif view_type == "Bottom":</span>
</span><span id="__span-0-757"><a id="__codelineno-0-757" name="__codelineno-0-757"></a><span class="s2"> view.viewBottom()</span>
</span><span id="__span-0-758"><a id="__codelineno-0-758" name="__codelineno-0-758"></a><span class="s2">elif view_type == "Left":</span>
</span><span id="__span-0-759"><a id="__codelineno-0-759" name="__codelineno-0-759"></a><span class="s2"> view.viewLeft()</span>
</span><span id="__span-0-760"><a id="__codelineno-0-760" name="__codelineno-0-760"></a><span class="s2">elif view_type == "Right":</span>
</span><span id="__span-0-761"><a id="__codelineno-0-761" name="__codelineno-0-761"></a><span class="s2"> view.viewRight()</span>
</span><span id="__span-0-762"><a id="__codelineno-0-762" name="__codelineno-0-762"></a>
</span><span id="__span-0-763"><a id="__codelineno-0-763" name="__codelineno-0-763"></a><span class="s2"># Save to temp file and read</span>
</span><span id="__span-0-764"><a id="__codelineno-0-764" name="__codelineno-0-764"></a><span class="s2">with tempfile.NamedTemporaryFile(suffix=".png", delete=False) as f:</span>
</span><span id="__span-0-765"><a id="__codelineno-0-765" name="__codelineno-0-765"></a><span class="s2"> temp_path = f.name</span>
</span><span id="__span-0-766"><a id="__codelineno-0-766" name="__codelineno-0-766"></a>
</span><span id="__span-0-767"><a id="__codelineno-0-767" name="__codelineno-0-767"></a><span class="s2">view.saveImage(temp_path, </span><span class="si">{</span><span class="n">width</span><span class="si">}</span><span class="s2">, </span><span class="si">{</span><span class="n">height</span><span class="si">}</span><span class="s2">, "Current")</span>
</span><span id="__span-0-768"><a id="__codelineno-0-768" name="__codelineno-0-768"></a>
</span><span id="__span-0-769"><a id="__codelineno-0-769" name="__codelineno-0-769"></a><span class="s2">with open(temp_path, "rb") as f:</span>
</span><span id="__span-0-770"><a id="__codelineno-0-770" name="__codelineno-0-770"></a><span class="s2"> image_data = base64.b64encode(f.read()).decode("utf-8")</span>
</span><span id="__span-0-771"><a id="__codelineno-0-771" name="__codelineno-0-771"></a>
</span><span id="__span-0-772"><a id="__codelineno-0-772" name="__codelineno-0-772"></a><span class="s2">os.unlink(temp_path)</span>
</span><span id="__span-0-773"><a id="__codelineno-0-773" name="__codelineno-0-773"></a>
</span><span id="__span-0-774"><a id="__codelineno-0-774" name="__codelineno-0-774"></a><span class="s2">_result_ = </span><span class="se">{{</span>
</span><span id="__span-0-775"><a id="__codelineno-0-775" name="__codelineno-0-775"></a><span class="s2"> "success": True,</span>
</span><span id="__span-0-776"><a id="__codelineno-0-776" name="__codelineno-0-776"></a><span class="s2"> "data": image_data,</span>
</span><span id="__span-0-777"><a id="__codelineno-0-777" name="__codelineno-0-777"></a><span class="s2"> "format": "png",</span>
</span><span id="__span-0-778"><a id="__codelineno-0-778" name="__codelineno-0-778"></a><span class="s2"> "width": </span><span class="si">{</span><span class="n">width</span><span class="si">}</span><span class="s2">,</span>
</span><span id="__span-0-779"><a id="__codelineno-0-779" name="__codelineno-0-779"></a><span class="s2"> "height": </span><span class="si">{</span><span class="n">height</span><span class="si">}</span><span class="s2">,</span>
</span><span id="__span-0-780"><a id="__codelineno-0-780" name="__codelineno-0-780"></a><span class="se">}}</span>
</span><span id="__span-0-781"><a id="__codelineno-0-781" name="__codelineno-0-781"></a><span class="s2">"""</span>
</span><span id="__span-0-782"><a id="__codelineno-0-782" name="__codelineno-0-782"></a> <span class="n">result</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">execute_python</span><span class="p">(</span><span class="n">code</span><span class="p">)</span>
</span><span id="__span-0-783"><a id="__codelineno-0-783" name="__codelineno-0-783"></a>
</span><span id="__span-0-784"><a id="__codelineno-0-784" name="__codelineno-0-784"></a> <span class="k">if</span> <span class="n">result</span><span class="o">.</span><span class="n">success</span> <span class="ow">and</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">:</span>
</span><span id="__span-0-785"><a id="__codelineno-0-785" name="__codelineno-0-785"></a> <span class="k">return</span> <span class="n">ScreenshotResult</span><span class="p">(</span>
</span><span id="__span-0-786"><a id="__codelineno-0-786" name="__codelineno-0-786"></a> <span class="n">success</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span>
</span><span id="__span-0-787"><a id="__codelineno-0-787" name="__codelineno-0-787"></a> <span class="n">data</span><span class="o">=</span><span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">[</span><span class="s2">"data"</span><span class="p">],</span>
</span><span id="__span-0-788"><a id="__codelineno-0-788" name="__codelineno-0-788"></a> <span class="nb">format</span><span class="o">=</span><span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">[</span><span class="s2">"format"</span><span class="p">],</span>
</span><span id="__span-0-789"><a id="__codelineno-0-789" name="__codelineno-0-789"></a> <span class="n">width</span><span class="o">=</span><span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">[</span><span class="s2">"width"</span><span class="p">],</span>
</span><span id="__span-0-790"><a id="__codelineno-0-790" name="__codelineno-0-790"></a> <span class="n">height</span><span class="o">=</span><span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">[</span><span class="s2">"height"</span><span class="p">],</span>
</span><span id="__span-0-791"><a id="__codelineno-0-791" name="__codelineno-0-791"></a> <span class="n">view_angle</span><span class="o">=</span><span class="n">view_angle</span><span class="p">,</span>
</span><span id="__span-0-792"><a id="__codelineno-0-792" name="__codelineno-0-792"></a> <span class="p">)</span>
</span><span id="__span-0-793"><a id="__codelineno-0-793" name="__codelineno-0-793"></a>
</span><span id="__span-0-794"><a id="__codelineno-0-794" name="__codelineno-0-794"></a> <span class="k">return</span> <span class="n">ScreenshotResult</span><span class="p">(</span>
</span><span id="__span-0-795"><a id="__codelineno-0-795" name="__codelineno-0-795"></a> <span class="n">success</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
</span><span id="__span-0-796"><a id="__codelineno-0-796" name="__codelineno-0-796"></a> <span class="n">error</span><span class="o">=</span><span class="n">result</span><span class="o">.</span><span class="n">error_traceback</span> <span class="ow">or</span> <span class="s2">"Failed to capture screenshot"</span><span class="p">,</span>
</span><span id="__span-0-797"><a id="__codelineno-0-797" name="__codelineno-0-797"></a> <span class="n">width</span><span class="o">=</span><span class="n">width</span><span class="p">,</span>
</span><span id="__span-0-798"><a id="__codelineno-0-798" name="__codelineno-0-798"></a> <span class="n">height</span><span class="o">=</span><span class="n">height</span><span class="p">,</span>
</span><span id="__span-0-799"><a id="__codelineno-0-799" name="__codelineno-0-799"></a> <span class="n">view_angle</span><span class="o">=</span><span class="n">view_angle</span><span class="p">,</span>
</span><span id="__span-0-800"><a id="__codelineno-0-800" name="__codelineno-0-800"></a> <span class="p">)</span>
</span><span id="__span-0-801"><a id="__codelineno-0-801" name="__codelineno-0-801"></a>
</span><span id="__span-0-802"><a id="__codelineno-0-802" name="__codelineno-0-802"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">set_view</span><span class="p">(</span>
</span><span id="__span-0-803"><a id="__codelineno-0-803" name="__codelineno-0-803"></a> <span class="bp">self</span><span class="p">,</span>
</span><span id="__span-0-804"><a id="__codelineno-0-804" name="__codelineno-0-804"></a> <span class="n">view_angle</span><span class="p">:</span> <span class="n">ViewAngle</span><span class="p">,</span>
</span><span id="__span-0-805"><a id="__codelineno-0-805" name="__codelineno-0-805"></a> <span class="n">doc_name</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-806"><a id="__codelineno-0-806" name="__codelineno-0-806"></a> <span class="p">)</span> <span class="o">-&gt;</span> <span class="kc">None</span><span class="p">:</span>
</span><span id="__span-0-807"><a id="__codelineno-0-807" name="__codelineno-0-807"></a><span class="w"> </span><span class="sd">"""Set the 3D view angle.</span>
</span><span id="__span-0-808"><a id="__codelineno-0-808" name="__codelineno-0-808"></a>
</span><span id="__span-0-809"><a id="__codelineno-0-809" name="__codelineno-0-809"></a><span class="sd"> Args:</span>
</span><span id="__span-0-810"><a id="__codelineno-0-810" name="__codelineno-0-810"></a><span class="sd"> view_angle: View angle to set.</span>
</span><span id="__span-0-811"><a id="__codelineno-0-811" name="__codelineno-0-811"></a><span class="sd"> doc_name: Document name (uses active if None).</span>
</span><span id="__span-0-812"><a id="__codelineno-0-812" name="__codelineno-0-812"></a><span class="sd"> """</span>
</span><span id="__span-0-813"><a id="__codelineno-0-813" name="__codelineno-0-813"></a> <span class="n">gui_available</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">is_gui_available</span><span class="p">()</span>
</span><span id="__span-0-814"><a id="__codelineno-0-814" name="__codelineno-0-814"></a>
</span><span id="__span-0-815"><a id="__codelineno-0-815" name="__codelineno-0-815"></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">gui_available</span><span class="p">:</span>
</span><span id="__span-0-816"><a id="__codelineno-0-816" name="__codelineno-0-816"></a> <span class="k">return</span> <span class="c1"># Silently ignore in headless mode</span>
</span><span id="__span-0-817"><a id="__codelineno-0-817" name="__codelineno-0-817"></a>
</span><span id="__span-0-818"><a id="__codelineno-0-818" name="__codelineno-0-818"></a> <span class="n">view_angle_str</span> <span class="o">=</span> <span class="n">view_angle</span><span class="o">.</span><span class="n">value</span>
</span><span id="__span-0-819"><a id="__codelineno-0-819" name="__codelineno-0-819"></a> <span class="n">code</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">"""</span>
</span><span id="__span-0-820"><a id="__codelineno-0-820" name="__codelineno-0-820"></a><span class="s2">doc = FreeCAD.ActiveDocument if </span><span class="si">{</span><span class="n">doc_name</span><span class="si">!r}</span><span class="s2"> is None else FreeCAD.getDocument(</span><span class="si">{</span><span class="n">doc_name</span><span class="si">!r}</span><span class="s2">)</span>
</span><span id="__span-0-821"><a id="__codelineno-0-821" name="__codelineno-0-821"></a><span class="s2">if doc is None:</span>
</span><span id="__span-0-822"><a id="__codelineno-0-822" name="__codelineno-0-822"></a><span class="s2"> raise ValueError("No document found")</span>
</span><span id="__span-0-823"><a id="__codelineno-0-823" name="__codelineno-0-823"></a>
</span><span id="__span-0-824"><a id="__codelineno-0-824" name="__codelineno-0-824"></a><span class="s2">view = FreeCADGui.ActiveDocument.ActiveView</span>
</span><span id="__span-0-825"><a id="__codelineno-0-825" name="__codelineno-0-825"></a><span class="s2">if view is None:</span>
</span><span id="__span-0-826"><a id="__codelineno-0-826" name="__codelineno-0-826"></a><span class="s2"> raise ValueError("No active view")</span>
</span><span id="__span-0-827"><a id="__codelineno-0-827" name="__codelineno-0-827"></a>
</span><span id="__span-0-828"><a id="__codelineno-0-828" name="__codelineno-0-828"></a><span class="s2">view_type = </span><span class="si">{</span><span class="n">view_angle_str</span><span class="si">!r}</span>
</span><span id="__span-0-829"><a id="__codelineno-0-829" name="__codelineno-0-829"></a><span class="s2">if view_type == "FitAll":</span>
</span><span id="__span-0-830"><a id="__codelineno-0-830" name="__codelineno-0-830"></a><span class="s2"> view.fitAll()</span>
</span><span id="__span-0-831"><a id="__codelineno-0-831" name="__codelineno-0-831"></a><span class="s2">elif view_type == "Isometric":</span>
</span><span id="__span-0-832"><a id="__codelineno-0-832" name="__codelineno-0-832"></a><span class="s2"> view.viewIsometric()</span>
</span><span id="__span-0-833"><a id="__codelineno-0-833" name="__codelineno-0-833"></a><span class="s2">elif view_type == "Front":</span>
</span><span id="__span-0-834"><a id="__codelineno-0-834" name="__codelineno-0-834"></a><span class="s2"> view.viewFront()</span>
</span><span id="__span-0-835"><a id="__codelineno-0-835" name="__codelineno-0-835"></a><span class="s2">elif view_type == "Back":</span>
</span><span id="__span-0-836"><a id="__codelineno-0-836" name="__codelineno-0-836"></a><span class="s2"> view.viewRear()</span>
</span><span id="__span-0-837"><a id="__codelineno-0-837" name="__codelineno-0-837"></a><span class="s2">elif view_type == "Top":</span>
</span><span id="__span-0-838"><a id="__codelineno-0-838" name="__codelineno-0-838"></a><span class="s2"> view.viewTop()</span>
</span><span id="__span-0-839"><a id="__codelineno-0-839" name="__codelineno-0-839"></a><span class="s2">elif view_type == "Bottom":</span>
</span><span id="__span-0-840"><a id="__codelineno-0-840" name="__codelineno-0-840"></a><span class="s2"> view.viewBottom()</span>
</span><span id="__span-0-841"><a id="__codelineno-0-841" name="__codelineno-0-841"></a><span class="s2">elif view_type == "Left":</span>
</span><span id="__span-0-842"><a id="__codelineno-0-842" name="__codelineno-0-842"></a><span class="s2"> view.viewLeft()</span>
</span><span id="__span-0-843"><a id="__codelineno-0-843" name="__codelineno-0-843"></a><span class="s2">elif view_type == "Right":</span>
</span><span id="__span-0-844"><a id="__codelineno-0-844" name="__codelineno-0-844"></a><span class="s2"> view.viewRight()</span>
</span><span id="__span-0-845"><a id="__codelineno-0-845" name="__codelineno-0-845"></a>
</span><span id="__span-0-846"><a id="__codelineno-0-846" name="__codelineno-0-846"></a><span class="s2">_result_ = True</span>
</span><span id="__span-0-847"><a id="__codelineno-0-847" name="__codelineno-0-847"></a><span class="s2">"""</span>
</span><span id="__span-0-848"><a id="__codelineno-0-848" name="__codelineno-0-848"></a> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">execute_python</span><span class="p">(</span><span class="n">code</span><span class="p">)</span>
</span><span id="__span-0-849"><a id="__codelineno-0-849" name="__codelineno-0-849"></a>
</span><span id="__span-0-850"><a id="__codelineno-0-850" name="__codelineno-0-850"></a> <span class="c1"># =========================================================================</span>
</span><span id="__span-0-851"><a id="__codelineno-0-851" name="__codelineno-0-851"></a> <span class="c1"># Macros</span>
</span><span id="__span-0-852"><a id="__codelineno-0-852" name="__codelineno-0-852"></a> <span class="c1"># =========================================================================</span>
</span><span id="__span-0-853"><a id="__codelineno-0-853" name="__codelineno-0-853"></a>
</span><span id="__span-0-854"><a id="__codelineno-0-854" name="__codelineno-0-854"></a> <span class="k">def</span><span class="w"> </span><span class="nf">_get_macro_path</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">Path</span><span class="p">:</span>
</span><span id="__span-0-855"><a id="__codelineno-0-855" name="__codelineno-0-855"></a><span class="w"> </span><span class="sd">"""Get the FreeCAD macro directory path."""</span>
</span><span id="__span-0-856"><a id="__codelineno-0-856" name="__codelineno-0-856"></a> <span class="c1"># Default FreeCAD macro locations</span>
</span><span id="__span-0-857"><a id="__codelineno-0-857" name="__codelineno-0-857"></a> <span class="k">if</span> <span class="n">sys</span><span class="o">.</span><span class="n">platform</span> <span class="o">==</span> <span class="s2">"darwin"</span><span class="p">:</span>
</span><span id="__span-0-858"><a id="__codelineno-0-858" name="__codelineno-0-858"></a> <span class="k">return</span> <span class="n">Path</span><span class="o">.</span><span class="n">home</span><span class="p">()</span> <span class="o">/</span> <span class="s2">"Library"</span> <span class="o">/</span> <span class="s2">"Application Support"</span> <span class="o">/</span> <span class="s2">"FreeCAD"</span> <span class="o">/</span> <span class="s2">"Macro"</span>
</span><span id="__span-0-859"><a id="__codelineno-0-859" name="__codelineno-0-859"></a> <span class="k">elif</span> <span class="n">sys</span><span class="o">.</span><span class="n">platform</span> <span class="o">==</span> <span class="s2">"win32"</span><span class="p">:</span>
</span><span id="__span-0-860"><a id="__codelineno-0-860" name="__codelineno-0-860"></a> <span class="k">return</span> <span class="n">Path</span><span class="p">(</span><span class="n">os</span><span class="o">.</span><span class="n">environ</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"APPDATA"</span><span class="p">,</span> <span class="s2">""</span><span class="p">))</span> <span class="o">/</span> <span class="s2">"FreeCAD"</span> <span class="o">/</span> <span class="s2">"Macro"</span>
</span><span id="__span-0-861"><a id="__codelineno-0-861" name="__codelineno-0-861"></a> <span class="k">else</span><span class="p">:</span>
</span><span id="__span-0-862"><a id="__codelineno-0-862" name="__codelineno-0-862"></a> <span class="k">return</span> <span class="n">Path</span><span class="o">.</span><span class="n">home</span><span class="p">()</span> <span class="o">/</span> <span class="s2">".local"</span> <span class="o">/</span> <span class="s2">"share"</span> <span class="o">/</span> <span class="s2">"FreeCAD"</span> <span class="o">/</span> <span class="s2">"Macro"</span>
</span><span id="__span-0-863"><a id="__codelineno-0-863" name="__codelineno-0-863"></a>
</span><span id="__span-0-864"><a id="__codelineno-0-864" name="__codelineno-0-864"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">get_macros</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">list</span><span class="p">[</span><span class="n">MacroInfo</span><span class="p">]:</span>
</span><span id="__span-0-865"><a id="__codelineno-0-865" name="__codelineno-0-865"></a><span class="w"> </span><span class="sd">"""Get list of available macros.</span>
</span><span id="__span-0-866"><a id="__codelineno-0-866" name="__codelineno-0-866"></a>
</span><span id="__span-0-867"><a id="__codelineno-0-867" name="__codelineno-0-867"></a><span class="sd"> Returns:</span>
</span><span id="__span-0-868"><a id="__codelineno-0-868" name="__codelineno-0-868"></a><span class="sd"> List of MacroInfo for each macro.</span>
</span><span id="__span-0-869"><a id="__codelineno-0-869" name="__codelineno-0-869"></a><span class="sd"> """</span>
</span><span id="__span-0-870"><a id="__codelineno-0-870" name="__codelineno-0-870"></a> <span class="n">macro_path</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_macro_path</span><span class="p">()</span>
</span><span id="__span-0-871"><a id="__codelineno-0-871" name="__codelineno-0-871"></a>
</span><span id="__span-0-872"><a id="__codelineno-0-872" name="__codelineno-0-872"></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">macro_path</span><span class="o">.</span><span class="n">exists</span><span class="p">():</span>
</span><span id="__span-0-873"><a id="__codelineno-0-873" name="__codelineno-0-873"></a> <span class="k">return</span> <span class="p">[]</span>
</span><span id="__span-0-874"><a id="__codelineno-0-874" name="__codelineno-0-874"></a>
</span><span id="__span-0-875"><a id="__codelineno-0-875" name="__codelineno-0-875"></a> <span class="n">macros</span> <span class="o">=</span> <span class="p">[]</span>
</span><span id="__span-0-876"><a id="__codelineno-0-876" name="__codelineno-0-876"></a> <span class="k">for</span> <span class="n">macro_file</span> <span class="ow">in</span> <span class="n">macro_path</span><span class="o">.</span><span class="n">glob</span><span class="p">(</span><span class="s2">"*.FCMacro"</span><span class="p">):</span>
</span><span id="__span-0-877"><a id="__codelineno-0-877" name="__codelineno-0-877"></a> <span class="n">description</span> <span class="o">=</span> <span class="s2">""</span>
</span><span id="__span-0-878"><a id="__codelineno-0-878" name="__codelineno-0-878"></a> <span class="k">try</span><span class="p">:</span>
</span><span id="__span-0-879"><a id="__codelineno-0-879" name="__codelineno-0-879"></a> <span class="n">content</span> <span class="o">=</span> <span class="n">macro_file</span><span class="o">.</span><span class="n">read_text</span><span class="p">()</span>
</span><span id="__span-0-880"><a id="__codelineno-0-880" name="__codelineno-0-880"></a> <span class="c1"># Extract description from first comment block</span>
</span><span id="__span-0-881"><a id="__codelineno-0-881" name="__codelineno-0-881"></a> <span class="k">for</span> <span class="n">line</span> <span class="ow">in</span> <span class="n">content</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s2">"</span><span class="se">\n</span><span class="s2">"</span><span class="p">):</span>
</span><span id="__span-0-882"><a id="__codelineno-0-882" name="__codelineno-0-882"></a> <span class="k">if</span> <span class="n">line</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s2">"#"</span><span class="p">):</span>
</span><span id="__span-0-883"><a id="__codelineno-0-883" name="__codelineno-0-883"></a> <span class="n">desc_line</span> <span class="o">=</span> <span class="n">line</span><span class="o">.</span><span class="n">lstrip</span><span class="p">(</span><span class="s2">"#"</span><span class="p">)</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span>
</span><span id="__span-0-884"><a id="__codelineno-0-884" name="__codelineno-0-884"></a> <span class="k">if</span> <span class="n">desc_line</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">desc_line</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s2">"!"</span><span class="p">):</span>
</span><span id="__span-0-885"><a id="__codelineno-0-885" name="__codelineno-0-885"></a> <span class="n">description</span> <span class="o">=</span> <span class="n">desc_line</span>
</span><span id="__span-0-886"><a id="__codelineno-0-886" name="__codelineno-0-886"></a> <span class="k">break</span>
</span><span id="__span-0-887"><a id="__codelineno-0-887" name="__codelineno-0-887"></a> <span class="k">except</span> <span class="ne">Exception</span><span class="p">:</span>
</span><span id="__span-0-888"><a id="__codelineno-0-888" name="__codelineno-0-888"></a> <span class="k">pass</span>
</span><span id="__span-0-889"><a id="__codelineno-0-889" name="__codelineno-0-889"></a>
</span><span id="__span-0-890"><a id="__codelineno-0-890" name="__codelineno-0-890"></a> <span class="n">macros</span><span class="o">.</span><span class="n">append</span><span class="p">(</span>
</span><span id="__span-0-891"><a id="__codelineno-0-891" name="__codelineno-0-891"></a> <span class="n">MacroInfo</span><span class="p">(</span>
</span><span id="__span-0-892"><a id="__codelineno-0-892" name="__codelineno-0-892"></a> <span class="n">name</span><span class="o">=</span><span class="n">macro_file</span><span class="o">.</span><span class="n">stem</span><span class="p">,</span>
</span><span id="__span-0-893"><a id="__codelineno-0-893" name="__codelineno-0-893"></a> <span class="n">path</span><span class="o">=</span><span class="nb">str</span><span class="p">(</span><span class="n">macro_file</span><span class="p">),</span>
</span><span id="__span-0-894"><a id="__codelineno-0-894" name="__codelineno-0-894"></a> <span class="n">description</span><span class="o">=</span><span class="n">description</span><span class="p">,</span>
</span><span id="__span-0-895"><a id="__codelineno-0-895" name="__codelineno-0-895"></a> <span class="n">is_system</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
</span><span id="__span-0-896"><a id="__codelineno-0-896" name="__codelineno-0-896"></a> <span class="p">)</span>
</span><span id="__span-0-897"><a id="__codelineno-0-897" name="__codelineno-0-897"></a> <span class="p">)</span>
</span><span id="__span-0-898"><a id="__codelineno-0-898" name="__codelineno-0-898"></a>
</span><span id="__span-0-899"><a id="__codelineno-0-899" name="__codelineno-0-899"></a> <span class="k">return</span> <span class="n">macros</span>
</span><span id="__span-0-900"><a id="__codelineno-0-900" name="__codelineno-0-900"></a>
</span><span id="__span-0-901"><a id="__codelineno-0-901" name="__codelineno-0-901"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">run_macro</span><span class="p">(</span>
</span><span id="__span-0-902"><a id="__codelineno-0-902" name="__codelineno-0-902"></a> <span class="bp">self</span><span class="p">,</span>
</span><span id="__span-0-903"><a id="__codelineno-0-903" name="__codelineno-0-903"></a> <span class="n">macro_name</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span>
</span><span id="__span-0-904"><a id="__codelineno-0-904" name="__codelineno-0-904"></a> <span class="n">args</span><span class="p">:</span> <span class="nb">dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Any</span><span class="p">]</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-905"><a id="__codelineno-0-905" name="__codelineno-0-905"></a> <span class="p">)</span> <span class="o">-&gt;</span> <span class="n">ExecutionResult</span><span class="p">:</span>
</span><span id="__span-0-906"><a id="__codelineno-0-906" name="__codelineno-0-906"></a><span class="w"> </span><span class="sd">"""Run a macro by name.</span>
</span><span id="__span-0-907"><a id="__codelineno-0-907" name="__codelineno-0-907"></a>
</span><span id="__span-0-908"><a id="__codelineno-0-908" name="__codelineno-0-908"></a><span class="sd"> Args:</span>
</span><span id="__span-0-909"><a id="__codelineno-0-909" name="__codelineno-0-909"></a><span class="sd"> macro_name: Macro name (without .FCMacro extension).</span>
</span><span id="__span-0-910"><a id="__codelineno-0-910" name="__codelineno-0-910"></a><span class="sd"> args: Arguments to pass to the macro.</span>
</span><span id="__span-0-911"><a id="__codelineno-0-911" name="__codelineno-0-911"></a>
</span><span id="__span-0-912"><a id="__codelineno-0-912" name="__codelineno-0-912"></a><span class="sd"> Returns:</span>
</span><span id="__span-0-913"><a id="__codelineno-0-913" name="__codelineno-0-913"></a><span class="sd"> ExecutionResult from macro execution.</span>
</span><span id="__span-0-914"><a id="__codelineno-0-914" name="__codelineno-0-914"></a><span class="sd"> """</span>
</span><span id="__span-0-915"><a id="__codelineno-0-915" name="__codelineno-0-915"></a> <span class="n">macro_path</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_macro_path</span><span class="p">()</span> <span class="o">/</span> <span class="sa">f</span><span class="s2">"</span><span class="si">{</span><span class="n">macro_name</span><span class="si">}</span><span class="s2">.FCMacro"</span>
</span><span id="__span-0-916"><a id="__codelineno-0-916" name="__codelineno-0-916"></a>
</span><span id="__span-0-917"><a id="__codelineno-0-917" name="__codelineno-0-917"></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">macro_path</span><span class="o">.</span><span class="n">exists</span><span class="p">():</span>
</span><span id="__span-0-918"><a id="__codelineno-0-918" name="__codelineno-0-918"></a> <span class="k">return</span> <span class="n">ExecutionResult</span><span class="p">(</span>
</span><span id="__span-0-919"><a id="__codelineno-0-919" name="__codelineno-0-919"></a> <span class="n">success</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
</span><span id="__span-0-920"><a id="__codelineno-0-920" name="__codelineno-0-920"></a> <span class="n">result</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-921"><a id="__codelineno-0-921" name="__codelineno-0-921"></a> <span class="n">stdout</span><span class="o">=</span><span class="s2">""</span><span class="p">,</span>
</span><span id="__span-0-922"><a id="__codelineno-0-922" name="__codelineno-0-922"></a> <span class="n">stderr</span><span class="o">=</span><span class="sa">f</span><span class="s2">"Macro not found: </span><span class="si">{</span><span class="n">macro_name</span><span class="si">}</span><span class="s2">"</span><span class="p">,</span>
</span><span id="__span-0-923"><a id="__codelineno-0-923" name="__codelineno-0-923"></a> <span class="n">execution_time_ms</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span>
</span><span id="__span-0-924"><a id="__codelineno-0-924" name="__codelineno-0-924"></a> <span class="n">error_type</span><span class="o">=</span><span class="s2">"FileNotFoundError"</span><span class="p">,</span>
</span><span id="__span-0-925"><a id="__codelineno-0-925" name="__codelineno-0-925"></a> <span class="p">)</span>
</span><span id="__span-0-926"><a id="__codelineno-0-926" name="__codelineno-0-926"></a>
</span><span id="__span-0-927"><a id="__codelineno-0-927" name="__codelineno-0-927"></a> <span class="k">try</span><span class="p">:</span>
</span><span id="__span-0-928"><a id="__codelineno-0-928" name="__codelineno-0-928"></a> <span class="n">macro_code</span> <span class="o">=</span> <span class="n">macro_path</span><span class="o">.</span><span class="n">read_text</span><span class="p">()</span>
</span><span id="__span-0-929"><a id="__codelineno-0-929" name="__codelineno-0-929"></a> <span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
</span><span id="__span-0-930"><a id="__codelineno-0-930" name="__codelineno-0-930"></a> <span class="k">return</span> <span class="n">ExecutionResult</span><span class="p">(</span>
</span><span id="__span-0-931"><a id="__codelineno-0-931" name="__codelineno-0-931"></a> <span class="n">success</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
</span><span id="__span-0-932"><a id="__codelineno-0-932" name="__codelineno-0-932"></a> <span class="n">result</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-933"><a id="__codelineno-0-933" name="__codelineno-0-933"></a> <span class="n">stdout</span><span class="o">=</span><span class="s2">""</span><span class="p">,</span>
</span><span id="__span-0-934"><a id="__codelineno-0-934" name="__codelineno-0-934"></a> <span class="n">stderr</span><span class="o">=</span><span class="sa">f</span><span class="s2">"Failed to read macro: </span><span class="si">{</span><span class="n">e</span><span class="si">}</span><span class="s2">"</span><span class="p">,</span>
</span><span id="__span-0-935"><a id="__codelineno-0-935" name="__codelineno-0-935"></a> <span class="n">execution_time_ms</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span>
</span><span id="__span-0-936"><a id="__codelineno-0-936" name="__codelineno-0-936"></a> <span class="n">error_type</span><span class="o">=</span><span class="nb">type</span><span class="p">(</span><span class="n">e</span><span class="p">)</span><span class="o">.</span><span class="vm">__name__</span><span class="p">,</span>
</span><span id="__span-0-937"><a id="__codelineno-0-937" name="__codelineno-0-937"></a> <span class="p">)</span>
</span><span id="__span-0-938"><a id="__codelineno-0-938" name="__codelineno-0-938"></a>
</span><span id="__span-0-939"><a id="__codelineno-0-939" name="__codelineno-0-939"></a> <span class="c1"># Prepend argument setup if provided</span>
</span><span id="__span-0-940"><a id="__codelineno-0-940" name="__codelineno-0-940"></a> <span class="k">if</span> <span class="n">args</span><span class="p">:</span>
</span><span id="__span-0-941"><a id="__codelineno-0-941" name="__codelineno-0-941"></a> <span class="n">args_setup</span> <span class="o">=</span> <span class="s2">"</span><span class="se">\n</span><span class="s2">"</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="sa">f</span><span class="s2">"</span><span class="si">{</span><span class="n">k</span><span class="si">}</span><span class="s2"> = </span><span class="si">{</span><span class="n">v</span><span class="si">!r}</span><span class="s2">"</span> <span class="k">for</span> <span class="n">k</span><span class="p">,</span> <span class="n">v</span> <span class="ow">in</span> <span class="n">args</span><span class="o">.</span><span class="n">items</span><span class="p">())</span>
</span><span id="__span-0-942"><a id="__codelineno-0-942" name="__codelineno-0-942"></a> <span class="n">macro_code</span> <span class="o">=</span> <span class="n">args_setup</span> <span class="o">+</span> <span class="s2">"</span><span class="se">\n</span><span class="s2">"</span> <span class="o">+</span> <span class="n">macro_code</span>
</span><span id="__span-0-943"><a id="__codelineno-0-943" name="__codelineno-0-943"></a>
</span><span id="__span-0-944"><a id="__codelineno-0-944" name="__codelineno-0-944"></a> <span class="k">return</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">execute_python</span><span class="p">(</span><span class="n">macro_code</span><span class="p">)</span>
</span><span id="__span-0-945"><a id="__codelineno-0-945" name="__codelineno-0-945"></a>
</span><span id="__span-0-946"><a id="__codelineno-0-946" name="__codelineno-0-946"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">create_macro</span><span class="p">(</span>
</span><span id="__span-0-947"><a id="__codelineno-0-947" name="__codelineno-0-947"></a> <span class="bp">self</span><span class="p">,</span>
</span><span id="__span-0-948"><a id="__codelineno-0-948" name="__codelineno-0-948"></a> <span class="n">name</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span>
</span><span id="__span-0-949"><a id="__codelineno-0-949" name="__codelineno-0-949"></a> <span class="n">code</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span>
</span><span id="__span-0-950"><a id="__codelineno-0-950" name="__codelineno-0-950"></a> <span class="n">description</span><span class="p">:</span> <span class="nb">str</span> <span class="o">=</span> <span class="s2">""</span><span class="p">,</span>
</span><span id="__span-0-951"><a id="__codelineno-0-951" name="__codelineno-0-951"></a> <span class="p">)</span> <span class="o">-&gt;</span> <span class="n">MacroInfo</span><span class="p">:</span>
</span><span id="__span-0-952"><a id="__codelineno-0-952" name="__codelineno-0-952"></a><span class="w"> </span><span class="sd">"""Create a new macro.</span>
</span><span id="__span-0-953"><a id="__codelineno-0-953" name="__codelineno-0-953"></a>
</span><span id="__span-0-954"><a id="__codelineno-0-954" name="__codelineno-0-954"></a><span class="sd"> Args:</span>
</span><span id="__span-0-955"><a id="__codelineno-0-955" name="__codelineno-0-955"></a><span class="sd"> name: Macro name (without extension).</span>
</span><span id="__span-0-956"><a id="__codelineno-0-956" name="__codelineno-0-956"></a><span class="sd"> code: Python code for the macro.</span>
</span><span id="__span-0-957"><a id="__codelineno-0-957" name="__codelineno-0-957"></a><span class="sd"> description: Macro description.</span>
</span><span id="__span-0-958"><a id="__codelineno-0-958" name="__codelineno-0-958"></a>
</span><span id="__span-0-959"><a id="__codelineno-0-959" name="__codelineno-0-959"></a><span class="sd"> Returns:</span>
</span><span id="__span-0-960"><a id="__codelineno-0-960" name="__codelineno-0-960"></a><span class="sd"> MacroInfo for the created macro.</span>
</span><span id="__span-0-961"><a id="__codelineno-0-961" name="__codelineno-0-961"></a><span class="sd"> """</span>
</span><span id="__span-0-962"><a id="__codelineno-0-962" name="__codelineno-0-962"></a> <span class="n">macro_path</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_macro_path</span><span class="p">()</span>
</span><span id="__span-0-963"><a id="__codelineno-0-963" name="__codelineno-0-963"></a> <span class="n">macro_path</span><span class="o">.</span><span class="n">mkdir</span><span class="p">(</span><span class="n">parents</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">exist_ok</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
</span><span id="__span-0-964"><a id="__codelineno-0-964" name="__codelineno-0-964"></a>
</span><span id="__span-0-965"><a id="__codelineno-0-965" name="__codelineno-0-965"></a> <span class="n">macro_file</span> <span class="o">=</span> <span class="n">macro_path</span> <span class="o">/</span> <span class="sa">f</span><span class="s2">"</span><span class="si">{</span><span class="n">name</span><span class="si">}</span><span class="s2">.FCMacro"</span>
</span><span id="__span-0-966"><a id="__codelineno-0-966" name="__codelineno-0-966"></a>
</span><span id="__span-0-967"><a id="__codelineno-0-967" name="__codelineno-0-967"></a> <span class="c1"># Add description as header comment</span>
</span><span id="__span-0-968"><a id="__codelineno-0-968" name="__codelineno-0-968"></a> <span class="n">header</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">"# </span><span class="si">{</span><span class="n">description</span><span class="si">}</span><span class="se">\n\n</span><span class="s2">"</span> <span class="k">if</span> <span class="n">description</span> <span class="k">else</span> <span class="s2">""</span>
</span><span id="__span-0-969"><a id="__codelineno-0-969" name="__codelineno-0-969"></a>
</span><span id="__span-0-970"><a id="__codelineno-0-970" name="__codelineno-0-970"></a> <span class="c1"># Add standard imports</span>
</span><span id="__span-0-971"><a id="__codelineno-0-971" name="__codelineno-0-971"></a> <span class="n">full_code</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">"""</span><span class="si">{</span><span class="n">header</span><span class="si">}</span><span class="s2"># -*- coding: utf-8 -*-</span>
</span><span id="__span-0-972"><a id="__codelineno-0-972" name="__codelineno-0-972"></a><span class="s2"># FreeCAD Macro: </span><span class="si">{</span><span class="n">name</span><span class="si">}</span>
</span><span id="__span-0-973"><a id="__codelineno-0-973" name="__codelineno-0-973"></a><span class="s2"># Created via MCP Bridge</span>
</span><span id="__span-0-974"><a id="__codelineno-0-974" name="__codelineno-0-974"></a>
</span><span id="__span-0-975"><a id="__codelineno-0-975" name="__codelineno-0-975"></a><span class="s2">import FreeCAD</span>
</span><span id="__span-0-976"><a id="__codelineno-0-976" name="__codelineno-0-976"></a><span class="s2">import FreeCADGui</span>
</span><span id="__span-0-977"><a id="__codelineno-0-977" name="__codelineno-0-977"></a>
</span><span id="__span-0-978"><a id="__codelineno-0-978" name="__codelineno-0-978"></a><span class="si">{</span><span class="n">code</span><span class="si">}</span>
</span><span id="__span-0-979"><a id="__codelineno-0-979" name="__codelineno-0-979"></a><span class="s2">"""</span>
</span><span id="__span-0-980"><a id="__codelineno-0-980" name="__codelineno-0-980"></a> <span class="n">macro_file</span><span class="o">.</span><span class="n">write_text</span><span class="p">(</span><span class="n">full_code</span><span class="p">)</span>
</span><span id="__span-0-981"><a id="__codelineno-0-981" name="__codelineno-0-981"></a>
</span><span id="__span-0-982"><a id="__codelineno-0-982" name="__codelineno-0-982"></a> <span class="k">return</span> <span class="n">MacroInfo</span><span class="p">(</span>
</span><span id="__span-0-983"><a id="__codelineno-0-983" name="__codelineno-0-983"></a> <span class="n">name</span><span class="o">=</span><span class="n">name</span><span class="p">,</span>
</span><span id="__span-0-984"><a id="__codelineno-0-984" name="__codelineno-0-984"></a> <span class="n">path</span><span class="o">=</span><span class="nb">str</span><span class="p">(</span><span class="n">macro_file</span><span class="p">),</span>
</span><span id="__span-0-985"><a id="__codelineno-0-985" name="__codelineno-0-985"></a> <span class="n">description</span><span class="o">=</span><span class="n">description</span><span class="p">,</span>
</span><span id="__span-0-986"><a id="__codelineno-0-986" name="__codelineno-0-986"></a> <span class="n">is_system</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
</span><span id="__span-0-987"><a id="__codelineno-0-987" name="__codelineno-0-987"></a> <span class="p">)</span>
</span><span id="__span-0-988"><a id="__codelineno-0-988" name="__codelineno-0-988"></a>
</span><span id="__span-0-989"><a id="__codelineno-0-989" name="__codelineno-0-989"></a> <span class="c1"># =========================================================================</span>
</span><span id="__span-0-990"><a id="__codelineno-0-990" name="__codelineno-0-990"></a> <span class="c1"># Workbenches</span>
</span><span id="__span-0-991"><a id="__codelineno-0-991" name="__codelineno-0-991"></a> <span class="c1"># =========================================================================</span>
</span><span id="__span-0-992"><a id="__codelineno-0-992" name="__codelineno-0-992"></a>
</span><span id="__span-0-993"><a id="__codelineno-0-993" name="__codelineno-0-993"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">get_workbenches</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">list</span><span class="p">[</span><span class="n">WorkbenchInfo</span><span class="p">]:</span>
</span><span id="__span-0-994"><a id="__codelineno-0-994" name="__codelineno-0-994"></a><span class="w"> </span><span class="sd">"""Get list of available workbenches.</span>
</span><span id="__span-0-995"><a id="__codelineno-0-995" name="__codelineno-0-995"></a>
</span><span id="__span-0-996"><a id="__codelineno-0-996" name="__codelineno-0-996"></a><span class="sd"> Returns:</span>
</span><span id="__span-0-997"><a id="__codelineno-0-997" name="__codelineno-0-997"></a><span class="sd"> List of WorkbenchInfo for each workbench.</span>
</span><span id="__span-0-998"><a id="__codelineno-0-998" name="__codelineno-0-998"></a><span class="sd"> """</span>
</span><span id="__span-0-999"><a id="__codelineno-0-999" name="__codelineno-0-999"></a> <span class="n">gui_available</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">is_gui_available</span><span class="p">()</span>
</span><span id="__span-0-1000"><a id="__codelineno-0-1000" name="__codelineno-0-1000"></a>
</span><span id="__span-0-1001"><a id="__codelineno-0-1001" name="__codelineno-0-1001"></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">gui_available</span><span class="p">:</span>
</span><span id="__span-0-1002"><a id="__codelineno-0-1002" name="__codelineno-0-1002"></a> <span class="c1"># Return common workbenches for headless mode</span>
</span><span id="__span-0-1003"><a id="__codelineno-0-1003" name="__codelineno-0-1003"></a> <span class="n">common_workbenches</span> <span class="o">=</span> <span class="p">[</span>
</span><span id="__span-0-1004"><a id="__codelineno-0-1004" name="__codelineno-0-1004"></a> <span class="s2">"StartWorkbench"</span><span class="p">,</span>
</span><span id="__span-0-1005"><a id="__codelineno-0-1005" name="__codelineno-0-1005"></a> <span class="s2">"PartWorkbench"</span><span class="p">,</span>
</span><span id="__span-0-1006"><a id="__codelineno-0-1006" name="__codelineno-0-1006"></a> <span class="s2">"PartDesignWorkbench"</span><span class="p">,</span>
</span><span id="__span-0-1007"><a id="__codelineno-0-1007" name="__codelineno-0-1007"></a> <span class="s2">"DraftWorkbench"</span><span class="p">,</span>
</span><span id="__span-0-1008"><a id="__codelineno-0-1008" name="__codelineno-0-1008"></a> <span class="s2">"SketcherWorkbench"</span><span class="p">,</span>
</span><span id="__span-0-1009"><a id="__codelineno-0-1009" name="__codelineno-0-1009"></a> <span class="s2">"MeshWorkbench"</span><span class="p">,</span>
</span><span id="__span-0-1010"><a id="__codelineno-0-1010" name="__codelineno-0-1010"></a> <span class="s2">"SpreadsheetWorkbench"</span><span class="p">,</span>
</span><span id="__span-0-1011"><a id="__codelineno-0-1011" name="__codelineno-0-1011"></a> <span class="p">]</span>
</span><span id="__span-0-1012"><a id="__codelineno-0-1012" name="__codelineno-0-1012"></a> <span class="k">return</span> <span class="p">[</span>
</span><span id="__span-0-1013"><a id="__codelineno-0-1013" name="__codelineno-0-1013"></a> <span class="n">WorkbenchInfo</span><span class="p">(</span><span class="n">name</span><span class="o">=</span><span class="n">wb</span><span class="p">,</span> <span class="n">label</span><span class="o">=</span><span class="n">wb</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s2">"Workbench"</span><span class="p">,</span> <span class="s2">""</span><span class="p">))</span>
</span><span id="__span-0-1014"><a id="__codelineno-0-1014" name="__codelineno-0-1014"></a> <span class="k">for</span> <span class="n">wb</span> <span class="ow">in</span> <span class="n">common_workbenches</span>
</span><span id="__span-0-1015"><a id="__codelineno-0-1015" name="__codelineno-0-1015"></a> <span class="p">]</span>
</span><span id="__span-0-1016"><a id="__codelineno-0-1016" name="__codelineno-0-1016"></a>
</span><span id="__span-0-1017"><a id="__codelineno-0-1017" name="__codelineno-0-1017"></a> <span class="n">code</span> <span class="o">=</span> <span class="s2">"""</span>
</span><span id="__span-0-1018"><a id="__codelineno-0-1018" name="__codelineno-0-1018"></a><span class="s2">workbenches = []</span>
</span><span id="__span-0-1019"><a id="__codelineno-0-1019" name="__codelineno-0-1019"></a><span class="s2">active_wb = FreeCADGui.activeWorkbench()</span>
</span><span id="__span-0-1020"><a id="__codelineno-0-1020" name="__codelineno-0-1020"></a><span class="s2">active_name = active_wb.__class__.__name__ if active_wb else None</span>
</span><span id="__span-0-1021"><a id="__codelineno-0-1021" name="__codelineno-0-1021"></a>
</span><span id="__span-0-1022"><a id="__codelineno-0-1022" name="__codelineno-0-1022"></a><span class="s2">for name in FreeCADGui.listWorkbenches():</span>
</span><span id="__span-0-1023"><a id="__codelineno-0-1023" name="__codelineno-0-1023"></a><span class="s2"> wb = FreeCADGui.getWorkbench(name)</span>
</span><span id="__span-0-1024"><a id="__codelineno-0-1024" name="__codelineno-0-1024"></a><span class="s2"> workbenches.append({</span>
</span><span id="__span-0-1025"><a id="__codelineno-0-1025" name="__codelineno-0-1025"></a><span class="s2"> "name": name,</span>
</span><span id="__span-0-1026"><a id="__codelineno-0-1026" name="__codelineno-0-1026"></a><span class="s2"> "label": wb.MenuText if hasattr(wb, "MenuText") else name,</span>
</span><span id="__span-0-1027"><a id="__codelineno-0-1027" name="__codelineno-0-1027"></a><span class="s2"> "icon": wb.Icon if hasattr(wb, "Icon") else "",</span>
</span><span id="__span-0-1028"><a id="__codelineno-0-1028" name="__codelineno-0-1028"></a><span class="s2"> "is_active": name == active_name,</span>
</span><span id="__span-0-1029"><a id="__codelineno-0-1029" name="__codelineno-0-1029"></a><span class="s2"> })</span>
</span><span id="__span-0-1030"><a id="__codelineno-0-1030" name="__codelineno-0-1030"></a>
</span><span id="__span-0-1031"><a id="__codelineno-0-1031" name="__codelineno-0-1031"></a><span class="s2">_result_ = workbenches</span>
</span><span id="__span-0-1032"><a id="__codelineno-0-1032" name="__codelineno-0-1032"></a><span class="s2">"""</span>
</span><span id="__span-0-1033"><a id="__codelineno-0-1033" name="__codelineno-0-1033"></a> <span class="n">result</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">execute_python</span><span class="p">(</span><span class="n">code</span><span class="p">)</span>
</span><span id="__span-0-1034"><a id="__codelineno-0-1034" name="__codelineno-0-1034"></a>
</span><span id="__span-0-1035"><a id="__codelineno-0-1035" name="__codelineno-0-1035"></a> <span class="k">if</span> <span class="n">result</span><span class="o">.</span><span class="n">success</span> <span class="ow">and</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">:</span>
</span><span id="__span-0-1036"><a id="__codelineno-0-1036" name="__codelineno-0-1036"></a> <span class="k">return</span> <span class="p">[</span><span class="n">WorkbenchInfo</span><span class="p">(</span><span class="o">**</span><span class="n">wb</span><span class="p">)</span> <span class="k">for</span> <span class="n">wb</span> <span class="ow">in</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">]</span>
</span><span id="__span-0-1037"><a id="__codelineno-0-1037" name="__codelineno-0-1037"></a> <span class="k">return</span> <span class="p">[]</span>
</span><span id="__span-0-1038"><a id="__codelineno-0-1038" name="__codelineno-0-1038"></a>
</span><span id="__span-0-1039"><a id="__codelineno-0-1039" name="__codelineno-0-1039"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">activate_workbench</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">workbench_name</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kc">None</span><span class="p">:</span>
</span><span id="__span-0-1040"><a id="__codelineno-0-1040" name="__codelineno-0-1040"></a><span class="w"> </span><span class="sd">"""Activate a workbench.</span>
</span><span id="__span-0-1041"><a id="__codelineno-0-1041" name="__codelineno-0-1041"></a>
</span><span id="__span-0-1042"><a id="__codelineno-0-1042" name="__codelineno-0-1042"></a><span class="sd"> Args:</span>
</span><span id="__span-0-1043"><a id="__codelineno-0-1043" name="__codelineno-0-1043"></a><span class="sd"> workbench_name: Workbench internal name.</span>
</span><span id="__span-0-1044"><a id="__codelineno-0-1044" name="__codelineno-0-1044"></a>
</span><span id="__span-0-1045"><a id="__codelineno-0-1045" name="__codelineno-0-1045"></a><span class="sd"> Raises:</span>
</span><span id="__span-0-1046"><a id="__codelineno-0-1046" name="__codelineno-0-1046"></a><span class="sd"> ValueError: If workbench not found.</span>
</span><span id="__span-0-1047"><a id="__codelineno-0-1047" name="__codelineno-0-1047"></a><span class="sd"> """</span>
</span><span id="__span-0-1048"><a id="__codelineno-0-1048" name="__codelineno-0-1048"></a> <span class="n">gui_available</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">is_gui_available</span><span class="p">()</span>
</span><span id="__span-0-1049"><a id="__codelineno-0-1049" name="__codelineno-0-1049"></a>
</span><span id="__span-0-1050"><a id="__codelineno-0-1050" name="__codelineno-0-1050"></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">gui_available</span><span class="p">:</span>
</span><span id="__span-0-1051"><a id="__codelineno-0-1051" name="__codelineno-0-1051"></a> <span class="k">return</span> <span class="c1"># Silently ignore in headless mode</span>
</span><span id="__span-0-1052"><a id="__codelineno-0-1052" name="__codelineno-0-1052"></a>
</span><span id="__span-0-1053"><a id="__codelineno-0-1053" name="__codelineno-0-1053"></a> <span class="n">code</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">"""</span>
</span><span id="__span-0-1054"><a id="__codelineno-0-1054" name="__codelineno-0-1054"></a><span class="s2">try:</span>
</span><span id="__span-0-1055"><a id="__codelineno-0-1055" name="__codelineno-0-1055"></a><span class="s2"> FreeCADGui.activateWorkbench(</span><span class="si">{</span><span class="n">workbench_name</span><span class="si">!r}</span><span class="s2">)</span>
</span><span id="__span-0-1056"><a id="__codelineno-0-1056" name="__codelineno-0-1056"></a><span class="s2"> _result_ = True</span>
</span><span id="__span-0-1057"><a id="__codelineno-0-1057" name="__codelineno-0-1057"></a><span class="s2">except Exception as e:</span>
</span><span id="__span-0-1058"><a id="__codelineno-0-1058" name="__codelineno-0-1058"></a><span class="s2"> raise ValueError(f"Failed to activate workbench: </span><span class="se">{{</span><span class="s2">e</span><span class="se">}}</span><span class="s2">")</span>
</span><span id="__span-0-1059"><a id="__codelineno-0-1059" name="__codelineno-0-1059"></a><span class="s2">"""</span>
</span><span id="__span-0-1060"><a id="__codelineno-0-1060" name="__codelineno-0-1060"></a> <span class="n">result</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">execute_python</span><span class="p">(</span><span class="n">code</span><span class="p">)</span>
</span><span id="__span-0-1061"><a id="__codelineno-0-1061" name="__codelineno-0-1061"></a>
</span><span id="__span-0-1062"><a id="__codelineno-0-1062" name="__codelineno-0-1062"></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">result</span><span class="o">.</span><span class="n">success</span><span class="p">:</span>
</span><span id="__span-0-1063"><a id="__codelineno-0-1063" name="__codelineno-0-1063"></a> <span class="n">error_msg</span> <span class="o">=</span> <span class="n">result</span><span class="o">.</span><span class="n">error_traceback</span> <span class="ow">or</span> <span class="s2">"Failed to activate workbench"</span>
</span><span id="__span-0-1064"><a id="__codelineno-0-1064" name="__codelineno-0-1064"></a> <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="n">error_msg</span><span class="p">)</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> <div class="doc doc-children"> <h5 id="freecad_mcp.bridge.embedded.EmbeddedBridge-functions">Functions<a href="#freecad_mcp.bridge.embedded.EmbeddedBridge-functions" class="headerlink" title="Permanent link">¶</a></h5> <div class="doc doc-object doc-function"> <h6 id="freecad_mcp.bridge.embedded.EmbeddedBridge.__init__" class="doc doc-heading"> <code class="highlight language-python"><span class="fm">__init__</span><span class="p">(</span><span class="n">freecad_path</span><span class="o">=</span><span class="kc">None</span><span class="p">)</span></code> <a href="#freecad_mcp.bridge.embedded.EmbeddedBridge.__init__" class="headerlink" title="Permanent link">¶</a></h6> <div class="doc doc-contents "> <p>Initialize the embedded bridge.</p> <p><span class="doc-section-title">Parameters:</span></p> <table> <thead> <tr> <th>Name</th> <th>Type</th> <th>Description</th> <th>Default</th> </tr> </thead> <tbody> <tr class="doc-section-item"> <td> <code>freecad_path</code> </td> <td> <code><span title="str">str</span> | None</code> </td> <td> <div class="doc-md-description"> <p>Path to FreeCAD's lib directory. If provided, this path will be added to sys.path before importing.</p> </div> </td> <td> <code>None</code> </td> </tr> </tbody> </table> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/embedded.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-45">45</a></span>
<span class="normal"><a href="#__codelineno-0-46">46</a></span>
<span class="normal"><a href="#__codelineno-0-47">47</a></span>
<span class="normal"><a href="#__codelineno-0-48">48</a></span>
<span class="normal"><a href="#__codelineno-0-49">49</a></span>
<span class="normal"><a href="#__codelineno-0-50">50</a></span>
<span class="normal"><a href="#__codelineno-0-51">51</a></span>
<span class="normal"><a href="#__codelineno-0-52">52</a></span>
<span class="normal"><a href="#__codelineno-0-53">53</a></span>
<span class="normal"><a href="#__codelineno-0-54">54</a></span>
<span class="normal"><a href="#__codelineno-0-55">55</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-45"><a id="__codelineno-0-45" name="__codelineno-0-45"></a><span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">freecad_path</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kc">None</span><span class="p">:</span>
</span><span id="__span-0-46"><a id="__codelineno-0-46" name="__codelineno-0-46"></a><span class="w"> </span><span class="sd">"""Initialize the embedded bridge.</span>
</span><span id="__span-0-47"><a id="__codelineno-0-47" name="__codelineno-0-47"></a>
</span><span id="__span-0-48"><a id="__codelineno-0-48" name="__codelineno-0-48"></a><span class="sd"> Args:</span>
</span><span id="__span-0-49"><a id="__codelineno-0-49" name="__codelineno-0-49"></a><span class="sd"> freecad_path: Path to FreeCAD's lib directory. If provided,</span>
</span><span id="__span-0-50"><a id="__codelineno-0-50" name="__codelineno-0-50"></a><span class="sd"> this path will be added to sys.path before importing.</span>
</span><span id="__span-0-51"><a id="__codelineno-0-51" name="__codelineno-0-51"></a><span class="sd"> """</span>
</span><span id="__span-0-52"><a id="__codelineno-0-52" name="__codelineno-0-52"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_freecad_path</span> <span class="o">=</span> <span class="n">freecad_path</span>
</span><span id="__span-0-53"><a id="__codelineno-0-53" name="__codelineno-0-53"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_fc_module</span><span class="p">:</span> <span class="n">Any</span> <span class="o">=</span> <span class="kc">None</span>
</span><span id="__span-0-54"><a id="__codelineno-0-54" name="__codelineno-0-54"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_executor</span> <span class="o">=</span> <span class="n">ThreadPoolExecutor</span><span class="p">(</span><span class="n">max_workers</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span> <span class="n">thread_name_prefix</span><span class="o">=</span><span class="s2">"freecad"</span><span class="p">)</span>
</span><span id="__span-0-55"><a id="__codelineno-0-55" name="__codelineno-0-55"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_connected</span> <span class="o">=</span> <span class="kc">False</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> </div> </div> <div class="doc doc-object doc-function"> <h6 id="freecad_mcp.bridge.embedded.EmbeddedBridge.activate_workbench" class="doc doc-heading"> <code class="highlight language-python"><span class="n">activate_workbench</span><span class="p">(</span><span class="n">workbench_name</span><span class="p">)</span></code> <span class="doc doc-labels"> <small class="doc doc-label doc-label-async"><code>async</code></small> </span> <a href="#freecad_mcp.bridge.embedded.EmbeddedBridge.activate_workbench" class="headerlink" title="Permanent link">¶</a></h6> <div class="doc doc-contents "> <p>Activate a workbench.</p> <p><span class="doc-section-title">Parameters:</span></p> <table> <thead> <tr> <th>Name</th> <th>Type</th> <th>Description</th> <th>Default</th> </tr> </thead> <tbody> <tr class="doc-section-item"> <td> <code>workbench_name</code> </td> <td> <code><span title="str">str</span></code> </td> <td> <div class="doc-md-description"> <p>Workbench internal name.</p> </div> </td> <td> <em>required</em> </td> </tr> </tbody> </table> <p><span class="doc-section-title">Raises:</span></p> <table> <thead> <tr> <th>Type</th> <th>Description</th> </tr> </thead> <tbody> <tr class="doc-section-item"> <td> <code><span title="ValueError">ValueError</span></code> </td> <td> <div class="doc-md-description"> <p>If workbench not found.</p> </div> </td> </tr> </tbody> </table> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/embedded.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-1039">1039</a></span>
<span class="normal"><a href="#__codelineno-0-1040">1040</a></span>
<span class="normal"><a href="#__codelineno-0-1041">1041</a></span>
<span class="normal"><a href="#__codelineno-0-1042">1042</a></span>
<span class="normal"><a href="#__codelineno-0-1043">1043</a></span>
<span class="normal"><a href="#__codelineno-0-1044">1044</a></span>
<span class="normal"><a href="#__codelineno-0-1045">1045</a></span>
<span class="normal"><a href="#__codelineno-0-1046">1046</a></span>
<span class="normal"><a href="#__codelineno-0-1047">1047</a></span>
<span class="normal"><a href="#__codelineno-0-1048">1048</a></span>
<span class="normal"><a href="#__codelineno-0-1049">1049</a></span>
<span class="normal"><a href="#__codelineno-0-1050">1050</a></span>
<span class="normal"><a href="#__codelineno-0-1051">1051</a></span>
<span class="normal"><a href="#__codelineno-0-1052">1052</a></span>
<span class="normal"><a href="#__codelineno-0-1053">1053</a></span>
<span class="normal"><a href="#__codelineno-0-1054">1054</a></span>
<span class="normal"><a href="#__codelineno-0-1055">1055</a></span>
<span class="normal"><a href="#__codelineno-0-1056">1056</a></span>
<span class="normal"><a href="#__codelineno-0-1057">1057</a></span>
<span class="normal"><a href="#__codelineno-0-1058">1058</a></span>
<span class="normal"><a href="#__codelineno-0-1059">1059</a></span>
<span class="normal"><a href="#__codelineno-0-1060">1060</a></span>
<span class="normal"><a href="#__codelineno-0-1061">1061</a></span>
<span class="normal"><a href="#__codelineno-0-1062">1062</a></span>
<span class="normal"><a href="#__codelineno-0-1063">1063</a></span>
<span class="normal"><a href="#__codelineno-0-1064">1064</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-1039"><a id="__codelineno-0-1039" name="__codelineno-0-1039"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">activate_workbench</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">workbench_name</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kc">None</span><span class="p">:</span>
</span><span id="__span-0-1040"><a id="__codelineno-0-1040" name="__codelineno-0-1040"></a><span class="w"> </span><span class="sd">"""Activate a workbench.</span>
</span><span id="__span-0-1041"><a id="__codelineno-0-1041" name="__codelineno-0-1041"></a>
</span><span id="__span-0-1042"><a id="__codelineno-0-1042" name="__codelineno-0-1042"></a><span class="sd"> Args:</span>
</span><span id="__span-0-1043"><a id="__codelineno-0-1043" name="__codelineno-0-1043"></a><span class="sd"> workbench_name: Workbench internal name.</span>
</span><span id="__span-0-1044"><a id="__codelineno-0-1044" name="__codelineno-0-1044"></a>
</span><span id="__span-0-1045"><a id="__codelineno-0-1045" name="__codelineno-0-1045"></a><span class="sd"> Raises:</span>
</span><span id="__span-0-1046"><a id="__codelineno-0-1046" name="__codelineno-0-1046"></a><span class="sd"> ValueError: If workbench not found.</span>
</span><span id="__span-0-1047"><a id="__codelineno-0-1047" name="__codelineno-0-1047"></a><span class="sd"> """</span>
</span><span id="__span-0-1048"><a id="__codelineno-0-1048" name="__codelineno-0-1048"></a> <span class="n">gui_available</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">is_gui_available</span><span class="p">()</span>
</span><span id="__span-0-1049"><a id="__codelineno-0-1049" name="__codelineno-0-1049"></a>
</span><span id="__span-0-1050"><a id="__codelineno-0-1050" name="__codelineno-0-1050"></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">gui_available</span><span class="p">:</span>
</span><span id="__span-0-1051"><a id="__codelineno-0-1051" name="__codelineno-0-1051"></a> <span class="k">return</span> <span class="c1"># Silently ignore in headless mode</span>
</span><span id="__span-0-1052"><a id="__codelineno-0-1052" name="__codelineno-0-1052"></a>
</span><span id="__span-0-1053"><a id="__codelineno-0-1053" name="__codelineno-0-1053"></a> <span class="n">code</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">"""</span>
</span><span id="__span-0-1054"><a id="__codelineno-0-1054" name="__codelineno-0-1054"></a><span class="s2">try:</span>
</span><span id="__span-0-1055"><a id="__codelineno-0-1055" name="__codelineno-0-1055"></a><span class="s2"> FreeCADGui.activateWorkbench(</span><span class="si">{</span><span class="n">workbench_name</span><span class="si">!r}</span><span class="s2">)</span>
</span><span id="__span-0-1056"><a id="__codelineno-0-1056" name="__codelineno-0-1056"></a><span class="s2"> _result_ = True</span>
</span><span id="__span-0-1057"><a id="__codelineno-0-1057" name="__codelineno-0-1057"></a><span class="s2">except Exception as e:</span>
</span><span id="__span-0-1058"><a id="__codelineno-0-1058" name="__codelineno-0-1058"></a><span class="s2"> raise ValueError(f"Failed to activate workbench: </span><span class="se">{{</span><span class="s2">e</span><span class="se">}}</span><span class="s2">")</span>
</span><span id="__span-0-1059"><a id="__codelineno-0-1059" name="__codelineno-0-1059"></a><span class="s2">"""</span>
</span><span id="__span-0-1060"><a id="__codelineno-0-1060" name="__codelineno-0-1060"></a> <span class="n">result</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">execute_python</span><span class="p">(</span><span class="n">code</span><span class="p">)</span>
</span><span id="__span-0-1061"><a id="__codelineno-0-1061" name="__codelineno-0-1061"></a>
</span><span id="__span-0-1062"><a id="__codelineno-0-1062" name="__codelineno-0-1062"></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">result</span><span class="o">.</span><span class="n">success</span><span class="p">:</span>
</span><span id="__span-0-1063"><a id="__codelineno-0-1063" name="__codelineno-0-1063"></a> <span class="n">error_msg</span> <span class="o">=</span> <span class="n">result</span><span class="o">.</span><span class="n">error_traceback</span> <span class="ow">or</span> <span class="s2">"Failed to activate workbench"</span>
</span><span id="__span-0-1064"><a id="__codelineno-0-1064" name="__codelineno-0-1064"></a> <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="n">error_msg</span><span class="p">)</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> </div> </div> <div class="doc doc-object doc-function"> <h6 id="freecad_mcp.bridge.embedded.EmbeddedBridge.close_document" class="doc doc-heading"> <code class="highlight language-python"><span class="n">close_document</span><span class="p">(</span><span class="n">doc_name</span><span class="o">=</span><span class="kc">None</span><span class="p">)</span></code> <span class="doc doc-labels"> <small class="doc doc-label doc-label-async"><code>async</code></small> </span> <a href="#freecad_mcp.bridge.embedded.EmbeddedBridge.close_document" class="headerlink" title="Permanent link">¶</a></h6> <div class="doc doc-contents "> <p>Close a document.</p> <p><span class="doc-section-title">Parameters:</span></p> <table> <thead> <tr> <th>Name</th> <th>Type</th> <th>Description</th> <th>Default</th> </tr> </thead> <tbody> <tr class="doc-section-item"> <td> <code>doc_name</code> </td> <td> <code><span title="str">str</span> | None</code> </td> <td> <div class="doc-md-description"> <p>Document name (uses active if None).</p> </div> </td> <td> <code>None</code> </td> </tr> </tbody> </table> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/embedded.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-497">497</a></span>
<span class="normal"><a href="#__codelineno-0-498">498</a></span>
<span class="normal"><a href="#__codelineno-0-499">499</a></span>
<span class="normal"><a href="#__codelineno-0-500">500</a></span>
<span class="normal"><a href="#__codelineno-0-501">501</a></span>
<span class="normal"><a href="#__codelineno-0-502">502</a></span>
<span class="normal"><a href="#__codelineno-0-503">503</a></span>
<span class="normal"><a href="#__codelineno-0-504">504</a></span>
<span class="normal"><a href="#__codelineno-0-505">505</a></span>
<span class="normal"><a href="#__codelineno-0-506">506</a></span>
<span class="normal"><a href="#__codelineno-0-507">507</a></span>
<span class="normal"><a href="#__codelineno-0-508">508</a></span>
<span class="normal"><a href="#__codelineno-0-509">509</a></span>
<span class="normal"><a href="#__codelineno-0-510">510</a></span>
<span class="normal"><a href="#__codelineno-0-511">511</a></span>
<span class="normal"><a href="#__codelineno-0-512">512</a></span>
<span class="normal"><a href="#__codelineno-0-513">513</a></span>
<span class="normal"><a href="#__codelineno-0-514">514</a></span>
<span class="normal"><a href="#__codelineno-0-515">515</a></span>
<span class="normal"><a href="#__codelineno-0-516">516</a></span>
<span class="normal"><a href="#__codelineno-0-517">517</a></span>
<span class="normal"><a href="#__codelineno-0-518">518</a></span>
<span class="normal"><a href="#__codelineno-0-519">519</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-497"><a id="__codelineno-0-497" name="__codelineno-0-497"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">close_document</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">doc_name</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kc">None</span><span class="p">:</span>
</span><span id="__span-0-498"><a id="__codelineno-0-498" name="__codelineno-0-498"></a><span class="w"> </span><span class="sd">"""Close a document.</span>
</span><span id="__span-0-499"><a id="__codelineno-0-499" name="__codelineno-0-499"></a>
</span><span id="__span-0-500"><a id="__codelineno-0-500" name="__codelineno-0-500"></a><span class="sd"> Args:</span>
</span><span id="__span-0-501"><a id="__codelineno-0-501" name="__codelineno-0-501"></a><span class="sd"> doc_name: Document name (uses active if None).</span>
</span><span id="__span-0-502"><a id="__codelineno-0-502" name="__codelineno-0-502"></a><span class="sd"> """</span>
</span><span id="__span-0-503"><a id="__codelineno-0-503" name="__codelineno-0-503"></a> <span class="n">code</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">"""</span>
</span><span id="__span-0-504"><a id="__codelineno-0-504" name="__codelineno-0-504"></a><span class="s2">doc_name = </span><span class="si">{</span><span class="n">doc_name</span><span class="si">!r}</span>
</span><span id="__span-0-505"><a id="__codelineno-0-505" name="__codelineno-0-505"></a><span class="s2">if doc_name is None:</span>
</span><span id="__span-0-506"><a id="__codelineno-0-506" name="__codelineno-0-506"></a><span class="s2"> doc = FreeCAD.ActiveDocument</span>
</span><span id="__span-0-507"><a id="__codelineno-0-507" name="__codelineno-0-507"></a><span class="s2"> if doc:</span>
</span><span id="__span-0-508"><a id="__codelineno-0-508" name="__codelineno-0-508"></a><span class="s2"> doc_name = doc.Name</span>
</span><span id="__span-0-509"><a id="__codelineno-0-509" name="__codelineno-0-509"></a><span class="s2"> else:</span>
</span><span id="__span-0-510"><a id="__codelineno-0-510" name="__codelineno-0-510"></a><span class="s2"> raise ValueError("No active document")</span>
</span><span id="__span-0-511"><a id="__codelineno-0-511" name="__codelineno-0-511"></a>
</span><span id="__span-0-512"><a id="__codelineno-0-512" name="__codelineno-0-512"></a><span class="s2">FreeCAD.closeDocument(doc_name)</span>
</span><span id="__span-0-513"><a id="__codelineno-0-513" name="__codelineno-0-513"></a><span class="s2">_result_ = True</span>
</span><span id="__span-0-514"><a id="__codelineno-0-514" name="__codelineno-0-514"></a><span class="s2">"""</span>
</span><span id="__span-0-515"><a id="__codelineno-0-515" name="__codelineno-0-515"></a> <span class="n">result</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">execute_python</span><span class="p">(</span><span class="n">code</span><span class="p">)</span>
</span><span id="__span-0-516"><a id="__codelineno-0-516" name="__codelineno-0-516"></a>
</span><span id="__span-0-517"><a id="__codelineno-0-517" name="__codelineno-0-517"></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">result</span><span class="o">.</span><span class="n">success</span><span class="p">:</span>
</span><span id="__span-0-518"><a id="__codelineno-0-518" name="__codelineno-0-518"></a> <span class="n">error_msg</span> <span class="o">=</span> <span class="n">result</span><span class="o">.</span><span class="n">error_traceback</span> <span class="ow">or</span> <span class="s2">"Failed to close document"</span>
</span><span id="__span-0-519"><a id="__codelineno-0-519" name="__codelineno-0-519"></a> <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="n">error_msg</span><span class="p">)</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> </div> </div> <div class="doc doc-object doc-function"> <h6 id="freecad_mcp.bridge.embedded.EmbeddedBridge.connect" class="doc doc-heading"> <code class="highlight language-python"><span class="n">connect</span><span class="p">()</span></code> <span class="doc doc-labels"> <small class="doc doc-label doc-label-async"><code>async</code></small> </span> <a href="#freecad_mcp.bridge.embedded.EmbeddedBridge.connect" class="headerlink" title="Permanent link">¶</a></h6> <div class="doc doc-contents "> <p>Import and initialize FreeCAD.</p> <p><span class="doc-section-title">Raises:</span></p> <table> <thead> <tr> <th>Type</th> <th>Description</th> </tr> </thead> <tbody> <tr class="doc-section-item"> <td> <code><span title="ConnectionError">ConnectionError</span></code> </td> <td> <div class="doc-md-description"> <p>If FreeCAD cannot be imported.</p> </div> </td> </tr> </tbody> </table> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/embedded.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-57">57</a></span>
<span class="normal"><a href="#__codelineno-0-58">58</a></span>
<span class="normal"><a href="#__codelineno-0-59">59</a></span>
<span class="normal"><a href="#__codelineno-0-60">60</a></span>
<span class="normal"><a href="#__codelineno-0-61">61</a></span>
<span class="normal"><a href="#__codelineno-0-62">62</a></span>
<span class="normal"><a href="#__codelineno-0-63">63</a></span>
<span class="normal"><a href="#__codelineno-0-64">64</a></span>
<span class="normal"><a href="#__codelineno-0-65">65</a></span>
<span class="normal"><a href="#__codelineno-0-66">66</a></span>
<span class="normal"><a href="#__codelineno-0-67">67</a></span>
<span class="normal"><a href="#__codelineno-0-68">68</a></span>
<span class="normal"><a href="#__codelineno-0-69">69</a></span>
<span class="normal"><a href="#__codelineno-0-70">70</a></span>
<span class="normal"><a href="#__codelineno-0-71">71</a></span>
<span class="normal"><a href="#__codelineno-0-72">72</a></span>
<span class="normal"><a href="#__codelineno-0-73">73</a></span>
<span class="normal"><a href="#__codelineno-0-74">74</a></span>
<span class="normal"><a href="#__codelineno-0-75">75</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-57"><a id="__codelineno-0-57" name="__codelineno-0-57"></a><span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">connect</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kc">None</span><span class="p">:</span>
</span><span id="__span-0-58"><a id="__codelineno-0-58" name="__codelineno-0-58"></a><span class="w"> </span><span class="sd">"""Import and initialize FreeCAD.</span>
</span><span id="__span-0-59"><a id="__codelineno-0-59" name="__codelineno-0-59"></a>
</span><span id="__span-0-60"><a id="__codelineno-0-60" name="__codelineno-0-60"></a><span class="sd"> Raises:</span>
</span><span id="__span-0-61"><a id="__codelineno-0-61" name="__codelineno-0-61"></a><span class="sd"> ConnectionError: If FreeCAD cannot be imported.</span>
</span><span id="__span-0-62"><a id="__codelineno-0-62" name="__codelineno-0-62"></a><span class="sd"> """</span>
</span><span id="__span-0-63"><a id="__codelineno-0-63" name="__codelineno-0-63"></a> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_freecad_path</span><span class="p">:</span>
</span><span id="__span-0-64"><a id="__codelineno-0-64" name="__codelineno-0-64"></a> <span class="n">sys</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">insert</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">_freecad_path</span><span class="p">)</span>
</span><span id="__span-0-65"><a id="__codelineno-0-65" name="__codelineno-0-65"></a>
</span><span id="__span-0-66"><a id="__codelineno-0-66" name="__codelineno-0-66"></a> <span class="n">loop</span> <span class="o">=</span> <span class="n">asyncio</span><span class="o">.</span><span class="n">get_event_loop</span><span class="p">()</span>
</span><span id="__span-0-67"><a id="__codelineno-0-67" name="__codelineno-0-67"></a> <span class="k">try</span><span class="p">:</span>
</span><span id="__span-0-68"><a id="__codelineno-0-68" name="__codelineno-0-68"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_fc_module</span> <span class="o">=</span> <span class="k">await</span> <span class="n">loop</span><span class="o">.</span><span class="n">run_in_executor</span><span class="p">(</span>
</span><span id="__span-0-69"><a id="__codelineno-0-69" name="__codelineno-0-69"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_executor</span><span class="p">,</span>
</span><span id="__span-0-70"><a id="__codelineno-0-70" name="__codelineno-0-70"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_import_freecad</span><span class="p">,</span>
</span><span id="__span-0-71"><a id="__codelineno-0-71" name="__codelineno-0-71"></a> <span class="p">)</span>
</span><span id="__span-0-72"><a id="__codelineno-0-72" name="__codelineno-0-72"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_connected</span> <span class="o">=</span> <span class="kc">True</span>
</span><span id="__span-0-73"><a id="__codelineno-0-73" name="__codelineno-0-73"></a> <span class="k">except</span> <span class="ne">ImportError</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
</span><span id="__span-0-74"><a id="__codelineno-0-74" name="__codelineno-0-74"></a> <span class="n">msg</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">"Failed to import FreeCAD: </span><span class="si">{</span><span class="n">e</span><span class="si">}</span><span class="s2">"</span>
</span><span id="__span-0-75"><a id="__codelineno-0-75" name="__codelineno-0-75"></a> <span class="k">raise</span> <span class="ne">ConnectionError</span><span class="p">(</span><span class="n">msg</span><span class="p">)</span> <span class="kn">from</span><span class="w"> </span><span class="nn">e</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> </div> </div> <div class="doc doc-object doc-function"> <h6 id="freecad_mcp.bridge.embedded.EmbeddedBridge.create_document" class="doc doc-heading"> <code class="highlight language-python"><span class="n">create_document</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">label</span><span class="o">=</span><span class="kc">None</span><span class="p">)</span></code> <span class="doc doc-labels"> <small class="doc doc-label doc-label-async"><code>async</code></small> </span> <a href="#freecad_mcp.bridge.embedded.EmbeddedBridge.create_document" class="headerlink" title="Permanent link">¶</a></h6> <div class="doc doc-contents "> <p>Create a new document.</p> <p><span class="doc-section-title">Parameters:</span></p> <table> <thead> <tr> <th>Name</th> <th>Type</th> <th>Description</th> <th>Default</th> </tr> </thead> <tbody> <tr class="doc-section-item"> <td> <code>name</code> </td> <td> <code><span title="str">str</span></code> </td> <td> <div class="doc-md-description"> <p>Internal document name (no spaces).</p> </div> </td> <td> <em>required</em> </td> </tr> <tr class="doc-section-item"> <td> <code>label</code> </td> <td> <code><span title="str">str</span> | None</code> </td> <td> <div class="doc-md-description"> <p>Display label (optional, defaults to name).</p> </div> </td> <td> <code>None</code> </td> </tr> </tbody> </table> <p><span class="doc-section-title">Returns:</span></p> <table> <thead> <tr> <th>Type</th> <th>Description</th> </tr> </thead> <tbody> <tr class="doc-section-item"> <td> <code><a class="autorefs autorefs-internal" title="DocumentInfo
dataclass
(freecad_mcp.bridge.base.DocumentInfo)" href="#freecad_mcp.bridge.base.DocumentInfo">DocumentInfo</a></code> </td> <td> <div class="doc-md-description"> <p>DocumentInfo for the created document.</p> </div> </td> </tr> </tbody> </table> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/embedded.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-390">390</a></span>
<span class="normal"><a href="#__codelineno-0-391">391</a></span>
<span class="normal"><a href="#__codelineno-0-392">392</a></span>
<span class="normal"><a href="#__codelineno-0-393">393</a></span>
<span class="normal"><a href="#__codelineno-0-394">394</a></span>
<span class="normal"><a href="#__codelineno-0-395">395</a></span>
<span class="normal"><a href="#__codelineno-0-396">396</a></span>
<span class="normal"><a href="#__codelineno-0-397">397</a></span>
<span class="normal"><a href="#__codelineno-0-398">398</a></span>
<span class="normal"><a href="#__codelineno-0-399">399</a></span>
<span class="normal"><a href="#__codelineno-0-400">400</a></span>
<span class="normal"><a href="#__codelineno-0-401">401</a></span>
<span class="normal"><a href="#__codelineno-0-402">402</a></span>
<span class="normal"><a href="#__codelineno-0-403">403</a></span>
<span class="normal"><a href="#__codelineno-0-404">404</a></span>
<span class="normal"><a href="#__codelineno-0-405">405</a></span>
<span class="normal"><a href="#__codelineno-0-406">406</a></span>
<span class="normal"><a href="#__codelineno-0-407">407</a></span>
<span class="normal"><a href="#__codelineno-0-408">408</a></span>
<span class="normal"><a href="#__codelineno-0-409">409</a></span>
<span class="normal"><a href="#__codelineno-0-410">410</a></span>
<span class="normal"><a href="#__codelineno-0-411">411</a></span>
<span class="normal"><a href="#__codelineno-0-412">412</a></span>
<span class="normal"><a href="#__codelineno-0-413">413</a></span>
<span class="normal"><a href="#__codelineno-0-414">414</a></span>
<span class="normal"><a href="#__codelineno-0-415">415</a></span>
<span class="normal"><a href="#__codelineno-0-416">416</a></span>
<span class="normal"><a href="#__codelineno-0-417">417</a></span>
<span class="normal"><a href="#__codelineno-0-418">418</a></span>
<span class="normal"><a href="#__codelineno-0-419">419</a></span>
<span class="normal"><a href="#__codelineno-0-420">420</a></span>
<span class="normal"><a href="#__codelineno-0-421">421</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-390"><a id="__codelineno-0-390" name="__codelineno-0-390"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">create_document</span><span class="p">(</span>
</span><span id="__span-0-391"><a id="__codelineno-0-391" name="__codelineno-0-391"></a> <span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">label</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span>
</span><span id="__span-0-392"><a id="__codelineno-0-392" name="__codelineno-0-392"></a> <span class="p">)</span> <span class="o">-&gt;</span> <span class="n">DocumentInfo</span><span class="p">:</span>
</span><span id="__span-0-393"><a id="__codelineno-0-393" name="__codelineno-0-393"></a><span class="w"> </span><span class="sd">"""Create a new document.</span>
</span><span id="__span-0-394"><a id="__codelineno-0-394" name="__codelineno-0-394"></a>
</span><span id="__span-0-395"><a id="__codelineno-0-395" name="__codelineno-0-395"></a><span class="sd"> Args:</span>
</span><span id="__span-0-396"><a id="__codelineno-0-396" name="__codelineno-0-396"></a><span class="sd"> name: Internal document name (no spaces).</span>
</span><span id="__span-0-397"><a id="__codelineno-0-397" name="__codelineno-0-397"></a><span class="sd"> label: Display label (optional, defaults to name).</span>
</span><span id="__span-0-398"><a id="__codelineno-0-398" name="__codelineno-0-398"></a>
</span><span id="__span-0-399"><a id="__codelineno-0-399" name="__codelineno-0-399"></a><span class="sd"> Returns:</span>
</span><span id="__span-0-400"><a id="__codelineno-0-400" name="__codelineno-0-400"></a><span class="sd"> DocumentInfo for the created document.</span>
</span><span id="__span-0-401"><a id="__codelineno-0-401" name="__codelineno-0-401"></a><span class="sd"> """</span>
</span><span id="__span-0-402"><a id="__codelineno-0-402" name="__codelineno-0-402"></a> <span class="n">label</span> <span class="o">=</span> <span class="n">label</span> <span class="ow">or</span> <span class="n">name</span>
</span><span id="__span-0-403"><a id="__codelineno-0-403" name="__codelineno-0-403"></a> <span class="n">result</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">execute_python</span><span class="p">(</span>
</span><span id="__span-0-404"><a id="__codelineno-0-404" name="__codelineno-0-404"></a> <span class="sa">f</span><span class="s2">"""</span>
</span><span id="__span-0-405"><a id="__codelineno-0-405" name="__codelineno-0-405"></a><span class="s2">doc = FreeCAD.newDocument(</span><span class="si">{</span><span class="n">name</span><span class="si">!r}</span><span class="s2">)</span>
</span><span id="__span-0-406"><a id="__codelineno-0-406" name="__codelineno-0-406"></a><span class="s2">doc.Label = </span><span class="si">{</span><span class="n">label</span><span class="si">!r}</span>
</span><span id="__span-0-407"><a id="__codelineno-0-407" name="__codelineno-0-407"></a><span class="s2">_result_ = </span><span class="se">{{</span>
</span><span id="__span-0-408"><a id="__codelineno-0-408" name="__codelineno-0-408"></a><span class="s2"> "name": doc.Name,</span>
</span><span id="__span-0-409"><a id="__codelineno-0-409" name="__codelineno-0-409"></a><span class="s2"> "label": doc.Label,</span>
</span><span id="__span-0-410"><a id="__codelineno-0-410" name="__codelineno-0-410"></a><span class="s2"> "path": doc.FileName or None,</span>
</span><span id="__span-0-411"><a id="__codelineno-0-411" name="__codelineno-0-411"></a><span class="s2"> "objects": [],</span>
</span><span id="__span-0-412"><a id="__codelineno-0-412" name="__codelineno-0-412"></a><span class="s2"> "is_modified": False,</span>
</span><span id="__span-0-413"><a id="__codelineno-0-413" name="__codelineno-0-413"></a><span class="se">}}</span>
</span><span id="__span-0-414"><a id="__codelineno-0-414" name="__codelineno-0-414"></a><span class="s2">"""</span>
</span><span id="__span-0-415"><a id="__codelineno-0-415" name="__codelineno-0-415"></a> <span class="p">)</span>
</span><span id="__span-0-416"><a id="__codelineno-0-416" name="__codelineno-0-416"></a>
</span><span id="__span-0-417"><a id="__codelineno-0-417" name="__codelineno-0-417"></a> <span class="k">if</span> <span class="n">result</span><span class="o">.</span><span class="n">success</span> <span class="ow">and</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">:</span>
</span><span id="__span-0-418"><a id="__codelineno-0-418" name="__codelineno-0-418"></a> <span class="k">return</span> <span class="n">DocumentInfo</span><span class="p">(</span><span class="o">**</span><span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">)</span>
</span><span id="__span-0-419"><a id="__codelineno-0-419" name="__codelineno-0-419"></a>
</span><span id="__span-0-420"><a id="__codelineno-0-420" name="__codelineno-0-420"></a> <span class="n">error_msg</span> <span class="o">=</span> <span class="n">result</span><span class="o">.</span><span class="n">error_traceback</span> <span class="ow">or</span> <span class="s2">"Failed to create document"</span>
</span><span id="__span-0-421"><a id="__codelineno-0-421" name="__codelineno-0-421"></a> <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="n">error_msg</span><span class="p">)</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> </div> </div> <div class="doc doc-object doc-function"> <h6 id="freecad_mcp.bridge.embedded.EmbeddedBridge.create_macro" class="doc doc-heading"> <code class="highlight language-python"><span class="n">create_macro</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">code</span><span class="p">,</span> <span class="n">description</span><span class="o">=</span><span class="s1">''</span><span class="p">)</span></code> <span class="doc doc-labels"> <small class="doc doc-label doc-label-async"><code>async</code></small> </span> <a href="#freecad_mcp.bridge.embedded.EmbeddedBridge.create_macro" class="headerlink" title="Permanent link">¶</a></h6> <div class="doc doc-contents "> <p>Create a new macro.</p> <p><span class="doc-section-title">Parameters:</span></p> <table> <thead> <tr> <th>Name</th> <th>Type</th> <th>Description</th> <th>Default</th> </tr> </thead> <tbody> <tr class="doc-section-item"> <td> <code>name</code> </td> <td> <code><span title="str">str</span></code> </td> <td> <div class="doc-md-description"> <p>Macro name (without extension).</p> </div> </td> <td> <em>required</em> </td> </tr> <tr class="doc-section-item"> <td> <code>code</code> </td> <td> <code><span title="str">str</span></code> </td> <td> <div class="doc-md-description"> <p>Python code for the macro.</p> </div> </td> <td> <em>required</em> </td> </tr> <tr class="doc-section-item"> <td> <code>description</code> </td> <td> <code><span title="str">str</span></code> </td> <td> <div class="doc-md-description"> <p>Macro description.</p> </div> </td> <td> <code>''</code> </td> </tr> </tbody> </table> <p><span class="doc-section-title">Returns:</span></p> <table> <thead> <tr> <th>Type</th> <th>Description</th> </tr> </thead> <tbody> <tr class="doc-section-item"> <td> <code><a class="autorefs autorefs-internal" title="MacroInfo
dataclass
(freecad_mcp.bridge.base.MacroInfo)" href="#freecad_mcp.bridge.base.MacroInfo">MacroInfo</a></code> </td> <td> <div class="doc-md-description"> <p>MacroInfo for the created macro.</p> </div> </td> </tr> </tbody> </table> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/embedded.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-946">946</a></span>
<span class="normal"><a href="#__codelineno-0-947">947</a></span>
<span class="normal"><a href="#__codelineno-0-948">948</a></span>
<span class="normal"><a href="#__codelineno-0-949">949</a></span>
<span class="normal"><a href="#__codelineno-0-950">950</a></span>
<span class="normal"><a href="#__codelineno-0-951">951</a></span>
<span class="normal"><a href="#__codelineno-0-952">952</a></span>
<span class="normal"><a href="#__codelineno-0-953">953</a></span>
<span class="normal"><a href="#__codelineno-0-954">954</a></span>
<span class="normal"><a href="#__codelineno-0-955">955</a></span>
<span class="normal"><a href="#__codelineno-0-956">956</a></span>
<span class="normal"><a href="#__codelineno-0-957">957</a></span>
<span class="normal"><a href="#__codelineno-0-958">958</a></span>
<span class="normal"><a href="#__codelineno-0-959">959</a></span>
<span class="normal"><a href="#__codelineno-0-960">960</a></span>
<span class="normal"><a href="#__codelineno-0-961">961</a></span>
<span class="normal"><a href="#__codelineno-0-962">962</a></span>
<span class="normal"><a href="#__codelineno-0-963">963</a></span>
<span class="normal"><a href="#__codelineno-0-964">964</a></span>
<span class="normal"><a href="#__codelineno-0-965">965</a></span>
<span class="normal"><a href="#__codelineno-0-966">966</a></span>
<span class="normal"><a href="#__codelineno-0-967">967</a></span>
<span class="normal"><a href="#__codelineno-0-968">968</a></span>
<span class="normal"><a href="#__codelineno-0-969">969</a></span>
<span class="normal"><a href="#__codelineno-0-970">970</a></span>
<span class="normal"><a href="#__codelineno-0-971">971</a></span>
<span class="normal"><a href="#__codelineno-0-972">972</a></span>
<span class="normal"><a href="#__codelineno-0-973">973</a></span>
<span class="normal"><a href="#__codelineno-0-974">974</a></span>
<span class="normal"><a href="#__codelineno-0-975">975</a></span>
<span class="normal"><a href="#__codelineno-0-976">976</a></span>
<span class="normal"><a href="#__codelineno-0-977">977</a></span>
<span class="normal"><a href="#__codelineno-0-978">978</a></span>
<span class="normal"><a href="#__codelineno-0-979">979</a></span>
<span class="normal"><a href="#__codelineno-0-980">980</a></span>
<span class="normal"><a href="#__codelineno-0-981">981</a></span>
<span class="normal"><a href="#__codelineno-0-982">982</a></span>
<span class="normal"><a href="#__codelineno-0-983">983</a></span>
<span class="normal"><a href="#__codelineno-0-984">984</a></span>
<span class="normal"><a href="#__codelineno-0-985">985</a></span>
<span class="normal"><a href="#__codelineno-0-986">986</a></span>
<span class="normal"><a href="#__codelineno-0-987">987</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-946"><a id="__codelineno-0-946" name="__codelineno-0-946"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">create_macro</span><span class="p">(</span>
</span><span id="__span-0-947"><a id="__codelineno-0-947" name="__codelineno-0-947"></a> <span class="bp">self</span><span class="p">,</span>
</span><span id="__span-0-948"><a id="__codelineno-0-948" name="__codelineno-0-948"></a> <span class="n">name</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span>
</span><span id="__span-0-949"><a id="__codelineno-0-949" name="__codelineno-0-949"></a> <span class="n">code</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span>
</span><span id="__span-0-950"><a id="__codelineno-0-950" name="__codelineno-0-950"></a> <span class="n">description</span><span class="p">:</span> <span class="nb">str</span> <span class="o">=</span> <span class="s2">""</span><span class="p">,</span>
</span><span id="__span-0-951"><a id="__codelineno-0-951" name="__codelineno-0-951"></a> <span class="p">)</span> <span class="o">-&gt;</span> <span class="n">MacroInfo</span><span class="p">:</span>
</span><span id="__span-0-952"><a id="__codelineno-0-952" name="__codelineno-0-952"></a><span class="w"> </span><span class="sd">"""Create a new macro.</span>
</span><span id="__span-0-953"><a id="__codelineno-0-953" name="__codelineno-0-953"></a>
</span><span id="__span-0-954"><a id="__codelineno-0-954" name="__codelineno-0-954"></a><span class="sd"> Args:</span>
</span><span id="__span-0-955"><a id="__codelineno-0-955" name="__codelineno-0-955"></a><span class="sd"> name: Macro name (without extension).</span>
</span><span id="__span-0-956"><a id="__codelineno-0-956" name="__codelineno-0-956"></a><span class="sd"> code: Python code for the macro.</span>
</span><span id="__span-0-957"><a id="__codelineno-0-957" name="__codelineno-0-957"></a><span class="sd"> description: Macro description.</span>
</span><span id="__span-0-958"><a id="__codelineno-0-958" name="__codelineno-0-958"></a>
</span><span id="__span-0-959"><a id="__codelineno-0-959" name="__codelineno-0-959"></a><span class="sd"> Returns:</span>
</span><span id="__span-0-960"><a id="__codelineno-0-960" name="__codelineno-0-960"></a><span class="sd"> MacroInfo for the created macro.</span>
</span><span id="__span-0-961"><a id="__codelineno-0-961" name="__codelineno-0-961"></a><span class="sd"> """</span>
</span><span id="__span-0-962"><a id="__codelineno-0-962" name="__codelineno-0-962"></a> <span class="n">macro_path</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_macro_path</span><span class="p">()</span>
</span><span id="__span-0-963"><a id="__codelineno-0-963" name="__codelineno-0-963"></a> <span class="n">macro_path</span><span class="o">.</span><span class="n">mkdir</span><span class="p">(</span><span class="n">parents</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">exist_ok</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
</span><span id="__span-0-964"><a id="__codelineno-0-964" name="__codelineno-0-964"></a>
</span><span id="__span-0-965"><a id="__codelineno-0-965" name="__codelineno-0-965"></a> <span class="n">macro_file</span> <span class="o">=</span> <span class="n">macro_path</span> <span class="o">/</span> <span class="sa">f</span><span class="s2">"</span><span class="si">{</span><span class="n">name</span><span class="si">}</span><span class="s2">.FCMacro"</span>
</span><span id="__span-0-966"><a id="__codelineno-0-966" name="__codelineno-0-966"></a>
</span><span id="__span-0-967"><a id="__codelineno-0-967" name="__codelineno-0-967"></a> <span class="c1"># Add description as header comment</span>
</span><span id="__span-0-968"><a id="__codelineno-0-968" name="__codelineno-0-968"></a> <span class="n">header</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">"# </span><span class="si">{</span><span class="n">description</span><span class="si">}</span><span class="se">\n\n</span><span class="s2">"</span> <span class="k">if</span> <span class="n">description</span> <span class="k">else</span> <span class="s2">""</span>
</span><span id="__span-0-969"><a id="__codelineno-0-969" name="__codelineno-0-969"></a>
</span><span id="__span-0-970"><a id="__codelineno-0-970" name="__codelineno-0-970"></a> <span class="c1"># Add standard imports</span>
</span><span id="__span-0-971"><a id="__codelineno-0-971" name="__codelineno-0-971"></a> <span class="n">full_code</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">"""</span><span class="si">{</span><span class="n">header</span><span class="si">}</span><span class="s2"># -*- coding: utf-8 -*-</span>
</span><span id="__span-0-972"><a id="__codelineno-0-972" name="__codelineno-0-972"></a><span class="s2"># FreeCAD Macro: </span><span class="si">{</span><span class="n">name</span><span class="si">}</span>
</span><span id="__span-0-973"><a id="__codelineno-0-973" name="__codelineno-0-973"></a><span class="s2"># Created via MCP Bridge</span>
</span><span id="__span-0-974"><a id="__codelineno-0-974" name="__codelineno-0-974"></a>
</span><span id="__span-0-975"><a id="__codelineno-0-975" name="__codelineno-0-975"></a><span class="s2">import FreeCAD</span>
</span><span id="__span-0-976"><a id="__codelineno-0-976" name="__codelineno-0-976"></a><span class="s2">import FreeCADGui</span>
</span><span id="__span-0-977"><a id="__codelineno-0-977" name="__codelineno-0-977"></a>
</span><span id="__span-0-978"><a id="__codelineno-0-978" name="__codelineno-0-978"></a><span class="si">{</span><span class="n">code</span><span class="si">}</span>
</span><span id="__span-0-979"><a id="__codelineno-0-979" name="__codelineno-0-979"></a><span class="s2">"""</span>
</span><span id="__span-0-980"><a id="__codelineno-0-980" name="__codelineno-0-980"></a> <span class="n">macro_file</span><span class="o">.</span><span class="n">write_text</span><span class="p">(</span><span class="n">full_code</span><span class="p">)</span>
</span><span id="__span-0-981"><a id="__codelineno-0-981" name="__codelineno-0-981"></a>
</span><span id="__span-0-982"><a id="__codelineno-0-982" name="__codelineno-0-982"></a> <span class="k">return</span> <span class="n">MacroInfo</span><span class="p">(</span>
</span><span id="__span-0-983"><a id="__codelineno-0-983" name="__codelineno-0-983"></a> <span class="n">name</span><span class="o">=</span><span class="n">name</span><span class="p">,</span>
</span><span id="__span-0-984"><a id="__codelineno-0-984" name="__codelineno-0-984"></a> <span class="n">path</span><span class="o">=</span><span class="nb">str</span><span class="p">(</span><span class="n">macro_file</span><span class="p">),</span>
</span><span id="__span-0-985"><a id="__codelineno-0-985" name="__codelineno-0-985"></a> <span class="n">description</span><span class="o">=</span><span class="n">description</span><span class="p">,</span>
</span><span id="__span-0-986"><a id="__codelineno-0-986" name="__codelineno-0-986"></a> <span class="n">is_system</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
</span><span id="__span-0-987"><a id="__codelineno-0-987" name="__codelineno-0-987"></a> <span class="p">)</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> </div> </div> <div class="doc doc-object doc-function"> <h6 id="freecad_mcp.bridge.embedded.EmbeddedBridge.create_object" class="doc doc-heading"> <code class="highlight language-python"><span class="n">create_object</span><span class="p">(</span><span class="n">type_id</span><span class="p">,</span> <span class="n">name</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">properties</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">doc_name</span><span class="o">=</span><span class="kc">None</span><span class="p">)</span></code> <span class="doc doc-labels"> <small class="doc doc-label doc-label-async"><code>async</code></small> </span> <a href="#freecad_mcp.bridge.embedded.EmbeddedBridge.create_object" class="headerlink" title="Permanent link">¶</a></h6> <div class="doc doc-contents "> <p>Create a new object.</p> <p><span class="doc-section-title">Parameters:</span></p> <table> <thead> <tr> <th>Name</th> <th>Type</th> <th>Description</th> <th>Default</th> </tr> </thead> <tbody> <tr class="doc-section-item"> <td> <code>type_id</code> </td> <td> <code><span title="str">str</span></code> </td> <td> <div class="doc-md-description"> <p>FreeCAD type ID (e.g., "Part::Box", "Part::Cylinder").</p> </div> </td> <td> <em>required</em> </td> </tr> <tr class="doc-section-item"> <td> <code>name</code> </td> <td> <code><span title="str">str</span> | None</code> </td> <td> <div class="doc-md-description"> <p>Object name (auto-generated if None).</p> </div> </td> <td> <code>None</code> </td> </tr> <tr class="doc-section-item"> <td> <code>properties</code> </td> <td> <code><span title="dict">dict</span>[<span title="str">str</span>, <span title="typing.Any">Any</span>] | None</code> </td> <td> <div class="doc-md-description"> <p>Initial property values.</p> </div> </td> <td> <code>None</code> </td> </tr> <tr class="doc-section-item"> <td> <code>doc_name</code> </td> <td> <code><span title="str">str</span> | None</code> </td> <td> <div class="doc-md-description"> <p>Target document (uses active if None).</p> </div> </td> <td> <code>None</code> </td> </tr> </tbody> </table> <p><span class="doc-section-title">Returns:</span></p> <table> <thead> <tr> <th>Type</th> <th>Description</th> </tr> </thead> <tbody> <tr class="doc-section-item"> <td> <code><a class="autorefs autorefs-internal" title="ObjectInfo
dataclass
(freecad_mcp.bridge.base.ObjectInfo)" href="#freecad_mcp.bridge.base.ObjectInfo">ObjectInfo</a></code> </td> <td> <div class="doc-md-description"> <p>ObjectInfo for the created object.</p> </div> </td> </tr> </tbody> </table> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/embedded.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-559">559</a></span>
<span class="normal"><a href="#__codelineno-0-560">560</a></span>
<span class="normal"><a href="#__codelineno-0-561">561</a></span>
<span class="normal"><a href="#__codelineno-0-562">562</a></span>
<span class="normal"><a href="#__codelineno-0-563">563</a></span>
<span class="normal"><a href="#__codelineno-0-564">564</a></span>
<span class="normal"><a href="#__codelineno-0-565">565</a></span>
<span class="normal"><a href="#__codelineno-0-566">566</a></span>
<span class="normal"><a href="#__codelineno-0-567">567</a></span>
<span class="normal"><a href="#__codelineno-0-568">568</a></span>
<span class="normal"><a href="#__codelineno-0-569">569</a></span>
<span class="normal"><a href="#__codelineno-0-570">570</a></span>
<span class="normal"><a href="#__codelineno-0-571">571</a></span>
<span class="normal"><a href="#__codelineno-0-572">572</a></span>
<span class="normal"><a href="#__codelineno-0-573">573</a></span>
<span class="normal"><a href="#__codelineno-0-574">574</a></span>
<span class="normal"><a href="#__codelineno-0-575">575</a></span>
<span class="normal"><a href="#__codelineno-0-576">576</a></span>
<span class="normal"><a href="#__codelineno-0-577">577</a></span>
<span class="normal"><a href="#__codelineno-0-578">578</a></span>
<span class="normal"><a href="#__codelineno-0-579">579</a></span>
<span class="normal"><a href="#__codelineno-0-580">580</a></span>
<span class="normal"><a href="#__codelineno-0-581">581</a></span>
<span class="normal"><a href="#__codelineno-0-582">582</a></span>
<span class="normal"><a href="#__codelineno-0-583">583</a></span>
<span class="normal"><a href="#__codelineno-0-584">584</a></span>
<span class="normal"><a href="#__codelineno-0-585">585</a></span>
<span class="normal"><a href="#__codelineno-0-586">586</a></span>
<span class="normal"><a href="#__codelineno-0-587">587</a></span>
<span class="normal"><a href="#__codelineno-0-588">588</a></span>
<span class="normal"><a href="#__codelineno-0-589">589</a></span>
<span class="normal"><a href="#__codelineno-0-590">590</a></span>
<span class="normal"><a href="#__codelineno-0-591">591</a></span>
<span class="normal"><a href="#__codelineno-0-592">592</a></span>
<span class="normal"><a href="#__codelineno-0-593">593</a></span>
<span class="normal"><a href="#__codelineno-0-594">594</a></span>
<span class="normal"><a href="#__codelineno-0-595">595</a></span>
<span class="normal"><a href="#__codelineno-0-596">596</a></span>
<span class="normal"><a href="#__codelineno-0-597">597</a></span>
<span class="normal"><a href="#__codelineno-0-598">598</a></span>
<span class="normal"><a href="#__codelineno-0-599">599</a></span>
<span class="normal"><a href="#__codelineno-0-600">600</a></span>
<span class="normal"><a href="#__codelineno-0-601">601</a></span>
<span class="normal"><a href="#__codelineno-0-602">602</a></span>
<span class="normal"><a href="#__codelineno-0-603">603</a></span>
<span class="normal"><a href="#__codelineno-0-604">604</a></span>
<span class="normal"><a href="#__codelineno-0-605">605</a></span>
<span class="normal"><a href="#__codelineno-0-606">606</a></span>
<span class="normal"><a href="#__codelineno-0-607">607</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-559"><a id="__codelineno-0-559" name="__codelineno-0-559"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">create_object</span><span class="p">(</span>
</span><span id="__span-0-560"><a id="__codelineno-0-560" name="__codelineno-0-560"></a> <span class="bp">self</span><span class="p">,</span>
</span><span id="__span-0-561"><a id="__codelineno-0-561" name="__codelineno-0-561"></a> <span class="n">type_id</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span>
</span><span id="__span-0-562"><a id="__codelineno-0-562" name="__codelineno-0-562"></a> <span class="n">name</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-563"><a id="__codelineno-0-563" name="__codelineno-0-563"></a> <span class="n">properties</span><span class="p">:</span> <span class="nb">dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Any</span><span class="p">]</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-564"><a id="__codelineno-0-564" name="__codelineno-0-564"></a> <span class="n">doc_name</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-565"><a id="__codelineno-0-565" name="__codelineno-0-565"></a> <span class="p">)</span> <span class="o">-&gt;</span> <span class="n">ObjectInfo</span><span class="p">:</span>
</span><span id="__span-0-566"><a id="__codelineno-0-566" name="__codelineno-0-566"></a><span class="w"> </span><span class="sd">"""Create a new object.</span>
</span><span id="__span-0-567"><a id="__codelineno-0-567" name="__codelineno-0-567"></a>
</span><span id="__span-0-568"><a id="__codelineno-0-568" name="__codelineno-0-568"></a><span class="sd"> Args:</span>
</span><span id="__span-0-569"><a id="__codelineno-0-569" name="__codelineno-0-569"></a><span class="sd"> type_id: FreeCAD type ID (e.g., "Part::Box", "Part::Cylinder").</span>
</span><span id="__span-0-570"><a id="__codelineno-0-570" name="__codelineno-0-570"></a><span class="sd"> name: Object name (auto-generated if None).</span>
</span><span id="__span-0-571"><a id="__codelineno-0-571" name="__codelineno-0-571"></a><span class="sd"> properties: Initial property values.</span>
</span><span id="__span-0-572"><a id="__codelineno-0-572" name="__codelineno-0-572"></a><span class="sd"> doc_name: Target document (uses active if None).</span>
</span><span id="__span-0-573"><a id="__codelineno-0-573" name="__codelineno-0-573"></a>
</span><span id="__span-0-574"><a id="__codelineno-0-574" name="__codelineno-0-574"></a><span class="sd"> Returns:</span>
</span><span id="__span-0-575"><a id="__codelineno-0-575" name="__codelineno-0-575"></a><span class="sd"> ObjectInfo for the created object.</span>
</span><span id="__span-0-576"><a id="__codelineno-0-576" name="__codelineno-0-576"></a><span class="sd"> """</span>
</span><span id="__span-0-577"><a id="__codelineno-0-577" name="__codelineno-0-577"></a> <span class="n">properties</span> <span class="o">=</span> <span class="n">properties</span> <span class="ow">or</span> <span class="p">{}</span>
</span><span id="__span-0-578"><a id="__codelineno-0-578" name="__codelineno-0-578"></a> <span class="n">code</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">"""</span>
</span><span id="__span-0-579"><a id="__codelineno-0-579" name="__codelineno-0-579"></a><span class="s2">doc = FreeCAD.ActiveDocument if </span><span class="si">{</span><span class="n">doc_name</span><span class="si">!r}</span><span class="s2"> is None else FreeCAD.getDocument(</span><span class="si">{</span><span class="n">doc_name</span><span class="si">!r}</span><span class="s2">)</span>
</span><span id="__span-0-580"><a id="__codelineno-0-580" name="__codelineno-0-580"></a><span class="s2">if doc is None:</span>
</span><span id="__span-0-581"><a id="__codelineno-0-581" name="__codelineno-0-581"></a><span class="s2"> raise ValueError("No document found")</span>
</span><span id="__span-0-582"><a id="__codelineno-0-582" name="__codelineno-0-582"></a>
</span><span id="__span-0-583"><a id="__codelineno-0-583" name="__codelineno-0-583"></a><span class="s2">obj = doc.addObject(</span><span class="si">{</span><span class="n">type_id</span><span class="si">!r}</span><span class="s2">, </span><span class="si">{</span><span class="n">name</span><span class="si">!r}</span><span class="s2"> or "")</span>
</span><span id="__span-0-584"><a id="__codelineno-0-584" name="__codelineno-0-584"></a>
</span><span id="__span-0-585"><a id="__codelineno-0-585" name="__codelineno-0-585"></a><span class="s2"># Set properties</span>
</span><span id="__span-0-586"><a id="__codelineno-0-586" name="__codelineno-0-586"></a><span class="s2">for prop_name, prop_val in </span><span class="si">{</span><span class="n">properties</span><span class="si">!r}</span><span class="s2">.items():</span>
</span><span id="__span-0-587"><a id="__codelineno-0-587" name="__codelineno-0-587"></a><span class="s2"> if hasattr(obj, prop_name):</span>
</span><span id="__span-0-588"><a id="__codelineno-0-588" name="__codelineno-0-588"></a><span class="s2"> setattr(obj, prop_name, prop_val)</span>
</span><span id="__span-0-589"><a id="__codelineno-0-589" name="__codelineno-0-589"></a>
</span><span id="__span-0-590"><a id="__codelineno-0-590" name="__codelineno-0-590"></a><span class="s2">doc.recompute()</span>
</span><span id="__span-0-591"><a id="__codelineno-0-591" name="__codelineno-0-591"></a>
</span><span id="__span-0-592"><a id="__codelineno-0-592" name="__codelineno-0-592"></a><span class="s2">_result_ = </span><span class="se">{{</span>
</span><span id="__span-0-593"><a id="__codelineno-0-593" name="__codelineno-0-593"></a><span class="s2"> "name": obj.Name,</span>
</span><span id="__span-0-594"><a id="__codelineno-0-594" name="__codelineno-0-594"></a><span class="s2"> "label": obj.Label,</span>
</span><span id="__span-0-595"><a id="__codelineno-0-595" name="__codelineno-0-595"></a><span class="s2"> "type_id": obj.TypeId,</span>
</span><span id="__span-0-596"><a id="__codelineno-0-596" name="__codelineno-0-596"></a><span class="s2"> "visibility": True,</span>
</span><span id="__span-0-597"><a id="__codelineno-0-597" name="__codelineno-0-597"></a><span class="s2"> "children": [c.Name for c in obj.OutList] if hasattr(obj, "OutList") else [],</span>
</span><span id="__span-0-598"><a id="__codelineno-0-598" name="__codelineno-0-598"></a><span class="s2"> "parents": [p.Name for p in obj.InList] if hasattr(obj, "InList") else [],</span>
</span><span id="__span-0-599"><a id="__codelineno-0-599" name="__codelineno-0-599"></a><span class="se">}}</span>
</span><span id="__span-0-600"><a id="__codelineno-0-600" name="__codelineno-0-600"></a><span class="s2">"""</span>
</span><span id="__span-0-601"><a id="__codelineno-0-601" name="__codelineno-0-601"></a> <span class="n">result</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">execute_python</span><span class="p">(</span><span class="n">code</span><span class="p">)</span>
</span><span id="__span-0-602"><a id="__codelineno-0-602" name="__codelineno-0-602"></a>
</span><span id="__span-0-603"><a id="__codelineno-0-603" name="__codelineno-0-603"></a> <span class="k">if</span> <span class="n">result</span><span class="o">.</span><span class="n">success</span> <span class="ow">and</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">:</span>
</span><span id="__span-0-604"><a id="__codelineno-0-604" name="__codelineno-0-604"></a> <span class="k">return</span> <span class="n">ObjectInfo</span><span class="p">(</span><span class="o">**</span><span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">)</span>
</span><span id="__span-0-605"><a id="__codelineno-0-605" name="__codelineno-0-605"></a>
</span><span id="__span-0-606"><a id="__codelineno-0-606" name="__codelineno-0-606"></a> <span class="n">error_msg</span> <span class="o">=</span> <span class="n">result</span><span class="o">.</span><span class="n">error_traceback</span> <span class="ow">or</span> <span class="s2">"Failed to create object"</span>
</span><span id="__span-0-607"><a id="__codelineno-0-607" name="__codelineno-0-607"></a> <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="n">error_msg</span><span class="p">)</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> </div> </div> <div class="doc doc-object doc-function"> <h6 id="freecad_mcp.bridge.embedded.EmbeddedBridge.delete_object" class="doc doc-heading"> <code class="highlight language-python"><span class="n">delete_object</span><span class="p">(</span><span class="n">obj_name</span><span class="p">,</span> <span class="n">doc_name</span><span class="o">=</span><span class="kc">None</span><span class="p">)</span></code> <span class="doc doc-labels"> <small class="doc doc-label doc-label-async"><code>async</code></small> </span> <a href="#freecad_mcp.bridge.embedded.EmbeddedBridge.delete_object" class="headerlink" title="Permanent link">¶</a></h6> <div class="doc doc-contents "> <p>Delete an object.</p> <p><span class="doc-section-title">Parameters:</span></p> <table> <thead> <tr> <th>Name</th> <th>Type</th> <th>Description</th> <th>Default</th> </tr> </thead> <tbody> <tr class="doc-section-item"> <td> <code>obj_name</code> </td> <td> <code><span title="str">str</span></code> </td> <td> <div class="doc-md-description"> <p>Name of the object to delete.</p> </div> </td> <td> <em>required</em> </td> </tr> <tr class="doc-section-item"> <td> <code>doc_name</code> </td> <td> <code><span title="str">str</span> | None</code> </td> <td> <div class="doc-md-description"> <p>Document name (uses active if None).</p> </div> </td> <td> <code>None</code> </td> </tr> </tbody> </table> <p><span class="doc-section-title">Raises:</span></p> <table> <thead> <tr> <th>Type</th> <th>Description</th> </tr> </thead> <tbody> <tr class="doc-section-item"> <td> <code><span title="ValueError">ValueError</span></code> </td> <td> <div class="doc-md-description"> <p>If object not found.</p> </div> </td> </tr> </tbody> </table> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/embedded.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-661">661</a></span>
<span class="normal"><a href="#__codelineno-0-662">662</a></span>
<span class="normal"><a href="#__codelineno-0-663">663</a></span>
<span class="normal"><a href="#__codelineno-0-664">664</a></span>
<span class="normal"><a href="#__codelineno-0-665">665</a></span>
<span class="normal"><a href="#__codelineno-0-666">666</a></span>
<span class="normal"><a href="#__codelineno-0-667">667</a></span>
<span class="normal"><a href="#__codelineno-0-668">668</a></span>
<span class="normal"><a href="#__codelineno-0-669">669</a></span>
<span class="normal"><a href="#__codelineno-0-670">670</a></span>
<span class="normal"><a href="#__codelineno-0-671">671</a></span>
<span class="normal"><a href="#__codelineno-0-672">672</a></span>
<span class="normal"><a href="#__codelineno-0-673">673</a></span>
<span class="normal"><a href="#__codelineno-0-674">674</a></span>
<span class="normal"><a href="#__codelineno-0-675">675</a></span>
<span class="normal"><a href="#__codelineno-0-676">676</a></span>
<span class="normal"><a href="#__codelineno-0-677">677</a></span>
<span class="normal"><a href="#__codelineno-0-678">678</a></span>
<span class="normal"><a href="#__codelineno-0-679">679</a></span>
<span class="normal"><a href="#__codelineno-0-680">680</a></span>
<span class="normal"><a href="#__codelineno-0-681">681</a></span>
<span class="normal"><a href="#__codelineno-0-682">682</a></span>
<span class="normal"><a href="#__codelineno-0-683">683</a></span>
<span class="normal"><a href="#__codelineno-0-684">684</a></span>
<span class="normal"><a href="#__codelineno-0-685">685</a></span>
<span class="normal"><a href="#__codelineno-0-686">686</a></span>
<span class="normal"><a href="#__codelineno-0-687">687</a></span>
<span class="normal"><a href="#__codelineno-0-688">688</a></span>
<span class="normal"><a href="#__codelineno-0-689">689</a></span>
<span class="normal"><a href="#__codelineno-0-690">690</a></span>
<span class="normal"><a href="#__codelineno-0-691">691</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-661"><a id="__codelineno-0-661" name="__codelineno-0-661"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">delete_object</span><span class="p">(</span>
</span><span id="__span-0-662"><a id="__codelineno-0-662" name="__codelineno-0-662"></a> <span class="bp">self</span><span class="p">,</span>
</span><span id="__span-0-663"><a id="__codelineno-0-663" name="__codelineno-0-663"></a> <span class="n">obj_name</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span>
</span><span id="__span-0-664"><a id="__codelineno-0-664" name="__codelineno-0-664"></a> <span class="n">doc_name</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-665"><a id="__codelineno-0-665" name="__codelineno-0-665"></a> <span class="p">)</span> <span class="o">-&gt;</span> <span class="kc">None</span><span class="p">:</span>
</span><span id="__span-0-666"><a id="__codelineno-0-666" name="__codelineno-0-666"></a><span class="w"> </span><span class="sd">"""Delete an object.</span>
</span><span id="__span-0-667"><a id="__codelineno-0-667" name="__codelineno-0-667"></a>
</span><span id="__span-0-668"><a id="__codelineno-0-668" name="__codelineno-0-668"></a><span class="sd"> Args:</span>
</span><span id="__span-0-669"><a id="__codelineno-0-669" name="__codelineno-0-669"></a><span class="sd"> obj_name: Name of the object to delete.</span>
</span><span id="__span-0-670"><a id="__codelineno-0-670" name="__codelineno-0-670"></a><span class="sd"> doc_name: Document name (uses active if None).</span>
</span><span id="__span-0-671"><a id="__codelineno-0-671" name="__codelineno-0-671"></a>
</span><span id="__span-0-672"><a id="__codelineno-0-672" name="__codelineno-0-672"></a><span class="sd"> Raises:</span>
</span><span id="__span-0-673"><a id="__codelineno-0-673" name="__codelineno-0-673"></a><span class="sd"> ValueError: If object not found.</span>
</span><span id="__span-0-674"><a id="__codelineno-0-674" name="__codelineno-0-674"></a><span class="sd"> """</span>
</span><span id="__span-0-675"><a id="__codelineno-0-675" name="__codelineno-0-675"></a> <span class="n">code</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">"""</span>
</span><span id="__span-0-676"><a id="__codelineno-0-676" name="__codelineno-0-676"></a><span class="s2">doc = FreeCAD.ActiveDocument if </span><span class="si">{</span><span class="n">doc_name</span><span class="si">!r}</span><span class="s2"> is None else FreeCAD.getDocument(</span><span class="si">{</span><span class="n">doc_name</span><span class="si">!r}</span><span class="s2">)</span>
</span><span id="__span-0-677"><a id="__codelineno-0-677" name="__codelineno-0-677"></a><span class="s2">if doc is None:</span>
</span><span id="__span-0-678"><a id="__codelineno-0-678" name="__codelineno-0-678"></a><span class="s2"> raise ValueError("No document found")</span>
</span><span id="__span-0-679"><a id="__codelineno-0-679" name="__codelineno-0-679"></a>
</span><span id="__span-0-680"><a id="__codelineno-0-680" name="__codelineno-0-680"></a><span class="s2">obj = doc.getObject(</span><span class="si">{</span><span class="n">obj_name</span><span class="si">!r}</span><span class="s2">)</span>
</span><span id="__span-0-681"><a id="__codelineno-0-681" name="__codelineno-0-681"></a><span class="s2">if obj is None:</span>
</span><span id="__span-0-682"><a id="__codelineno-0-682" name="__codelineno-0-682"></a><span class="s2"> raise ValueError(f"Object not found: </span><span class="si">{</span><span class="n">obj_name</span><span class="si">!r}</span><span class="s2">")</span>
</span><span id="__span-0-683"><a id="__codelineno-0-683" name="__codelineno-0-683"></a>
</span><span id="__span-0-684"><a id="__codelineno-0-684" name="__codelineno-0-684"></a><span class="s2">doc.removeObject(</span><span class="si">{</span><span class="n">obj_name</span><span class="si">!r}</span><span class="s2">)</span>
</span><span id="__span-0-685"><a id="__codelineno-0-685" name="__codelineno-0-685"></a><span class="s2">_result_ = True</span>
</span><span id="__span-0-686"><a id="__codelineno-0-686" name="__codelineno-0-686"></a><span class="s2">"""</span>
</span><span id="__span-0-687"><a id="__codelineno-0-687" name="__codelineno-0-687"></a> <span class="n">result</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">execute_python</span><span class="p">(</span><span class="n">code</span><span class="p">)</span>
</span><span id="__span-0-688"><a id="__codelineno-0-688" name="__codelineno-0-688"></a>
</span><span id="__span-0-689"><a id="__codelineno-0-689" name="__codelineno-0-689"></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">result</span><span class="o">.</span><span class="n">success</span><span class="p">:</span>
</span><span id="__span-0-690"><a id="__codelineno-0-690" name="__codelineno-0-690"></a> <span class="n">error_msg</span> <span class="o">=</span> <span class="n">result</span><span class="o">.</span><span class="n">error_traceback</span> <span class="ow">or</span> <span class="s2">"Failed to delete object"</span>
</span><span id="__span-0-691"><a id="__codelineno-0-691" name="__codelineno-0-691"></a> <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="n">error_msg</span><span class="p">)</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> </div> </div> <div class="doc doc-object doc-function"> <h6 id="freecad_mcp.bridge.embedded.EmbeddedBridge.disconnect" class="doc doc-heading"> <code class="highlight language-python"><span class="n">disconnect</span><span class="p">()</span></code> <span class="doc doc-labels"> <small class="doc doc-label doc-label-async"><code>async</code></small> </span> <a href="#freecad_mcp.bridge.embedded.EmbeddedBridge.disconnect" class="headerlink" title="Permanent link">¶</a></h6> <div class="doc doc-contents "> <p>Clean up resources.</p> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/embedded.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-83">83</a></span>
<span class="normal"><a href="#__codelineno-0-84">84</a></span>
<span class="normal"><a href="#__codelineno-0-85">85</a></span>
<span class="normal"><a href="#__codelineno-0-86">86</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-83"><a id="__codelineno-0-83" name="__codelineno-0-83"></a><span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">disconnect</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kc">None</span><span class="p">:</span>
</span><span id="__span-0-84"><a id="__codelineno-0-84" name="__codelineno-0-84"></a><span class="w"> </span><span class="sd">"""Clean up resources."""</span>
</span><span id="__span-0-85"><a id="__codelineno-0-85" name="__codelineno-0-85"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_connected</span> <span class="o">=</span> <span class="kc">False</span>
</span><span id="__span-0-86"><a id="__codelineno-0-86" name="__codelineno-0-86"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_executor</span><span class="o">.</span><span class="n">shutdown</span><span class="p">(</span><span class="n">wait</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> </div> </div> <div class="doc doc-object doc-function"> <h6 id="freecad_mcp.bridge.embedded.EmbeddedBridge.edit_object" class="doc doc-heading"> <code class="highlight language-python"><span class="n">edit_object</span><span class="p">(</span><span class="n">obj_name</span><span class="p">,</span> <span class="n">properties</span><span class="p">,</span> <span class="n">doc_name</span><span class="o">=</span><span class="kc">None</span><span class="p">)</span></code> <span class="doc doc-labels"> <small class="doc doc-label doc-label-async"><code>async</code></small> </span> <a href="#freecad_mcp.bridge.embedded.EmbeddedBridge.edit_object" class="headerlink" title="Permanent link">¶</a></h6> <div class="doc doc-contents "> <p>Edit object properties.</p> <p><span class="doc-section-title">Parameters:</span></p> <table> <thead> <tr> <th>Name</th> <th>Type</th> <th>Description</th> <th>Default</th> </tr> </thead> <tbody> <tr class="doc-section-item"> <td> <code>obj_name</code> </td> <td> <code><span title="str">str</span></code> </td> <td> <div class="doc-md-description"> <p>Name of the object to edit.</p> </div> </td> <td> <em>required</em> </td> </tr> <tr class="doc-section-item"> <td> <code>properties</code> </td> <td> <code><span title="dict">dict</span>[<span title="str">str</span>, <span title="typing.Any">Any</span>]</code> </td> <td> <div class="doc-md-description"> <p>Property values to set.</p> </div> </td> <td> <em>required</em> </td> </tr> <tr class="doc-section-item"> <td> <code>doc_name</code> </td> <td> <code><span title="str">str</span> | None</code> </td> <td> <div class="doc-md-description"> <p>Document name (uses active if None).</p> </div> </td> <td> <code>None</code> </td> </tr> </tbody> </table> <p><span class="doc-section-title">Returns:</span></p> <table> <thead> <tr> <th>Type</th> <th>Description</th> </tr> </thead> <tbody> <tr class="doc-section-item"> <td> <code><a class="autorefs autorefs-internal" title="ObjectInfo
dataclass
(freecad_mcp.bridge.base.ObjectInfo)" href="#freecad_mcp.bridge.base.ObjectInfo">ObjectInfo</a></code> </td> <td> <div class="doc-md-description"> <p>Updated ObjectInfo.</p> </div> </td> </tr> </tbody> </table> <p><span class="doc-section-title">Raises:</span></p> <table> <thead> <tr> <th>Type</th> <th>Description</th> </tr> </thead> <tbody> <tr class="doc-section-item"> <td> <code><span title="ValueError">ValueError</span></code> </td> <td> <div class="doc-md-description"> <p>If object not found.</p> </div> </td> </tr> </tbody> </table> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/embedded.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-609">609</a></span>
<span class="normal"><a href="#__codelineno-0-610">610</a></span>
<span class="normal"><a href="#__codelineno-0-611">611</a></span>
<span class="normal"><a href="#__codelineno-0-612">612</a></span>
<span class="normal"><a href="#__codelineno-0-613">613</a></span>
<span class="normal"><a href="#__codelineno-0-614">614</a></span>
<span class="normal"><a href="#__codelineno-0-615">615</a></span>
<span class="normal"><a href="#__codelineno-0-616">616</a></span>
<span class="normal"><a href="#__codelineno-0-617">617</a></span>
<span class="normal"><a href="#__codelineno-0-618">618</a></span>
<span class="normal"><a href="#__codelineno-0-619">619</a></span>
<span class="normal"><a href="#__codelineno-0-620">620</a></span>
<span class="normal"><a href="#__codelineno-0-621">621</a></span>
<span class="normal"><a href="#__codelineno-0-622">622</a></span>
<span class="normal"><a href="#__codelineno-0-623">623</a></span>
<span class="normal"><a href="#__codelineno-0-624">624</a></span>
<span class="normal"><a href="#__codelineno-0-625">625</a></span>
<span class="normal"><a href="#__codelineno-0-626">626</a></span>
<span class="normal"><a href="#__codelineno-0-627">627</a></span>
<span class="normal"><a href="#__codelineno-0-628">628</a></span>
<span class="normal"><a href="#__codelineno-0-629">629</a></span>
<span class="normal"><a href="#__codelineno-0-630">630</a></span>
<span class="normal"><a href="#__codelineno-0-631">631</a></span>
<span class="normal"><a href="#__codelineno-0-632">632</a></span>
<span class="normal"><a href="#__codelineno-0-633">633</a></span>
<span class="normal"><a href="#__codelineno-0-634">634</a></span>
<span class="normal"><a href="#__codelineno-0-635">635</a></span>
<span class="normal"><a href="#__codelineno-0-636">636</a></span>
<span class="normal"><a href="#__codelineno-0-637">637</a></span>
<span class="normal"><a href="#__codelineno-0-638">638</a></span>
<span class="normal"><a href="#__codelineno-0-639">639</a></span>
<span class="normal"><a href="#__codelineno-0-640">640</a></span>
<span class="normal"><a href="#__codelineno-0-641">641</a></span>
<span class="normal"><a href="#__codelineno-0-642">642</a></span>
<span class="normal"><a href="#__codelineno-0-643">643</a></span>
<span class="normal"><a href="#__codelineno-0-644">644</a></span>
<span class="normal"><a href="#__codelineno-0-645">645</a></span>
<span class="normal"><a href="#__codelineno-0-646">646</a></span>
<span class="normal"><a href="#__codelineno-0-647">647</a></span>
<span class="normal"><a href="#__codelineno-0-648">648</a></span>
<span class="normal"><a href="#__codelineno-0-649">649</a></span>
<span class="normal"><a href="#__codelineno-0-650">650</a></span>
<span class="normal"><a href="#__codelineno-0-651">651</a></span>
<span class="normal"><a href="#__codelineno-0-652">652</a></span>
<span class="normal"><a href="#__codelineno-0-653">653</a></span>
<span class="normal"><a href="#__codelineno-0-654">654</a></span>
<span class="normal"><a href="#__codelineno-0-655">655</a></span>
<span class="normal"><a href="#__codelineno-0-656">656</a></span>
<span class="normal"><a href="#__codelineno-0-657">657</a></span>
<span class="normal"><a href="#__codelineno-0-658">658</a></span>
<span class="normal"><a href="#__codelineno-0-659">659</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-609"><a id="__codelineno-0-609" name="__codelineno-0-609"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">edit_object</span><span class="p">(</span>
</span><span id="__span-0-610"><a id="__codelineno-0-610" name="__codelineno-0-610"></a> <span class="bp">self</span><span class="p">,</span>
</span><span id="__span-0-611"><a id="__codelineno-0-611" name="__codelineno-0-611"></a> <span class="n">obj_name</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span>
</span><span id="__span-0-612"><a id="__codelineno-0-612" name="__codelineno-0-612"></a> <span class="n">properties</span><span class="p">:</span> <span class="nb">dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Any</span><span class="p">],</span>
</span><span id="__span-0-613"><a id="__codelineno-0-613" name="__codelineno-0-613"></a> <span class="n">doc_name</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-614"><a id="__codelineno-0-614" name="__codelineno-0-614"></a> <span class="p">)</span> <span class="o">-&gt;</span> <span class="n">ObjectInfo</span><span class="p">:</span>
</span><span id="__span-0-615"><a id="__codelineno-0-615" name="__codelineno-0-615"></a><span class="w"> </span><span class="sd">"""Edit object properties.</span>
</span><span id="__span-0-616"><a id="__codelineno-0-616" name="__codelineno-0-616"></a>
</span><span id="__span-0-617"><a id="__codelineno-0-617" name="__codelineno-0-617"></a><span class="sd"> Args:</span>
</span><span id="__span-0-618"><a id="__codelineno-0-618" name="__codelineno-0-618"></a><span class="sd"> obj_name: Name of the object to edit.</span>
</span><span id="__span-0-619"><a id="__codelineno-0-619" name="__codelineno-0-619"></a><span class="sd"> properties: Property values to set.</span>
</span><span id="__span-0-620"><a id="__codelineno-0-620" name="__codelineno-0-620"></a><span class="sd"> doc_name: Document name (uses active if None).</span>
</span><span id="__span-0-621"><a id="__codelineno-0-621" name="__codelineno-0-621"></a>
</span><span id="__span-0-622"><a id="__codelineno-0-622" name="__codelineno-0-622"></a><span class="sd"> Returns:</span>
</span><span id="__span-0-623"><a id="__codelineno-0-623" name="__codelineno-0-623"></a><span class="sd"> Updated ObjectInfo.</span>
</span><span id="__span-0-624"><a id="__codelineno-0-624" name="__codelineno-0-624"></a>
</span><span id="__span-0-625"><a id="__codelineno-0-625" name="__codelineno-0-625"></a><span class="sd"> Raises:</span>
</span><span id="__span-0-626"><a id="__codelineno-0-626" name="__codelineno-0-626"></a><span class="sd"> ValueError: If object not found.</span>
</span><span id="__span-0-627"><a id="__codelineno-0-627" name="__codelineno-0-627"></a><span class="sd"> """</span>
</span><span id="__span-0-628"><a id="__codelineno-0-628" name="__codelineno-0-628"></a> <span class="n">code</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">"""</span>
</span><span id="__span-0-629"><a id="__codelineno-0-629" name="__codelineno-0-629"></a><span class="s2">doc = FreeCAD.ActiveDocument if </span><span class="si">{</span><span class="n">doc_name</span><span class="si">!r}</span><span class="s2"> is None else FreeCAD.getDocument(</span><span class="si">{</span><span class="n">doc_name</span><span class="si">!r}</span><span class="s2">)</span>
</span><span id="__span-0-630"><a id="__codelineno-0-630" name="__codelineno-0-630"></a><span class="s2">if doc is None:</span>
</span><span id="__span-0-631"><a id="__codelineno-0-631" name="__codelineno-0-631"></a><span class="s2"> raise ValueError("No document found")</span>
</span><span id="__span-0-632"><a id="__codelineno-0-632" name="__codelineno-0-632"></a>
</span><span id="__span-0-633"><a id="__codelineno-0-633" name="__codelineno-0-633"></a><span class="s2">obj = doc.getObject(</span><span class="si">{</span><span class="n">obj_name</span><span class="si">!r}</span><span class="s2">)</span>
</span><span id="__span-0-634"><a id="__codelineno-0-634" name="__codelineno-0-634"></a><span class="s2">if obj is None:</span>
</span><span id="__span-0-635"><a id="__codelineno-0-635" name="__codelineno-0-635"></a><span class="s2"> raise ValueError(f"Object not found: </span><span class="si">{</span><span class="n">obj_name</span><span class="si">!r}</span><span class="s2">")</span>
</span><span id="__span-0-636"><a id="__codelineno-0-636" name="__codelineno-0-636"></a>
</span><span id="__span-0-637"><a id="__codelineno-0-637" name="__codelineno-0-637"></a><span class="s2"># Set properties</span>
</span><span id="__span-0-638"><a id="__codelineno-0-638" name="__codelineno-0-638"></a><span class="s2">for prop_name, prop_val in </span><span class="si">{</span><span class="n">properties</span><span class="si">!r}</span><span class="s2">.items():</span>
</span><span id="__span-0-639"><a id="__codelineno-0-639" name="__codelineno-0-639"></a><span class="s2"> if hasattr(obj, prop_name):</span>
</span><span id="__span-0-640"><a id="__codelineno-0-640" name="__codelineno-0-640"></a><span class="s2"> setattr(obj, prop_name, prop_val)</span>
</span><span id="__span-0-641"><a id="__codelineno-0-641" name="__codelineno-0-641"></a>
</span><span id="__span-0-642"><a id="__codelineno-0-642" name="__codelineno-0-642"></a><span class="s2">doc.recompute()</span>
</span><span id="__span-0-643"><a id="__codelineno-0-643" name="__codelineno-0-643"></a>
</span><span id="__span-0-644"><a id="__codelineno-0-644" name="__codelineno-0-644"></a><span class="s2">_result_ = </span><span class="se">{{</span>
</span><span id="__span-0-645"><a id="__codelineno-0-645" name="__codelineno-0-645"></a><span class="s2"> "name": obj.Name,</span>
</span><span id="__span-0-646"><a id="__codelineno-0-646" name="__codelineno-0-646"></a><span class="s2"> "label": obj.Label,</span>
</span><span id="__span-0-647"><a id="__codelineno-0-647" name="__codelineno-0-647"></a><span class="s2"> "type_id": obj.TypeId,</span>
</span><span id="__span-0-648"><a id="__codelineno-0-648" name="__codelineno-0-648"></a><span class="s2"> "visibility": obj.ViewObject.Visibility if hasattr(obj, "ViewObject") and obj.ViewObject else True,</span>
</span><span id="__span-0-649"><a id="__codelineno-0-649" name="__codelineno-0-649"></a><span class="s2"> "children": [c.Name for c in obj.OutList] if hasattr(obj, "OutList") else [],</span>
</span><span id="__span-0-650"><a id="__codelineno-0-650" name="__codelineno-0-650"></a><span class="s2"> "parents": [p.Name for p in obj.InList] if hasattr(obj, "InList") else [],</span>
</span><span id="__span-0-651"><a id="__codelineno-0-651" name="__codelineno-0-651"></a><span class="se">}}</span>
</span><span id="__span-0-652"><a id="__codelineno-0-652" name="__codelineno-0-652"></a><span class="s2">"""</span>
</span><span id="__span-0-653"><a id="__codelineno-0-653" name="__codelineno-0-653"></a> <span class="n">result</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">execute_python</span><span class="p">(</span><span class="n">code</span><span class="p">)</span>
</span><span id="__span-0-654"><a id="__codelineno-0-654" name="__codelineno-0-654"></a>
</span><span id="__span-0-655"><a id="__codelineno-0-655" name="__codelineno-0-655"></a> <span class="k">if</span> <span class="n">result</span><span class="o">.</span><span class="n">success</span> <span class="ow">and</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">:</span>
</span><span id="__span-0-656"><a id="__codelineno-0-656" name="__codelineno-0-656"></a> <span class="k">return</span> <span class="n">ObjectInfo</span><span class="p">(</span><span class="o">**</span><span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">)</span>
</span><span id="__span-0-657"><a id="__codelineno-0-657" name="__codelineno-0-657"></a>
</span><span id="__span-0-658"><a id="__codelineno-0-658" name="__codelineno-0-658"></a> <span class="n">error_msg</span> <span class="o">=</span> <span class="n">result</span><span class="o">.</span><span class="n">error_traceback</span> <span class="ow">or</span> <span class="s2">"Failed to edit object"</span>
</span><span id="__span-0-659"><a id="__codelineno-0-659" name="__codelineno-0-659"></a> <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="n">error_msg</span><span class="p">)</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> </div> </div> <div class="doc doc-object doc-function"> <h6 id="freecad_mcp.bridge.embedded.EmbeddedBridge.execute_python" class="doc doc-heading"> <code class="highlight language-python"><span class="n">execute_python</span><span class="p">(</span><span class="n">code</span><span class="p">,</span> <span class="n">timeout_ms</span><span class="o">=</span><span class="mi">30000</span><span class="p">)</span></code> <span class="doc doc-labels"> <small class="doc doc-label doc-label-async"><code>async</code></small> </span> <a href="#freecad_mcp.bridge.embedded.EmbeddedBridge.execute_python" class="headerlink" title="Permanent link">¶</a></h6> <div class="doc doc-contents "> <p>Execute Python code in FreeCAD context.</p> <p><span class="doc-section-title">Parameters:</span></p> <table> <thead> <tr> <th>Name</th> <th>Type</th> <th>Description</th> <th>Default</th> </tr> </thead> <tbody> <tr class="doc-section-item"> <td> <code>code</code> </td> <td> <code><span title="str">str</span></code> </td> <td> <div class="doc-md-description"> <p>Python code to execute.</p> </div> </td> <td> <em>required</em> </td> </tr> <tr class="doc-section-item"> <td> <code>timeout_ms</code> </td> <td> <code><span title="int">int</span></code> </td> <td> <div class="doc-md-description"> <p>Maximum execution time in milliseconds.</p> </div> </td> <td> <code>30000</code> </td> </tr> </tbody> </table> <p><span class="doc-section-title">Returns:</span></p> <table> <thead> <tr> <th>Type</th> <th>Description</th> </tr> </thead> <tbody> <tr class="doc-section-item"> <td> <code><a class="autorefs autorefs-internal" title="ExecutionResult
dataclass
(freecad_mcp.bridge.base.ExecutionResult)" href="#freecad_mcp.bridge.base.ExecutionResult">ExecutionResult</a></code> </td> <td> <div class="doc-md-description"> <p>ExecutionResult with execution outcome.</p> </div> </td> </tr> </tbody> </table> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/embedded.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-92"> 92</a></span>
<span class="normal"><a href="#__codelineno-0-93"> 93</a></span>
<span class="normal"><a href="#__codelineno-0-94"> 94</a></span>
<span class="normal"><a href="#__codelineno-0-95"> 95</a></span>
<span class="normal"><a href="#__codelineno-0-96"> 96</a></span>
<span class="normal"><a href="#__codelineno-0-97"> 97</a></span>
<span class="normal"><a href="#__codelineno-0-98"> 98</a></span>
<span class="normal"><a href="#__codelineno-0-99"> 99</a></span>
<span class="normal"><a href="#__codelineno-0-100">100</a></span>
<span class="normal"><a href="#__codelineno-0-101">101</a></span>
<span class="normal"><a href="#__codelineno-0-102">102</a></span>
<span class="normal"><a href="#__codelineno-0-103">103</a></span>
<span class="normal"><a href="#__codelineno-0-104">104</a></span>
<span class="normal"><a href="#__codelineno-0-105">105</a></span>
<span class="normal"><a href="#__codelineno-0-106">106</a></span>
<span class="normal"><a href="#__codelineno-0-107">107</a></span>
<span class="normal"><a href="#__codelineno-0-108">108</a></span>
<span class="normal"><a href="#__codelineno-0-109">109</a></span>
<span class="normal"><a href="#__codelineno-0-110">110</a></span>
<span class="normal"><a href="#__codelineno-0-111">111</a></span>
<span class="normal"><a href="#__codelineno-0-112">112</a></span>
<span class="normal"><a href="#__codelineno-0-113">113</a></span>
<span class="normal"><a href="#__codelineno-0-114">114</a></span>
<span class="normal"><a href="#__codelineno-0-115">115</a></span>
<span class="normal"><a href="#__codelineno-0-116">116</a></span>
<span class="normal"><a href="#__codelineno-0-117">117</a></span>
<span class="normal"><a href="#__codelineno-0-118">118</a></span>
<span class="normal"><a href="#__codelineno-0-119">119</a></span>
<span class="normal"><a href="#__codelineno-0-120">120</a></span>
<span class="normal"><a href="#__codelineno-0-121">121</a></span>
<span class="normal"><a href="#__codelineno-0-122">122</a></span>
<span class="normal"><a href="#__codelineno-0-123">123</a></span>
<span class="normal"><a href="#__codelineno-0-124">124</a></span>
<span class="normal"><a href="#__codelineno-0-125">125</a></span>
<span class="normal"><a href="#__codelineno-0-126">126</a></span>
<span class="normal"><a href="#__codelineno-0-127">127</a></span>
<span class="normal"><a href="#__codelineno-0-128">128</a></span>
<span class="normal"><a href="#__codelineno-0-129">129</a></span>
<span class="normal"><a href="#__codelineno-0-130">130</a></span>
<span class="normal"><a href="#__codelineno-0-131">131</a></span>
<span class="normal"><a href="#__codelineno-0-132">132</a></span>
<span class="normal"><a href="#__codelineno-0-133">133</a></span>
<span class="normal"><a href="#__codelineno-0-134">134</a></span>
<span class="normal"><a href="#__codelineno-0-135">135</a></span>
<span class="normal"><a href="#__codelineno-0-136">136</a></span>
<span class="normal"><a href="#__codelineno-0-137">137</a></span>
<span class="normal"><a href="#__codelineno-0-138">138</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-92"><a id="__codelineno-0-92" name="__codelineno-0-92"></a><span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">execute_python</span><span class="p">(</span>
</span><span id="__span-0-93"><a id="__codelineno-0-93" name="__codelineno-0-93"></a> <span class="bp">self</span><span class="p">,</span>
</span><span id="__span-0-94"><a id="__codelineno-0-94" name="__codelineno-0-94"></a> <span class="n">code</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span>
</span><span id="__span-0-95"><a id="__codelineno-0-95" name="__codelineno-0-95"></a> <span class="n">timeout_ms</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">30000</span><span class="p">,</span>
</span><span id="__span-0-96"><a id="__codelineno-0-96" name="__codelineno-0-96"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">ExecutionResult</span><span class="p">:</span>
</span><span id="__span-0-97"><a id="__codelineno-0-97" name="__codelineno-0-97"></a><span class="w"> </span><span class="sd">"""Execute Python code in FreeCAD context.</span>
</span><span id="__span-0-98"><a id="__codelineno-0-98" name="__codelineno-0-98"></a>
</span><span id="__span-0-99"><a id="__codelineno-0-99" name="__codelineno-0-99"></a><span class="sd"> Args:</span>
</span><span id="__span-0-100"><a id="__codelineno-0-100" name="__codelineno-0-100"></a><span class="sd"> code: Python code to execute.</span>
</span><span id="__span-0-101"><a id="__codelineno-0-101" name="__codelineno-0-101"></a><span class="sd"> timeout_ms: Maximum execution time in milliseconds.</span>
</span><span id="__span-0-102"><a id="__codelineno-0-102" name="__codelineno-0-102"></a>
</span><span id="__span-0-103"><a id="__codelineno-0-103" name="__codelineno-0-103"></a><span class="sd"> Returns:</span>
</span><span id="__span-0-104"><a id="__codelineno-0-104" name="__codelineno-0-104"></a><span class="sd"> ExecutionResult with execution outcome.</span>
</span><span id="__span-0-105"><a id="__codelineno-0-105" name="__codelineno-0-105"></a><span class="sd"> """</span>
</span><span id="__span-0-106"><a id="__codelineno-0-106" name="__codelineno-0-106"></a> <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">_connected</span><span class="p">:</span>
</span><span id="__span-0-107"><a id="__codelineno-0-107" name="__codelineno-0-107"></a> <span class="k">return</span> <span class="n">ExecutionResult</span><span class="p">(</span>
</span><span id="__span-0-108"><a id="__codelineno-0-108" name="__codelineno-0-108"></a> <span class="n">success</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
</span><span id="__span-0-109"><a id="__codelineno-0-109" name="__codelineno-0-109"></a> <span class="n">result</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-110"><a id="__codelineno-0-110" name="__codelineno-0-110"></a> <span class="n">stdout</span><span class="o">=</span><span class="s2">""</span><span class="p">,</span>
</span><span id="__span-0-111"><a id="__codelineno-0-111" name="__codelineno-0-111"></a> <span class="n">stderr</span><span class="o">=</span><span class="s2">"FreeCAD bridge not connected"</span><span class="p">,</span>
</span><span id="__span-0-112"><a id="__codelineno-0-112" name="__codelineno-0-112"></a> <span class="n">execution_time_ms</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span>
</span><span id="__span-0-113"><a id="__codelineno-0-113" name="__codelineno-0-113"></a> <span class="n">error_type</span><span class="o">=</span><span class="s2">"ConnectionError"</span><span class="p">,</span>
</span><span id="__span-0-114"><a id="__codelineno-0-114" name="__codelineno-0-114"></a> <span class="n">error_traceback</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-115"><a id="__codelineno-0-115" name="__codelineno-0-115"></a> <span class="p">)</span>
</span><span id="__span-0-116"><a id="__codelineno-0-116" name="__codelineno-0-116"></a>
</span><span id="__span-0-117"><a id="__codelineno-0-117" name="__codelineno-0-117"></a> <span class="n">loop</span> <span class="o">=</span> <span class="n">asyncio</span><span class="o">.</span><span class="n">get_event_loop</span><span class="p">()</span>
</span><span id="__span-0-118"><a id="__codelineno-0-118" name="__codelineno-0-118"></a>
</span><span id="__span-0-119"><a id="__codelineno-0-119" name="__codelineno-0-119"></a> <span class="k">try</span><span class="p">:</span>
</span><span id="__span-0-120"><a id="__codelineno-0-120" name="__codelineno-0-120"></a> <span class="n">result</span> <span class="o">=</span> <span class="k">await</span> <span class="n">asyncio</span><span class="o">.</span><span class="n">wait_for</span><span class="p">(</span>
</span><span id="__span-0-121"><a id="__codelineno-0-121" name="__codelineno-0-121"></a> <span class="n">loop</span><span class="o">.</span><span class="n">run_in_executor</span><span class="p">(</span>
</span><span id="__span-0-122"><a id="__codelineno-0-122" name="__codelineno-0-122"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_executor</span><span class="p">,</span>
</span><span id="__span-0-123"><a id="__codelineno-0-123" name="__codelineno-0-123"></a> <span class="k">lambda</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">_execute_code</span><span class="p">(</span><span class="n">code</span><span class="p">),</span>
</span><span id="__span-0-124"><a id="__codelineno-0-124" name="__codelineno-0-124"></a> <span class="p">),</span>
</span><span id="__span-0-125"><a id="__codelineno-0-125" name="__codelineno-0-125"></a> <span class="n">timeout</span><span class="o">=</span><span class="n">timeout_ms</span> <span class="o">/</span> <span class="mi">1000</span><span class="p">,</span>
</span><span id="__span-0-126"><a id="__codelineno-0-126" name="__codelineno-0-126"></a> <span class="p">)</span>
</span><span id="__span-0-127"><a id="__codelineno-0-127" name="__codelineno-0-127"></a> <span class="k">except</span> <span class="ne">TimeoutError</span><span class="p">:</span>
</span><span id="__span-0-128"><a id="__codelineno-0-128" name="__codelineno-0-128"></a> <span class="k">return</span> <span class="n">ExecutionResult</span><span class="p">(</span>
</span><span id="__span-0-129"><a id="__codelineno-0-129" name="__codelineno-0-129"></a> <span class="n">success</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
</span><span id="__span-0-130"><a id="__codelineno-0-130" name="__codelineno-0-130"></a> <span class="n">result</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-131"><a id="__codelineno-0-131" name="__codelineno-0-131"></a> <span class="n">stdout</span><span class="o">=</span><span class="s2">""</span><span class="p">,</span>
</span><span id="__span-0-132"><a id="__codelineno-0-132" name="__codelineno-0-132"></a> <span class="n">stderr</span><span class="o">=</span><span class="sa">f</span><span class="s2">"Execution timed out after </span><span class="si">{</span><span class="n">timeout_ms</span><span class="si">}</span><span class="s2">ms"</span><span class="p">,</span>
</span><span id="__span-0-133"><a id="__codelineno-0-133" name="__codelineno-0-133"></a> <span class="n">execution_time_ms</span><span class="o">=</span><span class="nb">float</span><span class="p">(</span><span class="n">timeout_ms</span><span class="p">),</span>
</span><span id="__span-0-134"><a id="__codelineno-0-134" name="__codelineno-0-134"></a> <span class="n">error_type</span><span class="o">=</span><span class="s2">"TimeoutError"</span><span class="p">,</span>
</span><span id="__span-0-135"><a id="__codelineno-0-135" name="__codelineno-0-135"></a> <span class="n">error_traceback</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-136"><a id="__codelineno-0-136" name="__codelineno-0-136"></a> <span class="p">)</span>
</span><span id="__span-0-137"><a id="__codelineno-0-137" name="__codelineno-0-137"></a>
</span><span id="__span-0-138"><a id="__codelineno-0-138" name="__codelineno-0-138"></a> <span class="k">return</span> <span class="n">result</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> </div> </div> <div class="doc doc-object doc-function"> <h6 id="freecad_mcp.bridge.embedded.EmbeddedBridge.get_active_document" class="doc doc-heading"> <code class="highlight language-python"><span class="n">get_active_document</span><span class="p">()</span></code> <span class="doc doc-labels"> <small class="doc doc-label doc-label-async"><code>async</code></small> </span> <a href="#freecad_mcp.bridge.embedded.EmbeddedBridge.get_active_document" class="headerlink" title="Permanent link">¶</a></h6> <div class="doc doc-contents "> <p>Get the active document.</p> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/embedded.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-212">212</a></span>
<span class="normal"><a href="#__codelineno-0-213">213</a></span>
<span class="normal"><a href="#__codelineno-0-214">214</a></span>
<span class="normal"><a href="#__codelineno-0-215">215</a></span>
<span class="normal"><a href="#__codelineno-0-216">216</a></span>
<span class="normal"><a href="#__codelineno-0-217">217</a></span>
<span class="normal"><a href="#__codelineno-0-218">218</a></span>
<span class="normal"><a href="#__codelineno-0-219">219</a></span>
<span class="normal"><a href="#__codelineno-0-220">220</a></span>
<span class="normal"><a href="#__codelineno-0-221">221</a></span>
<span class="normal"><a href="#__codelineno-0-222">222</a></span>
<span class="normal"><a href="#__codelineno-0-223">223</a></span>
<span class="normal"><a href="#__codelineno-0-224">224</a></span>
<span class="normal"><a href="#__codelineno-0-225">225</a></span>
<span class="normal"><a href="#__codelineno-0-226">226</a></span>
<span class="normal"><a href="#__codelineno-0-227">227</a></span>
<span class="normal"><a href="#__codelineno-0-228">228</a></span>
<span class="normal"><a href="#__codelineno-0-229">229</a></span>
<span class="normal"><a href="#__codelineno-0-230">230</a></span>
<span class="normal"><a href="#__codelineno-0-231">231</a></span>
<span class="normal"><a href="#__codelineno-0-232">232</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-212"><a id="__codelineno-0-212" name="__codelineno-0-212"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">get_active_document</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">DocumentInfo</span> <span class="o">|</span> <span class="kc">None</span><span class="p">:</span>
</span><span id="__span-0-213"><a id="__codelineno-0-213" name="__codelineno-0-213"></a><span class="w"> </span><span class="sd">"""Get the active document."""</span>
</span><span id="__span-0-214"><a id="__codelineno-0-214" name="__codelineno-0-214"></a> <span class="n">result</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">execute_python</span><span class="p">(</span>
</span><span id="__span-0-215"><a id="__codelineno-0-215" name="__codelineno-0-215"></a><span class="w"> </span><span class="sd">"""</span>
</span><span id="__span-0-216"><a id="__codelineno-0-216" name="__codelineno-0-216"></a><span class="sd">doc = FreeCAD.ActiveDocument</span>
</span><span id="__span-0-217"><a id="__codelineno-0-217" name="__codelineno-0-217"></a><span class="sd">if doc:</span>
</span><span id="__span-0-218"><a id="__codelineno-0-218" name="__codelineno-0-218"></a><span class="sd"> _result_ = {</span>
</span><span id="__span-0-219"><a id="__codelineno-0-219" name="__codelineno-0-219"></a><span class="sd"> "name": doc.Name,</span>
</span><span id="__span-0-220"><a id="__codelineno-0-220" name="__codelineno-0-220"></a><span class="sd"> "path": doc.FileName or None,</span>
</span><span id="__span-0-221"><a id="__codelineno-0-221" name="__codelineno-0-221"></a><span class="sd"> "objects": [obj.Name for obj in doc.Objects],</span>
</span><span id="__span-0-222"><a id="__codelineno-0-222" name="__codelineno-0-222"></a><span class="sd"> "is_modified": doc.Modified if hasattr(doc, "Modified") else False,</span>
</span><span id="__span-0-223"><a id="__codelineno-0-223" name="__codelineno-0-223"></a><span class="sd"> "label": doc.Label,</span>
</span><span id="__span-0-224"><a id="__codelineno-0-224" name="__codelineno-0-224"></a><span class="sd"> }</span>
</span><span id="__span-0-225"><a id="__codelineno-0-225" name="__codelineno-0-225"></a><span class="sd">else:</span>
</span><span id="__span-0-226"><a id="__codelineno-0-226" name="__codelineno-0-226"></a><span class="sd"> _result_ = None</span>
</span><span id="__span-0-227"><a id="__codelineno-0-227" name="__codelineno-0-227"></a><span class="sd">"""</span>
</span><span id="__span-0-228"><a id="__codelineno-0-228" name="__codelineno-0-228"></a> <span class="p">)</span>
</span><span id="__span-0-229"><a id="__codelineno-0-229" name="__codelineno-0-229"></a>
</span><span id="__span-0-230"><a id="__codelineno-0-230" name="__codelineno-0-230"></a> <span class="k">if</span> <span class="n">result</span><span class="o">.</span><span class="n">success</span> <span class="ow">and</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">:</span>
</span><span id="__span-0-231"><a id="__codelineno-0-231" name="__codelineno-0-231"></a> <span class="k">return</span> <span class="n">DocumentInfo</span><span class="p">(</span><span class="o">**</span><span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">)</span>
</span><span id="__span-0-232"><a id="__codelineno-0-232" name="__codelineno-0-232"></a> <span class="k">return</span> <span class="kc">None</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> </div> </div> <div class="doc doc-object doc-function"> <h6 id="freecad_mcp.bridge.embedded.EmbeddedBridge.get_console_output" class="doc doc-heading"> <code class="highlight language-python"><span class="n">get_console_output</span><span class="p">(</span><span class="n">lines</span><span class="o">=</span><span class="mi">100</span><span class="p">)</span></code> <span class="doc doc-labels"> <small class="doc doc-label doc-label-async"><code>async</code></small> </span> <a href="#freecad_mcp.bridge.embedded.EmbeddedBridge.get_console_output" class="headerlink" title="Permanent link">¶</a></h6> <div class="doc doc-contents "> <p>Get recent console output.</p> <p>Note: In embedded mode, we don't have direct access to FreeCAD's console history, so we return an empty list or captured output.</p> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/embedded.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-287">287</a></span>
<span class="normal"><a href="#__codelineno-0-288">288</a></span>
<span class="normal"><a href="#__codelineno-0-289">289</a></span>
<span class="normal"><a href="#__codelineno-0-290">290</a></span>
<span class="normal"><a href="#__codelineno-0-291">291</a></span>
<span class="normal"><a href="#__codelineno-0-292">292</a></span>
<span class="normal"><a href="#__codelineno-0-293">293</a></span>
<span class="normal"><a href="#__codelineno-0-294">294</a></span>
<span class="normal"><a href="#__codelineno-0-295">295</a></span>
<span class="normal"><a href="#__codelineno-0-296">296</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-287"><a id="__codelineno-0-287" name="__codelineno-0-287"></a><span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">get_console_output</span><span class="p">(</span>
</span><span id="__span-0-288"><a id="__codelineno-0-288" name="__codelineno-0-288"></a> <span class="bp">self</span><span class="p">,</span>
</span><span id="__span-0-289"><a id="__codelineno-0-289" name="__codelineno-0-289"></a> <span class="n">lines</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">100</span><span class="p">,</span>
</span><span id="__span-0-290"><a id="__codelineno-0-290" name="__codelineno-0-290"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">list</span><span class="p">[</span><span class="nb">str</span><span class="p">]:</span>
</span><span id="__span-0-291"><a id="__codelineno-0-291" name="__codelineno-0-291"></a><span class="w"> </span><span class="sd">"""Get recent console output.</span>
</span><span id="__span-0-292"><a id="__codelineno-0-292" name="__codelineno-0-292"></a>
</span><span id="__span-0-293"><a id="__codelineno-0-293" name="__codelineno-0-293"></a><span class="sd"> Note: In embedded mode, we don't have direct access to FreeCAD's</span>
</span><span id="__span-0-294"><a id="__codelineno-0-294" name="__codelineno-0-294"></a><span class="sd"> console history, so we return an empty list or captured output.</span>
</span><span id="__span-0-295"><a id="__codelineno-0-295" name="__codelineno-0-295"></a><span class="sd"> """</span>
</span><span id="__span-0-296"><a id="__codelineno-0-296" name="__codelineno-0-296"></a> <span class="k">return</span> <span class="p">[]</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> </div> </div> <div class="doc doc-object doc-function"> <h6 id="freecad_mcp.bridge.embedded.EmbeddedBridge.get_documents" class="doc doc-heading"> <code class="highlight language-python"><span class="n">get_documents</span><span class="p">()</span></code> <span class="doc doc-labels"> <small class="doc doc-label doc-label-async"><code>async</code></small> </span> <a href="#freecad_mcp.bridge.embedded.EmbeddedBridge.get_documents" class="headerlink" title="Permanent link">¶</a></h6> <div class="doc doc-contents "> <p>Get list of open documents.</p> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/embedded.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-192">192</a></span>
<span class="normal"><a href="#__codelineno-0-193">193</a></span>
<span class="normal"><a href="#__codelineno-0-194">194</a></span>
<span class="normal"><a href="#__codelineno-0-195">195</a></span>
<span class="normal"><a href="#__codelineno-0-196">196</a></span>
<span class="normal"><a href="#__codelineno-0-197">197</a></span>
<span class="normal"><a href="#__codelineno-0-198">198</a></span>
<span class="normal"><a href="#__codelineno-0-199">199</a></span>
<span class="normal"><a href="#__codelineno-0-200">200</a></span>
<span class="normal"><a href="#__codelineno-0-201">201</a></span>
<span class="normal"><a href="#__codelineno-0-202">202</a></span>
<span class="normal"><a href="#__codelineno-0-203">203</a></span>
<span class="normal"><a href="#__codelineno-0-204">204</a></span>
<span class="normal"><a href="#__codelineno-0-205">205</a></span>
<span class="normal"><a href="#__codelineno-0-206">206</a></span>
<span class="normal"><a href="#__codelineno-0-207">207</a></span>
<span class="normal"><a href="#__codelineno-0-208">208</a></span>
<span class="normal"><a href="#__codelineno-0-209">209</a></span>
<span class="normal"><a href="#__codelineno-0-210">210</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-192"><a id="__codelineno-0-192" name="__codelineno-0-192"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">get_documents</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">list</span><span class="p">[</span><span class="n">DocumentInfo</span><span class="p">]:</span>
</span><span id="__span-0-193"><a id="__codelineno-0-193" name="__codelineno-0-193"></a><span class="w"> </span><span class="sd">"""Get list of open documents."""</span>
</span><span id="__span-0-194"><a id="__codelineno-0-194" name="__codelineno-0-194"></a> <span class="n">result</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">execute_python</span><span class="p">(</span>
</span><span id="__span-0-195"><a id="__codelineno-0-195" name="__codelineno-0-195"></a><span class="w"> </span><span class="sd">"""</span>
</span><span id="__span-0-196"><a id="__codelineno-0-196" name="__codelineno-0-196"></a><span class="sd">_result_ = []</span>
</span><span id="__span-0-197"><a id="__codelineno-0-197" name="__codelineno-0-197"></a><span class="sd">for doc in FreeCAD.listDocuments().values():</span>
</span><span id="__span-0-198"><a id="__codelineno-0-198" name="__codelineno-0-198"></a><span class="sd"> _result_.append({</span>
</span><span id="__span-0-199"><a id="__codelineno-0-199" name="__codelineno-0-199"></a><span class="sd"> "name": doc.Name,</span>
</span><span id="__span-0-200"><a id="__codelineno-0-200" name="__codelineno-0-200"></a><span class="sd"> "path": doc.FileName or None,</span>
</span><span id="__span-0-201"><a id="__codelineno-0-201" name="__codelineno-0-201"></a><span class="sd"> "objects": [obj.Name for obj in doc.Objects],</span>
</span><span id="__span-0-202"><a id="__codelineno-0-202" name="__codelineno-0-202"></a><span class="sd"> "is_modified": doc.Modified if hasattr(doc, "Modified") else False,</span>
</span><span id="__span-0-203"><a id="__codelineno-0-203" name="__codelineno-0-203"></a><span class="sd"> "label": doc.Label,</span>
</span><span id="__span-0-204"><a id="__codelineno-0-204" name="__codelineno-0-204"></a><span class="sd"> })</span>
</span><span id="__span-0-205"><a id="__codelineno-0-205" name="__codelineno-0-205"></a><span class="sd">"""</span>
</span><span id="__span-0-206"><a id="__codelineno-0-206" name="__codelineno-0-206"></a> <span class="p">)</span>
</span><span id="__span-0-207"><a id="__codelineno-0-207" name="__codelineno-0-207"></a>
</span><span id="__span-0-208"><a id="__codelineno-0-208" name="__codelineno-0-208"></a> <span class="k">if</span> <span class="n">result</span><span class="o">.</span><span class="n">success</span> <span class="ow">and</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">:</span>
</span><span id="__span-0-209"><a id="__codelineno-0-209" name="__codelineno-0-209"></a> <span class="k">return</span> <span class="p">[</span><span class="n">DocumentInfo</span><span class="p">(</span><span class="o">**</span><span class="n">doc</span><span class="p">)</span> <span class="k">for</span> <span class="n">doc</span> <span class="ow">in</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">]</span>
</span><span id="__span-0-210"><a id="__codelineno-0-210" name="__codelineno-0-210"></a> <span class="k">return</span> <span class="p">[]</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> </div> </div> <div class="doc doc-object doc-function"> <h6 id="freecad_mcp.bridge.embedded.EmbeddedBridge.get_freecad_version" class="doc doc-heading"> <code class="highlight language-python"><span class="n">get_freecad_version</span><span class="p">()</span></code> <span class="doc doc-labels"> <small class="doc doc-label doc-label-async"><code>async</code></small> </span> <a href="#freecad_mcp.bridge.embedded.EmbeddedBridge.get_freecad_version" class="headerlink" title="Permanent link">¶</a></h6> <div class="doc doc-contents "> <p>Get FreeCAD version information.</p> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/embedded.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-298">298</a></span>
<span class="normal"><a href="#__codelineno-0-299">299</a></span>
<span class="normal"><a href="#__codelineno-0-300">300</a></span>
<span class="normal"><a href="#__codelineno-0-301">301</a></span>
<span class="normal"><a href="#__codelineno-0-302">302</a></span>
<span class="normal"><a href="#__codelineno-0-303">303</a></span>
<span class="normal"><a href="#__codelineno-0-304">304</a></span>
<span class="normal"><a href="#__codelineno-0-305">305</a></span>
<span class="normal"><a href="#__codelineno-0-306">306</a></span>
<span class="normal"><a href="#__codelineno-0-307">307</a></span>
<span class="normal"><a href="#__codelineno-0-308">308</a></span>
<span class="normal"><a href="#__codelineno-0-309">309</a></span>
<span class="normal"><a href="#__codelineno-0-310">310</a></span>
<span class="normal"><a href="#__codelineno-0-311">311</a></span>
<span class="normal"><a href="#__codelineno-0-312">312</a></span>
<span class="normal"><a href="#__codelineno-0-313">313</a></span>
<span class="normal"><a href="#__codelineno-0-314">314</a></span>
<span class="normal"><a href="#__codelineno-0-315">315</a></span>
<span class="normal"><a href="#__codelineno-0-316">316</a></span>
<span class="normal"><a href="#__codelineno-0-317">317</a></span>
<span class="normal"><a href="#__codelineno-0-318">318</a></span>
<span class="normal"><a href="#__codelineno-0-319">319</a></span>
<span class="normal"><a href="#__codelineno-0-320">320</a></span>
<span class="normal"><a href="#__codelineno-0-321">321</a></span>
<span class="normal"><a href="#__codelineno-0-322">322</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-298"><a id="__codelineno-0-298" name="__codelineno-0-298"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">get_freecad_version</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Any</span><span class="p">]:</span>
</span><span id="__span-0-299"><a id="__codelineno-0-299" name="__codelineno-0-299"></a><span class="w"> </span><span class="sd">"""Get FreeCAD version information."""</span>
</span><span id="__span-0-300"><a id="__codelineno-0-300" name="__codelineno-0-300"></a> <span class="n">result</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">execute_python</span><span class="p">(</span>
</span><span id="__span-0-301"><a id="__codelineno-0-301" name="__codelineno-0-301"></a><span class="w"> </span><span class="sd">"""</span>
</span><span id="__span-0-302"><a id="__codelineno-0-302" name="__codelineno-0-302"></a><span class="sd">import sys</span>
</span><span id="__span-0-303"><a id="__codelineno-0-303" name="__codelineno-0-303"></a><span class="sd">_result_ = {</span>
</span><span id="__span-0-304"><a id="__codelineno-0-304" name="__codelineno-0-304"></a><span class="sd"> "version": ".".join(str(x) for x in FreeCAD.Version()[:3]),</span>
</span><span id="__span-0-305"><a id="__codelineno-0-305" name="__codelineno-0-305"></a><span class="sd"> "version_tuple": FreeCAD.Version()[:3],</span>
</span><span id="__span-0-306"><a id="__codelineno-0-306" name="__codelineno-0-306"></a><span class="sd"> "build_date": FreeCAD.Version()[3] if len(FreeCAD.Version()) &gt; 3 else "unknown",</span>
</span><span id="__span-0-307"><a id="__codelineno-0-307" name="__codelineno-0-307"></a><span class="sd"> "python_version": sys.version,</span>
</span><span id="__span-0-308"><a id="__codelineno-0-308" name="__codelineno-0-308"></a><span class="sd"> "gui_available": hasattr(FreeCAD, "GuiUp") and FreeCAD.GuiUp,</span>
</span><span id="__span-0-309"><a id="__codelineno-0-309" name="__codelineno-0-309"></a><span class="sd">}</span>
</span><span id="__span-0-310"><a id="__codelineno-0-310" name="__codelineno-0-310"></a><span class="sd">"""</span>
</span><span id="__span-0-311"><a id="__codelineno-0-311" name="__codelineno-0-311"></a> <span class="p">)</span>
</span><span id="__span-0-312"><a id="__codelineno-0-312" name="__codelineno-0-312"></a>
</span><span id="__span-0-313"><a id="__codelineno-0-313" name="__codelineno-0-313"></a> <span class="k">if</span> <span class="n">result</span><span class="o">.</span><span class="n">success</span> <span class="ow">and</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">:</span>
</span><span id="__span-0-314"><a id="__codelineno-0-314" name="__codelineno-0-314"></a> <span class="k">return</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span>
</span><span id="__span-0-315"><a id="__codelineno-0-315" name="__codelineno-0-315"></a>
</span><span id="__span-0-316"><a id="__codelineno-0-316" name="__codelineno-0-316"></a> <span class="k">return</span> <span class="p">{</span>
</span><span id="__span-0-317"><a id="__codelineno-0-317" name="__codelineno-0-317"></a> <span class="s2">"version"</span><span class="p">:</span> <span class="s2">"unknown"</span><span class="p">,</span>
</span><span id="__span-0-318"><a id="__codelineno-0-318" name="__codelineno-0-318"></a> <span class="s2">"version_tuple"</span><span class="p">:</span> <span class="p">[],</span>
</span><span id="__span-0-319"><a id="__codelineno-0-319" name="__codelineno-0-319"></a> <span class="s2">"build_date"</span><span class="p">:</span> <span class="s2">"unknown"</span><span class="p">,</span>
</span><span id="__span-0-320"><a id="__codelineno-0-320" name="__codelineno-0-320"></a> <span class="s2">"python_version"</span><span class="p">:</span> <span class="n">sys</span><span class="o">.</span><span class="n">version</span><span class="p">,</span>
</span><span id="__span-0-321"><a id="__codelineno-0-321" name="__codelineno-0-321"></a> <span class="s2">"gui_available"</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span>
</span><span id="__span-0-322"><a id="__codelineno-0-322" name="__codelineno-0-322"></a> <span class="p">}</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> </div> </div> <div class="doc doc-object doc-function"> <h6 id="freecad_mcp.bridge.embedded.EmbeddedBridge.get_macros" class="doc doc-heading"> <code class="highlight language-python"><span class="n">get_macros</span><span class="p">()</span></code> <span class="doc doc-labels"> <small class="doc doc-label doc-label-async"><code>async</code></small> </span> <a href="#freecad_mcp.bridge.embedded.EmbeddedBridge.get_macros" class="headerlink" title="Permanent link">¶</a></h6> <div class="doc doc-contents "> <p>Get list of available macros.</p> <p><span class="doc-section-title">Returns:</span></p> <table> <thead> <tr> <th>Type</th> <th>Description</th> </tr> </thead> <tbody> <tr class="doc-section-item"> <td> <code><span title="list">list</span>[<a class="autorefs autorefs-internal" title="MacroInfo
dataclass
(freecad_mcp.bridge.base.MacroInfo)" href="#freecad_mcp.bridge.base.MacroInfo">MacroInfo</a>]</code> </td> <td> <div class="doc-md-description"> <p>List of MacroInfo for each macro.</p> </div> </td> </tr> </tbody> </table> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/embedded.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-864">864</a></span>
<span class="normal"><a href="#__codelineno-0-865">865</a></span>
<span class="normal"><a href="#__codelineno-0-866">866</a></span>
<span class="normal"><a href="#__codelineno-0-867">867</a></span>
<span class="normal"><a href="#__codelineno-0-868">868</a></span>
<span class="normal"><a href="#__codelineno-0-869">869</a></span>
<span class="normal"><a href="#__codelineno-0-870">870</a></span>
<span class="normal"><a href="#__codelineno-0-871">871</a></span>
<span class="normal"><a href="#__codelineno-0-872">872</a></span>
<span class="normal"><a href="#__codelineno-0-873">873</a></span>
<span class="normal"><a href="#__codelineno-0-874">874</a></span>
<span class="normal"><a href="#__codelineno-0-875">875</a></span>
<span class="normal"><a href="#__codelineno-0-876">876</a></span>
<span class="normal"><a href="#__codelineno-0-877">877</a></span>
<span class="normal"><a href="#__codelineno-0-878">878</a></span>
<span class="normal"><a href="#__codelineno-0-879">879</a></span>
<span class="normal"><a href="#__codelineno-0-880">880</a></span>
<span class="normal"><a href="#__codelineno-0-881">881</a></span>
<span class="normal"><a href="#__codelineno-0-882">882</a></span>
<span class="normal"><a href="#__codelineno-0-883">883</a></span>
<span class="normal"><a href="#__codelineno-0-884">884</a></span>
<span class="normal"><a href="#__codelineno-0-885">885</a></span>
<span class="normal"><a href="#__codelineno-0-886">886</a></span>
<span class="normal"><a href="#__codelineno-0-887">887</a></span>
<span class="normal"><a href="#__codelineno-0-888">888</a></span>
<span class="normal"><a href="#__codelineno-0-889">889</a></span>
<span class="normal"><a href="#__codelineno-0-890">890</a></span>
<span class="normal"><a href="#__codelineno-0-891">891</a></span>
<span class="normal"><a href="#__codelineno-0-892">892</a></span>
<span class="normal"><a href="#__codelineno-0-893">893</a></span>
<span class="normal"><a href="#__codelineno-0-894">894</a></span>
<span class="normal"><a href="#__codelineno-0-895">895</a></span>
<span class="normal"><a href="#__codelineno-0-896">896</a></span>
<span class="normal"><a href="#__codelineno-0-897">897</a></span>
<span class="normal"><a href="#__codelineno-0-898">898</a></span>
<span class="normal"><a href="#__codelineno-0-899">899</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-864"><a id="__codelineno-0-864" name="__codelineno-0-864"></a><span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">get_macros</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">list</span><span class="p">[</span><span class="n">MacroInfo</span><span class="p">]:</span>
</span><span id="__span-0-865"><a id="__codelineno-0-865" name="__codelineno-0-865"></a><span class="w"> </span><span class="sd">"""Get list of available macros.</span>
</span><span id="__span-0-866"><a id="__codelineno-0-866" name="__codelineno-0-866"></a>
</span><span id="__span-0-867"><a id="__codelineno-0-867" name="__codelineno-0-867"></a><span class="sd"> Returns:</span>
</span><span id="__span-0-868"><a id="__codelineno-0-868" name="__codelineno-0-868"></a><span class="sd"> List of MacroInfo for each macro.</span>
</span><span id="__span-0-869"><a id="__codelineno-0-869" name="__codelineno-0-869"></a><span class="sd"> """</span>
</span><span id="__span-0-870"><a id="__codelineno-0-870" name="__codelineno-0-870"></a> <span class="n">macro_path</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_macro_path</span><span class="p">()</span>
</span><span id="__span-0-871"><a id="__codelineno-0-871" name="__codelineno-0-871"></a>
</span><span id="__span-0-872"><a id="__codelineno-0-872" name="__codelineno-0-872"></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">macro_path</span><span class="o">.</span><span class="n">exists</span><span class="p">():</span>
</span><span id="__span-0-873"><a id="__codelineno-0-873" name="__codelineno-0-873"></a> <span class="k">return</span> <span class="p">[]</span>
</span><span id="__span-0-874"><a id="__codelineno-0-874" name="__codelineno-0-874"></a>
</span><span id="__span-0-875"><a id="__codelineno-0-875" name="__codelineno-0-875"></a> <span class="n">macros</span> <span class="o">=</span> <span class="p">[]</span>
</span><span id="__span-0-876"><a id="__codelineno-0-876" name="__codelineno-0-876"></a> <span class="k">for</span> <span class="n">macro_file</span> <span class="ow">in</span> <span class="n">macro_path</span><span class="o">.</span><span class="n">glob</span><span class="p">(</span><span class="s2">"*.FCMacro"</span><span class="p">):</span>
</span><span id="__span-0-877"><a id="__codelineno-0-877" name="__codelineno-0-877"></a> <span class="n">description</span> <span class="o">=</span> <span class="s2">""</span>
</span><span id="__span-0-878"><a id="__codelineno-0-878" name="__codelineno-0-878"></a> <span class="k">try</span><span class="p">:</span>
</span><span id="__span-0-879"><a id="__codelineno-0-879" name="__codelineno-0-879"></a> <span class="n">content</span> <span class="o">=</span> <span class="n">macro_file</span><span class="o">.</span><span class="n">read_text</span><span class="p">()</span>
</span><span id="__span-0-880"><a id="__codelineno-0-880" name="__codelineno-0-880"></a> <span class="c1"># Extract description from first comment block</span>
</span><span id="__span-0-881"><a id="__codelineno-0-881" name="__codelineno-0-881"></a> <span class="k">for</span> <span class="n">line</span> <span class="ow">in</span> <span class="n">content</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s2">"</span><span class="se">\n</span><span class="s2">"</span><span class="p">):</span>
</span><span id="__span-0-882"><a id="__codelineno-0-882" name="__codelineno-0-882"></a> <span class="k">if</span> <span class="n">line</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s2">"#"</span><span class="p">):</span>
</span><span id="__span-0-883"><a id="__codelineno-0-883" name="__codelineno-0-883"></a> <span class="n">desc_line</span> <span class="o">=</span> <span class="n">line</span><span class="o">.</span><span class="n">lstrip</span><span class="p">(</span><span class="s2">"#"</span><span class="p">)</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span>
</span><span id="__span-0-884"><a id="__codelineno-0-884" name="__codelineno-0-884"></a> <span class="k">if</span> <span class="n">desc_line</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">desc_line</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s2">"!"</span><span class="p">):</span>
</span><span id="__span-0-885"><a id="__codelineno-0-885" name="__codelineno-0-885"></a> <span class="n">description</span> <span class="o">=</span> <span class="n">desc_line</span>
</span><span id="__span-0-886"><a id="__codelineno-0-886" name="__codelineno-0-886"></a> <span class="k">break</span>
</span><span id="__span-0-887"><a id="__codelineno-0-887" name="__codelineno-0-887"></a> <span class="k">except</span> <span class="ne">Exception</span><span class="p">:</span>
</span><span id="__span-0-888"><a id="__codelineno-0-888" name="__codelineno-0-888"></a> <span class="k">pass</span>
</span><span id="__span-0-889"><a id="__codelineno-0-889" name="__codelineno-0-889"></a>
</span><span id="__span-0-890"><a id="__codelineno-0-890" name="__codelineno-0-890"></a> <span class="n">macros</span><span class="o">.</span><span class="n">append</span><span class="p">(</span>
</span><span id="__span-0-891"><a id="__codelineno-0-891" name="__codelineno-0-891"></a> <span class="n">MacroInfo</span><span class="p">(</span>
</span><span id="__span-0-892"><a id="__codelineno-0-892" name="__codelineno-0-892"></a> <span class="n">name</span><span class="o">=</span><span class="n">macro_file</span><span class="o">.</span><span class="n">stem</span><span class="p">,</span>
</span><span id="__span-0-893"><a id="__codelineno-0-893" name="__codelineno-0-893"></a> <span class="n">path</span><span class="o">=</span><span class="nb">str</span><span class="p">(</span><span class="n">macro_file</span><span class="p">),</span>
</span><span id="__span-0-894"><a id="__codelineno-0-894" name="__codelineno-0-894"></a> <span class="n">description</span><span class="o">=</span><span class="n">description</span><span class="p">,</span>
</span><span id="__span-0-895"><a id="__codelineno-0-895" name="__codelineno-0-895"></a> <span class="n">is_system</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
</span><span id="__span-0-896"><a id="__codelineno-0-896" name="__codelineno-0-896"></a> <span class="p">)</span>
</span><span id="__span-0-897"><a id="__codelineno-0-897" name="__codelineno-0-897"></a> <span class="p">)</span>
</span><span id="__span-0-898"><a id="__codelineno-0-898" name="__codelineno-0-898"></a>
</span><span id="__span-0-899"><a id="__codelineno-0-899" name="__codelineno-0-899"></a> <span class="k">return</span> <span class="n">macros</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> </div> </div> <div class="doc doc-object doc-function"> <h6 id="freecad_mcp.bridge.embedded.EmbeddedBridge.get_object" class="doc doc-heading"> <code class="highlight language-python"><span class="n">get_object</span><span class="p">(</span><span class="n">obj_name</span><span class="p">,</span> <span class="n">doc_name</span><span class="o">=</span><span class="kc">None</span><span class="p">)</span></code> <span class="doc doc-labels"> <small class="doc doc-label doc-label-async"><code>async</code></small> </span> <a href="#freecad_mcp.bridge.embedded.EmbeddedBridge.get_object" class="headerlink" title="Permanent link">¶</a></h6> <div class="doc doc-contents "> <p>Get detailed object information.</p> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/embedded.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-234">234</a></span>
<span class="normal"><a href="#__codelineno-0-235">235</a></span>
<span class="normal"><a href="#__codelineno-0-236">236</a></span>
<span class="normal"><a href="#__codelineno-0-237">237</a></span>
<span class="normal"><a href="#__codelineno-0-238">238</a></span>
<span class="normal"><a href="#__codelineno-0-239">239</a></span>
<span class="normal"><a href="#__codelineno-0-240">240</a></span>
<span class="normal"><a href="#__codelineno-0-241">241</a></span>
<span class="normal"><a href="#__codelineno-0-242">242</a></span>
<span class="normal"><a href="#__codelineno-0-243">243</a></span>
<span class="normal"><a href="#__codelineno-0-244">244</a></span>
<span class="normal"><a href="#__codelineno-0-245">245</a></span>
<span class="normal"><a href="#__codelineno-0-246">246</a></span>
<span class="normal"><a href="#__codelineno-0-247">247</a></span>
<span class="normal"><a href="#__codelineno-0-248">248</a></span>
<span class="normal"><a href="#__codelineno-0-249">249</a></span>
<span class="normal"><a href="#__codelineno-0-250">250</a></span>
<span class="normal"><a href="#__codelineno-0-251">251</a></span>
<span class="normal"><a href="#__codelineno-0-252">252</a></span>
<span class="normal"><a href="#__codelineno-0-253">253</a></span>
<span class="normal"><a href="#__codelineno-0-254">254</a></span>
<span class="normal"><a href="#__codelineno-0-255">255</a></span>
<span class="normal"><a href="#__codelineno-0-256">256</a></span>
<span class="normal"><a href="#__codelineno-0-257">257</a></span>
<span class="normal"><a href="#__codelineno-0-258">258</a></span>
<span class="normal"><a href="#__codelineno-0-259">259</a></span>
<span class="normal"><a href="#__codelineno-0-260">260</a></span>
<span class="normal"><a href="#__codelineno-0-261">261</a></span>
<span class="normal"><a href="#__codelineno-0-262">262</a></span>
<span class="normal"><a href="#__codelineno-0-263">263</a></span>
<span class="normal"><a href="#__codelineno-0-264">264</a></span>
<span class="normal"><a href="#__codelineno-0-265">265</a></span>
<span class="normal"><a href="#__codelineno-0-266">266</a></span>
<span class="normal"><a href="#__codelineno-0-267">267</a></span>
<span class="normal"><a href="#__codelineno-0-268">268</a></span>
<span class="normal"><a href="#__codelineno-0-269">269</a></span>
<span class="normal"><a href="#__codelineno-0-270">270</a></span>
<span class="normal"><a href="#__codelineno-0-271">271</a></span>
<span class="normal"><a href="#__codelineno-0-272">272</a></span>
<span class="normal"><a href="#__codelineno-0-273">273</a></span>
<span class="normal"><a href="#__codelineno-0-274">274</a></span>
<span class="normal"><a href="#__codelineno-0-275">275</a></span>
<span class="normal"><a href="#__codelineno-0-276">276</a></span>
<span class="normal"><a href="#__codelineno-0-277">277</a></span>
<span class="normal"><a href="#__codelineno-0-278">278</a></span>
<span class="normal"><a href="#__codelineno-0-279">279</a></span>
<span class="normal"><a href="#__codelineno-0-280">280</a></span>
<span class="normal"><a href="#__codelineno-0-281">281</a></span>
<span class="normal"><a href="#__codelineno-0-282">282</a></span>
<span class="normal"><a href="#__codelineno-0-283">283</a></span>
<span class="normal"><a href="#__codelineno-0-284">284</a></span>
<span class="normal"><a href="#__codelineno-0-285">285</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-234"><a id="__codelineno-0-234" name="__codelineno-0-234"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">get_object</span><span class="p">(</span>
</span><span id="__span-0-235"><a id="__codelineno-0-235" name="__codelineno-0-235"></a> <span class="bp">self</span><span class="p">,</span>
</span><span id="__span-0-236"><a id="__codelineno-0-236" name="__codelineno-0-236"></a> <span class="n">obj_name</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span>
</span><span id="__span-0-237"><a id="__codelineno-0-237" name="__codelineno-0-237"></a> <span class="n">doc_name</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-238"><a id="__codelineno-0-238" name="__codelineno-0-238"></a> <span class="p">)</span> <span class="o">-&gt;</span> <span class="n">ObjectInfo</span><span class="p">:</span>
</span><span id="__span-0-239"><a id="__codelineno-0-239" name="__codelineno-0-239"></a><span class="w"> </span><span class="sd">"""Get detailed object information."""</span>
</span><span id="__span-0-240"><a id="__codelineno-0-240" name="__codelineno-0-240"></a> <span class="n">result</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">execute_python</span><span class="p">(</span>
</span><span id="__span-0-241"><a id="__codelineno-0-241" name="__codelineno-0-241"></a> <span class="sa">f</span><span class="s2">"""</span>
</span><span id="__span-0-242"><a id="__codelineno-0-242" name="__codelineno-0-242"></a><span class="s2">doc = FreeCAD.ActiveDocument if </span><span class="si">{</span><span class="n">doc_name</span><span class="si">!r}</span><span class="s2"> is None else FreeCAD.getDocument(</span><span class="si">{</span><span class="n">doc_name</span><span class="si">!r}</span><span class="s2">)</span>
</span><span id="__span-0-243"><a id="__codelineno-0-243" name="__codelineno-0-243"></a><span class="s2">if doc is None:</span>
</span><span id="__span-0-244"><a id="__codelineno-0-244" name="__codelineno-0-244"></a><span class="s2"> raise ValueError("No document found")</span>
</span><span id="__span-0-245"><a id="__codelineno-0-245" name="__codelineno-0-245"></a>
</span><span id="__span-0-246"><a id="__codelineno-0-246" name="__codelineno-0-246"></a><span class="s2">obj = doc.getObject(</span><span class="si">{</span><span class="n">obj_name</span><span class="si">!r}</span><span class="s2">)</span>
</span><span id="__span-0-247"><a id="__codelineno-0-247" name="__codelineno-0-247"></a><span class="s2">if obj is None:</span>
</span><span id="__span-0-248"><a id="__codelineno-0-248" name="__codelineno-0-248"></a><span class="s2"> raise ValueError(f"Object not found: </span><span class="si">{</span><span class="n">obj_name</span><span class="si">!r}</span><span class="s2">")</span>
</span><span id="__span-0-249"><a id="__codelineno-0-249" name="__codelineno-0-249"></a>
</span><span id="__span-0-250"><a id="__codelineno-0-250" name="__codelineno-0-250"></a><span class="s2">props = </span><span class="se">{{}}</span>
</span><span id="__span-0-251"><a id="__codelineno-0-251" name="__codelineno-0-251"></a><span class="s2">for prop in obj.PropertiesList:</span>
</span><span id="__span-0-252"><a id="__codelineno-0-252" name="__codelineno-0-252"></a><span class="s2"> try:</span>
</span><span id="__span-0-253"><a id="__codelineno-0-253" name="__codelineno-0-253"></a><span class="s2"> val = getattr(obj, prop)</span>
</span><span id="__span-0-254"><a id="__codelineno-0-254" name="__codelineno-0-254"></a><span class="s2"> if hasattr(val, '__class__') and val.__class__.__module__ != 'builtins':</span>
</span><span id="__span-0-255"><a id="__codelineno-0-255" name="__codelineno-0-255"></a><span class="s2"> val = str(val)</span>
</span><span id="__span-0-256"><a id="__codelineno-0-256" name="__codelineno-0-256"></a><span class="s2"> props[prop] = val</span>
</span><span id="__span-0-257"><a id="__codelineno-0-257" name="__codelineno-0-257"></a><span class="s2"> except Exception:</span>
</span><span id="__span-0-258"><a id="__codelineno-0-258" name="__codelineno-0-258"></a><span class="s2"> props[prop] = "&lt;unreadable&gt;"</span>
</span><span id="__span-0-259"><a id="__codelineno-0-259" name="__codelineno-0-259"></a>
</span><span id="__span-0-260"><a id="__codelineno-0-260" name="__codelineno-0-260"></a><span class="s2">shape_info = None</span>
</span><span id="__span-0-261"><a id="__codelineno-0-261" name="__codelineno-0-261"></a><span class="s2">if hasattr(obj, "Shape"):</span>
</span><span id="__span-0-262"><a id="__codelineno-0-262" name="__codelineno-0-262"></a><span class="s2"> shape = obj.Shape</span>
</span><span id="__span-0-263"><a id="__codelineno-0-263" name="__codelineno-0-263"></a><span class="s2"> shape_info = </span><span class="se">{{</span>
</span><span id="__span-0-264"><a id="__codelineno-0-264" name="__codelineno-0-264"></a><span class="s2"> "type": shape.ShapeType,</span>
</span><span id="__span-0-265"><a id="__codelineno-0-265" name="__codelineno-0-265"></a><span class="s2"> "volume": shape.Volume if hasattr(shape, "Volume") else None,</span>
</span><span id="__span-0-266"><a id="__codelineno-0-266" name="__codelineno-0-266"></a><span class="s2"> "area": shape.Area if hasattr(shape, "Area") else None,</span>
</span><span id="__span-0-267"><a id="__codelineno-0-267" name="__codelineno-0-267"></a><span class="s2"> "is_valid": shape.isValid(),</span>
</span><span id="__span-0-268"><a id="__codelineno-0-268" name="__codelineno-0-268"></a><span class="s2"> </span><span class="se">}}</span>
</span><span id="__span-0-269"><a id="__codelineno-0-269" name="__codelineno-0-269"></a>
</span><span id="__span-0-270"><a id="__codelineno-0-270" name="__codelineno-0-270"></a><span class="s2">_result_ = </span><span class="se">{{</span>
</span><span id="__span-0-271"><a id="__codelineno-0-271" name="__codelineno-0-271"></a><span class="s2"> "name": obj.Name,</span>
</span><span id="__span-0-272"><a id="__codelineno-0-272" name="__codelineno-0-272"></a><span class="s2"> "label": obj.Label,</span>
</span><span id="__span-0-273"><a id="__codelineno-0-273" name="__codelineno-0-273"></a><span class="s2"> "type_id": obj.TypeId,</span>
</span><span id="__span-0-274"><a id="__codelineno-0-274" name="__codelineno-0-274"></a><span class="s2"> "properties": props,</span>
</span><span id="__span-0-275"><a id="__codelineno-0-275" name="__codelineno-0-275"></a><span class="s2"> "shape_info": shape_info,</span>
</span><span id="__span-0-276"><a id="__codelineno-0-276" name="__codelineno-0-276"></a><span class="s2"> "children": [c.Name for c in obj.OutList] if hasattr(obj, "OutList") else [],</span>
</span><span id="__span-0-277"><a id="__codelineno-0-277" name="__codelineno-0-277"></a><span class="se">}}</span>
</span><span id="__span-0-278"><a id="__codelineno-0-278" name="__codelineno-0-278"></a><span class="s2">"""</span>
</span><span id="__span-0-279"><a id="__codelineno-0-279" name="__codelineno-0-279"></a> <span class="p">)</span>
</span><span id="__span-0-280"><a id="__codelineno-0-280" name="__codelineno-0-280"></a>
</span><span id="__span-0-281"><a id="__codelineno-0-281" name="__codelineno-0-281"></a> <span class="k">if</span> <span class="n">result</span><span class="o">.</span><span class="n">success</span> <span class="ow">and</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">:</span>
</span><span id="__span-0-282"><a id="__codelineno-0-282" name="__codelineno-0-282"></a> <span class="k">return</span> <span class="n">ObjectInfo</span><span class="p">(</span><span class="o">**</span><span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">)</span>
</span><span id="__span-0-283"><a id="__codelineno-0-283" name="__codelineno-0-283"></a>
</span><span id="__span-0-284"><a id="__codelineno-0-284" name="__codelineno-0-284"></a> <span class="n">error_msg</span> <span class="o">=</span> <span class="n">result</span><span class="o">.</span><span class="n">error_traceback</span> <span class="ow">or</span> <span class="s2">"Failed to get object"</span>
</span><span id="__span-0-285"><a id="__codelineno-0-285" name="__codelineno-0-285"></a> <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="n">error_msg</span><span class="p">)</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> </div> </div> <div class="doc doc-object doc-function"> <h6 id="freecad_mcp.bridge.embedded.EmbeddedBridge.get_objects" class="doc doc-heading"> <code class="highlight language-python"><span class="n">get_objects</span><span class="p">(</span><span class="n">doc_name</span><span class="o">=</span><span class="kc">None</span><span class="p">)</span></code> <span class="doc doc-labels"> <small class="doc doc-label doc-label-async"><code>async</code></small> </span> <a href="#freecad_mcp.bridge.embedded.EmbeddedBridge.get_objects" class="headerlink" title="Permanent link">¶</a></h6> <div class="doc doc-contents "> <p>Get all objects in a document.</p> <p><span class="doc-section-title">Parameters:</span></p> <table> <thead> <tr> <th>Name</th> <th>Type</th> <th>Description</th> <th>Default</th> </tr> </thead> <tbody> <tr class="doc-section-item"> <td> <code>doc_name</code> </td> <td> <code><span title="str">str</span> | None</code> </td> <td> <div class="doc-md-description"> <p>Document name (uses active if None).</p> </div> </td> <td> <code>None</code> </td> </tr> </tbody> </table> <p><span class="doc-section-title">Returns:</span></p> <table> <thead> <tr> <th>Type</th> <th>Description</th> </tr> </thead> <tbody> <tr class="doc-section-item"> <td> <code><span title="list">list</span>[<a class="autorefs autorefs-internal" title="ObjectInfo
dataclass
(freecad_mcp.bridge.base.ObjectInfo)" href="#freecad_mcp.bridge.base.ObjectInfo">ObjectInfo</a>]</code> </td> <td> <div class="doc-md-description"> <p>List of ObjectInfo for each object.</p> </div> </td> </tr> </tbody> </table> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/embedded.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-525">525</a></span>
<span class="normal"><a href="#__codelineno-0-526">526</a></span>
<span class="normal"><a href="#__codelineno-0-527">527</a></span>
<span class="normal"><a href="#__codelineno-0-528">528</a></span>
<span class="normal"><a href="#__codelineno-0-529">529</a></span>
<span class="normal"><a href="#__codelineno-0-530">530</a></span>
<span class="normal"><a href="#__codelineno-0-531">531</a></span>
<span class="normal"><a href="#__codelineno-0-532">532</a></span>
<span class="normal"><a href="#__codelineno-0-533">533</a></span>
<span class="normal"><a href="#__codelineno-0-534">534</a></span>
<span class="normal"><a href="#__codelineno-0-535">535</a></span>
<span class="normal"><a href="#__codelineno-0-536">536</a></span>
<span class="normal"><a href="#__codelineno-0-537">537</a></span>
<span class="normal"><a href="#__codelineno-0-538">538</a></span>
<span class="normal"><a href="#__codelineno-0-539">539</a></span>
<span class="normal"><a href="#__codelineno-0-540">540</a></span>
<span class="normal"><a href="#__codelineno-0-541">541</a></span>
<span class="normal"><a href="#__codelineno-0-542">542</a></span>
<span class="normal"><a href="#__codelineno-0-543">543</a></span>
<span class="normal"><a href="#__codelineno-0-544">544</a></span>
<span class="normal"><a href="#__codelineno-0-545">545</a></span>
<span class="normal"><a href="#__codelineno-0-546">546</a></span>
<span class="normal"><a href="#__codelineno-0-547">547</a></span>
<span class="normal"><a href="#__codelineno-0-548">548</a></span>
<span class="normal"><a href="#__codelineno-0-549">549</a></span>
<span class="normal"><a href="#__codelineno-0-550">550</a></span>
<span class="normal"><a href="#__codelineno-0-551">551</a></span>
<span class="normal"><a href="#__codelineno-0-552">552</a></span>
<span class="normal"><a href="#__codelineno-0-553">553</a></span>
<span class="normal"><a href="#__codelineno-0-554">554</a></span>
<span class="normal"><a href="#__codelineno-0-555">555</a></span>
<span class="normal"><a href="#__codelineno-0-556">556</a></span>
<span class="normal"><a href="#__codelineno-0-557">557</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-525"><a id="__codelineno-0-525" name="__codelineno-0-525"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">get_objects</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">doc_name</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">list</span><span class="p">[</span><span class="n">ObjectInfo</span><span class="p">]:</span>
</span><span id="__span-0-526"><a id="__codelineno-0-526" name="__codelineno-0-526"></a><span class="w"> </span><span class="sd">"""Get all objects in a document.</span>
</span><span id="__span-0-527"><a id="__codelineno-0-527" name="__codelineno-0-527"></a>
</span><span id="__span-0-528"><a id="__codelineno-0-528" name="__codelineno-0-528"></a><span class="sd"> Args:</span>
</span><span id="__span-0-529"><a id="__codelineno-0-529" name="__codelineno-0-529"></a><span class="sd"> doc_name: Document name (uses active if None).</span>
</span><span id="__span-0-530"><a id="__codelineno-0-530" name="__codelineno-0-530"></a>
</span><span id="__span-0-531"><a id="__codelineno-0-531" name="__codelineno-0-531"></a><span class="sd"> Returns:</span>
</span><span id="__span-0-532"><a id="__codelineno-0-532" name="__codelineno-0-532"></a><span class="sd"> List of ObjectInfo for each object.</span>
</span><span id="__span-0-533"><a id="__codelineno-0-533" name="__codelineno-0-533"></a><span class="sd"> """</span>
</span><span id="__span-0-534"><a id="__codelineno-0-534" name="__codelineno-0-534"></a> <span class="n">code</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">"""</span>
</span><span id="__span-0-535"><a id="__codelineno-0-535" name="__codelineno-0-535"></a><span class="s2">doc = FreeCAD.ActiveDocument if </span><span class="si">{</span><span class="n">doc_name</span><span class="si">!r}</span><span class="s2"> is None else FreeCAD.getDocument(</span><span class="si">{</span><span class="n">doc_name</span><span class="si">!r}</span><span class="s2">)</span>
</span><span id="__span-0-536"><a id="__codelineno-0-536" name="__codelineno-0-536"></a><span class="s2">if doc is None:</span>
</span><span id="__span-0-537"><a id="__codelineno-0-537" name="__codelineno-0-537"></a><span class="s2"> raise ValueError("No document found")</span>
</span><span id="__span-0-538"><a id="__codelineno-0-538" name="__codelineno-0-538"></a>
</span><span id="__span-0-539"><a id="__codelineno-0-539" name="__codelineno-0-539"></a><span class="s2">objects = []</span>
</span><span id="__span-0-540"><a id="__codelineno-0-540" name="__codelineno-0-540"></a><span class="s2">for obj in doc.Objects:</span>
</span><span id="__span-0-541"><a id="__codelineno-0-541" name="__codelineno-0-541"></a><span class="s2"> obj_info = </span><span class="se">{{</span>
</span><span id="__span-0-542"><a id="__codelineno-0-542" name="__codelineno-0-542"></a><span class="s2"> "name": obj.Name,</span>
</span><span id="__span-0-543"><a id="__codelineno-0-543" name="__codelineno-0-543"></a><span class="s2"> "label": obj.Label,</span>
</span><span id="__span-0-544"><a id="__codelineno-0-544" name="__codelineno-0-544"></a><span class="s2"> "type_id": obj.TypeId,</span>
</span><span id="__span-0-545"><a id="__codelineno-0-545" name="__codelineno-0-545"></a><span class="s2"> "visibility": obj.ViewObject.Visibility if hasattr(obj, "ViewObject") and obj.ViewObject else True,</span>
</span><span id="__span-0-546"><a id="__codelineno-0-546" name="__codelineno-0-546"></a><span class="s2"> "children": [c.Name for c in obj.OutList] if hasattr(obj, "OutList") else [],</span>
</span><span id="__span-0-547"><a id="__codelineno-0-547" name="__codelineno-0-547"></a><span class="s2"> "parents": [p.Name for p in obj.InList] if hasattr(obj, "InList") else [],</span>
</span><span id="__span-0-548"><a id="__codelineno-0-548" name="__codelineno-0-548"></a><span class="s2"> </span><span class="se">}}</span>
</span><span id="__span-0-549"><a id="__codelineno-0-549" name="__codelineno-0-549"></a><span class="s2"> objects.append(obj_info)</span>
</span><span id="__span-0-550"><a id="__codelineno-0-550" name="__codelineno-0-550"></a>
</span><span id="__span-0-551"><a id="__codelineno-0-551" name="__codelineno-0-551"></a><span class="s2">_result_ = objects</span>
</span><span id="__span-0-552"><a id="__codelineno-0-552" name="__codelineno-0-552"></a><span class="s2">"""</span>
</span><span id="__span-0-553"><a id="__codelineno-0-553" name="__codelineno-0-553"></a> <span class="n">result</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">execute_python</span><span class="p">(</span><span class="n">code</span><span class="p">)</span>
</span><span id="__span-0-554"><a id="__codelineno-0-554" name="__codelineno-0-554"></a>
</span><span id="__span-0-555"><a id="__codelineno-0-555" name="__codelineno-0-555"></a> <span class="k">if</span> <span class="n">result</span><span class="o">.</span><span class="n">success</span> <span class="ow">and</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">:</span>
</span><span id="__span-0-556"><a id="__codelineno-0-556" name="__codelineno-0-556"></a> <span class="k">return</span> <span class="p">[</span><span class="n">ObjectInfo</span><span class="p">(</span><span class="o">**</span><span class="n">obj</span><span class="p">)</span> <span class="k">for</span> <span class="n">obj</span> <span class="ow">in</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">]</span>
</span><span id="__span-0-557"><a id="__codelineno-0-557" name="__codelineno-0-557"></a> <span class="k">return</span> <span class="p">[]</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> </div> </div> <div class="doc doc-object doc-function"> <h6 id="freecad_mcp.bridge.embedded.EmbeddedBridge.get_screenshot" class="doc doc-heading"> <code class="highlight language-python"><span class="n">get_screenshot</span><span class="p">(</span><span class="n">view_angle</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">width</span><span class="o">=</span><span class="mi">800</span><span class="p">,</span> <span class="n">height</span><span class="o">=</span><span class="mi">600</span><span class="p">,</span> <span class="n">doc_name</span><span class="o">=</span><span class="kc">None</span><span class="p">)</span></code> <span class="doc doc-labels"> <small class="doc doc-label doc-label-async"><code>async</code></small> </span> <a href="#freecad_mcp.bridge.embedded.EmbeddedBridge.get_screenshot" class="headerlink" title="Permanent link">¶</a></h6> <div class="doc doc-contents "> <p>Capture a screenshot of the 3D view.</p> <p>Note: In embedded headless mode, screenshots are typically not available.</p> <p><span class="doc-section-title">Parameters:</span></p> <table> <thead> <tr> <th>Name</th> <th>Type</th> <th>Description</th> <th>Default</th> </tr> </thead> <tbody> <tr class="doc-section-item"> <td> <code>view_angle</code> </td> <td> <code><a class="autorefs autorefs-internal" title="ViewAngle (freecad_mcp.bridge.base.ViewAngle)" href="#freecad_mcp.bridge.base.ViewAngle">ViewAngle</a> | None</code> </td> <td> <div class="doc-md-description"> <p>View angle to set before capture.</p> </div> </td> <td> <code>None</code> </td> </tr> <tr class="doc-section-item"> <td> <code>width</code> </td> <td> <code><span title="int">int</span></code> </td> <td> <div class="doc-md-description"> <p>Image width in pixels.</p> </div> </td> <td> <code>800</code> </td> </tr> <tr class="doc-section-item"> <td> <code>height</code> </td> <td> <code><span title="int">int</span></code> </td> <td> <div class="doc-md-description"> <p>Image height in pixels.</p> </div> </td> <td> <code>600</code> </td> </tr> <tr class="doc-section-item"> <td> <code>doc_name</code> </td> <td> <code><span title="str">str</span> | None</code> </td> <td> <div class="doc-md-description"> <p>Document name (uses active if None).</p> </div> </td> <td> <code>None</code> </td> </tr> </tbody> </table> <p><span class="doc-section-title">Returns:</span></p> <table> <thead> <tr> <th>Type</th> <th>Description</th> </tr> </thead> <tbody> <tr class="doc-section-item"> <td> <code><a class="autorefs autorefs-internal" title="ScreenshotResult
dataclass
(freecad_mcp.bridge.base.ScreenshotResult)" href="#freecad_mcp.bridge.base.ScreenshotResult">ScreenshotResult</a></code> </td> <td> <div class="doc-md-description"> <p>ScreenshotResult with image data or error.</p> </div> </td> </tr> </tbody> </table> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/embedded.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-697">697</a></span>
<span class="normal"><a href="#__codelineno-0-698">698</a></span>
<span class="normal"><a href="#__codelineno-0-699">699</a></span>
<span class="normal"><a href="#__codelineno-0-700">700</a></span>
<span class="normal"><a href="#__codelineno-0-701">701</a></span>
<span class="normal"><a href="#__codelineno-0-702">702</a></span>
<span class="normal"><a href="#__codelineno-0-703">703</a></span>
<span class="normal"><a href="#__codelineno-0-704">704</a></span>
<span class="normal"><a href="#__codelineno-0-705">705</a></span>
<span class="normal"><a href="#__codelineno-0-706">706</a></span>
<span class="normal"><a href="#__codelineno-0-707">707</a></span>
<span class="normal"><a href="#__codelineno-0-708">708</a></span>
<span class="normal"><a href="#__codelineno-0-709">709</a></span>
<span class="normal"><a href="#__codelineno-0-710">710</a></span>
<span class="normal"><a href="#__codelineno-0-711">711</a></span>
<span class="normal"><a href="#__codelineno-0-712">712</a></span>
<span class="normal"><a href="#__codelineno-0-713">713</a></span>
<span class="normal"><a href="#__codelineno-0-714">714</a></span>
<span class="normal"><a href="#__codelineno-0-715">715</a></span>
<span class="normal"><a href="#__codelineno-0-716">716</a></span>
<span class="normal"><a href="#__codelineno-0-717">717</a></span>
<span class="normal"><a href="#__codelineno-0-718">718</a></span>
<span class="normal"><a href="#__codelineno-0-719">719</a></span>
<span class="normal"><a href="#__codelineno-0-720">720</a></span>
<span class="normal"><a href="#__codelineno-0-721">721</a></span>
<span class="normal"><a href="#__codelineno-0-722">722</a></span>
<span class="normal"><a href="#__codelineno-0-723">723</a></span>
<span class="normal"><a href="#__codelineno-0-724">724</a></span>
<span class="normal"><a href="#__codelineno-0-725">725</a></span>
<span class="normal"><a href="#__codelineno-0-726">726</a></span>
<span class="normal"><a href="#__codelineno-0-727">727</a></span>
<span class="normal"><a href="#__codelineno-0-728">728</a></span>
<span class="normal"><a href="#__codelineno-0-729">729</a></span>
<span class="normal"><a href="#__codelineno-0-730">730</a></span>
<span class="normal"><a href="#__codelineno-0-731">731</a></span>
<span class="normal"><a href="#__codelineno-0-732">732</a></span>
<span class="normal"><a href="#__codelineno-0-733">733</a></span>
<span class="normal"><a href="#__codelineno-0-734">734</a></span>
<span class="normal"><a href="#__codelineno-0-735">735</a></span>
<span class="normal"><a href="#__codelineno-0-736">736</a></span>
<span class="normal"><a href="#__codelineno-0-737">737</a></span>
<span class="normal"><a href="#__codelineno-0-738">738</a></span>
<span class="normal"><a href="#__codelineno-0-739">739</a></span>
<span class="normal"><a href="#__codelineno-0-740">740</a></span>
<span class="normal"><a href="#__codelineno-0-741">741</a></span>
<span class="normal"><a href="#__codelineno-0-742">742</a></span>
<span class="normal"><a href="#__codelineno-0-743">743</a></span>
<span class="normal"><a href="#__codelineno-0-744">744</a></span>
<span class="normal"><a href="#__codelineno-0-745">745</a></span>
<span class="normal"><a href="#__codelineno-0-746">746</a></span>
<span class="normal"><a href="#__codelineno-0-747">747</a></span>
<span class="normal"><a href="#__codelineno-0-748">748</a></span>
<span class="normal"><a href="#__codelineno-0-749">749</a></span>
<span class="normal"><a href="#__codelineno-0-750">750</a></span>
<span class="normal"><a href="#__codelineno-0-751">751</a></span>
<span class="normal"><a href="#__codelineno-0-752">752</a></span>
<span class="normal"><a href="#__codelineno-0-753">753</a></span>
<span class="normal"><a href="#__codelineno-0-754">754</a></span>
<span class="normal"><a href="#__codelineno-0-755">755</a></span>
<span class="normal"><a href="#__codelineno-0-756">756</a></span>
<span class="normal"><a href="#__codelineno-0-757">757</a></span>
<span class="normal"><a href="#__codelineno-0-758">758</a></span>
<span class="normal"><a href="#__codelineno-0-759">759</a></span>
<span class="normal"><a href="#__codelineno-0-760">760</a></span>
<span class="normal"><a href="#__codelineno-0-761">761</a></span>
<span class="normal"><a href="#__codelineno-0-762">762</a></span>
<span class="normal"><a href="#__codelineno-0-763">763</a></span>
<span class="normal"><a href="#__codelineno-0-764">764</a></span>
<span class="normal"><a href="#__codelineno-0-765">765</a></span>
<span class="normal"><a href="#__codelineno-0-766">766</a></span>
<span class="normal"><a href="#__codelineno-0-767">767</a></span>
<span class="normal"><a href="#__codelineno-0-768">768</a></span>
<span class="normal"><a href="#__codelineno-0-769">769</a></span>
<span class="normal"><a href="#__codelineno-0-770">770</a></span>
<span class="normal"><a href="#__codelineno-0-771">771</a></span>
<span class="normal"><a href="#__codelineno-0-772">772</a></span>
<span class="normal"><a href="#__codelineno-0-773">773</a></span>
<span class="normal"><a href="#__codelineno-0-774">774</a></span>
<span class="normal"><a href="#__codelineno-0-775">775</a></span>
<span class="normal"><a href="#__codelineno-0-776">776</a></span>
<span class="normal"><a href="#__codelineno-0-777">777</a></span>
<span class="normal"><a href="#__codelineno-0-778">778</a></span>
<span class="normal"><a href="#__codelineno-0-779">779</a></span>
<span class="normal"><a href="#__codelineno-0-780">780</a></span>
<span class="normal"><a href="#__codelineno-0-781">781</a></span>
<span class="normal"><a href="#__codelineno-0-782">782</a></span>
<span class="normal"><a href="#__codelineno-0-783">783</a></span>
<span class="normal"><a href="#__codelineno-0-784">784</a></span>
<span class="normal"><a href="#__codelineno-0-785">785</a></span>
<span class="normal"><a href="#__codelineno-0-786">786</a></span>
<span class="normal"><a href="#__codelineno-0-787">787</a></span>
<span class="normal"><a href="#__codelineno-0-788">788</a></span>
<span class="normal"><a href="#__codelineno-0-789">789</a></span>
<span class="normal"><a href="#__codelineno-0-790">790</a></span>
<span class="normal"><a href="#__codelineno-0-791">791</a></span>
<span class="normal"><a href="#__codelineno-0-792">792</a></span>
<span class="normal"><a href="#__codelineno-0-793">793</a></span>
<span class="normal"><a href="#__codelineno-0-794">794</a></span>
<span class="normal"><a href="#__codelineno-0-795">795</a></span>
<span class="normal"><a href="#__codelineno-0-796">796</a></span>
<span class="normal"><a href="#__codelineno-0-797">797</a></span>
<span class="normal"><a href="#__codelineno-0-798">798</a></span>
<span class="normal"><a href="#__codelineno-0-799">799</a></span>
<span class="normal"><a href="#__codelineno-0-800">800</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-697"><a id="__codelineno-0-697" name="__codelineno-0-697"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">get_screenshot</span><span class="p">(</span>
</span><span id="__span-0-698"><a id="__codelineno-0-698" name="__codelineno-0-698"></a> <span class="bp">self</span><span class="p">,</span>
</span><span id="__span-0-699"><a id="__codelineno-0-699" name="__codelineno-0-699"></a> <span class="n">view_angle</span><span class="p">:</span> <span class="n">ViewAngle</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-700"><a id="__codelineno-0-700" name="__codelineno-0-700"></a> <span class="n">width</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">800</span><span class="p">,</span>
</span><span id="__span-0-701"><a id="__codelineno-0-701" name="__codelineno-0-701"></a> <span class="n">height</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">600</span><span class="p">,</span>
</span><span id="__span-0-702"><a id="__codelineno-0-702" name="__codelineno-0-702"></a> <span class="n">doc_name</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-703"><a id="__codelineno-0-703" name="__codelineno-0-703"></a> <span class="p">)</span> <span class="o">-&gt;</span> <span class="n">ScreenshotResult</span><span class="p">:</span>
</span><span id="__span-0-704"><a id="__codelineno-0-704" name="__codelineno-0-704"></a><span class="w"> </span><span class="sd">"""Capture a screenshot of the 3D view.</span>
</span><span id="__span-0-705"><a id="__codelineno-0-705" name="__codelineno-0-705"></a>
</span><span id="__span-0-706"><a id="__codelineno-0-706" name="__codelineno-0-706"></a><span class="sd"> Note: In embedded headless mode, screenshots are typically not available.</span>
</span><span id="__span-0-707"><a id="__codelineno-0-707" name="__codelineno-0-707"></a>
</span><span id="__span-0-708"><a id="__codelineno-0-708" name="__codelineno-0-708"></a><span class="sd"> Args:</span>
</span><span id="__span-0-709"><a id="__codelineno-0-709" name="__codelineno-0-709"></a><span class="sd"> view_angle: View angle to set before capture.</span>
</span><span id="__span-0-710"><a id="__codelineno-0-710" name="__codelineno-0-710"></a><span class="sd"> width: Image width in pixels.</span>
</span><span id="__span-0-711"><a id="__codelineno-0-711" name="__codelineno-0-711"></a><span class="sd"> height: Image height in pixels.</span>
</span><span id="__span-0-712"><a id="__codelineno-0-712" name="__codelineno-0-712"></a><span class="sd"> doc_name: Document name (uses active if None).</span>
</span><span id="__span-0-713"><a id="__codelineno-0-713" name="__codelineno-0-713"></a>
</span><span id="__span-0-714"><a id="__codelineno-0-714" name="__codelineno-0-714"></a><span class="sd"> Returns:</span>
</span><span id="__span-0-715"><a id="__codelineno-0-715" name="__codelineno-0-715"></a><span class="sd"> ScreenshotResult with image data or error.</span>
</span><span id="__span-0-716"><a id="__codelineno-0-716" name="__codelineno-0-716"></a><span class="sd"> """</span>
</span><span id="__span-0-717"><a id="__codelineno-0-717" name="__codelineno-0-717"></a> <span class="c1"># Check if GUI is available</span>
</span><span id="__span-0-718"><a id="__codelineno-0-718" name="__codelineno-0-718"></a> <span class="n">gui_available</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">is_gui_available</span><span class="p">()</span>
</span><span id="__span-0-719"><a id="__codelineno-0-719" name="__codelineno-0-719"></a>
</span><span id="__span-0-720"><a id="__codelineno-0-720" name="__codelineno-0-720"></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">gui_available</span><span class="p">:</span>
</span><span id="__span-0-721"><a id="__codelineno-0-721" name="__codelineno-0-721"></a> <span class="k">return</span> <span class="n">ScreenshotResult</span><span class="p">(</span>
</span><span id="__span-0-722"><a id="__codelineno-0-722" name="__codelineno-0-722"></a> <span class="n">success</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
</span><span id="__span-0-723"><a id="__codelineno-0-723" name="__codelineno-0-723"></a> <span class="n">error</span><span class="o">=</span><span class="s2">"Screenshots not available in headless mode"</span><span class="p">,</span>
</span><span id="__span-0-724"><a id="__codelineno-0-724" name="__codelineno-0-724"></a> <span class="n">width</span><span class="o">=</span><span class="n">width</span><span class="p">,</span>
</span><span id="__span-0-725"><a id="__codelineno-0-725" name="__codelineno-0-725"></a> <span class="n">height</span><span class="o">=</span><span class="n">height</span><span class="p">,</span>
</span><span id="__span-0-726"><a id="__codelineno-0-726" name="__codelineno-0-726"></a> <span class="n">view_angle</span><span class="o">=</span><span class="n">view_angle</span><span class="p">,</span>
</span><span id="__span-0-727"><a id="__codelineno-0-727" name="__codelineno-0-727"></a> <span class="p">)</span>
</span><span id="__span-0-728"><a id="__codelineno-0-728" name="__codelineno-0-728"></a>
</span><span id="__span-0-729"><a id="__codelineno-0-729" name="__codelineno-0-729"></a> <span class="c1"># If GUI is available, attempt screenshot</span>
</span><span id="__span-0-730"><a id="__codelineno-0-730" name="__codelineno-0-730"></a> <span class="n">view_angle_str</span> <span class="o">=</span> <span class="n">view_angle</span><span class="o">.</span><span class="n">value</span> <span class="k">if</span> <span class="n">view_angle</span> <span class="k">else</span> <span class="s2">"Isometric"</span>
</span><span id="__span-0-731"><a id="__codelineno-0-731" name="__codelineno-0-731"></a> <span class="n">code</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">"""</span>
</span><span id="__span-0-732"><a id="__codelineno-0-732" name="__codelineno-0-732"></a><span class="s2">import base64</span>
</span><span id="__span-0-733"><a id="__codelineno-0-733" name="__codelineno-0-733"></a><span class="s2">import tempfile</span>
</span><span id="__span-0-734"><a id="__codelineno-0-734" name="__codelineno-0-734"></a><span class="s2">import os</span>
</span><span id="__span-0-735"><a id="__codelineno-0-735" name="__codelineno-0-735"></a>
</span><span id="__span-0-736"><a id="__codelineno-0-736" name="__codelineno-0-736"></a><span class="s2">doc = FreeCAD.ActiveDocument if </span><span class="si">{</span><span class="n">doc_name</span><span class="si">!r}</span><span class="s2"> is None else FreeCAD.getDocument(</span><span class="si">{</span><span class="n">doc_name</span><span class="si">!r}</span><span class="s2">)</span>
</span><span id="__span-0-737"><a id="__codelineno-0-737" name="__codelineno-0-737"></a><span class="s2">if doc is None:</span>
</span><span id="__span-0-738"><a id="__codelineno-0-738" name="__codelineno-0-738"></a><span class="s2"> raise ValueError("No document found")</span>
</span><span id="__span-0-739"><a id="__codelineno-0-739" name="__codelineno-0-739"></a>
</span><span id="__span-0-740"><a id="__codelineno-0-740" name="__codelineno-0-740"></a><span class="s2">view = FreeCADGui.ActiveDocument.ActiveView</span>
</span><span id="__span-0-741"><a id="__codelineno-0-741" name="__codelineno-0-741"></a><span class="s2">if view is None:</span>
</span><span id="__span-0-742"><a id="__codelineno-0-742" name="__codelineno-0-742"></a><span class="s2"> raise ValueError("No active view")</span>
</span><span id="__span-0-743"><a id="__codelineno-0-743" name="__codelineno-0-743"></a>
</span><span id="__span-0-744"><a id="__codelineno-0-744" name="__codelineno-0-744"></a><span class="s2"># Set view angle</span>
</span><span id="__span-0-745"><a id="__codelineno-0-745" name="__codelineno-0-745"></a><span class="s2">view_type = </span><span class="si">{</span><span class="n">view_angle_str</span><span class="si">!r}</span>
</span><span id="__span-0-746"><a id="__codelineno-0-746" name="__codelineno-0-746"></a><span class="s2">if view_type == "FitAll":</span>
</span><span id="__span-0-747"><a id="__codelineno-0-747" name="__codelineno-0-747"></a><span class="s2"> view.fitAll()</span>
</span><span id="__span-0-748"><a id="__codelineno-0-748" name="__codelineno-0-748"></a><span class="s2">elif view_type == "Isometric":</span>
</span><span id="__span-0-749"><a id="__codelineno-0-749" name="__codelineno-0-749"></a><span class="s2"> view.viewIsometric()</span>
</span><span id="__span-0-750"><a id="__codelineno-0-750" name="__codelineno-0-750"></a><span class="s2">elif view_type == "Front":</span>
</span><span id="__span-0-751"><a id="__codelineno-0-751" name="__codelineno-0-751"></a><span class="s2"> view.viewFront()</span>
</span><span id="__span-0-752"><a id="__codelineno-0-752" name="__codelineno-0-752"></a><span class="s2">elif view_type == "Back":</span>
</span><span id="__span-0-753"><a id="__codelineno-0-753" name="__codelineno-0-753"></a><span class="s2"> view.viewRear()</span>
</span><span id="__span-0-754"><a id="__codelineno-0-754" name="__codelineno-0-754"></a><span class="s2">elif view_type == "Top":</span>
</span><span id="__span-0-755"><a id="__codelineno-0-755" name="__codelineno-0-755"></a><span class="s2"> view.viewTop()</span>
</span><span id="__span-0-756"><a id="__codelineno-0-756" name="__codelineno-0-756"></a><span class="s2">elif view_type == "Bottom":</span>
</span><span id="__span-0-757"><a id="__codelineno-0-757" name="__codelineno-0-757"></a><span class="s2"> view.viewBottom()</span>
</span><span id="__span-0-758"><a id="__codelineno-0-758" name="__codelineno-0-758"></a><span class="s2">elif view_type == "Left":</span>
</span><span id="__span-0-759"><a id="__codelineno-0-759" name="__codelineno-0-759"></a><span class="s2"> view.viewLeft()</span>
</span><span id="__span-0-760"><a id="__codelineno-0-760" name="__codelineno-0-760"></a><span class="s2">elif view_type == "Right":</span>
</span><span id="__span-0-761"><a id="__codelineno-0-761" name="__codelineno-0-761"></a><span class="s2"> view.viewRight()</span>
</span><span id="__span-0-762"><a id="__codelineno-0-762" name="__codelineno-0-762"></a>
</span><span id="__span-0-763"><a id="__codelineno-0-763" name="__codelineno-0-763"></a><span class="s2"># Save to temp file and read</span>
</span><span id="__span-0-764"><a id="__codelineno-0-764" name="__codelineno-0-764"></a><span class="s2">with tempfile.NamedTemporaryFile(suffix=".png", delete=False) as f:</span>
</span><span id="__span-0-765"><a id="__codelineno-0-765" name="__codelineno-0-765"></a><span class="s2"> temp_path = f.name</span>
</span><span id="__span-0-766"><a id="__codelineno-0-766" name="__codelineno-0-766"></a>
</span><span id="__span-0-767"><a id="__codelineno-0-767" name="__codelineno-0-767"></a><span class="s2">view.saveImage(temp_path, </span><span class="si">{</span><span class="n">width</span><span class="si">}</span><span class="s2">, </span><span class="si">{</span><span class="n">height</span><span class="si">}</span><span class="s2">, "Current")</span>
</span><span id="__span-0-768"><a id="__codelineno-0-768" name="__codelineno-0-768"></a>
</span><span id="__span-0-769"><a id="__codelineno-0-769" name="__codelineno-0-769"></a><span class="s2">with open(temp_path, "rb") as f:</span>
</span><span id="__span-0-770"><a id="__codelineno-0-770" name="__codelineno-0-770"></a><span class="s2"> image_data = base64.b64encode(f.read()).decode("utf-8")</span>
</span><span id="__span-0-771"><a id="__codelineno-0-771" name="__codelineno-0-771"></a>
</span><span id="__span-0-772"><a id="__codelineno-0-772" name="__codelineno-0-772"></a><span class="s2">os.unlink(temp_path)</span>
</span><span id="__span-0-773"><a id="__codelineno-0-773" name="__codelineno-0-773"></a>
</span><span id="__span-0-774"><a id="__codelineno-0-774" name="__codelineno-0-774"></a><span class="s2">_result_ = </span><span class="se">{{</span>
</span><span id="__span-0-775"><a id="__codelineno-0-775" name="__codelineno-0-775"></a><span class="s2"> "success": True,</span>
</span><span id="__span-0-776"><a id="__codelineno-0-776" name="__codelineno-0-776"></a><span class="s2"> "data": image_data,</span>
</span><span id="__span-0-777"><a id="__codelineno-0-777" name="__codelineno-0-777"></a><span class="s2"> "format": "png",</span>
</span><span id="__span-0-778"><a id="__codelineno-0-778" name="__codelineno-0-778"></a><span class="s2"> "width": </span><span class="si">{</span><span class="n">width</span><span class="si">}</span><span class="s2">,</span>
</span><span id="__span-0-779"><a id="__codelineno-0-779" name="__codelineno-0-779"></a><span class="s2"> "height": </span><span class="si">{</span><span class="n">height</span><span class="si">}</span><span class="s2">,</span>
</span><span id="__span-0-780"><a id="__codelineno-0-780" name="__codelineno-0-780"></a><span class="se">}}</span>
</span><span id="__span-0-781"><a id="__codelineno-0-781" name="__codelineno-0-781"></a><span class="s2">"""</span>
</span><span id="__span-0-782"><a id="__codelineno-0-782" name="__codelineno-0-782"></a> <span class="n">result</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">execute_python</span><span class="p">(</span><span class="n">code</span><span class="p">)</span>
</span><span id="__span-0-783"><a id="__codelineno-0-783" name="__codelineno-0-783"></a>
</span><span id="__span-0-784"><a id="__codelineno-0-784" name="__codelineno-0-784"></a> <span class="k">if</span> <span class="n">result</span><span class="o">.</span><span class="n">success</span> <span class="ow">and</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">:</span>
</span><span id="__span-0-785"><a id="__codelineno-0-785" name="__codelineno-0-785"></a> <span class="k">return</span> <span class="n">ScreenshotResult</span><span class="p">(</span>
</span><span id="__span-0-786"><a id="__codelineno-0-786" name="__codelineno-0-786"></a> <span class="n">success</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span>
</span><span id="__span-0-787"><a id="__codelineno-0-787" name="__codelineno-0-787"></a> <span class="n">data</span><span class="o">=</span><span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">[</span><span class="s2">"data"</span><span class="p">],</span>
</span><span id="__span-0-788"><a id="__codelineno-0-788" name="__codelineno-0-788"></a> <span class="nb">format</span><span class="o">=</span><span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">[</span><span class="s2">"format"</span><span class="p">],</span>
</span><span id="__span-0-789"><a id="__codelineno-0-789" name="__codelineno-0-789"></a> <span class="n">width</span><span class="o">=</span><span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">[</span><span class="s2">"width"</span><span class="p">],</span>
</span><span id="__span-0-790"><a id="__codelineno-0-790" name="__codelineno-0-790"></a> <span class="n">height</span><span class="o">=</span><span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">[</span><span class="s2">"height"</span><span class="p">],</span>
</span><span id="__span-0-791"><a id="__codelineno-0-791" name="__codelineno-0-791"></a> <span class="n">view_angle</span><span class="o">=</span><span class="n">view_angle</span><span class="p">,</span>
</span><span id="__span-0-792"><a id="__codelineno-0-792" name="__codelineno-0-792"></a> <span class="p">)</span>
</span><span id="__span-0-793"><a id="__codelineno-0-793" name="__codelineno-0-793"></a>
</span><span id="__span-0-794"><a id="__codelineno-0-794" name="__codelineno-0-794"></a> <span class="k">return</span> <span class="n">ScreenshotResult</span><span class="p">(</span>
</span><span id="__span-0-795"><a id="__codelineno-0-795" name="__codelineno-0-795"></a> <span class="n">success</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
</span><span id="__span-0-796"><a id="__codelineno-0-796" name="__codelineno-0-796"></a> <span class="n">error</span><span class="o">=</span><span class="n">result</span><span class="o">.</span><span class="n">error_traceback</span> <span class="ow">or</span> <span class="s2">"Failed to capture screenshot"</span><span class="p">,</span>
</span><span id="__span-0-797"><a id="__codelineno-0-797" name="__codelineno-0-797"></a> <span class="n">width</span><span class="o">=</span><span class="n">width</span><span class="p">,</span>
</span><span id="__span-0-798"><a id="__codelineno-0-798" name="__codelineno-0-798"></a> <span class="n">height</span><span class="o">=</span><span class="n">height</span><span class="p">,</span>
</span><span id="__span-0-799"><a id="__codelineno-0-799" name="__codelineno-0-799"></a> <span class="n">view_angle</span><span class="o">=</span><span class="n">view_angle</span><span class="p">,</span>
</span><span id="__span-0-800"><a id="__codelineno-0-800" name="__codelineno-0-800"></a> <span class="p">)</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> </div> </div> <div class="doc doc-object doc-function"> <h6 id="freecad_mcp.bridge.embedded.EmbeddedBridge.get_status" class="doc doc-heading"> <code class="highlight language-python"><span class="n">get_status</span><span class="p">()</span></code> <span class="doc doc-labels"> <small class="doc doc-label doc-label-async"><code>async</code></small> </span> <a href="#freecad_mcp.bridge.embedded.EmbeddedBridge.get_status" class="headerlink" title="Permanent link">¶</a></h6> <div class="doc doc-contents "> <p>Get detailed connection status.</p> <p><span class="doc-section-title">Returns:</span></p> <table> <thead> <tr> <th>Type</th> <th>Description</th> </tr> </thead> <tbody> <tr class="doc-section-item"> <td> <code><a class="autorefs autorefs-internal" title="ConnectionStatus
dataclass
(freecad_mcp.bridge.base.ConnectionStatus)" href="#freecad_mcp.bridge.base.ConnectionStatus">ConnectionStatus</a></code> </td> <td> <div class="doc-md-description"> <p>ConnectionStatus with full status information.</p> </div> </td> </tr> </tbody> </table> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/embedded.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-354">354</a></span>
<span class="normal"><a href="#__codelineno-0-355">355</a></span>
<span class="normal"><a href="#__codelineno-0-356">356</a></span>
<span class="normal"><a href="#__codelineno-0-357">357</a></span>
<span class="normal"><a href="#__codelineno-0-358">358</a></span>
<span class="normal"><a href="#__codelineno-0-359">359</a></span>
<span class="normal"><a href="#__codelineno-0-360">360</a></span>
<span class="normal"><a href="#__codelineno-0-361">361</a></span>
<span class="normal"><a href="#__codelineno-0-362">362</a></span>
<span class="normal"><a href="#__codelineno-0-363">363</a></span>
<span class="normal"><a href="#__codelineno-0-364">364</a></span>
<span class="normal"><a href="#__codelineno-0-365">365</a></span>
<span class="normal"><a href="#__codelineno-0-366">366</a></span>
<span class="normal"><a href="#__codelineno-0-367">367</a></span>
<span class="normal"><a href="#__codelineno-0-368">368</a></span>
<span class="normal"><a href="#__codelineno-0-369">369</a></span>
<span class="normal"><a href="#__codelineno-0-370">370</a></span>
<span class="normal"><a href="#__codelineno-0-371">371</a></span>
<span class="normal"><a href="#__codelineno-0-372">372</a></span>
<span class="normal"><a href="#__codelineno-0-373">373</a></span>
<span class="normal"><a href="#__codelineno-0-374">374</a></span>
<span class="normal"><a href="#__codelineno-0-375">375</a></span>
<span class="normal"><a href="#__codelineno-0-376">376</a></span>
<span class="normal"><a href="#__codelineno-0-377">377</a></span>
<span class="normal"><a href="#__codelineno-0-378">378</a></span>
<span class="normal"><a href="#__codelineno-0-379">379</a></span>
<span class="normal"><a href="#__codelineno-0-380">380</a></span>
<span class="normal"><a href="#__codelineno-0-381">381</a></span>
<span class="normal"><a href="#__codelineno-0-382">382</a></span>
<span class="normal"><a href="#__codelineno-0-383">383</a></span>
<span class="normal"><a href="#__codelineno-0-384">384</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-354"><a id="__codelineno-0-354" name="__codelineno-0-354"></a><span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">get_status</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">ConnectionStatus</span><span class="p">:</span>
</span><span id="__span-0-355"><a id="__codelineno-0-355" name="__codelineno-0-355"></a><span class="w"> </span><span class="sd">"""Get detailed connection status.</span>
</span><span id="__span-0-356"><a id="__codelineno-0-356" name="__codelineno-0-356"></a>
</span><span id="__span-0-357"><a id="__codelineno-0-357" name="__codelineno-0-357"></a><span class="sd"> Returns:</span>
</span><span id="__span-0-358"><a id="__codelineno-0-358" name="__codelineno-0-358"></a><span class="sd"> ConnectionStatus with full status information.</span>
</span><span id="__span-0-359"><a id="__codelineno-0-359" name="__codelineno-0-359"></a><span class="sd"> """</span>
</span><span id="__span-0-360"><a id="__codelineno-0-360" name="__codelineno-0-360"></a> <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">_connected</span><span class="p">:</span>
</span><span id="__span-0-361"><a id="__codelineno-0-361" name="__codelineno-0-361"></a> <span class="k">return</span> <span class="n">ConnectionStatus</span><span class="p">(</span>
</span><span id="__span-0-362"><a id="__codelineno-0-362" name="__codelineno-0-362"></a> <span class="n">connected</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
</span><span id="__span-0-363"><a id="__codelineno-0-363" name="__codelineno-0-363"></a> <span class="n">mode</span><span class="o">=</span><span class="s2">"embedded"</span><span class="p">,</span>
</span><span id="__span-0-364"><a id="__codelineno-0-364" name="__codelineno-0-364"></a> <span class="n">error</span><span class="o">=</span><span class="s2">"Not connected"</span><span class="p">,</span>
</span><span id="__span-0-365"><a id="__codelineno-0-365" name="__codelineno-0-365"></a> <span class="p">)</span>
</span><span id="__span-0-366"><a id="__codelineno-0-366" name="__codelineno-0-366"></a>
</span><span id="__span-0-367"><a id="__codelineno-0-367" name="__codelineno-0-367"></a> <span class="k">try</span><span class="p">:</span>
</span><span id="__span-0-368"><a id="__codelineno-0-368" name="__codelineno-0-368"></a> <span class="n">ping_ms</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">ping</span><span class="p">()</span>
</span><span id="__span-0-369"><a id="__codelineno-0-369" name="__codelineno-0-369"></a> <span class="n">version_info</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_freecad_version</span><span class="p">()</span>
</span><span id="__span-0-370"><a id="__codelineno-0-370" name="__codelineno-0-370"></a> <span class="n">gui_available</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">is_gui_available</span><span class="p">()</span>
</span><span id="__span-0-371"><a id="__codelineno-0-371" name="__codelineno-0-371"></a>
</span><span id="__span-0-372"><a id="__codelineno-0-372" name="__codelineno-0-372"></a> <span class="k">return</span> <span class="n">ConnectionStatus</span><span class="p">(</span>
</span><span id="__span-0-373"><a id="__codelineno-0-373" name="__codelineno-0-373"></a> <span class="n">connected</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span>
</span><span id="__span-0-374"><a id="__codelineno-0-374" name="__codelineno-0-374"></a> <span class="n">mode</span><span class="o">=</span><span class="s2">"embedded"</span><span class="p">,</span>
</span><span id="__span-0-375"><a id="__codelineno-0-375" name="__codelineno-0-375"></a> <span class="n">freecad_version</span><span class="o">=</span><span class="n">version_info</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"version"</span><span class="p">,</span> <span class="s2">"unknown"</span><span class="p">),</span>
</span><span id="__span-0-376"><a id="__codelineno-0-376" name="__codelineno-0-376"></a> <span class="n">gui_available</span><span class="o">=</span><span class="n">gui_available</span><span class="p">,</span>
</span><span id="__span-0-377"><a id="__codelineno-0-377" name="__codelineno-0-377"></a> <span class="n">last_ping_ms</span><span class="o">=</span><span class="n">ping_ms</span><span class="p">,</span>
</span><span id="__span-0-378"><a id="__codelineno-0-378" name="__codelineno-0-378"></a> <span class="p">)</span>
</span><span id="__span-0-379"><a id="__codelineno-0-379" name="__codelineno-0-379"></a> <span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
</span><span id="__span-0-380"><a id="__codelineno-0-380" name="__codelineno-0-380"></a> <span class="k">return</span> <span class="n">ConnectionStatus</span><span class="p">(</span>
</span><span id="__span-0-381"><a id="__codelineno-0-381" name="__codelineno-0-381"></a> <span class="n">connected</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
</span><span id="__span-0-382"><a id="__codelineno-0-382" name="__codelineno-0-382"></a> <span class="n">mode</span><span class="o">=</span><span class="s2">"embedded"</span><span class="p">,</span>
</span><span id="__span-0-383"><a id="__codelineno-0-383" name="__codelineno-0-383"></a> <span class="n">error</span><span class="o">=</span><span class="nb">str</span><span class="p">(</span><span class="n">e</span><span class="p">),</span>
</span><span id="__span-0-384"><a id="__codelineno-0-384" name="__codelineno-0-384"></a> <span class="p">)</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> </div> </div> <div class="doc doc-object doc-function"> <h6 id="freecad_mcp.bridge.embedded.EmbeddedBridge.get_workbenches" class="doc doc-heading"> <code class="highlight language-python"><span class="n">get_workbenches</span><span class="p">()</span></code> <span class="doc doc-labels"> <small class="doc doc-label doc-label-async"><code>async</code></small> </span> <a href="#freecad_mcp.bridge.embedded.EmbeddedBridge.get_workbenches" class="headerlink" title="Permanent link">¶</a></h6> <div class="doc doc-contents "> <p>Get list of available workbenches.</p> <p><span class="doc-section-title">Returns:</span></p> <table> <thead> <tr> <th>Type</th> <th>Description</th> </tr> </thead> <tbody> <tr class="doc-section-item"> <td> <code><span title="list">list</span>[<a class="autorefs autorefs-internal" title="WorkbenchInfo
dataclass
(freecad_mcp.bridge.base.WorkbenchInfo)" href="#freecad_mcp.bridge.base.WorkbenchInfo">WorkbenchInfo</a>]</code> </td> <td> <div class="doc-md-description"> <p>List of WorkbenchInfo for each workbench.</p> </div> </td> </tr> </tbody> </table> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/embedded.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-993"> 993</a></span>
<span class="normal"><a href="#__codelineno-0-994"> 994</a></span>
<span class="normal"><a href="#__codelineno-0-995"> 995</a></span>
<span class="normal"><a href="#__codelineno-0-996"> 996</a></span>
<span class="normal"><a href="#__codelineno-0-997"> 997</a></span>
<span class="normal"><a href="#__codelineno-0-998"> 998</a></span>
<span class="normal"><a href="#__codelineno-0-999"> 999</a></span>
<span class="normal"><a href="#__codelineno-0-1000">1000</a></span>
<span class="normal"><a href="#__codelineno-0-1001">1001</a></span>
<span class="normal"><a href="#__codelineno-0-1002">1002</a></span>
<span class="normal"><a href="#__codelineno-0-1003">1003</a></span>
<span class="normal"><a href="#__codelineno-0-1004">1004</a></span>
<span class="normal"><a href="#__codelineno-0-1005">1005</a></span>
<span class="normal"><a href="#__codelineno-0-1006">1006</a></span>
<span class="normal"><a href="#__codelineno-0-1007">1007</a></span>
<span class="normal"><a href="#__codelineno-0-1008">1008</a></span>
<span class="normal"><a href="#__codelineno-0-1009">1009</a></span>
<span class="normal"><a href="#__codelineno-0-1010">1010</a></span>
<span class="normal"><a href="#__codelineno-0-1011">1011</a></span>
<span class="normal"><a href="#__codelineno-0-1012">1012</a></span>
<span class="normal"><a href="#__codelineno-0-1013">1013</a></span>
<span class="normal"><a href="#__codelineno-0-1014">1014</a></span>
<span class="normal"><a href="#__codelineno-0-1015">1015</a></span>
<span class="normal"><a href="#__codelineno-0-1016">1016</a></span>
<span class="normal"><a href="#__codelineno-0-1017">1017</a></span>
<span class="normal"><a href="#__codelineno-0-1018">1018</a></span>
<span class="normal"><a href="#__codelineno-0-1019">1019</a></span>
<span class="normal"><a href="#__codelineno-0-1020">1020</a></span>
<span class="normal"><a href="#__codelineno-0-1021">1021</a></span>
<span class="normal"><a href="#__codelineno-0-1022">1022</a></span>
<span class="normal"><a href="#__codelineno-0-1023">1023</a></span>
<span class="normal"><a href="#__codelineno-0-1024">1024</a></span>
<span class="normal"><a href="#__codelineno-0-1025">1025</a></span>
<span class="normal"><a href="#__codelineno-0-1026">1026</a></span>
<span class="normal"><a href="#__codelineno-0-1027">1027</a></span>
<span class="normal"><a href="#__codelineno-0-1028">1028</a></span>
<span class="normal"><a href="#__codelineno-0-1029">1029</a></span>
<span class="normal"><a href="#__codelineno-0-1030">1030</a></span>
<span class="normal"><a href="#__codelineno-0-1031">1031</a></span>
<span class="normal"><a href="#__codelineno-0-1032">1032</a></span>
<span class="normal"><a href="#__codelineno-0-1033">1033</a></span>
<span class="normal"><a href="#__codelineno-0-1034">1034</a></span>
<span class="normal"><a href="#__codelineno-0-1035">1035</a></span>
<span class="normal"><a href="#__codelineno-0-1036">1036</a></span>
<span class="normal"><a href="#__codelineno-0-1037">1037</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-993"><a id="__codelineno-0-993" name="__codelineno-0-993"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">get_workbenches</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">list</span><span class="p">[</span><span class="n">WorkbenchInfo</span><span class="p">]:</span>
</span><span id="__span-0-994"><a id="__codelineno-0-994" name="__codelineno-0-994"></a><span class="w"> </span><span class="sd">"""Get list of available workbenches.</span>
</span><span id="__span-0-995"><a id="__codelineno-0-995" name="__codelineno-0-995"></a>
</span><span id="__span-0-996"><a id="__codelineno-0-996" name="__codelineno-0-996"></a><span class="sd"> Returns:</span>
</span><span id="__span-0-997"><a id="__codelineno-0-997" name="__codelineno-0-997"></a><span class="sd"> List of WorkbenchInfo for each workbench.</span>
</span><span id="__span-0-998"><a id="__codelineno-0-998" name="__codelineno-0-998"></a><span class="sd"> """</span>
</span><span id="__span-0-999"><a id="__codelineno-0-999" name="__codelineno-0-999"></a> <span class="n">gui_available</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">is_gui_available</span><span class="p">()</span>
</span><span id="__span-0-1000"><a id="__codelineno-0-1000" name="__codelineno-0-1000"></a>
</span><span id="__span-0-1001"><a id="__codelineno-0-1001" name="__codelineno-0-1001"></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">gui_available</span><span class="p">:</span>
</span><span id="__span-0-1002"><a id="__codelineno-0-1002" name="__codelineno-0-1002"></a> <span class="c1"># Return common workbenches for headless mode</span>
</span><span id="__span-0-1003"><a id="__codelineno-0-1003" name="__codelineno-0-1003"></a> <span class="n">common_workbenches</span> <span class="o">=</span> <span class="p">[</span>
</span><span id="__span-0-1004"><a id="__codelineno-0-1004" name="__codelineno-0-1004"></a> <span class="s2">"StartWorkbench"</span><span class="p">,</span>
</span><span id="__span-0-1005"><a id="__codelineno-0-1005" name="__codelineno-0-1005"></a> <span class="s2">"PartWorkbench"</span><span class="p">,</span>
</span><span id="__span-0-1006"><a id="__codelineno-0-1006" name="__codelineno-0-1006"></a> <span class="s2">"PartDesignWorkbench"</span><span class="p">,</span>
</span><span id="__span-0-1007"><a id="__codelineno-0-1007" name="__codelineno-0-1007"></a> <span class="s2">"DraftWorkbench"</span><span class="p">,</span>
</span><span id="__span-0-1008"><a id="__codelineno-0-1008" name="__codelineno-0-1008"></a> <span class="s2">"SketcherWorkbench"</span><span class="p">,</span>
</span><span id="__span-0-1009"><a id="__codelineno-0-1009" name="__codelineno-0-1009"></a> <span class="s2">"MeshWorkbench"</span><span class="p">,</span>
</span><span id="__span-0-1010"><a id="__codelineno-0-1010" name="__codelineno-0-1010"></a> <span class="s2">"SpreadsheetWorkbench"</span><span class="p">,</span>
</span><span id="__span-0-1011"><a id="__codelineno-0-1011" name="__codelineno-0-1011"></a> <span class="p">]</span>
</span><span id="__span-0-1012"><a id="__codelineno-0-1012" name="__codelineno-0-1012"></a> <span class="k">return</span> <span class="p">[</span>
</span><span id="__span-0-1013"><a id="__codelineno-0-1013" name="__codelineno-0-1013"></a> <span class="n">WorkbenchInfo</span><span class="p">(</span><span class="n">name</span><span class="o">=</span><span class="n">wb</span><span class="p">,</span> <span class="n">label</span><span class="o">=</span><span class="n">wb</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s2">"Workbench"</span><span class="p">,</span> <span class="s2">""</span><span class="p">))</span>
</span><span id="__span-0-1014"><a id="__codelineno-0-1014" name="__codelineno-0-1014"></a> <span class="k">for</span> <span class="n">wb</span> <span class="ow">in</span> <span class="n">common_workbenches</span>
</span><span id="__span-0-1015"><a id="__codelineno-0-1015" name="__codelineno-0-1015"></a> <span class="p">]</span>
</span><span id="__span-0-1016"><a id="__codelineno-0-1016" name="__codelineno-0-1016"></a>
</span><span id="__span-0-1017"><a id="__codelineno-0-1017" name="__codelineno-0-1017"></a> <span class="n">code</span> <span class="o">=</span> <span class="s2">"""</span>
</span><span id="__span-0-1018"><a id="__codelineno-0-1018" name="__codelineno-0-1018"></a><span class="s2">workbenches = []</span>
</span><span id="__span-0-1019"><a id="__codelineno-0-1019" name="__codelineno-0-1019"></a><span class="s2">active_wb = FreeCADGui.activeWorkbench()</span>
</span><span id="__span-0-1020"><a id="__codelineno-0-1020" name="__codelineno-0-1020"></a><span class="s2">active_name = active_wb.__class__.__name__ if active_wb else None</span>
</span><span id="__span-0-1021"><a id="__codelineno-0-1021" name="__codelineno-0-1021"></a>
</span><span id="__span-0-1022"><a id="__codelineno-0-1022" name="__codelineno-0-1022"></a><span class="s2">for name in FreeCADGui.listWorkbenches():</span>
</span><span id="__span-0-1023"><a id="__codelineno-0-1023" name="__codelineno-0-1023"></a><span class="s2"> wb = FreeCADGui.getWorkbench(name)</span>
</span><span id="__span-0-1024"><a id="__codelineno-0-1024" name="__codelineno-0-1024"></a><span class="s2"> workbenches.append({</span>
</span><span id="__span-0-1025"><a id="__codelineno-0-1025" name="__codelineno-0-1025"></a><span class="s2"> "name": name,</span>
</span><span id="__span-0-1026"><a id="__codelineno-0-1026" name="__codelineno-0-1026"></a><span class="s2"> "label": wb.MenuText if hasattr(wb, "MenuText") else name,</span>
</span><span id="__span-0-1027"><a id="__codelineno-0-1027" name="__codelineno-0-1027"></a><span class="s2"> "icon": wb.Icon if hasattr(wb, "Icon") else "",</span>
</span><span id="__span-0-1028"><a id="__codelineno-0-1028" name="__codelineno-0-1028"></a><span class="s2"> "is_active": name == active_name,</span>
</span><span id="__span-0-1029"><a id="__codelineno-0-1029" name="__codelineno-0-1029"></a><span class="s2"> })</span>
</span><span id="__span-0-1030"><a id="__codelineno-0-1030" name="__codelineno-0-1030"></a>
</span><span id="__span-0-1031"><a id="__codelineno-0-1031" name="__codelineno-0-1031"></a><span class="s2">_result_ = workbenches</span>
</span><span id="__span-0-1032"><a id="__codelineno-0-1032" name="__codelineno-0-1032"></a><span class="s2">"""</span>
</span><span id="__span-0-1033"><a id="__codelineno-0-1033" name="__codelineno-0-1033"></a> <span class="n">result</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">execute_python</span><span class="p">(</span><span class="n">code</span><span class="p">)</span>
</span><span id="__span-0-1034"><a id="__codelineno-0-1034" name="__codelineno-0-1034"></a>
</span><span id="__span-0-1035"><a id="__codelineno-0-1035" name="__codelineno-0-1035"></a> <span class="k">if</span> <span class="n">result</span><span class="o">.</span><span class="n">success</span> <span class="ow">and</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">:</span>
</span><span id="__span-0-1036"><a id="__codelineno-0-1036" name="__codelineno-0-1036"></a> <span class="k">return</span> <span class="p">[</span><span class="n">WorkbenchInfo</span><span class="p">(</span><span class="o">**</span><span class="n">wb</span><span class="p">)</span> <span class="k">for</span> <span class="n">wb</span> <span class="ow">in</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">]</span>
</span><span id="__span-0-1037"><a id="__codelineno-0-1037" name="__codelineno-0-1037"></a> <span class="k">return</span> <span class="p">[]</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> </div> </div> <div class="doc doc-object doc-function"> <h6 id="freecad_mcp.bridge.embedded.EmbeddedBridge.is_connected" class="doc doc-heading"> <code class="highlight language-python"><span class="n">is_connected</span><span class="p">()</span></code> <span class="doc doc-labels"> <small class="doc doc-label doc-label-async"><code>async</code></small> </span> <a href="#freecad_mcp.bridge.embedded.EmbeddedBridge.is_connected" class="headerlink" title="Permanent link">¶</a></h6> <div class="doc doc-contents "> <p>Check if FreeCAD is imported and available.</p> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/embedded.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-88">88</a></span>
<span class="normal"><a href="#__codelineno-0-89">89</a></span>
<span class="normal"><a href="#__codelineno-0-90">90</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-88"><a id="__codelineno-0-88" name="__codelineno-0-88"></a><span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">is_connected</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">bool</span><span class="p">:</span>
</span><span id="__span-0-89"><a id="__codelineno-0-89" name="__codelineno-0-89"></a><span class="w"> </span><span class="sd">"""Check if FreeCAD is imported and available."""</span>
</span><span id="__span-0-90"><a id="__codelineno-0-90" name="__codelineno-0-90"></a> <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_connected</span> <span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">_fc_module</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> </div> </div> <div class="doc doc-object doc-function"> <h6 id="freecad_mcp.bridge.embedded.EmbeddedBridge.is_gui_available" class="doc doc-heading"> <code class="highlight language-python"><span class="n">is_gui_available</span><span class="p">()</span></code> <span class="doc doc-labels"> <small class="doc doc-label doc-label-async"><code>async</code></small> </span> <a href="#freecad_mcp.bridge.embedded.EmbeddedBridge.is_gui_available" class="headerlink" title="Permanent link">¶</a></h6> <div class="doc doc-contents "> <p>Check if GUI is available.</p> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/embedded.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-324">324</a></span>
<span class="normal"><a href="#__codelineno-0-325">325</a></span>
<span class="normal"><a href="#__codelineno-0-326">326</a></span>
<span class="normal"><a href="#__codelineno-0-327">327</a></span>
<span class="normal"><a href="#__codelineno-0-328">328</a></span>
<span class="normal"><a href="#__codelineno-0-329">329</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-324"><a id="__codelineno-0-324" name="__codelineno-0-324"></a><span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">is_gui_available</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">bool</span><span class="p">:</span>
</span><span id="__span-0-325"><a id="__codelineno-0-325" name="__codelineno-0-325"></a><span class="w"> </span><span class="sd">"""Check if GUI is available."""</span>
</span><span id="__span-0-326"><a id="__codelineno-0-326" name="__codelineno-0-326"></a> <span class="n">result</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">execute_python</span><span class="p">(</span>
</span><span id="__span-0-327"><a id="__codelineno-0-327" name="__codelineno-0-327"></a> <span class="s2">"_result_ = hasattr(FreeCAD, 'GuiUp') and FreeCAD.GuiUp"</span>
</span><span id="__span-0-328"><a id="__codelineno-0-328" name="__codelineno-0-328"></a> <span class="p">)</span>
</span><span id="__span-0-329"><a id="__codelineno-0-329" name="__codelineno-0-329"></a> <span class="k">return</span> <span class="nb">bool</span><span class="p">(</span><span class="n">result</span><span class="o">.</span><span class="n">success</span> <span class="ow">and</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">)</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> </div> </div> <div class="doc doc-object doc-function"> <h6 id="freecad_mcp.bridge.embedded.EmbeddedBridge.open_document" class="doc doc-heading"> <code class="highlight language-python"><span class="n">open_document</span><span class="p">(</span><span class="n">path</span><span class="p">)</span></code> <span class="doc doc-labels"> <small class="doc doc-label doc-label-async"><code>async</code></small> </span> <a href="#freecad_mcp.bridge.embedded.EmbeddedBridge.open_document" class="headerlink" title="Permanent link">¶</a></h6> <div class="doc doc-contents "> <p>Open an existing document.</p> <p><span class="doc-section-title">Parameters:</span></p> <table> <thead> <tr> <th>Name</th> <th>Type</th> <th>Description</th> <th>Default</th> </tr> </thead> <tbody> <tr class="doc-section-item"> <td> <code>path</code> </td> <td> <code><span title="str">str</span></code> </td> <td> <div class="doc-md-description"> <p>Path to the .FCStd file.</p> </div> </td> <td> <em>required</em> </td> </tr> </tbody> </table> <p><span class="doc-section-title">Returns:</span></p> <table> <thead> <tr> <th>Type</th> <th>Description</th> </tr> </thead> <tbody> <tr class="doc-section-item"> <td> <code><a class="autorefs autorefs-internal" title="DocumentInfo
dataclass
(freecad_mcp.bridge.base.DocumentInfo)" href="#freecad_mcp.bridge.base.DocumentInfo">DocumentInfo</a></code> </td> <td> <div class="doc-md-description"> <p>DocumentInfo for the opened document.</p> </div> </td> </tr> </tbody> </table> <p><span class="doc-section-title">Raises:</span></p> <table> <thead> <tr> <th>Type</th> <th>Description</th> </tr> </thead> <tbody> <tr class="doc-section-item"> <td> <code><span title="FileNotFoundError">FileNotFoundError</span></code> </td> <td> <div class="doc-md-description"> <p>If file doesn't exist.</p> </div> </td> </tr> <tr class="doc-section-item"> <td> <code><span title="ValueError">ValueError</span></code> </td> <td> <div class="doc-md-description"> <p>If file is not a valid FreeCAD document.</p> </div> </td> </tr> </tbody> </table> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/embedded.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-423">423</a></span>
<span class="normal"><a href="#__codelineno-0-424">424</a></span>
<span class="normal"><a href="#__codelineno-0-425">425</a></span>
<span class="normal"><a href="#__codelineno-0-426">426</a></span>
<span class="normal"><a href="#__codelineno-0-427">427</a></span>
<span class="normal"><a href="#__codelineno-0-428">428</a></span>
<span class="normal"><a href="#__codelineno-0-429">429</a></span>
<span class="normal"><a href="#__codelineno-0-430">430</a></span>
<span class="normal"><a href="#__codelineno-0-431">431</a></span>
<span class="normal"><a href="#__codelineno-0-432">432</a></span>
<span class="normal"><a href="#__codelineno-0-433">433</a></span>
<span class="normal"><a href="#__codelineno-0-434">434</a></span>
<span class="normal"><a href="#__codelineno-0-435">435</a></span>
<span class="normal"><a href="#__codelineno-0-436">436</a></span>
<span class="normal"><a href="#__codelineno-0-437">437</a></span>
<span class="normal"><a href="#__codelineno-0-438">438</a></span>
<span class="normal"><a href="#__codelineno-0-439">439</a></span>
<span class="normal"><a href="#__codelineno-0-440">440</a></span>
<span class="normal"><a href="#__codelineno-0-441">441</a></span>
<span class="normal"><a href="#__codelineno-0-442">442</a></span>
<span class="normal"><a href="#__codelineno-0-443">443</a></span>
<span class="normal"><a href="#__codelineno-0-444">444</a></span>
<span class="normal"><a href="#__codelineno-0-445">445</a></span>
<span class="normal"><a href="#__codelineno-0-446">446</a></span>
<span class="normal"><a href="#__codelineno-0-447">447</a></span>
<span class="normal"><a href="#__codelineno-0-448">448</a></span>
<span class="normal"><a href="#__codelineno-0-449">449</a></span>
<span class="normal"><a href="#__codelineno-0-450">450</a></span>
<span class="normal"><a href="#__codelineno-0-451">451</a></span>
<span class="normal"><a href="#__codelineno-0-452">452</a></span>
<span class="normal"><a href="#__codelineno-0-453">453</a></span>
<span class="normal"><a href="#__codelineno-0-454">454</a></span>
<span class="normal"><a href="#__codelineno-0-455">455</a></span>
<span class="normal"><a href="#__codelineno-0-456">456</a></span>
<span class="normal"><a href="#__codelineno-0-457">457</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-423"><a id="__codelineno-0-423" name="__codelineno-0-423"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">open_document</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">path</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">DocumentInfo</span><span class="p">:</span>
</span><span id="__span-0-424"><a id="__codelineno-0-424" name="__codelineno-0-424"></a><span class="w"> </span><span class="sd">"""Open an existing document.</span>
</span><span id="__span-0-425"><a id="__codelineno-0-425" name="__codelineno-0-425"></a>
</span><span id="__span-0-426"><a id="__codelineno-0-426" name="__codelineno-0-426"></a><span class="sd"> Args:</span>
</span><span id="__span-0-427"><a id="__codelineno-0-427" name="__codelineno-0-427"></a><span class="sd"> path: Path to the .FCStd file.</span>
</span><span id="__span-0-428"><a id="__codelineno-0-428" name="__codelineno-0-428"></a>
</span><span id="__span-0-429"><a id="__codelineno-0-429" name="__codelineno-0-429"></a><span class="sd"> Returns:</span>
</span><span id="__span-0-430"><a id="__codelineno-0-430" name="__codelineno-0-430"></a><span class="sd"> DocumentInfo for the opened document.</span>
</span><span id="__span-0-431"><a id="__codelineno-0-431" name="__codelineno-0-431"></a>
</span><span id="__span-0-432"><a id="__codelineno-0-432" name="__codelineno-0-432"></a><span class="sd"> Raises:</span>
</span><span id="__span-0-433"><a id="__codelineno-0-433" name="__codelineno-0-433"></a><span class="sd"> FileNotFoundError: If file doesn't exist.</span>
</span><span id="__span-0-434"><a id="__codelineno-0-434" name="__codelineno-0-434"></a><span class="sd"> ValueError: If file is not a valid FreeCAD document.</span>
</span><span id="__span-0-435"><a id="__codelineno-0-435" name="__codelineno-0-435"></a><span class="sd"> """</span>
</span><span id="__span-0-436"><a id="__codelineno-0-436" name="__codelineno-0-436"></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">Path</span><span class="p">(</span><span class="n">path</span><span class="p">)</span><span class="o">.</span><span class="n">exists</span><span class="p">():</span>
</span><span id="__span-0-437"><a id="__codelineno-0-437" name="__codelineno-0-437"></a> <span class="n">msg</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">"File not found: </span><span class="si">{</span><span class="n">path</span><span class="si">}</span><span class="s2">"</span>
</span><span id="__span-0-438"><a id="__codelineno-0-438" name="__codelineno-0-438"></a> <span class="k">raise</span> <span class="ne">FileNotFoundError</span><span class="p">(</span><span class="n">msg</span><span class="p">)</span>
</span><span id="__span-0-439"><a id="__codelineno-0-439" name="__codelineno-0-439"></a>
</span><span id="__span-0-440"><a id="__codelineno-0-440" name="__codelineno-0-440"></a> <span class="n">result</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">execute_python</span><span class="p">(</span>
</span><span id="__span-0-441"><a id="__codelineno-0-441" name="__codelineno-0-441"></a> <span class="sa">f</span><span class="s2">"""</span>
</span><span id="__span-0-442"><a id="__codelineno-0-442" name="__codelineno-0-442"></a><span class="s2">doc = FreeCAD.openDocument(</span><span class="si">{</span><span class="n">path</span><span class="si">!r}</span><span class="s2">)</span>
</span><span id="__span-0-443"><a id="__codelineno-0-443" name="__codelineno-0-443"></a><span class="s2">_result_ = </span><span class="se">{{</span>
</span><span id="__span-0-444"><a id="__codelineno-0-444" name="__codelineno-0-444"></a><span class="s2"> "name": doc.Name,</span>
</span><span id="__span-0-445"><a id="__codelineno-0-445" name="__codelineno-0-445"></a><span class="s2"> "label": doc.Label,</span>
</span><span id="__span-0-446"><a id="__codelineno-0-446" name="__codelineno-0-446"></a><span class="s2"> "path": doc.FileName or None,</span>
</span><span id="__span-0-447"><a id="__codelineno-0-447" name="__codelineno-0-447"></a><span class="s2"> "objects": [obj.Name for obj in doc.Objects],</span>
</span><span id="__span-0-448"><a id="__codelineno-0-448" name="__codelineno-0-448"></a><span class="s2"> "is_modified": doc.Modified if hasattr(doc, "Modified") else False,</span>
</span><span id="__span-0-449"><a id="__codelineno-0-449" name="__codelineno-0-449"></a><span class="se">}}</span>
</span><span id="__span-0-450"><a id="__codelineno-0-450" name="__codelineno-0-450"></a><span class="s2">"""</span>
</span><span id="__span-0-451"><a id="__codelineno-0-451" name="__codelineno-0-451"></a> <span class="p">)</span>
</span><span id="__span-0-452"><a id="__codelineno-0-452" name="__codelineno-0-452"></a>
</span><span id="__span-0-453"><a id="__codelineno-0-453" name="__codelineno-0-453"></a> <span class="k">if</span> <span class="n">result</span><span class="o">.</span><span class="n">success</span> <span class="ow">and</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">:</span>
</span><span id="__span-0-454"><a id="__codelineno-0-454" name="__codelineno-0-454"></a> <span class="k">return</span> <span class="n">DocumentInfo</span><span class="p">(</span><span class="o">**</span><span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">)</span>
</span><span id="__span-0-455"><a id="__codelineno-0-455" name="__codelineno-0-455"></a>
</span><span id="__span-0-456"><a id="__codelineno-0-456" name="__codelineno-0-456"></a> <span class="n">error_msg</span> <span class="o">=</span> <span class="n">result</span><span class="o">.</span><span class="n">error_traceback</span> <span class="ow">or</span> <span class="s2">"Failed to open document"</span>
</span><span id="__span-0-457"><a id="__codelineno-0-457" name="__codelineno-0-457"></a> <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="n">error_msg</span><span class="p">)</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> </div> </div> <div class="doc doc-object doc-function"> <h6 id="freecad_mcp.bridge.embedded.EmbeddedBridge.ping" class="doc doc-heading"> <code class="highlight language-python"><span class="n">ping</span><span class="p">()</span></code> <span class="doc doc-labels"> <small class="doc doc-label doc-label-async"><code>async</code></small> </span> <a href="#freecad_mcp.bridge.embedded.EmbeddedBridge.ping" class="headerlink" title="Permanent link">¶</a></h6> <div class="doc doc-contents "> <p>Ping FreeCAD to check connection and measure latency.</p> <p><span class="doc-section-title">Returns:</span></p> <table> <thead> <tr> <th>Type</th> <th>Description</th> </tr> </thead> <tbody> <tr class="doc-section-item"> <td> <code><span title="float">float</span></code> </td> <td> <div class="doc-md-description"> <p>Round-trip time in milliseconds.</p> </div> </td> </tr> </tbody> </table> <p><span class="doc-section-title">Raises:</span></p> <table> <thead> <tr> <th>Type</th> <th>Description</th> </tr> </thead> <tbody> <tr class="doc-section-item"> <td> <code><span title="ConnectionError">ConnectionError</span></code> </td> <td> <div class="doc-md-description"> <p>If not connected.</p> </div> </td> </tr> </tbody> </table> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/embedded.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-331">331</a></span>
<span class="normal"><a href="#__codelineno-0-332">332</a></span>
<span class="normal"><a href="#__codelineno-0-333">333</a></span>
<span class="normal"><a href="#__codelineno-0-334">334</a></span>
<span class="normal"><a href="#__codelineno-0-335">335</a></span>
<span class="normal"><a href="#__codelineno-0-336">336</a></span>
<span class="normal"><a href="#__codelineno-0-337">337</a></span>
<span class="normal"><a href="#__codelineno-0-338">338</a></span>
<span class="normal"><a href="#__codelineno-0-339">339</a></span>
<span class="normal"><a href="#__codelineno-0-340">340</a></span>
<span class="normal"><a href="#__codelineno-0-341">341</a></span>
<span class="normal"><a href="#__codelineno-0-342">342</a></span>
<span class="normal"><a href="#__codelineno-0-343">343</a></span>
<span class="normal"><a href="#__codelineno-0-344">344</a></span>
<span class="normal"><a href="#__codelineno-0-345">345</a></span>
<span class="normal"><a href="#__codelineno-0-346">346</a></span>
<span class="normal"><a href="#__codelineno-0-347">347</a></span>
<span class="normal"><a href="#__codelineno-0-348">348</a></span>
<span class="normal"><a href="#__codelineno-0-349">349</a></span>
<span class="normal"><a href="#__codelineno-0-350">350</a></span>
<span class="normal"><a href="#__codelineno-0-351">351</a></span>
<span class="normal"><a href="#__codelineno-0-352">352</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-331"><a id="__codelineno-0-331" name="__codelineno-0-331"></a><span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">ping</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">float</span><span class="p">:</span>
</span><span id="__span-0-332"><a id="__codelineno-0-332" name="__codelineno-0-332"></a><span class="w"> </span><span class="sd">"""Ping FreeCAD to check connection and measure latency.</span>
</span><span id="__span-0-333"><a id="__codelineno-0-333" name="__codelineno-0-333"></a>
</span><span id="__span-0-334"><a id="__codelineno-0-334" name="__codelineno-0-334"></a><span class="sd"> Returns:</span>
</span><span id="__span-0-335"><a id="__codelineno-0-335" name="__codelineno-0-335"></a><span class="sd"> Round-trip time in milliseconds.</span>
</span><span id="__span-0-336"><a id="__codelineno-0-336" name="__codelineno-0-336"></a>
</span><span id="__span-0-337"><a id="__codelineno-0-337" name="__codelineno-0-337"></a><span class="sd"> Raises:</span>
</span><span id="__span-0-338"><a id="__codelineno-0-338" name="__codelineno-0-338"></a><span class="sd"> ConnectionError: If not connected.</span>
</span><span id="__span-0-339"><a id="__codelineno-0-339" name="__codelineno-0-339"></a><span class="sd"> """</span>
</span><span id="__span-0-340"><a id="__codelineno-0-340" name="__codelineno-0-340"></a> <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">_connected</span><span class="p">:</span>
</span><span id="__span-0-341"><a id="__codelineno-0-341" name="__codelineno-0-341"></a> <span class="n">msg</span> <span class="o">=</span> <span class="s2">"Not connected to FreeCAD"</span>
</span><span id="__span-0-342"><a id="__codelineno-0-342" name="__codelineno-0-342"></a> <span class="k">raise</span> <span class="ne">ConnectionError</span><span class="p">(</span><span class="n">msg</span><span class="p">)</span>
</span><span id="__span-0-343"><a id="__codelineno-0-343" name="__codelineno-0-343"></a>
</span><span id="__span-0-344"><a id="__codelineno-0-344" name="__codelineno-0-344"></a> <span class="n">start</span> <span class="o">=</span> <span class="n">time</span><span class="o">.</span><span class="n">perf_counter</span><span class="p">()</span>
</span><span id="__span-0-345"><a id="__codelineno-0-345" name="__codelineno-0-345"></a> <span class="n">result</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">execute_python</span><span class="p">(</span><span class="s2">"_result_ = True"</span><span class="p">)</span>
</span><span id="__span-0-346"><a id="__codelineno-0-346" name="__codelineno-0-346"></a> <span class="n">elapsed</span> <span class="o">=</span> <span class="p">(</span><span class="n">time</span><span class="o">.</span><span class="n">perf_counter</span><span class="p">()</span> <span class="o">-</span> <span class="n">start</span><span class="p">)</span> <span class="o">*</span> <span class="mi">1000</span>
</span><span id="__span-0-347"><a id="__codelineno-0-347" name="__codelineno-0-347"></a>
</span><span id="__span-0-348"><a id="__codelineno-0-348" name="__codelineno-0-348"></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">result</span><span class="o">.</span><span class="n">success</span><span class="p">:</span>
</span><span id="__span-0-349"><a id="__codelineno-0-349" name="__codelineno-0-349"></a> <span class="n">msg</span> <span class="o">=</span> <span class="s2">"Ping failed"</span>
</span><span id="__span-0-350"><a id="__codelineno-0-350" name="__codelineno-0-350"></a> <span class="k">raise</span> <span class="ne">ConnectionError</span><span class="p">(</span><span class="n">msg</span><span class="p">)</span>
</span><span id="__span-0-351"><a id="__codelineno-0-351" name="__codelineno-0-351"></a>
</span><span id="__span-0-352"><a id="__codelineno-0-352" name="__codelineno-0-352"></a> <span class="k">return</span> <span class="n">elapsed</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> </div> </div> <div class="doc doc-object doc-function"> <h6 id="freecad_mcp.bridge.embedded.EmbeddedBridge.run_macro" class="doc doc-heading"> <code class="highlight language-python"><span class="n">run_macro</span><span class="p">(</span><span class="n">macro_name</span><span class="p">,</span> <span class="n">args</span><span class="o">=</span><span class="kc">None</span><span class="p">)</span></code> <span class="doc doc-labels"> <small class="doc doc-label doc-label-async"><code>async</code></small> </span> <a href="#freecad_mcp.bridge.embedded.EmbeddedBridge.run_macro" class="headerlink" title="Permanent link">¶</a></h6> <div class="doc doc-contents "> <p>Run a macro by name.</p> <p><span class="doc-section-title">Parameters:</span></p> <table> <thead> <tr> <th>Name</th> <th>Type</th> <th>Description</th> <th>Default</th> </tr> </thead> <tbody> <tr class="doc-section-item"> <td> <code>macro_name</code> </td> <td> <code><span title="str">str</span></code> </td> <td> <div class="doc-md-description"> <p>Macro name (without .FCMacro extension).</p> </div> </td> <td> <em>required</em> </td> </tr> <tr class="doc-section-item"> <td> <code>args</code> </td> <td> <code><span title="dict">dict</span>[<span title="str">str</span>, <span title="typing.Any">Any</span>] | None</code> </td> <td> <div class="doc-md-description"> <p>Arguments to pass to the macro.</p> </div> </td> <td> <code>None</code> </td> </tr> </tbody> </table> <p><span class="doc-section-title">Returns:</span></p> <table> <thead> <tr> <th>Type</th> <th>Description</th> </tr> </thead> <tbody> <tr class="doc-section-item"> <td> <code><a class="autorefs autorefs-internal" title="ExecutionResult
dataclass
(freecad_mcp.bridge.base.ExecutionResult)" href="#freecad_mcp.bridge.base.ExecutionResult">ExecutionResult</a></code> </td> <td> <div class="doc-md-description"> <p>ExecutionResult from macro execution.</p> </div> </td> </tr> </tbody> </table> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/embedded.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-901">901</a></span>
<span class="normal"><a href="#__codelineno-0-902">902</a></span>
<span class="normal"><a href="#__codelineno-0-903">903</a></span>
<span class="normal"><a href="#__codelineno-0-904">904</a></span>
<span class="normal"><a href="#__codelineno-0-905">905</a></span>
<span class="normal"><a href="#__codelineno-0-906">906</a></span>
<span class="normal"><a href="#__codelineno-0-907">907</a></span>
<span class="normal"><a href="#__codelineno-0-908">908</a></span>
<span class="normal"><a href="#__codelineno-0-909">909</a></span>
<span class="normal"><a href="#__codelineno-0-910">910</a></span>
<span class="normal"><a href="#__codelineno-0-911">911</a></span>
<span class="normal"><a href="#__codelineno-0-912">912</a></span>
<span class="normal"><a href="#__codelineno-0-913">913</a></span>
<span class="normal"><a href="#__codelineno-0-914">914</a></span>
<span class="normal"><a href="#__codelineno-0-915">915</a></span>
<span class="normal"><a href="#__codelineno-0-916">916</a></span>
<span class="normal"><a href="#__codelineno-0-917">917</a></span>
<span class="normal"><a href="#__codelineno-0-918">918</a></span>
<span class="normal"><a href="#__codelineno-0-919">919</a></span>
<span class="normal"><a href="#__codelineno-0-920">920</a></span>
<span class="normal"><a href="#__codelineno-0-921">921</a></span>
<span class="normal"><a href="#__codelineno-0-922">922</a></span>
<span class="normal"><a href="#__codelineno-0-923">923</a></span>
<span class="normal"><a href="#__codelineno-0-924">924</a></span>
<span class="normal"><a href="#__codelineno-0-925">925</a></span>
<span class="normal"><a href="#__codelineno-0-926">926</a></span>
<span class="normal"><a href="#__codelineno-0-927">927</a></span>
<span class="normal"><a href="#__codelineno-0-928">928</a></span>
<span class="normal"><a href="#__codelineno-0-929">929</a></span>
<span class="normal"><a href="#__codelineno-0-930">930</a></span>
<span class="normal"><a href="#__codelineno-0-931">931</a></span>
<span class="normal"><a href="#__codelineno-0-932">932</a></span>
<span class="normal"><a href="#__codelineno-0-933">933</a></span>
<span class="normal"><a href="#__codelineno-0-934">934</a></span>
<span class="normal"><a href="#__codelineno-0-935">935</a></span>
<span class="normal"><a href="#__codelineno-0-936">936</a></span>
<span class="normal"><a href="#__codelineno-0-937">937</a></span>
<span class="normal"><a href="#__codelineno-0-938">938</a></span>
<span class="normal"><a href="#__codelineno-0-939">939</a></span>
<span class="normal"><a href="#__codelineno-0-940">940</a></span>
<span class="normal"><a href="#__codelineno-0-941">941</a></span>
<span class="normal"><a href="#__codelineno-0-942">942</a></span>
<span class="normal"><a href="#__codelineno-0-943">943</a></span>
<span class="normal"><a href="#__codelineno-0-944">944</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-901"><a id="__codelineno-0-901" name="__codelineno-0-901"></a><span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">run_macro</span><span class="p">(</span>
</span><span id="__span-0-902"><a id="__codelineno-0-902" name="__codelineno-0-902"></a> <span class="bp">self</span><span class="p">,</span>
</span><span id="__span-0-903"><a id="__codelineno-0-903" name="__codelineno-0-903"></a> <span class="n">macro_name</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span>
</span><span id="__span-0-904"><a id="__codelineno-0-904" name="__codelineno-0-904"></a> <span class="n">args</span><span class="p">:</span> <span class="nb">dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Any</span><span class="p">]</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-905"><a id="__codelineno-0-905" name="__codelineno-0-905"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">ExecutionResult</span><span class="p">:</span>
</span><span id="__span-0-906"><a id="__codelineno-0-906" name="__codelineno-0-906"></a><span class="w"> </span><span class="sd">"""Run a macro by name.</span>
</span><span id="__span-0-907"><a id="__codelineno-0-907" name="__codelineno-0-907"></a>
</span><span id="__span-0-908"><a id="__codelineno-0-908" name="__codelineno-0-908"></a><span class="sd"> Args:</span>
</span><span id="__span-0-909"><a id="__codelineno-0-909" name="__codelineno-0-909"></a><span class="sd"> macro_name: Macro name (without .FCMacro extension).</span>
</span><span id="__span-0-910"><a id="__codelineno-0-910" name="__codelineno-0-910"></a><span class="sd"> args: Arguments to pass to the macro.</span>
</span><span id="__span-0-911"><a id="__codelineno-0-911" name="__codelineno-0-911"></a>
</span><span id="__span-0-912"><a id="__codelineno-0-912" name="__codelineno-0-912"></a><span class="sd"> Returns:</span>
</span><span id="__span-0-913"><a id="__codelineno-0-913" name="__codelineno-0-913"></a><span class="sd"> ExecutionResult from macro execution.</span>
</span><span id="__span-0-914"><a id="__codelineno-0-914" name="__codelineno-0-914"></a><span class="sd"> """</span>
</span><span id="__span-0-915"><a id="__codelineno-0-915" name="__codelineno-0-915"></a> <span class="n">macro_path</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_macro_path</span><span class="p">()</span> <span class="o">/</span> <span class="sa">f</span><span class="s2">"</span><span class="si">{</span><span class="n">macro_name</span><span class="si">}</span><span class="s2">.FCMacro"</span>
</span><span id="__span-0-916"><a id="__codelineno-0-916" name="__codelineno-0-916"></a>
</span><span id="__span-0-917"><a id="__codelineno-0-917" name="__codelineno-0-917"></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">macro_path</span><span class="o">.</span><span class="n">exists</span><span class="p">():</span>
</span><span id="__span-0-918"><a id="__codelineno-0-918" name="__codelineno-0-918"></a> <span class="k">return</span> <span class="n">ExecutionResult</span><span class="p">(</span>
</span><span id="__span-0-919"><a id="__codelineno-0-919" name="__codelineno-0-919"></a> <span class="n">success</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
</span><span id="__span-0-920"><a id="__codelineno-0-920" name="__codelineno-0-920"></a> <span class="n">result</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-921"><a id="__codelineno-0-921" name="__codelineno-0-921"></a> <span class="n">stdout</span><span class="o">=</span><span class="s2">""</span><span class="p">,</span>
</span><span id="__span-0-922"><a id="__codelineno-0-922" name="__codelineno-0-922"></a> <span class="n">stderr</span><span class="o">=</span><span class="sa">f</span><span class="s2">"Macro not found: </span><span class="si">{</span><span class="n">macro_name</span><span class="si">}</span><span class="s2">"</span><span class="p">,</span>
</span><span id="__span-0-923"><a id="__codelineno-0-923" name="__codelineno-0-923"></a> <span class="n">execution_time_ms</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span>
</span><span id="__span-0-924"><a id="__codelineno-0-924" name="__codelineno-0-924"></a> <span class="n">error_type</span><span class="o">=</span><span class="s2">"FileNotFoundError"</span><span class="p">,</span>
</span><span id="__span-0-925"><a id="__codelineno-0-925" name="__codelineno-0-925"></a> <span class="p">)</span>
</span><span id="__span-0-926"><a id="__codelineno-0-926" name="__codelineno-0-926"></a>
</span><span id="__span-0-927"><a id="__codelineno-0-927" name="__codelineno-0-927"></a> <span class="k">try</span><span class="p">:</span>
</span><span id="__span-0-928"><a id="__codelineno-0-928" name="__codelineno-0-928"></a> <span class="n">macro_code</span> <span class="o">=</span> <span class="n">macro_path</span><span class="o">.</span><span class="n">read_text</span><span class="p">()</span>
</span><span id="__span-0-929"><a id="__codelineno-0-929" name="__codelineno-0-929"></a> <span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
</span><span id="__span-0-930"><a id="__codelineno-0-930" name="__codelineno-0-930"></a> <span class="k">return</span> <span class="n">ExecutionResult</span><span class="p">(</span>
</span><span id="__span-0-931"><a id="__codelineno-0-931" name="__codelineno-0-931"></a> <span class="n">success</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
</span><span id="__span-0-932"><a id="__codelineno-0-932" name="__codelineno-0-932"></a> <span class="n">result</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-933"><a id="__codelineno-0-933" name="__codelineno-0-933"></a> <span class="n">stdout</span><span class="o">=</span><span class="s2">""</span><span class="p">,</span>
</span><span id="__span-0-934"><a id="__codelineno-0-934" name="__codelineno-0-934"></a> <span class="n">stderr</span><span class="o">=</span><span class="sa">f</span><span class="s2">"Failed to read macro: </span><span class="si">{</span><span class="n">e</span><span class="si">}</span><span class="s2">"</span><span class="p">,</span>
</span><span id="__span-0-935"><a id="__codelineno-0-935" name="__codelineno-0-935"></a> <span class="n">execution_time_ms</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span>
</span><span id="__span-0-936"><a id="__codelineno-0-936" name="__codelineno-0-936"></a> <span class="n">error_type</span><span class="o">=</span><span class="nb">type</span><span class="p">(</span><span class="n">e</span><span class="p">)</span><span class="o">.</span><span class="vm">__name__</span><span class="p">,</span>
</span><span id="__span-0-937"><a id="__codelineno-0-937" name="__codelineno-0-937"></a> <span class="p">)</span>
</span><span id="__span-0-938"><a id="__codelineno-0-938" name="__codelineno-0-938"></a>
</span><span id="__span-0-939"><a id="__codelineno-0-939" name="__codelineno-0-939"></a> <span class="c1"># Prepend argument setup if provided</span>
</span><span id="__span-0-940"><a id="__codelineno-0-940" name="__codelineno-0-940"></a> <span class="k">if</span> <span class="n">args</span><span class="p">:</span>
</span><span id="__span-0-941"><a id="__codelineno-0-941" name="__codelineno-0-941"></a> <span class="n">args_setup</span> <span class="o">=</span> <span class="s2">"</span><span class="se">\n</span><span class="s2">"</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="sa">f</span><span class="s2">"</span><span class="si">{</span><span class="n">k</span><span class="si">}</span><span class="s2"> = </span><span class="si">{</span><span class="n">v</span><span class="si">!r}</span><span class="s2">"</span> <span class="k">for</span> <span class="n">k</span><span class="p">,</span> <span class="n">v</span> <span class="ow">in</span> <span class="n">args</span><span class="o">.</span><span class="n">items</span><span class="p">())</span>
</span><span id="__span-0-942"><a id="__codelineno-0-942" name="__codelineno-0-942"></a> <span class="n">macro_code</span> <span class="o">=</span> <span class="n">args_setup</span> <span class="o">+</span> <span class="s2">"</span><span class="se">\n</span><span class="s2">"</span> <span class="o">+</span> <span class="n">macro_code</span>
</span><span id="__span-0-943"><a id="__codelineno-0-943" name="__codelineno-0-943"></a>
</span><span id="__span-0-944"><a id="__codelineno-0-944" name="__codelineno-0-944"></a> <span class="k">return</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">execute_python</span><span class="p">(</span><span class="n">macro_code</span><span class="p">)</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> </div> </div> <div class="doc doc-object doc-function"> <h6 id="freecad_mcp.bridge.embedded.EmbeddedBridge.save_document" class="doc doc-heading"> <code class="highlight language-python"><span class="n">save_document</span><span class="p">(</span><span class="n">doc_name</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">path</span><span class="o">=</span><span class="kc">None</span><span class="p">)</span></code> <span class="doc doc-labels"> <small class="doc doc-label doc-label-async"><code>async</code></small> </span> <a href="#freecad_mcp.bridge.embedded.EmbeddedBridge.save_document" class="headerlink" title="Permanent link">¶</a></h6> <div class="doc doc-contents "> <p>Save a document.</p> <p><span class="doc-section-title">Parameters:</span></p> <table> <thead> <tr> <th>Name</th> <th>Type</th> <th>Description</th> <th>Default</th> </tr> </thead> <tbody> <tr class="doc-section-item"> <td> <code>doc_name</code> </td> <td> <code><span title="str">str</span> | None</code> </td> <td> <div class="doc-md-description"> <p>Document name (uses active if None).</p> </div> </td> <td> <code>None</code> </td> </tr> <tr class="doc-section-item"> <td> <code>path</code> </td> <td> <code><span title="str">str</span> | None</code> </td> <td> <div class="doc-md-description"> <p>Save path (uses existing path if None).</p> </div> </td> <td> <code>None</code> </td> </tr> </tbody> </table> <p><span class="doc-section-title">Returns:</span></p> <table> <thead> <tr> <th>Type</th> <th>Description</th> </tr> </thead> <tbody> <tr class="doc-section-item"> <td> <code><span title="str">str</span></code> </td> <td> <div class="doc-md-description"> <p>Path where document was saved.</p> </div> </td> </tr> </tbody> </table> <p><span class="doc-section-title">Raises:</span></p> <table> <thead> <tr> <th>Type</th> <th>Description</th> </tr> </thead> <tbody> <tr class="doc-section-item"> <td> <code><span title="ValueError">ValueError</span></code> </td> <td> <div class="doc-md-description"> <p>If document not found or no path specified for new doc.</p> </div> </td> </tr> </tbody> </table> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/embedded.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-459">459</a></span>
<span class="normal"><a href="#__codelineno-0-460">460</a></span>
<span class="normal"><a href="#__codelineno-0-461">461</a></span>
<span class="normal"><a href="#__codelineno-0-462">462</a></span>
<span class="normal"><a href="#__codelineno-0-463">463</a></span>
<span class="normal"><a href="#__codelineno-0-464">464</a></span>
<span class="normal"><a href="#__codelineno-0-465">465</a></span>
<span class="normal"><a href="#__codelineno-0-466">466</a></span>
<span class="normal"><a href="#__codelineno-0-467">467</a></span>
<span class="normal"><a href="#__codelineno-0-468">468</a></span>
<span class="normal"><a href="#__codelineno-0-469">469</a></span>
<span class="normal"><a href="#__codelineno-0-470">470</a></span>
<span class="normal"><a href="#__codelineno-0-471">471</a></span>
<span class="normal"><a href="#__codelineno-0-472">472</a></span>
<span class="normal"><a href="#__codelineno-0-473">473</a></span>
<span class="normal"><a href="#__codelineno-0-474">474</a></span>
<span class="normal"><a href="#__codelineno-0-475">475</a></span>
<span class="normal"><a href="#__codelineno-0-476">476</a></span>
<span class="normal"><a href="#__codelineno-0-477">477</a></span>
<span class="normal"><a href="#__codelineno-0-478">478</a></span>
<span class="normal"><a href="#__codelineno-0-479">479</a></span>
<span class="normal"><a href="#__codelineno-0-480">480</a></span>
<span class="normal"><a href="#__codelineno-0-481">481</a></span>
<span class="normal"><a href="#__codelineno-0-482">482</a></span>
<span class="normal"><a href="#__codelineno-0-483">483</a></span>
<span class="normal"><a href="#__codelineno-0-484">484</a></span>
<span class="normal"><a href="#__codelineno-0-485">485</a></span>
<span class="normal"><a href="#__codelineno-0-486">486</a></span>
<span class="normal"><a href="#__codelineno-0-487">487</a></span>
<span class="normal"><a href="#__codelineno-0-488">488</a></span>
<span class="normal"><a href="#__codelineno-0-489">489</a></span>
<span class="normal"><a href="#__codelineno-0-490">490</a></span>
<span class="normal"><a href="#__codelineno-0-491">491</a></span>
<span class="normal"><a href="#__codelineno-0-492">492</a></span>
<span class="normal"><a href="#__codelineno-0-493">493</a></span>
<span class="normal"><a href="#__codelineno-0-494">494</a></span>
<span class="normal"><a href="#__codelineno-0-495">495</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-459"><a id="__codelineno-0-459" name="__codelineno-0-459"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">save_document</span><span class="p">(</span>
</span><span id="__span-0-460"><a id="__codelineno-0-460" name="__codelineno-0-460"></a> <span class="bp">self</span><span class="p">,</span>
</span><span id="__span-0-461"><a id="__codelineno-0-461" name="__codelineno-0-461"></a> <span class="n">doc_name</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-462"><a id="__codelineno-0-462" name="__codelineno-0-462"></a> <span class="n">path</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-463"><a id="__codelineno-0-463" name="__codelineno-0-463"></a> <span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">str</span><span class="p">:</span>
</span><span id="__span-0-464"><a id="__codelineno-0-464" name="__codelineno-0-464"></a><span class="w"> </span><span class="sd">"""Save a document.</span>
</span><span id="__span-0-465"><a id="__codelineno-0-465" name="__codelineno-0-465"></a>
</span><span id="__span-0-466"><a id="__codelineno-0-466" name="__codelineno-0-466"></a><span class="sd"> Args:</span>
</span><span id="__span-0-467"><a id="__codelineno-0-467" name="__codelineno-0-467"></a><span class="sd"> doc_name: Document name (uses active if None).</span>
</span><span id="__span-0-468"><a id="__codelineno-0-468" name="__codelineno-0-468"></a><span class="sd"> path: Save path (uses existing path if None).</span>
</span><span id="__span-0-469"><a id="__codelineno-0-469" name="__codelineno-0-469"></a>
</span><span id="__span-0-470"><a id="__codelineno-0-470" name="__codelineno-0-470"></a><span class="sd"> Returns:</span>
</span><span id="__span-0-471"><a id="__codelineno-0-471" name="__codelineno-0-471"></a><span class="sd"> Path where document was saved.</span>
</span><span id="__span-0-472"><a id="__codelineno-0-472" name="__codelineno-0-472"></a>
</span><span id="__span-0-473"><a id="__codelineno-0-473" name="__codelineno-0-473"></a><span class="sd"> Raises:</span>
</span><span id="__span-0-474"><a id="__codelineno-0-474" name="__codelineno-0-474"></a><span class="sd"> ValueError: If document not found or no path specified for new doc.</span>
</span><span id="__span-0-475"><a id="__codelineno-0-475" name="__codelineno-0-475"></a><span class="sd"> """</span>
</span><span id="__span-0-476"><a id="__codelineno-0-476" name="__codelineno-0-476"></a> <span class="n">code</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">"""</span>
</span><span id="__span-0-477"><a id="__codelineno-0-477" name="__codelineno-0-477"></a><span class="s2">doc = FreeCAD.ActiveDocument if </span><span class="si">{</span><span class="n">doc_name</span><span class="si">!r}</span><span class="s2"> is None else FreeCAD.getDocument(</span><span class="si">{</span><span class="n">doc_name</span><span class="si">!r}</span><span class="s2">)</span>
</span><span id="__span-0-478"><a id="__codelineno-0-478" name="__codelineno-0-478"></a><span class="s2">if doc is None:</span>
</span><span id="__span-0-479"><a id="__codelineno-0-479" name="__codelineno-0-479"></a><span class="s2"> raise ValueError("No active document" if </span><span class="si">{</span><span class="n">doc_name</span><span class="si">!r}</span><span class="s2"> is None else f"Document not found: </span><span class="si">{</span><span class="n">doc_name</span><span class="si">!r}</span><span class="s2">")</span>
</span><span id="__span-0-480"><a id="__codelineno-0-480" name="__codelineno-0-480"></a>
</span><span id="__span-0-481"><a id="__codelineno-0-481" name="__codelineno-0-481"></a><span class="s2">save_path = </span><span class="si">{</span><span class="n">path</span><span class="si">!r}</span><span class="s2"> or doc.FileName</span>
</span><span id="__span-0-482"><a id="__codelineno-0-482" name="__codelineno-0-482"></a><span class="s2">if not save_path:</span>
</span><span id="__span-0-483"><a id="__codelineno-0-483" name="__codelineno-0-483"></a><span class="s2"> raise ValueError("No path specified for new document")</span>
</span><span id="__span-0-484"><a id="__codelineno-0-484" name="__codelineno-0-484"></a>
</span><span id="__span-0-485"><a id="__codelineno-0-485" name="__codelineno-0-485"></a><span class="s2">doc.saveAs(save_path)</span>
</span><span id="__span-0-486"><a id="__codelineno-0-486" name="__codelineno-0-486"></a><span class="s2">_result_ = save_path</span>
</span><span id="__span-0-487"><a id="__codelineno-0-487" name="__codelineno-0-487"></a><span class="s2">"""</span>
</span><span id="__span-0-488"><a id="__codelineno-0-488" name="__codelineno-0-488"></a>
</span><span id="__span-0-489"><a id="__codelineno-0-489" name="__codelineno-0-489"></a> <span class="n">result</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">execute_python</span><span class="p">(</span><span class="n">code</span><span class="p">)</span>
</span><span id="__span-0-490"><a id="__codelineno-0-490" name="__codelineno-0-490"></a>
</span><span id="__span-0-491"><a id="__codelineno-0-491" name="__codelineno-0-491"></a> <span class="k">if</span> <span class="n">result</span><span class="o">.</span><span class="n">success</span> <span class="ow">and</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span><span class="p">:</span>
</span><span id="__span-0-492"><a id="__codelineno-0-492" name="__codelineno-0-492"></a> <span class="k">return</span> <span class="n">result</span><span class="o">.</span><span class="n">result</span>
</span><span id="__span-0-493"><a id="__codelineno-0-493" name="__codelineno-0-493"></a>
</span><span id="__span-0-494"><a id="__codelineno-0-494" name="__codelineno-0-494"></a> <span class="n">error_msg</span> <span class="o">=</span> <span class="n">result</span><span class="o">.</span><span class="n">error_traceback</span> <span class="ow">or</span> <span class="s2">"Failed to save document"</span>
</span><span id="__span-0-495"><a id="__codelineno-0-495" name="__codelineno-0-495"></a> <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="n">error_msg</span><span class="p">)</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> </div> </div> <div class="doc doc-object doc-function"> <h6 id="freecad_mcp.bridge.embedded.EmbeddedBridge.set_view" class="doc doc-heading"> <code class="highlight language-python"><span class="n">set_view</span><span class="p">(</span><span class="n">view_angle</span><span class="p">,</span> <span class="n">doc_name</span><span class="o">=</span><span class="kc">None</span><span class="p">)</span></code> <span class="doc doc-labels"> <small class="doc doc-label doc-label-async"><code>async</code></small> </span> <a href="#freecad_mcp.bridge.embedded.EmbeddedBridge.set_view" class="headerlink" title="Permanent link">¶</a></h6> <div class="doc doc-contents "> <p>Set the 3D view angle.</p> <p><span class="doc-section-title">Parameters:</span></p> <table> <thead> <tr> <th>Name</th> <th>Type</th> <th>Description</th> <th>Default</th> </tr> </thead> <tbody> <tr class="doc-section-item"> <td> <code>view_angle</code> </td> <td> <code><a class="autorefs autorefs-internal" title="ViewAngle (freecad_mcp.bridge.base.ViewAngle)" href="#freecad_mcp.bridge.base.ViewAngle">ViewAngle</a></code> </td> <td> <div class="doc-md-description"> <p>View angle to set.</p> </div> </td> <td> <em>required</em> </td> </tr> <tr class="doc-section-item"> <td> <code>doc_name</code> </td> <td> <code><span title="str">str</span> | None</code> </td> <td> <div class="doc-md-description"> <p>Document name (uses active if None).</p> </div> </td> <td> <code>None</code> </td> </tr> </tbody> </table> <details class="mkdocstrings-source"> <summary>Source code in <code>src/freecad_mcp/bridge/embedded.py</code></summary> <div class="language-python highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-802">802</a></span>
<span class="normal"><a href="#__codelineno-0-803">803</a></span>
<span class="normal"><a href="#__codelineno-0-804">804</a></span>
<span class="normal"><a href="#__codelineno-0-805">805</a></span>
<span class="normal"><a href="#__codelineno-0-806">806</a></span>
<span class="normal"><a href="#__codelineno-0-807">807</a></span>
<span class="normal"><a href="#__codelineno-0-808">808</a></span>
<span class="normal"><a href="#__codelineno-0-809">809</a></span>
<span class="normal"><a href="#__codelineno-0-810">810</a></span>
<span class="normal"><a href="#__codelineno-0-811">811</a></span>
<span class="normal"><a href="#__codelineno-0-812">812</a></span>
<span class="normal"><a href="#__codelineno-0-813">813</a></span>
<span class="normal"><a href="#__codelineno-0-814">814</a></span>
<span class="normal"><a href="#__codelineno-0-815">815</a></span>
<span class="normal"><a href="#__codelineno-0-816">816</a></span>
<span class="normal"><a href="#__codelineno-0-817">817</a></span>
<span class="normal"><a href="#__codelineno-0-818">818</a></span>
<span class="normal"><a href="#__codelineno-0-819">819</a></span>
<span class="normal"><a href="#__codelineno-0-820">820</a></span>
<span class="normal"><a href="#__codelineno-0-821">821</a></span>
<span class="normal"><a href="#__codelineno-0-822">822</a></span>
<span class="normal"><a href="#__codelineno-0-823">823</a></span>
<span class="normal"><a href="#__codelineno-0-824">824</a></span>
<span class="normal"><a href="#__codelineno-0-825">825</a></span>
<span class="normal"><a href="#__codelineno-0-826">826</a></span>
<span class="normal"><a href="#__codelineno-0-827">827</a></span>
<span class="normal"><a href="#__codelineno-0-828">828</a></span>
<span class="normal"><a href="#__codelineno-0-829">829</a></span>
<span class="normal"><a href="#__codelineno-0-830">830</a></span>
<span class="normal"><a href="#__codelineno-0-831">831</a></span>
<span class="normal"><a href="#__codelineno-0-832">832</a></span>
<span class="normal"><a href="#__codelineno-0-833">833</a></span>
<span class="normal"><a href="#__codelineno-0-834">834</a></span>
<span class="normal"><a href="#__codelineno-0-835">835</a></span>
<span class="normal"><a href="#__codelineno-0-836">836</a></span>
<span class="normal"><a href="#__codelineno-0-837">837</a></span>
<span class="normal"><a href="#__codelineno-0-838">838</a></span>
<span class="normal"><a href="#__codelineno-0-839">839</a></span>
<span class="normal"><a href="#__codelineno-0-840">840</a></span>
<span class="normal"><a href="#__codelineno-0-841">841</a></span>
<span class="normal"><a href="#__codelineno-0-842">842</a></span>
<span class="normal"><a href="#__codelineno-0-843">843</a></span>
<span class="normal"><a href="#__codelineno-0-844">844</a></span>
<span class="normal"><a href="#__codelineno-0-845">845</a></span>
<span class="normal"><a href="#__codelineno-0-846">846</a></span>
<span class="normal"><a href="#__codelineno-0-847">847</a></span>
<span class="normal"><a href="#__codelineno-0-848">848</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-802"><a id="__codelineno-0-802" name="__codelineno-0-802"></a> <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">set_view</span><span class="p">(</span>
</span><span id="__span-0-803"><a id="__codelineno-0-803" name="__codelineno-0-803"></a> <span class="bp">self</span><span class="p">,</span>
</span><span id="__span-0-804"><a id="__codelineno-0-804" name="__codelineno-0-804"></a> <span class="n">view_angle</span><span class="p">:</span> <span class="n">ViewAngle</span><span class="p">,</span>
</span><span id="__span-0-805"><a id="__codelineno-0-805" name="__codelineno-0-805"></a> <span class="n">doc_name</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="__span-0-806"><a id="__codelineno-0-806" name="__codelineno-0-806"></a> <span class="p">)</span> <span class="o">-&gt;</span> <span class="kc">None</span><span class="p">:</span>
</span><span id="__span-0-807"><a id="__codelineno-0-807" name="__codelineno-0-807"></a><span class="w"> </span><span class="sd">"""Set the 3D view angle.</span>
</span><span id="__span-0-808"><a id="__codelineno-0-808" name="__codelineno-0-808"></a>
</span><span id="__span-0-809"><a id="__codelineno-0-809" name="__codelineno-0-809"></a><span class="sd"> Args:</span>
</span><span id="__span-0-810"><a id="__codelineno-0-810" name="__codelineno-0-810"></a><span class="sd"> view_angle: View angle to set.</span>
</span><span id="__span-0-811"><a id="__codelineno-0-811" name="__codelineno-0-811"></a><span class="sd"> doc_name: Document name (uses active if None).</span>
</span><span id="__span-0-812"><a id="__codelineno-0-812" name="__codelineno-0-812"></a><span class="sd"> """</span>
</span><span id="__span-0-813"><a id="__codelineno-0-813" name="__codelineno-0-813"></a> <span class="n">gui_available</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">is_gui_available</span><span class="p">()</span>
</span><span id="__span-0-814"><a id="__codelineno-0-814" name="__codelineno-0-814"></a>
</span><span id="__span-0-815"><a id="__codelineno-0-815" name="__codelineno-0-815"></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">gui_available</span><span class="p">:</span>
</span><span id="__span-0-816"><a id="__codelineno-0-816" name="__codelineno-0-816"></a> <span class="k">return</span> <span class="c1"># Silently ignore in headless mode</span>
</span><span id="__span-0-817"><a id="__codelineno-0-817" name="__codelineno-0-817"></a>
</span><span id="__span-0-818"><a id="__codelineno-0-818" name="__codelineno-0-818"></a> <span class="n">view_angle_str</span> <span class="o">=</span> <span class="n">view_angle</span><span class="o">.</span><span class="n">value</span>
</span><span id="__span-0-819"><a id="__codelineno-0-819" name="__codelineno-0-819"></a> <span class="n">code</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">"""</span>
</span><span id="__span-0-820"><a id="__codelineno-0-820" name="__codelineno-0-820"></a><span class="s2">doc = FreeCAD.ActiveDocument if </span><span class="si">{</span><span class="n">doc_name</span><span class="si">!r}</span><span class="s2"> is None else FreeCAD.getDocument(</span><span class="si">{</span><span class="n">doc_name</span><span class="si">!r}</span><span class="s2">)</span>
</span><span id="__span-0-821"><a id="__codelineno-0-821" name="__codelineno-0-821"></a><span class="s2">if doc is None:</span>
</span><span id="__span-0-822"><a id="__codelineno-0-822" name="__codelineno-0-822"></a><span class="s2"> raise ValueError("No document found")</span>
</span><span id="__span-0-823"><a id="__codelineno-0-823" name="__codelineno-0-823"></a>
</span><span id="__span-0-824"><a id="__codelineno-0-824" name="__codelineno-0-824"></a><span class="s2">view = FreeCADGui.ActiveDocument.ActiveView</span>
</span><span id="__span-0-825"><a id="__codelineno-0-825" name="__codelineno-0-825"></a><span class="s2">if view is None:</span>
</span><span id="__span-0-826"><a id="__codelineno-0-826" name="__codelineno-0-826"></a><span class="s2"> raise ValueError("No active view")</span>
</span><span id="__span-0-827"><a id="__codelineno-0-827" name="__codelineno-0-827"></a>
</span><span id="__span-0-828"><a id="__codelineno-0-828" name="__codelineno-0-828"></a><span class="s2">view_type = </span><span class="si">{</span><span class="n">view_angle_str</span><span class="si">!r}</span>
</span><span id="__span-0-829"><a id="__codelineno-0-829" name="__codelineno-0-829"></a><span class="s2">if view_type == "FitAll":</span>
</span><span id="__span-0-830"><a id="__codelineno-0-830" name="__codelineno-0-830"></a><span class="s2"> view.fitAll()</span>
</span><span id="__span-0-831"><a id="__codelineno-0-831" name="__codelineno-0-831"></a><span class="s2">elif view_type == "Isometric":</span>
</span><span id="__span-0-832"><a id="__codelineno-0-832" name="__codelineno-0-832"></a><span class="s2"> view.viewIsometric()</span>
</span><span id="__span-0-833"><a id="__codelineno-0-833" name="__codelineno-0-833"></a><span class="s2">elif view_type == "Front":</span>
</span><span id="__span-0-834"><a id="__codelineno-0-834" name="__codelineno-0-834"></a><span class="s2"> view.viewFront()</span>
</span><span id="__span-0-835"><a id="__codelineno-0-835" name="__codelineno-0-835"></a><span class="s2">elif view_type == "Back":</span>
</span><span id="__span-0-836"><a id="__codelineno-0-836" name="__codelineno-0-836"></a><span class="s2"> view.viewRear()</span>
</span><span id="__span-0-837"><a id="__codelineno-0-837" name="__codelineno-0-837"></a><span class="s2">elif view_type == "Top":</span>
</span><span id="__span-0-838"><a id="__codelineno-0-838" name="__codelineno-0-838"></a><span class="s2"> view.viewTop()</span>
</span><span id="__span-0-839"><a id="__codelineno-0-839" name="__codelineno-0-839"></a><span class="s2">elif view_type == "Bottom":</span>
</span><span id="__span-0-840"><a id="__codelineno-0-840" name="__codelineno-0-840"></a><span class="s2"> view.viewBottom()</span>
</span><span id="__span-0-841"><a id="__codelineno-0-841" name="__codelineno-0-841"></a><span class="s2">elif view_type == "Left":</span>
</span><span id="__span-0-842"><a id="__codelineno-0-842" name="__codelineno-0-842"></a><span class="s2"> view.viewLeft()</span>
</span><span id="__span-0-843"><a id="__codelineno-0-843" name="__codelineno-0-843"></a><span class="s2">elif view_type == "Right":</span>
</span><span id="__span-0-844"><a id="__codelineno-0-844" name="__codelineno-0-844"></a><span class="s2"> view.viewRight()</span>
</span><span id="__span-0-845"><a id="__codelineno-0-845" name="__codelineno-0-845"></a>
</span><span id="__span-0-846"><a id="__codelineno-0-846" name="__codelineno-0-846"></a><span class="s2">_result_ = True</span>
</span><span id="__span-0-847"><a id="__codelineno-0-847" name="__codelineno-0-847"></a><span class="s2">"""</span>
</span><span id="__span-0-848"><a id="__codelineno-0-848" name="__codelineno-0-848"></a> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">execute_python</span><span class="p">(</span><span class="n">code</span><span class="p">)</span>
</span></code></pre></div></td></tr></tbody></table></div> </details> </div> </div> </div> </div> </div> </div> </div> </div><p>options: show_root_heading: true show_source: true</p> <aside class="md-source-file"> <span class="md-source-file__fact"> <span class="md-icon" title="Last update"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M21 13.1c-.1 0-.3.1-.4.2l-1 1 2.1 2.1 1-1c.2-.2.2-.6 0-.8l-1.3-1.3c-.1-.1-.2-.2-.4-.2m-1.9 1.8-6.1 6V23h2.1l6.1-6.1zM12.5 7v5.2l4 2.4-1 1L11 13V7zM11 21.9c-5.1-.5-9-4.8-9-9.9C2 6.5 6.5 2 12 2c5.3 0 9.6 4.1 10 9.3-.3-.1-.6-.2-1-.2s-.7.1-1 .2C19.6 7.2 16.2 4 12 4c-4.4 0-8 3.6-8 8 0 4.1 3.1 7.5 7.1 7.9l-.1.2z"></path></svg> </span> <span class="git-revision-date-localized-plugin git-revision-date-localized-plugin-timeago" title="January 10, 2026 23:26:33 UTC"><span class="timeago" datetime="2026-01-10T23:26:33+00:00" locale="en"></span></span><span class="git-revision-date-localized-plugin git-revision-date-localized-plugin-iso_date" title="January 10, 2026 23:26:33 UTC">2026-01-10</span> </span> <span class="md-source-file__fact"> <span class="md-icon" title="Created"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M14.47 15.08 11 13V7h1.5v5.25l3.08 1.83c-.41.28-.79.62-1.11 1m-1.39 4.84c-.36.05-.71.08-1.08.08-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8c0 .37-.03.72-.08 1.08.69.1 1.33.32 1.92.64.1-.56.16-1.13.16-1.72 0-5.5-4.5-10-10-10S2 6.5 2 12s4.47 10 10 10c.59 0 1.16-.06 1.72-.16-.32-.59-.54-1.23-.64-1.92M18 15v3h-3v2h3v3h2v-3h3v-2h-3v-3z"></path></svg> </span> <span class="git-revision-date-localized-plugin git-revision-date-localized-plugin-timeago" title="January 6, 2026 23:44:27 UTC"><span class="timeago" datetime="2026-01-06T23:44:27+00:00" locale="en"></span></span><span class="git-revision-date-localized-plugin git-revision-date-localized-plugin-iso_date" title="January 6, 2026 23:44:27 UTC">2026-01-06</span> </span> </aside> </article> </div> <script>var tabs=__md_get("__tabs");if(Array.isArray(tabs))e:for(var set of document.querySelectorAll(".tabbed-set")){var labels=set.querySelector(".tabbed-labels");for(var tab of tabs)for(var label of labels.getElementsByTagName("label"))if(label.innerText.trim()===tab){var input=document.getElementById(label.htmlFor);input.checked=!0;continue e}}</script> <script>var target=document.getElementById(location.hash.slice(1));target&&target.name&&(target.checked=target.name.startsWith("__tabbed_"))</script> </div> <button type="button" class="md-top md-icon" data-md-component="top" hidden> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M13 20h-2V8l-5.5 5.5-1.42-1.42L12 4.16l7.92 7.92-1.42 1.42L13 8z"></path></svg> Back to top </button> </main> <footer class="md-footer"> <div class="md-footer-meta md-typeset"> <div class="md-footer-meta__inner md-grid"> <div class="md-copyright"> Made with <a href="https://squidfunk.github.io/mkdocs-material/" target="_blank" rel="noopener"> Material for MkDocs </a> </div> <div class="md-social"> <a href="https://github.com/spkane/freecad-addon-robust-mcp-server" target="_blank" rel="noopener" title="github.com" class="md-social__link"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!-- Font Awesome Free 7.1.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc.--><path d="M173.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6m-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3m44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9M252.8 8C114.1 8 8 113.3 8 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C436.2 457.8 504 362.9 504 252 504 113.3 391.5 8 252.8 8M105.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1m-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7m32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1m-11.4-14.7c-1.6 1-1.6 3.6 0 5.9s4.3 3.3 5.6 2.3c1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2"></path></svg> </a> <a href="https://hub.docker.com/r/spkane/freecad-robust-mcp" target="_blank" rel="noopener" title="hub.docker.com" class="md-social__link"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512"><!-- Font Awesome Free 7.1.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc.--><path d="M349.9 236.3h-66.1v-59.4h66.1zm0-204.3h-66.1v60.7h66.1zm78.2 144.8H362v59.4h66.1zm-156.3-72.1h-66.1v60.1h66.1zm78.1 0h-66.1v60.1h66.1zm276.8 100c-14.4-9.7-47.6-13.2-73.1-8.4-3.3-24-16.7-44.9-41.1-63.7l-14-9.3-9.3 14c-18.4 27.8-23.4 73.6-3.7 103.8-8.7 4.7-25.8 11.1-48.4 10.7H2.4c-8.7 50.8 5.8 116.8 44 162.1 37.1 43.9 92.7 66.2 165.4 66.2 157.4 0 273.9-72.5 328.4-204.2 21.4.4 67.6.1 91.3-45.2 1.5-2.5 6.6-13.2 8.5-17.1zm-511.1-27.9h-66v59.4h66.1v-59.4zm78.1 0h-66.1v59.4h66.1zm78.1 0h-66.1v59.4h66.1zm-78.1-72.1h-66.1v60.1h66.1z"></path></svg> </a> <a href="https://pypi.org/project/freecad-robust-mcp/" target="_blank" rel="noopener" title="pypi.org" class="md-social__link"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!-- Font Awesome Free 7.1.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc.--><path d="M439.8 200.5c-7.7-30.9-22.3-54.2-53.4-54.2h-40.1v47.4c0 36.8-31.2 67.8-66.8 67.8H172.7c-29.2 0-53.4 25-53.4 54.3v101.8c0 29 25.2 46 53.4 54.3 33.8 9.9 66.3 11.7 106.8 0 26.9-7.8 53.4-23.5 53.4-54.3v-40.7H226.2v-13.6h160.2c31.1 0 42.6-21.7 53.4-54.2 11.2-33.5 10.7-65.7 0-108.6M286.2 444.7a20.4 20.4 0 1 1 0-40.7 20.4 20.4 0 1 1 0 40.7M167.8 248.1h106.8c29.7 0 53.4-24.5 53.4-54.3V91.9c0-29-24.4-50.7-53.4-55.6-35.8-5.9-74.7-5.6-106.8.1-45.2 8-53.4 24.7-53.4 55.6v40.7h106.9v13.6h-147c-31.1 0-58.3 18.7-66.8 54.2-9.8 40.7-10.2 66.1 0 108.6 7.6 31.6 25.7 54.2 56.8 54.2H101v-48.8c0-35.3 30.5-66.4 66.8-66.4m-6.6-183.4a20.4 20.4 0 1 1 0 40.8 20.4 20.4 0 1 1 0-40.8"></path></svg> </a> </div> </div> </div> </footer> </div> <div class="md-dialog" data-md-component="dialog"> <div class="md-dialog__inner md-typeset"></div> </div> <script id="__config" type="application/json">{"annotate": null, "base": "../..", "features": ["content.code.copy", "content.code.annotate", "content.tabs.link", "navigation.instant", "navigation.tracking", "navigation.tabs", "navigation.sections", "navigation.top", "toc.follow", "search.suggest", "search.highlight", "search.share"], "search": "../../assets/javascripts/workers/search.2c215733.min.js", "tags": null, "translations": {"clipboard.copied": "Copied to clipboard", "clipboard.copy": "Copy to clipboard", "search.result.more.one": "1 more on this page", "search.result.more.other": "# more on this page", "search.result.none": "No matching documents", "search.result.one": "1 matching document", "search.result.other": "# matching documents", "search.result.placeholder": "Type to start searching", "search.result.term.missing": "Missing", "select.version": "Select version"}, "version": {"default": "latest", "provider": "mike"}}</script> <script src="../../assets/javascripts/bundle.79ae519e.min.js"></script> <script src="../../js/timeago.min.js"></script> <script src="../../js/timeago_mkdocs_material.js"></script> <script id="init-glightbox">const lightbox = GLightbox({"touchNavigation": true, "loop": false, "zoomable": true, "draggable": true, "openEffect": "zoom", "closeEffect": "zoom", "slideEffect": "slide"});
document$.subscribe(()=>{ lightbox.reload(); });
</script></body></html>