Jump to content

twk

Member
  • Posts

    971
  • Joined

  • Last visited

Reputation

575 Spectacular

Personal Information

  • Occupation
    Architectural Designer
  • Homepage
    www.cba-design.co.nz
  • Location
    New Zealand

Recent Profile Visitors

11,242 profile views
  1. Introducing RevCloud Plus – Smarter Revision Clouds for Vectorworks Hi everyone, Over the years you would have seen me mentioning a few of the internal tools and workflows we use at CBA Design while discussing scripting and Vectorworks workflows around the forum. We thought it was finally time to start sharing some of them more publicly and one of the first tools we’re preparing for release is RevCloud Plus. RevCloud Plus is being released through CADPax Software Solutions — a new branch of CBA Design Ltd (https://www.cba-design.co.nz). An architectural practice based in Auckland, New Zealand, who over the years have developed quite a large collection of internal Vectorworks plugins, scripts, and workflow tools to help our team work more efficiently. CADPax really grew out of necessity from day-to-day architectural production work, and we’re now at a point where we finally have a bit more time to focus on releasing some of these tools publicly. RevCloud Plus came about from a fairly simple problem: The native Vectorworks revision clouds, (that work well graphically) didn't have a suitable workflow for us around labels, revision data, issue management, and title block coordination. This has always felt a bit disconnected for larger documentation sets. So we built a workflow that combines those parts together into a single object tool. Current features include: Revision cloud + label together as one object Revision and issue metadata support Store in object revision/approval data Store in object who created the bubble, on what machine they created, as well as who last edited, and on what machine last edited (for multiple user projects/Project Sharing) Configurable bubble and label styles Exchange workflow with Vectorworks title block revision data Plugin object can push/pull data to and from the Title Block Revision journal Active / non-active revision states Through classes and visibility toggles Cloud + label class controls Built around real architectural documentation workflows The plugin has been used internally on live projects for quite a while now, and we’re currently cleaning it up for wider release. Release status We're working through the help files and help videos now, along with the Vectorworks 2026 Partner Program application. Vectorworks 2025 does not require that process, so anyone using VW2025 who is interested can contact us directly. We’re primarily Windows users, and we’re currently arranging testing on Mac as well before the wider public release. At this stage we’re aiming to have RevCloud Plus ready for public release in the next week or two, as we finalise these last pieces. The website is still being built, but if anyone is interested, has questions, or would like early access information, feel free to post here, DM me directly, or email us below and we can add you to the waitlist: info@cadpax.com We also have a number of other Vectorworks plugins in the works as well, all developed from tools we use regularly in our own architectural workflow, including: Timber Retaining Wall Tool Height in Relation to Boundary Envelope Tool Document Issue Manager, which works alongside RevCloud Plus and a number of other internal tools we’re preparing for release So watch this space, and join the waitlist if you’d like to be notified as these become available. We’d also be interested to hear how others are currently handling revision cloud + title block workflows in Vectorworks, and pain points we can think about in later versions. Cheers, Tui
  2. The github reference is less than ideal for manual searches, but I believe the move was done so the updating was more transparent (ie git commits, forks, PRs, etc), git was and still is a difficult workflow for me to wrap my head around, I personally use it for basic version tracking (commit messages, etc). One of the positive side effects, is that any public repository on github is available to be scanned and contextualized by LLM agents. One such being Deepwiki ( I added the Vectorworks Development Wiki to it, and use it often. I just copy and pasted your first post question and the result was near instant. I encourage anyone developing in vectorworks to use it. Quick screengrab: Vectorworks-developer-scripting-DeepWiki.mp4
  3. I learnt recently that the Quick Search in Vectorworks 2026 can expose tools/menu items even if they're not in your current workspace.
  4. Thanks @Lada. But 2027! 🙃.. that's a long wait. I would've thought that with subscriptions and incremental updates between versions, expanding API access wouldn’t necessarily be tied only to major releases, especially for exposing existing internal data rather than introducing new functionality. But for context here's what I'm needing it for: I’ve built an internal document auditor to enforce office standards and perform QA checks across: Layers (Sheets and Design) Classes Records Worksheets Viewports Plugin Styles: Data tags Drawing Labels Reference Markers Elevation Markers Detail Call outs Section Markers The two major gaps preventing this from being complete are: Viewport Plug-in Styles At the moment there is no way to: Query which plug-in styles are assigned to a viewport Validate those styles against office standards Flag non-compliant viewports Even read-only access here would unlock a lot of automation. 2. Data Visualizations There currently appears to be no API access to: List Data Visualizations present in a document Determine which Data Visualization(s) are applied to a given viewport Inspect, at minimum: Criteria used Classes / objects affected Visual overrides being applied Ideally this would also allow assigning or swapping Data Visualizations programmatically, but even query-only access would be a significant step forward. Thanks for the reply, and here's to hoping we could get some of this before 2027. Ive already made enhancement requests for this, a couple of years ago
  5. Hi all, I’m trying to determine whether there is any Script / API access to: Reading or detecting Viewport Styles applied to a viewport Reading or detecting Data Visualizations applied to a viewport (Ideally) assigning or swapping these programmatically I’ve searched the scripting documentation and reviewed the current Viewport object selectors here: https://github.com/Vectorworks/developer-scripting/blob/main/Function Reference/Appendix/pages/Appendix G - Object Selectors.md From what I can see, the selectors cover general viewport properties (update state, render background, view type, position, etc.), but nothing appears to relate to Viewport Styles or Data Visualizations. @Vlado Thanks, Tui
  6. The experience has been great. Very intuitive and helps you understand vectorworks scripting concepts. Used it a lot for understanding how textures are called, etc.
  7. Hi @klinzey, care to elaborate what is mentioned here? What are .vs and .px files? and are you saying if we change our python module files, from .py to .px this will then work with encryption and obfuscation? or just encryption? I feel there are bits left out in this explanation.
  8. The problem is that the code uses vs.MoveTo() and vs.LineTo() to create the worktop profile, which creates an open path of line segments rather than a closed polygon. When you extrude an open path, Vectorworks creates a hollow shell instead of a solid object. vs.BeginXtrd(bottom_z, top_z) first = True for (x, y) in pts: if first: vs.MoveTo(x, y) first = False else: vs.LineTo(x, y) vs.EndXtrd() The Fix: You need to use vs.BeginPoly(), vs.AddPoint(), and vs.EndPoly() to create a proper closed polygon before extruding: vs.BeginXtrd(bottom_z, top_z) vs.BeginPoly() for (x, y) in pts: vs.AddPoint(x, y) vs.EndPoly() vs.EndXtrd() worktop = vs.LNewObj() Note: You don't need to manually close the polygon by appending pts[0] to your points list - vs.EndPoly() automatically closes the polygon for you. So you can remove the line pts.append(pts[0]) from your point-building code. Notes The BeginPoly()/AddPoint()/EndPoly() sequence creates a proper closed polygon object that can be extruded into a solid. The rest of your code correctly uses vs.Rect() for rectangular profiles, which is why those extrusions work properly.
  9. This is almost certainly an SEO content marketing strategy. According to Claude research, every major CAD company does this — Autodesk publishes "What is CAD?" articles, Onshape has "Learn CAD the Easy Way" beginner content, etc. The goal isn't to help existing users. It's to: Rank for high-volume educational search terms Build domain authority across their entire site Capture students and researchers at the awareness stage Own the educational keywords in their space It's a numbers game — publish educational content → rank on Google → maybe 0.5% of that traffic eventually converts. Meanwhile, the Newsroom Digest gets sent to actual architects who already know what detail drawings are. Not criticizing the strategy necessarily, but yeah — the disconnect between the email audience and the article audience is real. Would be better to see "Advanced Detailing Workflows in VW2026" or "Data-Driven Detail Generation" in users' inbox.
  10. Interesting Idea. You can place the temp images on a layer somewhere and reference in with the Image function.
  11. here are some screenshots: The temp object/drawing on document, the worksheet with the values, and the object info palette: The Plugin-Manager, the Plugin Definition: The Parameters: also plugin needs to be event enabled:
  12. I recently indexed the entire Vectorworks official scripting documentation from GitHub using DeepWiki - it's a service that creates an AI-powered chat interface for any GitHub repository's documentation. (<Vectorworks/developer-scripting>) Instead of hunting through dozens of markdown files trying to figure out event-enabled plugins, I just asked DeepWiki directly and it guided me through the entire process. I used it to build this complete testWorksheet.py example that does exactly what you're asking for - dynamically populating popup choices from worksheet data. # testWorksheet.py import vs # Event constants kObjOnInitXProperties = 5 kParametricRecalculate = 3 kObjOnWidgetPrep = 41 kObjOnAddState = 44 # Added constant for clarity # Property constants kObjXPropHasUIOverride = 8 kObjXHasCustomWidgetVisibilities = 12 kObjXPropAcceptStates = 18 # Added constant for clarity kParametricEnableStateEventing = 590 # Added constant for clarity # Event result constants kObjectEventHandled = -8 # Configuration constants POPUP_PARAM_NAME = "WorksheetValues" # Change to match your popup parameter name WORKSHEET_NAME_PARAM = "WorksheetName" def read_popup_values_from_worksheet(worksheet_name: str, start_row: int = 2, end_row: int = 20, column: int = 1): """ How/Why: Reads a clean list of values from a specific worksheet column so a popup can reflect external data. - Uses Vectorworks worksheet API safely, ignoring empty cells and trimming strings. - Keeps row/column 1-based to match VW conventions. """ popup_values = [] # Locate worksheet ws_h = vs.GetObject(worksheet_name) if not ws_h: vs.AlrtDialog(f'Worksheet "{worksheet_name}" not found') return popup_values # Collect values (strings prioritized; numbers converted) for row in range(start_row, end_row + 1): try: if not vs.IsValidWSCell(ws_h, row, column): continue if vs.IsWSCellString(ws_h, row, column): s = vs.GetWSCellStringN(ws_h, row, column) if s and s.strip(): popup_values.append(s.strip()) elif vs.IsWSCellNumber(ws_h, row, column): val = vs.GetWSCellValue(ws_h, row, column) popup_values.append(str(val)) except Exception as e: # Keep robust on malformed cell content vs.AlrtDialog(f"Worksheet read error at row {row}, col {column}: {e}") return popup_values def populate_popup_from_worksheet(widget_id: int, worksheet_name: str): """ How/Why: Rebuilds the popup choices to reflect current worksheet content during WidgetPrep, ensuring OIP shows up-to-date options without forcing recalculation. """ # Reset current popup items vs.vsoWidgetPopupClear(widget_id) # Validate input if not worksheet_name or not worksheet_name.strip(): return # Configure read window start_row = 2 # Skip header end_row = 20 # Adjust for your data column = 1 # 1-based # Read and add values = read_popup_values_from_worksheet(worksheet_name, start_row, end_row, column) for value_id, display_text in enumerate(values): # Note: API takes integer IDs; documentation may show string vs.vsoWidgetPopupAdd(widget_id, value_id, display_text) # Optional separator + edit affordance if values: vs.vsoWidgetPopupAdd(widget_id, len(values), "-") vs.vsoWidgetPopupAdd(widget_id, len(values) + 1, "Edit Worksheet...") def create_plugin_geometry(): """ How/Why: Keeps geometry creation isolated so ParametricRecalculate stays tidy and testable. Replace this with your actual object creation code. """ # Example placeholder geometry vs.Rect(0, 0, 100, 100) vs.Circle(50, 50, 25) vs.Line((0, 0), (100, 100)) # 3D example: # vs.Box(0, 0, 0, 100, 100, 50) def main(): """ How/Why: Central event router that follows VW's event-enabled plugin rules. - InitX: declare capabilities and insert OIP widgets - AddState: only add state (no other logic) - WidgetPrep: populate dynamic UI (popups, visibilities, etc.) - Recalculate: build/update geometry and clear plugin state """ event, message = vs.vsoGetEventInfo() # Get plugin info (may be incomplete very early during init; do not exit early) ok, plugin_name, plugin_handle, record_handle, wall_handle = vs.GetCustomObjectInfo() # Map param name to OIP widget ID (param index is 0-based; widget ID is 1-based) # Guard for name lookup to avoid exceptions during very early init popup_param_index = None if plugin_name: idx = vs.vsoParamName2Index(plugin_name, POPUP_PARAM_NAME) if idx is not None and idx >= 0: popup_param_index = idx + 1 if event == kObjOnInitXProperties: # Enable extended behaviors and insert OIP widgets vs.SetObjPropVS(kObjXPropHasUIOverride, True) vs.SetObjPropVS(kObjXHasCustomWidgetVisibilities, True) vs.SetPrefInt(kParametricEnableStateEventing, 1) vs.SetObjPropVS(kObjXPropAcceptStates, True) vs.vsoInsertAllParams() elif event == kObjOnAddState: # VW rule: only add current state here if plugin_handle: _ = vs.vsoStateAddCurrent(plugin_handle, message) elif event == kObjOnWidgetPrep: # Rebuild dynamic popup content if popup_param_index is not None and plugin_handle and plugin_name: ws_name = vs.GetRField(plugin_handle, plugin_name, WORKSHEET_NAME_PARAM) if ws_name and ws_name.strip(): populate_popup_from_worksheet(popup_param_index, ws_name) # Must mark as handled vs.vsoSetEventResult(kObjectEventHandled) elif event == kParametricRecalculate: # Main geometry update create_plugin_geometry() # Clear state after successful recalc if plugin_handle: vs.vsoStateClear(plugin_handle) # PIOs are executed by VW; keep for standalone testing if needed: # if __name__ == "__main__": # main() This is honestly a game-changer for learning Vectorworks scripting. Tools like LLMs (ChatGPT/Claude/Gemini, etc) and now DeepWiki make it so much easier than the old days of digging through scattered documentation and forum posts. You can literally have a conversation with the official docs! This link is another prompt I asked it to prepare docs on event-enabled plugins using the script as context - really helpful for understanding the full workflow. https://deepwiki.com/search/earlier-we-built-this-code-tog_a8da7663-214c-428f-8690-e5863ffcac2b?mode=fast Basically: Event-Enabled Plugin Quick Reference Your testWorksheet.py demonstrates a parametric plugin that handles four key events to customize the Object Info Palette and manage dynamic content. Core Events Event 5 (InitXProperties) - Plugin setup Enable UI customization with SetObjPropVS(kObjXPropHasUIOverride, True) Add all parameters as widgets with vsoInsertAllParams() Event 44 (AddState) - State tracking Only call vsoStateAddCurrent(plugin_handle, message) - nothing else! Event 41 (WidgetPrep) - Dynamic UI updates Populate your popup with vsoWidgetPopupClear() and vsoWidgetPopupAdd() Must end with vsoSetEventResult(-8) Event 3 (ParametricRecalculate) - Geometry creation Create your geometry here Always call vsoStateClear(plugin_handle) when finished Key Documentation Links: Object Events Overview - Complete event system guide Parametric Custom Shape Pane Popup - Dynamic popup examples Plug-in with widget basic example - Python widget tutorial Widget Tips: Use vsoParamName2Index(plugin_name, param_name) + 1 to get widget IDs Parameter index is 0-based, widget ID is 1-based (hence the +1) The pattern is simple: setup (5) → track changes (44) → update UI (41) → create geometry (3).
  13. Yes, you need to have an event-enabled plugin to do this
  14. You use the stake tool, and set the parameters accordingly. (Mode=Set eleve to site model)
×
×
  • Create New...