PageSourceSearch

https://docs-vrgeo-version3.netlify.app/assets/js/8c280407.3d6a9b3a.js

js docs-vrgeo-version3.netlify.app collected 2026-10-03 10:40:17 UTC 17,569 bytes, 1 lines download raw bytes

1"use strict";(globalThis.webpackChunkvrgs_docs_v_3_1=globalThis.webpackChunkvrgs_docs_v_3_1||[]).push([[4729],{83341(e,n,t){t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>a,default:()=>d,frontMatter:()=>o,metadata:()=>i,toc:()=>h});const i=JSON.parse('{"id":"general/setup-system/python-scripting","title":"Python Scripting","description":"Run Python inside VRGS \u2014 the script editor and its ribbon tab, the console, installing packages with pip, and a complete reference for the ten functions in the built-in vrgs module.","source":"@site/docs/general/setup-system/python-scripting.md","sourceDirName":"general/setup-system","slug":"/general/setup-system/python-scripting","permalink":"/docs/next/general/setup-system/python-scripting","draft":false,"unlisted":false,"editUrl":"https://github.com/vrgeoscience/vrgs_docs_v3/tree/master/docs/general/setup-system/python-scripting.md","tags":[],"version":"current","sidebarPosition":5.5,"frontMatter":{"id":"python-scripting","title":"Python Scripting","sidebar_label":"Python Scripting","description":"Run Python inside VRGS \u2014 the script editor and its ribbon tab, the console, installing packages with pip, and a complete reference for the ten functions in the built-in vrgs module.","keywords":["Python","scripting","vrgs module","automation","numpy","pip","attributes","API"],"sidebar_position":5.5},"sidebar":"docs","previous":{"title":"Project Properties","permalink":"/docs/next/general/setup-system/project-properties"},"next":{"title":"Third-Party Licenses","permalink":"/docs/next/general/setup-system/third-party-licenses"}}');var s=t(74848),r=t(28453);const o={id:"python-scripting",title:"Python Scripting",sidebar_label:"Python Scripting",description:"Run Python inside VRGS \u2014 the script editor and its ribbon tab, the console, installing packages with pip, and a complete reference for the ten functions in the built-in vrgs module.",keywords:["Python","scripting","vrgs module","automation","numpy","pip","attributes","API"],sidebar_position:5.5},a=void 0,l={},h=[{value:"Opening the editor",id:"opening-the-editor",level:2},{value:"Output",id:"output",level:2},{value:"Installing packages",id:"installing-packages",level:2},{value:"The <code>vrgs</code> module",id:"the-vrgs-module",level:2},{value:"Listing what is in the project",id:"listing-what-is-in-the-project",level:3},{value:"Geometry",id:"geometry",level:3},{value:"Attributes",id:"attributes",level:3},{value:"Writing an attribute back",id:"writing-an-attribute-back",level:3},{value:"Orientations",id:"orientations",level:3},{value:"A worked example",id:"a-worked-example",level:2},{value:"Limits worth knowing",id:"limits-worth-knowing",level:2},{value:"Tips and troubleshooting",id:"tips-and-troubleshooting",level:2},{value:"See also",id:"see-also",level:2}];function c(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h2:"h2",h3:"h3",li:"li",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,r.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsxs)(n.p,{children:["VRGS embeds a ",(0,s.jsx)(n.strong,{children:"Python 3.13"})," interpreter and exposes the current project to it\nthrough a built-in module called ",(0,s.jsx)(n.code,{children:"vrgs"}),". Scripts run inside the running\napplication against the project you have open \u2014 this is not a batch interface\nthat loads a project from disk."]}),"\n",(0,s.jsx)(n.p,{children:"The API is deliberately small: ten functions that let you read geometry and\nattributes out of meshes and point clouds, read the project's orientations, and\npush a computed attribute back onto a mesh so it can be coloured, filtered and\nsaved like any other. Anything you can express in NumPy, scikit-learn or SciPy\ncan therefore be run against a VRGS model and its result brought back into the\n3D view."}),"\n",(0,s.jsx)(n.h2,{id:"opening-the-editor",children:"Opening the editor"}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Home ribbon \u2192 Windows \u2192 Python Script"})}),"\n",(0,s.jsxs)(n.p,{children:["This opens a script editor window, and with it a context-sensitive ",(0,s.jsx)(n.strong,{children:"Python"}),"\nribbon tab:"]}),"\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Panel"}),(0,s.jsx)(n.th,{children:"Command"}),(0,s.jsx)(n.th,{children:"What it does"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.strong,{children:"Save"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.strong,{children:"Save Script"})}),(0,s.jsx)(n.td,{children:"Write the script to its file."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.strong,{children:"Display"})}),(0,s.jsxs)(n.td,{children:[(0,s.jsx)(n.strong,{children:"Increase Size"})," / ",(0,s.jsx)(n.strong,{children:"Decrease Size"})," / ",(0,s.jsx)(n.strong,{children:"Font"})]}),(0,s.jsx)(n.td,{children:"Editor font controls."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.strong,{children:"Run"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.strong,{children:"Run"})}),(0,s.jsx)(n.td,{children:"Execute the script in the embedded interpreter."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.strong,{children:"Run"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.strong,{children:"Python Output"})}),(0,s.jsxs)(n.td,{children:["Open the console window that shows the script's output in real time. Its dropdown has ",(0,s.jsx)(n.strong,{children:"Clear Console"}),"."]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.strong,{children:"Run"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.strong,{children:"Command Prompt"})}),(0,s.jsxs)(n.td,{children:["Open a Windows command prompt \u2014 this is how you run ",(0,s.jsx)(n.code,{children:"pip install"}),"."]})]})]})]}),"\n",(0,s.jsx)(n.p,{children:"A new script starts from a template that shows the shape of the thing:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-python",children:'import numpy as np\nimport vrg
1s\n\nprint("List Of Meshes", vrgs.mesh_list())\nprint("List Of Point Clouds", vrgs.pointcloud_list())\n'})}),"\n",(0,s.jsx)(n.h2,{id:"output",children:"Output"}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"print()"})," and any error traceback are captured and routed to VRGS:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["With the ",(0,s.jsx)(n.strong,{children:"Python Output"})," console open, output appears there as it is\nproduced."]}),"\n",(0,s.jsxs)(n.li,{children:["With no console open, output is collected and written to the ",(0,s.jsx)(n.strong,{children:"messages\npanel"})," when the script finishes."]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"For a long-running script, open the console first \u2014 otherwise you see nothing\nuntil it is over."}),"\n",(0,s.jsx)(n.h2,{id:"installing-packages",children:"Installing packages"}),"\n",(0,s.jsxs)(n.p,{children:["The interpreter is a normal Python installation, so ",(0,s.jsx)(n.code,{children:"pip"})," works. Use\n",(0,s.jsx)(n.strong,{children:"Command Prompt"})," on the Python ribbon tab, then:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"pip install scipy scikit-learn matplotlib\n"})}),"\n",(0,s.jsx)(n.p,{children:"Packages installed this way are available to scripts on the next run. NumPy is\nalready present."}),"\n",(0,s.jsx)(n.admonition,{title:"Where the interpreter lives",type:"note",children:(0,s.jsxs)(n.p,{children:["The Python home is set by ",(0,s.jsx)(n.strong,{children:"Python Path"})," in\n",(0,s.jsx)(n.a,{href:"/docs/next/general/setup-system/project-properties",children:"Project Properties"})," \u2192 ",(0,s.jsx)(n.em,{children:"Advanced & Diagnostics"})," \u2014 the\nfolder containing the Python 3.13 runtime. If scripts fail to start, check that\nfirst; VRGS logs the Python version it found when it initialises."]})}),"\n",(0,s.jsxs)(n.h2,{id:"the-vrgs-module",children:["The ",(0,s.jsx)(n.code,{children:"vrgs"})," module"]}),"\n",(0,s.jsx)(n.p,{children:"Ten functions, all of them free functions on the module. Object names are the\nnames shown in the project tree."}),"\n",(0,s.jsx)(n.h3,{id:"listing-what-is-in-the-project",children:"Listing what is in the project"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-python",children:"vrgs.mesh_list()        # -> [(name, record_id), ...]\nvrgs.pointcloud_list()  # -> [(name, record_id), ...]\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Both return a list of ",(0,s.jsx)(n.code,{children:"(name, record_id)"})," tuples covering every mesh or point\ncloud in the project, including those inside groups."]}),"\n",(0,s.jsx)(n.h3,{id:"geometry",children:"Geometry"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-python",children:"vrgs.mesh_vertices(mesh_name)         # -> [[x, y, z], ...]\nvrgs.pointcloud_vertices(cloud_name)  # -> [[x, y, z], ...]\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Every vertex of the named object, in project coordinates. Returns ",(0,s.jsx)(n.code,{children:"None"})," if no\nobject of that type has that name."]}),"\n",(0,s.jsx)(n.h3,{id:"attributes",children:"Attributes"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-python",children:"vrgs.mesh_attribute_list(mesh_name)         # -> [attribute_name, ...]\nvrgs.pointcloud_attribute_list(cloud_name)  # -> [attribute_name, ...]\n\nvrgs.mesh_attribute(mesh_name, attribute_name)         # -> [value, ...]\nvrgs.pointcloud_attribute(cloud_name, attribute_name)  # -> [value, ...]\n"})}),"\n",(0,s.jsxs)(n.p,{children:["The list functions give you the attribute layers an object carries; the value\nfunctions give you one layer's values, in vertex order \u2014 so element ",(0,s.jsx)(n.em,{children:"i"})," of the\nattribute list corresponds to vertex ",(0,s.jsx)(n.em,{children:"i"})," of the geometry list."]}),"\n",(0,s.jsx)(n.h3,{id:"writing-an-attribute-back",children:"Writing an attribute back"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-python",children:"vrgs.mesh_add_attribute(mesh_name, attribute_name, values)  # -> True / False\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Creates a new ",(0,s.jsx)(n.strong,{children:"per-vertex attribute layer"})," on the named mesh and fills it from\n",(0,s.jsx)(n.code,{children:"values"}),", which must be a list as long as the mesh's vertex count. Returns\n",(0,s.jsx)(n.code,{children:"True"})," on success, ",(0,s.jsx)(n.code,{children:"False"})," if the mesh was not found or the list was not usable."]}),"\n",(0,s.jsx)(n.p,{children:"The new layer's range and histogram are computed automatically, the display is\nrefreshed, and the project is marked as 
1needing a save \u2014 so the attribute is\nimmediately available for colouring and filtering, and persists once you save."}),"\n",(0,s.jsx)(n.admonition,{title:"The new layer is integer-typed",type:"caution",children:(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"mesh_add_attribute"})," creates an ",(0,s.jsx)(n.strong,{children:"integer"})," attribute layer, so floating-point\nvalues are truncated. It is the right function for a class label, a cluster ID\nor a boolean flag. To bring a continuous value back, scale it to a useful\ninteger range first (for example curvature \xd7 1000), or compute it inside VRGS\ninstead \u2014 see ",(0,s.jsx)(n.a,{href:"/docs/next/general/meshes-point-clouds/attributes",children:"Attributes"}),"."]})}),"\n",(0,s.jsx)(n.h3,{id:"orientations",children:"Orientations"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-python",children:"vrgs.orientations()\n# -> [(name, tree_path, record_id, x, y, z, dip, azimuth), ...]\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Every orientation measurement in the project, each as an eight-element tuple:\nits name, its full path in the interpretation tree, its record number, its\nposition, and its dip and dip-azimuth. This is the route to running your own\nclustering or statistics over a structural dataset \u2014 see\n",(0,s.jsx)(n.a,{href:"/docs/next/general/interpretation/basic-interpretation",children:"Basic Interpretation"})," for how\norientations are made in the first place."]}),"\n",(0,s.jsx)(n.h2,{id:"a-worked-example",children:"A worked example"}),"\n",(0,s.jsx)(n.p,{children:"Classify a mesh's vertices by elevation and write the class back as an attribute\nyou can colour by:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-python",children:'import numpy as np\nimport vrg
1s\n\n# Take the first mesh in the project.\nmeshes = vrgs.mesh_list()\nif not meshes:\n    print("No meshes in this project")\nelse:\n    name = meshes[0][0]\n    print("Working on", name)\n\n    verts = np.array(vrgs.mesh_vertices(name))\n    z = verts[:, 2]\n\n    # Five equal-interval elevation bands, as integer class IDs.\n    bands = np.digitize(z, np.linspace(z.min(), z.max(), 6)[1:-1])\n\n    ok = vrgs.mesh_add_attribute(name, "Elevation Band", bands.tolist())\n    print("Attribute written:", ok)\n'})}),"\n",(0,s.jsxs)(n.p,{children:["Run it, then colour the mesh by ",(0,s.jsx)(n.strong,{children:"Elevation Band"})," from its attribute list."]}),"\n",(0,s.jsx)(n.p,{children:"The same shape works for anything: read vertices and existing attributes, do the\nwork in NumPy or scikit-learn, write an integer result back."}),"\n",(0,s.jsx)(n.h2,{id:"limits-worth-knowing",children:"Limits worth knowing"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"The API is read-mostly."})," You can read geometry, attributes and\norientations, and write one thing back \u2014 a per-vertex integer attribute on a\nmesh. There is no scripted access to creating polylines, running commands, or\ndriving the camera."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Point clouds are read-only."})," There is no ",(0,s.jsx)(n.code,{children:"pointcloud_add_attribute"}),"."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Names must match the tree exactly"}),", and a name that does not resolve\nreturns ",(0,s.jsx)(n.code,{children:"None"})," rather than raising \u2014 check for it."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Scripts run on the UI thread."})," A long computation makes VRGS unresponsive\nwhile it runs. Print progress so you can see it is alive."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsxs)(n.strong,{children:[(0,s.jsx)(n.code,{children:"help(vrgs)"})," is not reliable."]})," Several functions carry a copy-pasted\ndocstring that describes a different function. The reference above is the\nbehaviour; the docstrings are not."]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"tips-and-troubleshooting",children:"Tips and troubleshooting"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Nothing happens when I click Run."})," Open ",(0,s.jsx)(n.strong,{children:"Python Output"})," first \u2014 the error\nis almost certainly there. With the console closed, output only appears at the\nend."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsxs)(n.strong,{children:[(0,s.jsx)(n.code,{children:"import vrgs"})," fails."]})," The module is registered by VRGS's own interpreter,\nso it only exists inside a script run from the Python tab. It cannot be\nimported from an external Python."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsxs)(n.strong,{children:[(0,s.jsx)(n.code,{children:"import numpy"})," fails."]})," Check ",(0,s.jsx)(n.strong,{children:"Python Path"})," in Project Properties points\nat the runtime VRGS ships with, not another Python on the machine."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"The attribute appears but everything is one colour."})," Integer truncation \u2014\nyour values were all between 0 and 1. Scale them up."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"The vertex count does not match my array."})," ",(0,s.jsx)(n.code,{children:"mesh_vertices"})," returns every\nvertex including those hidden by filtering; do not assume it matches a\nfiltered view."]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"see-also",children:"See also"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"/docs/next/general/meshes-point-clouds/attributes",children:"Attributes"})," \u2014 what VRGS can compute without scripting."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"/docs/next/general/setup-system/project-properties",children:"Project Properties"})," \u2014 the Python Path setting."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"/docs/next/general/setup-system/ai-ml-requirements",children:"AI & Machine Learning Requirements"})," \u2014 the built-in machine-learning tools."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"/docs/next/general/interpretation/basic-interpretation",children:"Basic Interpretation"})," \u2014 where orientations come from."]}),"\n"]})]})}function d(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(c,{...e})}):c(e)}},28453(e,n,t){t.d(n,{R:()=>o,x:()=>a});var i=t(96540);const s={},r=i.createContext(s);function o(e){const n=i.useContext(r);return i.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:o(e.components),i.createElement(r.Provider,{value:n},e.children)}}}]);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.