# -*- coding: utf-8 -*- # # Gravity load chasing -- PLACEHOLDER. Nothing is implemented. # # It does not write to the Revit model and never will -- like Lateral # Extract, this is meant to be an extractor: read the model, write a file # elsewhere. This one's target is Excel -- it is meant to extract # information and write an Excel workbook. The owner's framing, verbatim # (2026-08-30): # # gravity-load-chasing 是设计,但是我一两句话说不清楚。这不是一个现在就要推的 # 项目,先做个按钮跟占位符出来。这将是一个不小于 panel_lift 的功能性按钮。 # # "I cannot say it in a sentence or two" is a statement about the problem, so # this file does not try to say it either. It states what is settled, states # that the rest is not, and prints the list of open questions -- above all the # ones only he can answer, because those are what the placeholder is FOR. A # placeholder that quietly starts making engineering assumptions is worse than # an empty one; a placeholder that collects the open questions is worth having. # # The full document is QNA/gravity-load-chasing.md. This script deliberately # carries the substance rather than only a pointer: the person who presses the # button is in Revit, not in a text editor, and "see the file" is how a # placeholder becomes a dead end. # # WHAT THIS FILE MUST NOT GROW INTO # --------------------------------- # No arithmetic. No load model, no tributary rule, no accumulation. No # knowledge key, no schema field, no config default, no data structure, no file # format. None of that has been chosen by anybody, and structure invented ahead # of the method is how a placeholder turns into a set of assumptions nobody # agreed to. If something looks obviously needed, it goes in the QNA document # as a PROPOSAL and waits. # # It also reads nothing. Not geometry, not parameters, not the knowledge # layers. It opens no Transaction, because there is nothing to write and there # never will be from this file. The only thing it touches is the model's title, # so the report says which session printed it. # pylint: disable=import-error,invalid-name,broad-except # `__title__` mirrors bundle.yaml's `title:` and is otherwise dead -- # pyRevit reads it only `if not self.meta`. It is kept in step so that # trimming a bundle file cannot bring an old name back. One line, no # `\n`: this button is a row in a `.pulldown`, and a row has no second # line to put one on. __title__ = 'Gravity (WIP)' import os from pyrevit import revit, script doc = revit.doc output = script.get_output() output.close_others() TITLE = 'Gravity Load Chasing' NOTES = 'QNA/gravity-load-chasing.md' def notes_path(): """Absolute path to the design-notes document, if it can be found. Four levels up from this file is the extension folder; one more is the repo. Purely a convenience for the reader -- a miss costs a line, never the report. """ try: here = os.path.dirname(os.path.abspath(__file__)) repo = os.path.abspath(os.path.join(here, '..', '..', '..', '..')) found = os.path.join(repo, 'QNA', 'gravity-load-chasing.md') if os.path.isfile(found): return found except Exception: pass return None # --------------------------------------------------------------- the report output.print_md('# {0} — NOT IMPLEMENTED'.format(TITLE)) output.print_md( '**None of this feature is built.** There is no calculation behind this ' 'button, and nothing was read from the model to produce this page. That ' 'is deliberate and it is the whole state of the work: a button, and a ' 'document holding the questions.') try: output.print_md('Model **{0}** — opened, not read.'.format(doc.Title)) except Exception: pass output.print_md('---') output.print_md('## What it will be') output.print_md( 'Gravity load chasing, as the owner put it on 2026-08-30: *"it is ' 'design, but I cannot say it in a sentence or two. It is not a project ' 'to push right now — make a button and a placeholder first. It ' 'will be a functional button no smaller than Panel Lift Check."*') output.print_md( 'One thing beyond that quote is already settled: like Lateral Extract, ' 'this tool does not write to the Revit model and never will. Both are ' 'extractors — read the model, write a file elsewhere. This one\'s ' 'target is **Excel**: it is meant to extract information and write an ' 'Excel workbook. Nothing here does that yet.') output.print_md( 'Only four things follow from the quote itself, and nothing here will ' 'pretend to more:') output.print_md( '1. It is **design**, not checking.\n' '2. It **cannot yet be specified**, and that is a fact about the ' 'problem, not about anybody\'s time.\n' '3. It is **not being pushed now**.\n' '4. When it is built it is a **full feature** — its own ' 'engineering core, its own report, its own tests — at least the ' 'size of Panel Lift Check.') output.print_md('## Two boundaries that are already settled') output.print_md( '**It is design, not checking, and the liability is different.** ' 'Everything else on this panel reviews work that already exists — ' 'Ticket QC compares a drawn ticket to the model, Panel Lift Check judges ' 'rigging somebody placed, Reinforcing Suggestion proposes donors for a ' 'human to accept. In each case the original work is still there to look ' 'at if the tool is wrong. Gravity load chasing produces the answer ' 'itself, and it goes out under an engineer\'s seal. That has to shape ' 'the design from the first commit; it cannot be added at the end.') output.print_md( '**Its input is not the current model.** It needs old jobs and their ' 'spreadsheets as samples and controls — mass-layout among them. ' 'Nothing else in this extension works that way. Those files also carry ' 'client and job identity, which may never enter the repository, so where ' 'the controls live is a real constraint on the project layout and not a ' 'detail for later.') output.print_md( '**Carried forward from the reinforcing work** (see ' '`QNA/reinforcing-suggestion-brief.md`): the plant standard bands ' 'vertical reinforcing `0.2H / PER DESIGN / 0.2H`, and the middle band is ' 'explicitly the engineer\'s own calculation for that one piece. The ' 'reinforcing matcher is forbidden from proposing it, because presenting ' 'one panel\'s design calculation as another panel\'s answer would look ' 'exactly like an ordinary suggestion. Gravity load chasing stands on the ' 'same ground — its entire output is that class of quantity. So the ' 'rule here is the mirror image: **a result from one job must never ' 'become an input to another by any automatic path**, and nothing this ' 'tool produces may ever be presented with the confidence the checking ' 'tools use.') output.print_md('## What it will need from you before it can be built') output.print_md( 'This is the useful half of a placeholder. None of these have answers ' 'yet, and none will be invented:') output.print_md( '- **Old jobs, and the spreadsheets that go with them.** Which ones, and ' 'where they can be reached from — they cannot live in the ' 'repository.\n' '- **Mass-layout: what it actually is.** A spreadsheet, a tool, a stage ' 'of the job? Who produces it, when, in what format?\n' '- **Which of those jobs are the controls**, and what counts as passing ' '— reproducing your number to within what tolerance, on which ' 'quantities?\n' '- **Whether the spreadsheets are machine-readable** — fixed ' 'columns and stable sheet names, or hand-formatted per job. This is a ' 'large fork: a parser, or an import UI.\n' '- **What is being chased, over what unit, producing what.** One panel, ' 'one wall line, a whole building; a number per piece, a table, a ' 'drawing.\n' '- **Which method governs** — which standard and edition, and ' 'whether the plant has its own that supersedes it.\n' '- **Which loads are in scope**, and what arrives as given rather than ' 'computed.\n' '- **Design, or a first pass an engineer edits.** Different products, ' 'not different wordings.\n' '- **Read-only, or not.** Everything in this extension is read-only ' 'today. Is this the feature that changes that?') output.print_md('## The five that block everything else') output.print_md( 'The rest can be discovered while building. These cannot — each ' 'one changes the shape of the whole thing, and getting one wrong is a ' 'rewrite rather than a fix:') output.print_md( '1. What is being chased, over what unit, producing what.\n' '2. What mass-layout is, and whether the sample spreadsheets can be read ' 'by a program.\n' '3. Where the controls live, given that they are client work.\n' '4. Design or first pass; read-only or not.\n' '5. Which method governs.') output.print_md('## What was deliberately not built') output.print_md( 'So it reads as a decision and not an oversight: no load model, no ' 'tributary logic, no accumulation rule, no arithmetic. No knowledge key, ' 'no schema field, no config default, no data structure, no file format. ' 'No library module on either side of the CPython boundary. Anything that ' 'looked obviously needed was written into the notes as a **proposal** ' 'instead, so that it gets chosen rather than inherited.') output.print_md('---') found = notes_path() if found: output.print_md( 'The full scope, every open question, and the proposals are in ' '`{0}`.'.format(found)) else: output.print_md( 'The full scope, every open question, and the proposals are in ' '`{0}` in the repository.'.format(NOTES)) output.print_md( 'Answers are welcome anywhere — in that file, or in ' '`QNA/questions.md` the usual way. Until they arrive this button stays ' 'exactly as honest as it is now.')