CoolFace
Apppublic

venkat112/venkat_glb_creation

sourceHugging Faceupdated 8mo agoView on Hugging Face
0likes
code_generator.js527 linesDownload Raw Back to scripts
1// Code Generator2// Generates Node.js (Three.js) or Blender Python code from scene graph3 4export class CodeGenerator {5  generateNodeJS(sceneGraph, sceneData) {6    let code = `// GLB Generation Code (Three.js + GLTFExporter)7// Generated automatically from scene description8// Run: npm install three @gltf-transform/core @gltf-transform/functions9 10import * as THREE from 'three';11import { GLTFExporter } from 'three/examples/jsm/exporters/GLTFExporter.js';12import { Document, NodeIO } from '@gltf-transform/core';13import { dedup, resample, draco } from '@gltf-transform/functions';14import fs from 'fs';15 16const scene = new THREE.Scene();17const sceneData = ${JSON.stringify(sceneData, null, 2)};18 19// Environment setup20scene.background = new THREE.Color(${this.colorToThreeJS(sceneData.lighting?.color || [1, 1, 1])});21scene.fog = ${sceneData.effects?.fog ? `new THREE.FogExp2(${this.colorToThreeJS([0.8, 0.8, 0.9])}, 0.05)` : 'null'};22 23// Create ground24function createGround() {25  const groundGeometry = new THREE.PlaneGeometry(${sceneData.ground?.size || 20}, ${sceneData.ground?.size || 20});26  const groundMaterial = new THREE.MeshStandardMaterial({27    color: ${this.colorToThreeJS(sceneData.ground?.color || [0.5, 0.5, 0.5])},28    roughness: ${sceneData.ground?.roughness || 0.8},29    metalness: ${sceneData.ground?.metallic || 0.0}30  });31  const ground = new THREE.Mesh(groundGeometry, groundMaterial);32  ground.rotation.x = -Math.PI / 2;33  scene.add(ground);34  return ground;35}36 37// Create object helper38function createObject(objData) {39  let geometry, material, mesh;40  41  switch(objData.type) {42    case 'cube':43      geometry = new THREE.BoxGeometry(44        objData.size || 1,45        objData.size || 1,46        objData.size || 147      );48      break;49    case 'sphere':50      geometry = new THREE.SphereGeometry(51        objData.radius || 0.5,52        32,53        3254      );55      break;56    case 'cylinder':57      geometry = new THREE.CylinderGeometry(58        objData.radius || 0.5,59        objData.radius || 0.5,60        objData.size || 1,61        3262      );63      break;64    case 'cone':65      geometry = new THREE.ConeGeometry(66        objData.radius || 0.5,67        objData.size || 1,68        3269      );70      break;71    case 'plane':72      geometry = new THREE.PlaneGeometry(73        objData.size || 10,74        objData.size || 1075      );76      break;77    default:78      geometry = new THREE.BoxGeometry(1, 1, 1);79  }80  81  const color = objData.color || [0.8, 0.8, 0.8, 1];82  material = new THREE.MeshStandardMaterial({83    color: new THREE.Color(color[0], color[1], color[2]),84    roughness: objData.roughness || 0.5,85    metalness: objData.metallic || 0.0,86    transparent: color[3] < 1,87    opacity: color[3] || 188  });89  90  if (objData.emission) {91    material.emissive = new THREE.Color(92      objData.emission[0],93      objData.emission[1],94      objData.emission[2]95    );96    material.emissiveIntensity = objData.emissionStrength || 1.0;97  }98  99  mesh = new THREE.Mesh(geometry, material);100  mesh.position.set(101    objData.location[0] || 0,102    objData.location[1] || 0,103    objData.location[2] || 0104  );105  mesh.rotation.set(106    objData.rotation[0] || 0,107    objData.rotation[1] || 0,108    objData.rotation[2] || 0109  );110  mesh.scale.set(111    objData.scale[0] || 1,112    objData.scale[1] || 1,113    objData.scale[2] || 1114  );115  mesh.name = objData.name || 'Object';116  117  scene.add(mesh);118  return mesh;119}120 121// Create avatar122function createAvatar(avatarData) {123  const group = new THREE.Group();124  group.name = avatarData.name || 'Avatar';125  126  // Simple humanoid from primitives127  const torso = new THREE.Mesh(128    new THREE.CylinderGeometry(0.25, 0.25, 0.8, 32),129    new THREE.MeshStandardMaterial({ color: 0xffccaa })130  );131  torso.position.y = 1.0;132  group.add(torso);133  134  const head = new THREE.Mesh(135    new THREE.SphereGeometry(0.18, 32, 32),136    new THREE.MeshStandardMaterial({ color: 0xffccaa })137  );138  head.position.y = 1.9;139  group.add(head);140  141  // Arms142  const leftArm = new THREE.Mesh(143    new THREE.BoxGeometry(0.2, 0.4, 0.2),144    new THREE.MeshStandardMaterial({ color: 0xffccaa })145  );146  leftArm.position.set(-0.45, 1.3, 0);147  group.add(leftArm);148  149  const rightArm = new THREE.Mesh(150    new THREE.BoxGeometry(0.2, 0.4, 0.2),151    new THREE.MeshStandardMaterial({ color: 0xffccaa })152  );153  rightArm.position.set(0.45, 1.3, 0);154  group.add(rightArm);155  156  // Legs157  const leftLeg = new THREE.Mesh(158    new THREE.BoxGeometry(0.25, 0.75, 0.25),159    new THREE.MeshStandardMaterial({ color: 0x4444ff })160  );161  leftLeg.position.set(-0.18, 0.5, 0);162  group.add(leftLeg);163  164  const rightLeg = new THREE.Mesh(165    new THREE.BoxGeometry(0.25, 0.75, 0.25),166    new THREE.MeshStandardMaterial({ color: 0x4444ff })167  );168  rightLeg.position.set(0.18, 0.5, 0);169  group.add(rightLeg);170  171  group.position.set(172    avatarData.position[0] || 0,173    avatarData.position[1] || 0,174    avatarData.position[2] || 0175  );176  group.scale.set(177    avatarData.scale || 1,178    avatarData.scale || 1,179    avatarData.scale || 1180  );181  182  scene.add(group);183  return group;184}185 186// Create lights187function createLights(lightingData) {188  if (lightingData.lights) {189    lightingData.lights.forEach(light => {190      let lightObj;191      switch(light.type) {192        case 'SUN':193        case 'DIRECTIONAL':194          lightObj = new THREE.DirectionalLight(195            new THREE.Color(light.color || lightingData.color || [1, 1, 1]),196            light.energy || 1197          );198          lightObj.position.set(199            light.location[0] || 10,200            light.location[1] || -10,201            light.location[2] || 10202          );203          break;204        case 'POINT':205          lightObj = new THREE.PointLight(206            new THREE.Color(light.color || lightingData.color || [1, 1, 1]),207            light.energy || 50,208            100209          );210          lightObj.position.set(211            light.location[0] || 0,212            light.location[1] || 0,213            light.location[2] || 2214          );215          break;216        case 'SPOT':217          lightObj = new THREE.SpotLight(218            new THREE.Color(light.color || lightingData.color || [1, 1, 1]),219            light.energy || 50220          );221          lightObj.position.set(222            light.location[0] || 0,223            light.location[1] || 0,224            light.location[2] || 2225          );226          break;227        default:228          lightObj = new THREE.AmbientLight(229            new THREE.Color(lightingData.color || [1, 1, 1]),230            lightingData.ambient_strength || 0.3231          );232      }233      scene.add(lightObj);234    });235  }236  237  // Ambient light238  const ambientLight = new THREE.AmbientLight(239    new THREE.Color(lightingData.color || [1, 1, 1]),240    lightingData.ambient_strength || 0.3241  );242  scene.add(ambientLight);243}244 245// Create camera246function createCamera(cameraData) {247  const camera = new THREE.PerspectiveCamera(248    cameraData.fov || 50,249    16 / 9,250    0.1,251    1000252  );253  camera.position.set(254    cameraData.position[0] || 4,255    cameraData.position[1] || -4,256    cameraData.position[2] || 2.2257  );258  camera.rotation.set(259    cameraData.rotation[0] || 1.05,260    cameraData.rotation[1] || 0,261    cameraData.rotation[2] || 0.78262  );263  return camera;264}265 266// Build scene267console.log('Building scene...');268createGround();269sceneData.objects?.forEach(obj => createObject(obj));270if (sceneData.avatar?.present) {271  createAvatar(sceneData.avatar);272}273createLights(sceneData.lighting);274const camera = createCamera(sceneData.camera);275 276// Export to GLB277console.log('Exporting to GLB...');278const exporter = new GLTFExporter();279const options = {280  binary: true,281  includeCustomExtensions: true282};283 284exporter.parse(285  scene,286  (result) => {287    fs.writeFileSync('scene.glb', Buffer.from(result));288    console.log('GLB file saved as scene.glb');289  },290  (error) => {291    console.error('Export error:', error);292  }293);294`;295 296    return code;297  }298 299  generateBlenderPython(sceneGraph, sceneData) {300    let code = `# Blender Python Script for GLB Generation301# Generated automatically from scene description302# Run: blender --background --python this_script.py303 304import bpy305import json306import mathutils307 308def clear_scene():309    bpy.ops.wm.read_factory_settings(use_empty=True)310 311def make_pbr_material(name, base_color=(1,1,1,1), roughness=0.5, metallic=0.0, emission=None, emission_strength=1.0):312    mat = bpy.data.materials.new(name)313    mat.use_nodes = True314    nodes = mat.node_tree.nodes315    links = mat.node_tree.links316    nodes.clear()317    318    output = nodes.new(type="ShaderNodeOutputMaterial")319    principled = nodes.new(type="ShaderNodeBsdfPrincipled")320    principled.inputs['Base Color'].default_value = base_color321    principled.inputs['Roughness'].default_value = roughness322    principled.inputs['Metallic'].default_value = metallic323    324    if emission:325        principled.inputs['Emission'].default_value = (*emission[:3], 1.0)326        principled.inputs['Emission Strength'].default_value = emission_strength327    328    links.new(principled.outputs['BSDF'], output.inputs['Surface'])329    return mat330 331def create_object(obj_data):332    typ = obj_data.get('type', 'cube')333    location = obj_data.get('location', [0, 0, 0])334    rotation = obj_data.get('rotation', [0, 0, 0])335    scale = obj_data.get('scale', [1, 1, 1])336    name = obj_data.get('name', 'Object')337    338    if typ == 'cube':339        bpy.ops.mesh.primitive_cube_add(size=obj_data.get('size', 1), location=location)340    elif typ == 'sphere':341        bpy.ops.mesh.primitive_uv_sphere_add(radius=obj_data.get('radius', 0.5), location=location)342    elif typ == 'cylinder':343        bpy.ops.mesh.primitive_cylinder_add(vertices=32, radius=obj_data.get('radius', 0.5), 344                                           depth=obj_data.get('size', 1), location=location)345    elif typ == 'cone':346        bpy.ops.mesh.primitive_cone_add(vertices=32, radius1=obj_data.get('radius', 0.5),347                                       depth=obj_data.get('size', 1), location=location)348    elif typ == 'plane':349        bpy.ops.mesh.primitive_plane_add(size=obj_data.get('size', 10), location=location)350    else:351        bpy.ops.mesh.primitive_cube_add(size=1, location=location)352    353    obj = bpy.context.object354    obj.name = name355    obj.rotation_euler = rotation356    obj.scale = scale357    358    # Apply material359    color = obj_data.get('color', [0.8, 0.8, 0.8, 1])360    mat = make_pbr_material(361        f"mat_{name}",362        base_color=tuple(color),363        roughness=obj_data.get('roughness', 0.5),364        metallic=obj_data.get('metallic', 0.0),365        emission=obj_data.get('emission'),366        emission_strength=obj_data.get('emissionStrength', 1.0)367    )368    obj.data.materials.append(mat)369    370    return obj371 372def create_avatar(avatar_data):373    # Simple humanoid from primitives374    bpy.ops.mesh.primitive_cylinder_add(vertices=32, radius=0.25, depth=0.8, location=(0, 0, 1.0))375    torso = bpy.context.object376    torso.name = f"{avatar_data.get('name', 'Avatar')}_Torso"377    378    bpy.ops.mesh.primitive_uv_sphere_add(radius=0.18, location=(0, 0, 1.9))379    head = bpy.context.object380    head.name = f"{avatar_data.get('name', 'Avatar')}_Head"381    382    # Arms and legs (simplified)383    bpy.ops.mesh.primitive_cube_add(size=0.2, location=(-0.45, 0, 1.3))384    left_arm = bpy.context.object385    left_arm.scale[1] = 2.0386    left_arm.name = f"{avatar_data.get('name', 'Avatar')}_L_Arm"387    388    bpy.ops.mesh.primitive_cube_add(size=0.2, location=(0.45, 0, 1.3))389    right_arm = bpy.context.object390    right_arm.scale[1] = 2.0391    right_arm.name = f"{avatar_data.get('name', 'Avatar')}_R_Arm"392    393    bpy.ops.mesh.primitive_cube_add(size=0.25, location=(-0.18, 0, 0.5))394    left_leg = bpy.context.object395    left_leg.scale[2] = 1.5396    left_leg.name = f"{avatar_data.get('name', 'Avatar')}_L_Leg"397    398    bpy.ops.mesh.primitive_cube_add(size=0.25, location=(0.18, 0, 0.5))399    right_leg = bpy.context.object400    right_leg.scale[2] = 1.5401    right_leg.name = f"{avatar_data.get('name', 'Avatar')}_R_Leg"402    403    # Join all parts404    bpy.ops.object.select_all(action='DESELECT')405    for part in [torso, head, left_arm, right_arm, left_leg, right_leg]:406        part.select_set(True)407    bpy.context.view_layer.objects.active = torso408    bpy.ops.object.join()409    410    avatar = bpy.context.object411    avatar.name = avatar_data.get('name', 'Avatar')412    avatar.location = avatar_data.get('position', [0, 0, 0])413    avatar.scale = [avatar_data.get('scale', 1.0)] * 3414    415    mat = make_pbr_material("AvatarMat", base_color=(1, 0.8, 0.6, 1))416    avatar.data.materials.append(mat)417    418    return avatar419 420def create_lights(lighting_data):421    if lighting_data.get('lights'):422        for light in lighting_data['lights']:423            light_type = light.get('type', 'POINT')424            location = light.get('location', [0, 0, 2])425            energy = light.get('energy', 50)426            color = light.get('color', lighting_data.get('color', [1, 1, 1]))427            428            if light_type == 'SUN':429                bpy.ops.object.light_add(type='SUN', location=location)430                sun = bpy.context.object431                sun.data.energy = energy432                sun.data.color = color433            elif light_type == 'POINT':434                bpy.ops.object.light_add(type='POINT', location=location)435                point = bpy.context.object436                point.data.energy = energy437                point.data.color = color438            elif light_type == 'SPOT':439                bpy.ops.object.light_add(type='SPOT', location=location)440                spot = bpy.context.object441                spot.data.energy = energy442                spot.data.color = color443    444    # Ambient light445    bpy.context.scene.world.use_nodes = True446    world_nodes = bpy.context.scene.world.node_tree.nodes447    world_nodes['Background'].inputs['Strength'].default_value = lighting_data.get('ambient_strength', 0.3)448    world_nodes['Background'].inputs['Color'].default_value = (*lighting_data.get('color', [1, 1, 1]), 1)449 450def create_camera(camera_data):451    bpy.ops.object.camera_add(location=camera_data.get('position', [4, -4, 2.2]))452    cam = bpy.context.object453    cam.rotation_euler = camera_data.get('rotation', [1.05, 0, 0.78])454    bpy.context.scene.camera = cam455    cam.data.lens = 50456    cam.data.sensor_width = 36457 458# Scene data459scene_data = ${JSON.stringify(sceneData, null, 2)}460 461# Clear and build scene462clear_scene()463 464# Ground465if scene_data.get('ground'):466    ground = scene_data['ground']467    bpy.ops.mesh.primitive_plane_add(size=ground.get('size', 20), location=(0, 0, 0))468    ground_obj = bpy.context.object469    ground_obj.name = "Ground"470    mat = make_pbr_material(471        "GroundMat",472        base_color=tuple(ground.get('color', [0.5, 0.5, 0.5, 1])),473        roughness=ground.get('roughness', 0.8),474        metallic=ground.get('metallic', 0.0)475    )476    ground_obj.data.materials.append(mat)477 478# Objects479if scene_data.get('objects'):480    for obj_data in scene_data['objects']:481        create_object(obj_data)482 483# Avatar484if scene_data.get('avatar') and scene_data['avatar'].get('present'):485    create_avatar(scene_data['avatar'])486 487# Lighting488if scene_data.get('lighting'):489    create_lights(scene_data['lighting'])490 491# Camera492if scene_data.get('camera'):493    create_camera(scene_data['camera'])494 495# Scene settings496bpy.context.scene.render.engine = 'CYCLES'497bpy.context.scene.cycles.device = 'CPU'498 499# Export GLB500output_path = 'scene.glb'501export_kwargs = {502    "filepath": output_path,503    "export_format": "GLB",504    "export_apply": True,505    "export_texcoords": True,506    "export_normals": True,507    "export_materials": "EXPORT",508    "export_colors": True,509    "export_extras": True,510}511 512bpy.ops.export_scene.gltf(**export_kwargs)513print(f"Exported: {output_path}")514`;515 516    return code;517  }518 519  colorToThreeJS(color) {520    if (Array.isArray(color) && color.length >= 3) {521      return `0x${Math.floor(color[0] * 255).toString(16).padStart(2, '0')}${Math.floor(color[1] * 255).toString(16).padStart(2, '0')}${Math.floor(color[2] * 255).toString(16).padStart(2, '0')}`;522    }523    return '0xffffff';524  }525}526 527