Hey there!
We would like to implement your newest feature of selecting a geometry in the 3d view and further process this in grasshopper. Because the grasshopper calculation can only be made when the âfacadeâ is selected, we thougt of splitting the input (geometry and data) and selection and the output in two pages. But we are stuck at this stage. How do we define the pages in our controller and how do we make a geometryview that is only for selecting the facade without processing it? (processing should be done in the second page)
This is our state of the script:
from io import BytesIO
import json
import rhino3dm
import os
from viktor import ViktorController, File
from viktor.parametrization import NumberField, FileField, Text, Step, ViktorParametrization, OptionField, OptionListElement, ActionButton, GeometrySelectField, GeometryMultiSelectField
from viktor.external.generic import GenericAnalysis
from viktor.views import GeometryAndDataView, GeometryAndDataResult, DataGroup, DataItem
class Parametrization(ViktorParametrization):
intro = Text("## PV Machbarkeitsanalyse \n Das Script Level 1 berechnet den Ertrag der jeweiligen Input Fassaden FlÀche \n\n Laden sie Ihre FassadenflÀche und Kontextgeometrien hoch und geben sie die vorgegebenen Parameter an:")
# Input fields
step_1 = Step("Stufe 1: Modellupload", ['run_grasshopper'])
step_1.selected_geometry = GeometrySelectField("WÀhle eine FassadenflÀche aus")
step_1.selected_geometries = GeometryMultiSelectField("WĂ€hle die Umgebungsgeometrie aus")
step_1.Modell = FileField('Modell', file_types=['.3dm'], max_size=100_000_000)
step_2 = Step("Stufe 2: Berechnung", views=['run_grasshopper'])
step_2.Modultyp = OptionField('Modultyp', options=[OptionListElement('0', 'L 1300x875'),
OptionListElement('1', 'Q 1300x720'),
OptionListElement('2', 'M 985x875'),
OptionListElement('3', 'S 985x720')], default=0)
step_2.Eigenverbrauch = NumberField("Eigenverbrauch in % des Gesamtertrages", default=50)
step_2.Investitionskosten = NumberField("Investitionskosten", default=10000)
step_2.Instandhaltungskosten = NumberField("Instandhaltungskosten in % der Investitionskosten", default=2.0)
step_2.Foerderbeitrag = NumberField("Förderbeitrag %", default=6)
step_2.Strompreis = NumberField("Strompreis(Fr./kWh)", default=1.0)
step_2.Einspeiseverguetung = NumberField("Einspeiseverguetung(Fr./kWh)", default=1)
step_2.Zeitraum = NumberField("Zeitraum(Jahre)", default=5)
class Controller(ViktorController):
label = 'My Entity Type'
parametrization = Parametrization(width=30)
@GeometryAndDataView("Geometry", duration_guess=0, update_label='Run Grasshopper')
def run_grasshopper(self, params, **kwargs):
rhino_upload = params['Modell'].file
selected_geometry = params.selected_geometry
selected_geometries = params.selected_geometries
# Read the rhino file
gh_file = rhino3dm.File3dm.FromByteArray(rhino_upload.getvalue_binary())
facade = selected_geometry
context = selected_geometries
encoded_facade = []
encoded_context = []
# Durchlaufen aller Objekte und Kodieren der zum gewĂŒnschten Layer gehörenden
for obj in gh_file.Objects:
if facade:
geom = obj.Geometry
# Kodieren des Geometrieobjekts
encoded_data = json.dumps(geom.Encode())
encoded_facade.append(encoded_data)
for obj in gh_file.Objects:
if context:
geom = obj.Geometry
# Kodieren des Geometrieobjekts
encoded_data2 = json.dumps(geom.Encode())
encoded_context.append(encoded_data2)
# Erstellen einer JSON-Datei aus den Eingabeparametern
#new dictinary
params.pop("Modell")
params['encoded_facade'] = encoded_facade
params['encoded_context'] = encoded_context
input_json = json.dumps(params) # Konvertieren aller Parameter inklusive der Geometrie in JSON
print(params)
# Erstellen der Eingabedateien fĂŒr die Analyse
files = [
('input.json', BytesIO(bytes(input_json, 'utf8'))),
]
# Run the Grasshopper analysis and obtain the output files
generic_analysis = GenericAnalysis(files=files, executable_key="run_grasshopper", output_filenames=[
"geometry.3dm", "output.json"
])
generic_analysis.execute(timeout=60)
rhino_3dm_file = generic_analysis.get_output_file("geometry.3dm", as_file=True)
output_values: File = generic_analysis.get_output_file("output.json", as_file=True)
# Create a DataGroup object to display output data
output_dict = json.loads(output_values.getvalue())
print(output_dict)
data_group = DataGroup(
*[DataItem(key.replace("_", " "), val) for key, val in output_dict.items()]
)
return GeometryAndDataResult(geometry=rhino_3dm_file, geometry_type="3dm", data=data_group)
Thanks for your help!