feat: Add legacy shaders, model I/O, and project panel functionality
continuous-integration/drone/push Build is passing
continuous-integration/drone/push Build is passing
- Introduced `legacy-shaders.js` containing vertex and fragment shaders for rendering. - Implemented `model-io.js` for parsing and encoding GLB files, ensuring compatibility with glTF 2.0. - Created `project-panel.js` to manage project resources and survey overlays, enhancing user interaction. - Added `solar.js` for calculating solar positions based on UTC time, latitude, and longitude. - Developed `three-renderer.js` as a standard backend for Three.js, managing scene rendering and material synchronization. - Included a new GLB model `dum.glb` for testing and demonstration purposes. - Established `data_checks.mjs` for validating model data and ensuring integrity of assets. - Created `prepare_export.py` to facilitate Blender GLB exports, maintaining material and node references. - Added `vendor_three.py` to download and configure a local version of Three.js for the project.
This commit is contained in:
@@ -0,0 +1,65 @@
|
||||
"""Run in Blender, not system Python:
|
||||
blender --background --python blender/prepare_model.py
|
||||
Creates an editable .blend next to this script. Existing scene is replaced.
|
||||
Keeps every configuration variant; helper collections are hidden in viewport.
|
||||
"""
|
||||
from pathlib import Path
|
||||
import json
|
||||
import bpy
|
||||
|
||||
ROOT=Path(__file__).resolve().parent.parent
|
||||
SOURCE=ROOT/'models'/'dum.glb'
|
||||
TARGET=Path(__file__).resolve().parent/'dum_locenice.blend'
|
||||
if not SOURCE.is_file():
|
||||
raise FileNotFoundError(SOURCE)
|
||||
if TARGET.exists():
|
||||
raise FileExistsError(f'Rename or remove {TARGET} before running again.')
|
||||
bpy.ops.wm.read_factory_settings(use_empty=True)
|
||||
bpy.ops.import_scene.gltf(filepath=str(SOURCE))
|
||||
defaults=json.loads((ROOT/'data'/'catalog.json').read_text())['defaults']
|
||||
scene=bpy.context.scene
|
||||
scene.unit_settings.system='METRIC'
|
||||
scene.unit_settings.scale_length=1.0
|
||||
collections={}
|
||||
for name in ['01_Exterior','02_Interior_walls','03_Kitchen_and_furniture','04_Site','05_Cutaway_alternatives','06_Standards_alternatives']:
|
||||
col=bpy.data.collections.new(name);scene.collection.children.link(col);collections[name]=col
|
||||
for obj in list(scene.objects):
|
||||
if obj.type!='MESH':continue
|
||||
props=obj
|
||||
if props.get('stdHidden') or props.get('stdWhen') or props.get('stdBlind'):
|
||||
key='06_Standards_alternatives'
|
||||
elif props.get('interiorLayer') in ['cut','cutShell']:
|
||||
key='05_Cutaway_alternatives'
|
||||
elif props.get('interiorLayer')=='furniture':
|
||||
key='03_Kitchen_and_furniture'
|
||||
elif props.get('interiorLayer'):
|
||||
key='02_Interior_walls'
|
||||
elif props.get('siteLayer') or props.get('legacySite'):
|
||||
key='04_Site'
|
||||
else:key='01_Exterior'
|
||||
for c in list(obj.users_collection):c.objects.unlink(obj)
|
||||
collections[key].objects.link(obj)
|
||||
# Stable ID comes from the GLB extras. Do not delete it during future editing.
|
||||
obj['locenice_edit_note']='Keep loceniceId and configuration properties.'
|
||||
condition=props.get('stdWhen',{})
|
||||
hidden=bool(props.get('stdHidden')) or bool(props.get('stdBlind') and not defaults['blinds'])
|
||||
if hasattr(condition,'items'):
|
||||
hidden=hidden or any(defaults.get(k)!=v for k,v in condition.items())
|
||||
obj.hide_set(hidden)
|
||||
obj.hide_render=hidden
|
||||
collections['05_Cutaway_alternatives'].hide_viewport=True
|
||||
# Keep matching default variants visible; all alternatives remain in the file.
|
||||
note=bpy.data.texts.new('READ_ME_Locenice')
|
||||
note.write('''This is a visualisation mesh, not BIM. Units: metres.
|
||||
The source includes multiple, mutually exclusive variants in the same location.
|
||||
Use named collections to inspect them. Do not join all meshes or all materials.
|
||||
loceniceId, stdWhen, stdBlind, windowNode and interiorLayer must stay on objects.
|
||||
Detailed construction dimensions come from the project, not reference photos.
|
||||
After exporting all variants to GLB, run tools/prepare_export.py.
|
||||
Blender reorders glTF nodes, materials and textures. The included web manifest
|
||||
is indexed for the supplied GLB; the preparation tool rebinds stable IDs.
|
||||
A changed wall or cabinet also requires checking web collision volumes / camera presets.
|
||||
''')
|
||||
scene['locenice_metadata_json']=json.dumps(json.loads((ROOT/'data'/'scene.json').read_text()),ensure_ascii=False)
|
||||
bpy.ops.wm.save_as_mainfile(filepath=str(TARGET))
|
||||
print('Saved:',TARGET)
|
||||
Reference in New Issue
Block a user