Hey there,
this is for the people working with VisualArq and Rhino.
Rhino knows Layer States, VisualArq generates the 2D Documentation.
Layer States are pretty powerful to “filter” the documentationprocess, so you want one planview with only the doors, one with walls but without the windows and so on;
To achieve that, you can set Rhino Layer States.
Setting the desired Layer State, and updtading afterwards is a little bit annoying, and can be confusing.
So, i had the idea (i know this concept for documentation output from one of the big bim players, but its not REVIT XD) to link the Rhino Layer States to the VisualArq Plan and Section Views.
So: Set a key named “ES” for your plan and section views. The value has to be the name of the Layer State you want to “link” to the VisualArq Planview/SectionView.
To start the Script, a Layer State named “Default” has to be set aswell; The script will not start without this Default Layer State.
Default should define your general view properties, so layer colours and so on, as its called a default setting ![]()
If your knew to layer states, check them out first, have a look at how they behave.
I made the script with ChatGpt, im an architect no programmer, so this thing here is a working prototype, a proof of concept.
I’ll link it to my toolbar… oh gosh i love Rhino and VisualArq is getting better every day ![]()
Alle Angaben wie immer ohne Gewähr ![]()
Anyway, HAVE FUN with this ![]()
-- coding: utf-8 --
“”"
VisualARQ Documentation Generator
Idle-state version
Supports:
- Plan Views (*Planansicht)
- Section Views (*Schnittansicht)
Execution:
- Check that the required BASE layer state exists.
- Restore BASE layer state.
- Discover documentation views.
- Group by ES user text.
- For each ES:
- Restore layer state
- Idle
- Select documentation objects
- Idle
- Run _vaUpdate
- Restore BASE layer state.
“”"
import Rhino
BASE_LAYER_STATE = “Default”
USERTEXT_KEY = “ES”
class LayerStateJob(object):
def init(self, state):
self.state = state
self.views = # (guid, type)
class DocumentationGenerator(object):
def __init__(self):
self.doc = Rhino.RhinoDoc.ActiveDoc
self.jobs = []
self.lookup = {}
self.job_index = -1
self.phase = "init"
def check_base_layer_state(self):
names = list(self.doc.NamedLayerStates.Names)
if BASE_LAYER_STATE not in names:
print("")
print("=" * 70)
print("ERROR")
print("=" * 70)
print("")
print("Required base layer state '{}' not found.".format(BASE_LAYER_STATE))
print("Please create or rename a Named Layer State to '{}'.".format(BASE_LAYER_STATE))
print("")
print("The documentation generator always restores this")
print("layer state before and after every update queue.")
print("")
print("Made with my 8 Euro ChatGpt subscription. JS ")
print("")
print("Layer State named Default has to be set to make the script work. 384 xD")
return False
return True
def discover(self):
self.jobs = []
self.lookup = {}
print("Discovering documentation views...")
for obj in self.doc.Objects:
if not isinstance(obj, Rhino.DocObjects.InstanceObject):
continue
idef = obj.InstanceDefinition
if idef is None:
continue
if not (
idef.Name.startswith("*Planansicht")
or idef.Name.startswith("*Schnittansicht")
):
continue
state = obj.Attributes.GetUserString(USERTEXT_KEY)
if not state:
continue
if state not in self.lookup:
job = LayerStateJob(state)
self.lookup[state] = job
self.jobs.append(job)
typ = "PlanView"
if idef.Name.startswith("*Schnittansicht"):
typ = "SectionView"
self.lookup[state].views.append((obj.Id, typ))
print("Found {} layer state job(s).".format(len(self.jobs)))
def restore(self, state):
print("")
print("Restoring layer state '{}'".format(state))
self.doc.NamedLayerStates.Restore(
state,
Rhino.DocObjects.Tables.RestoreLayerProperties.All
)
self.doc.Views.Redraw()
def select_current(self):
self.doc.Objects.UnselectAll()
job = self.jobs[self.job_index]
print("Selecting {} documentation object(s):".format(len(job.views)))
for gid, typ in job.views:
self.doc.Objects.Select(gid)
print(" {:12} {}".format(typ, gid))
self.doc.Views.Redraw()
def idle(self, sender, e):
if self.phase == "init":
self.discover()
self.restore(BASE_LAYER_STATE)
self.phase = "next"
elif self.phase == "next":
self.job_index += 1
if self.job_index >= len(self.jobs):
self.restore(BASE_LAYER_STATE)
Rhino.RhinoApp.Idle -= self.idle
print("")
print("=" * 70)
print("Documentation update finished.")
print("=" * 70)
return
job = self.jobs[self.job_index]
print("")
print("=" * 70)
print("Job {} / {}".format(self.job_index + 1, len(self.jobs)))
print("Layer State: {}".format(job.state))
print("=" * 70)
self.restore(job.state)
self.phase = "select"
elif self.phase == "select":
self.select_current()
self.phase = "update"
elif self.phase == "update":
print("Running _vaUpdate...")
Rhino.RhinoApp.RunScript("_vaUpdate", True)
self.doc.Objects.UnselectAll()
self.doc.Views.Redraw()
self.phase = "next"
def run(self):
print("")
print("=" * 70)
print("VisualARQ Documentation Generator")
print("=" * 70)
print("Required base layer state : '{}'".format(BASE_LAYER_STATE))
print("")
if not self.check_base_layer_state():
return
print("Base layer state found.")
print("Starting update queue...")
print("")
Rhino.RhinoApp.Idle += self.idle
if name == “main”:
DocumentationGenerator().run()