def add_random_objects(scene_struct, args, camera, idx):
    """
  Add random objects to the current blender scene
  """

    # Load the property file
    with open(args.properties_json, 'r') as f:
        properties = json.load(f)
        color_name_to_rgba = {}
        for name, rgb in properties['colors'].items():
            rgba = [float(c) / 255.0 for c in rgb] + [1.0]
            color_name_to_rgba[name] = rgba
        material_mapping = [(v, k) for k, v in properties['materials'].items()]
        object_mapping = [(v, k) for k, v in properties['shapes'].items()]
        size_mapping = list(properties['sizes'].items())

    objects = []
    blender_objects = []
    cob = clevr_scene[idx]['objects']
    num_objects = len(cob)
    for i in range(num_objects):

        sf = cob[i]
        theta = sf['rotation']
        obj_name_out = sf['shape']
        obj_name = restore_util.get_obj_name(obj_name_out)
        size_name = sf['size']
        r = restore_util.get_by_size(size_name)
        if obj_name == 'Cube':
            r /= math.sqrt(2)
        x, y = sf['3d_coords'][:2]
        mat_name_out = sf['material']
        mat_name = restore_util.get_by_mat_name_out(mat_name_out)

        color_name = sf['color']
        rgb = restore_util.get_by_colorname(color_name)
        rgba = [float(c) / 255.0 for c in rgb] + [1.0]

        # Actually add the object to the scene
        utils.add_object(args.shape_dir, obj_name, r, (x, y), theta=theta)
        obj = bpy.context.object
        blender_objects.append(obj)

        # Attach a random material
        utils.add_material(mat_name, Color=rgba)

        # Record data about the object in the scene data structure
        pixel_coords, _wh = utils.get_camera_coords(camera, obj.location)
        #pixel_coords = utils.get_camera_coords(camera, obj.location)
        objects.append({
            'shape': obj_name_out,
            'size': size_name,
            'material': mat_name_out,
            '3d_coords': tuple(obj.location),
            'rotation': theta,
            'pixel_coords': pixel_coords,
            'color': color_name,
        })

    return objects, blender_objects
Ejemplo n.º 2
0
def add_objects(scene_struct, camera, objects):
    """
  Add objects to the current blender scene
  """
    blender_objects = []
    for obj in objects:

        # Actually add the object to the scene
        utils.add_object(args.shape_dir,
                         obj["shape"],
                         obj["size"],
                         obj["location"],
                         theta=obj["rotation"])
        bobj = bpy.context.object

        blender_objects.append(bobj)
        utils.add_material(obj["material"], Color=obj["color"])
        obj["pixel_coords"] = utils.get_camera_coords(camera, bobj.location)

        import numpy as np
        loc = np.array(bobj.location)
        dim = np.array(bobj.dimensions)
        half = dim / 2
        corners = []
        corners.append(loc + half * [1, 1, 1])
        corners.append(loc + half * [1, 1, -1])
        corners.append(loc + half * [1, -1, 1])
        corners.append(loc + half * [1, -1, -1])
        corners.append(loc + half * [-1, 1, 1])
        corners.append(loc + half * [-1, 1, -1])
        corners.append(loc + half * [-1, -1, 1])
        corners.append(loc + half * [-1, -1, -1])

        import mathutils
        corners_camera_coords = np.array([
            utils.get_camera_coords(camera, mathutils.Vector(tuple(corner)))
            for corner in corners
        ])

        xmax = np.amax(corners_camera_coords[:, 0])
        ymax = np.amax(corners_camera_coords[:, 1])
        xmin = np.amin(corners_camera_coords[:, 0])
        ymin = np.amin(corners_camera_coords[:, 1])
        obj["bbox"] = (float(xmin), float(ymin), float(xmax), float(ymax))
    return blender_objects
Ejemplo n.º 3
0
def transform_random_objects(scene_struct, blender_objects, camera):
    c = 0
    objects = scene_struct['objects']
    positions = [obj.location for obj in blender_objects]
    for obj in blender_objects:
        loc = obj.location
        x_t = min(max(loc[0] + random.uniform(-1.5, 1.5), -3), 3)
        y_t = min(max(loc[1] + random.uniform(-1.5, 1.5), -3), 3)
        obj.location = Vector((x_t, y_t, loc[2]))
        pixel_coords = utils.get_camera_coords(camera, obj.location)
        objects[c]['3d_coords'] = tuple(obj.location)
        objects[c]['pixel_coords'] = pixel_coords
        c = c + 1
    scene_struct['objects'] = objects
    return blender_objects, scene_struct
Ejemplo n.º 4
0
 def logical_representation(self):
     return {
         "material":
         self.material,
         "size":
         self.size,
         "shape":
         self.shape,
         "color":
         self.color,
         "rotation":
         self.rotation,
         "pixel_coords":
         utils.get_camera_coords(self._factory.camera,
                                 self._blender_object.location),
         "3d_coords":
         tuple(self._blender_object.location)
     }
 def render_object(obj):
     obj_name_out = obj['shape']
     obj_name = [k for k, v in object_mapping if v == obj_name_out][0]
     color_name = obj['color']
     rgba = color_name_to_rgba[color_name]
     size_name = obj['size']
     r = [v for k, v in size_mapping if k == size_name][0]
     if obj_name == 'Cube':
         r /= math.sqrt(2)
     theta = obj['rotation']
     mat_name_out = obj['material']
     mat_name = [k for k, v in material_mapping if v == mat_name_out][0]
     x, y, z = obj['3d_coords']
     position = (x, y, r)
     utils.add_object(args.shape_dir, obj_name, r, (x, y), theta=theta)
     new_blend_obj = bpy.context.object
     utils.add_material(mat_name, Color=rgba)
     new_pixel_coords = utils.get_camera_coords(camera,
                                                new_blend_obj.location)
     return new_blend_obj, position, new_pixel_coords
Ejemplo n.º 6
0
def add_random_objects(scene_struct, num_objects, args, camera, init_positions, sizes=[], inout=False):
  """
  Add random objects to the current blender scene
  """
  # Load the property file
  print(init_positions)
  color_name_to_rgba = {}
  with open(args.properties_json, 'r') as f:
    properties = json.load(f)
    for name, rgb in properties['colors'].items():
      rgba = [float(c) / 255.0 for c in rgb] + [1.0]
      color_name_to_rgba[name] = rgba
    material_mapping = [(v, k) for k, v in properties['materials'].items()]
    object_mapping = [(v, k) for k, v in properties['shapes'].items()]
    size_mapping = list(properties['sizes'].items())

  shape_color_combos = None
  if args.shape_color_combos_json is not None:
    with open(args.shape_color_combos_json, 'r') as f:
      shape_color_combos = list(json.load(f).items())

  positions = []
  objects = []
  blender_objects = []
  for i in range(num_objects):
    if len(sizes) == 1 and i != 0:
      # Choose a random size
      size_name, r = random.choice(size_mapping)
    else:
      size_name, r = sizes[i]

    x, y, z = init_positions[i]


    # Choose random color and shape
    if shape_color_combos is None:
      obj_name, obj_name_out = random.choice(object_mapping)
      color_name, rgba = random.choice(list(color_name_to_rgba.items()))

      if inout and i == 0:
        obj_name, obj_name_out = ('Tray', 'tray')
        color_name, rgba = ('gray', [0.5, 0.5, 0.5, 1])
      # elif i == 0:
      #   obj_name, obj_name_out = ('SmoothCube_v2', 'cube')
      #   color_name, rgba = ('red', [0.67, 0.13, 0.13, 1])
      # elif i == 1:
      #   obj_name, obj_name_out = ('SmoothCube_v2', 'cube')
      #   color_name, rgba = ('blue', color_name_to_rgba['blue'])
      # elif i == 2:
      #   obj_name, obj_name_out = ('SmoothCylinder', 'cylinder')
      #   color_name, rgba = ('green', color_name_to_rgba['green'])
      
    else:
      obj_name_out, color_choices = random.choice(shape_color_combos)
      color_name = random.choice(color_choices)
      obj_name = [k for k, v in object_mapping if v == obj_name_out][0]
      rgba = color_name_to_rgba[color_name]

    # For cube, adjust the size a bit
    if obj_name == 'Cube':
      r /= math.sqrt(2)

    theta = 0

    # Actually add the object to the scene
    utils.add_object(args.shape_dir, obj_name, r, (x, y, z), theta=theta)
    obj = bpy.context.object
    blender_objects.append(obj)

    positions.append((x, y, z, r))

    # Attach a random material
    mat_name, mat_name_out = random.choice(material_mapping)

    if i == 0 or i == 1:
      mat_name = "Rubber"
    elif i == 2:
      mat_name = "MyMetal"

    utils.add_material(mat_name, Color=rgba)

    # Record data about the object in the scene data structure
    pixel_coords = utils.get_camera_coords(camera, obj.location)
    objects.append({
      'shape': obj_name_out,
      'size': size_name,
      'material': mat_name_out,
      '3d_coords': tuple(obj.location),
      'r' : r,
      'rotation': theta,
      'pixel_coords': pixel_coords,
      'color': color_name,
    })

  # Check that all objects are at least partially visible in the rendered image
  all_visible = check_visibility(blender_objects, objects, args.min_pixels_per_object)
  if not all_visible:
    # If any of the objects are fully occluded then start over; delete all
    # objects from the scene and place them all again.
    print('Some objects are occluded; replacing objects')
    for obj in blender_objects:
      utils.delete_object(obj)
    return add_random_objects(scene_struct, num_objects, args, camera, init_positions + np.random.uniform(low=-0.05, high=0.05, size=(np.array(init_positions).shape)), sizes=sizes, inout=inout)

  return objects, blender_objects
Ejemplo n.º 7
0
def render_scene(args,
    num_objects=5,
    num_images=0,
    output_split='none',
    image_template='render.png',
    scene_template='render_json',
    arr_template='arr',
    output_blendfile=None,
    directions={1: 'no', 2: 'no', 3: 'no', 4: 'no', 5: 'no', 6: 'no'}
  ):
  
  for object_name in bpy.data.objects.keys():
    if 'Sphere' in object_name or\
       'Cylinder' in object_name or\
       'Cube' in object_name or\
       'Duck' in object_name or\
       'Peg' in object_name or\
       'Disk' in object_name or\
       'Bowl' in object_name:
       utils.delete_object_by_name(object_name)

  # Load materials
  utils.load_materials(args.material_dir)

  # Set render arguments so we can get pixel coordinates later.
  # We use functionality specific to the CYCLES renderer so BLENDER_RENDER
  # cannot be used.
  render_args = bpy.context.scene.render
  render_args.engine = "CYCLES"
  render_args.resolution_x = args.width
  render_args.resolution_y = args.height
  render_args.resolution_percentage = 100
  render_args.tile_x = args.render_tile_size
  render_args.tile_y = args.render_tile_size
  if args.use_gpu == 1:
    # Blender changed the API for enabling CUDA at some point
    if bpy.app.version < (2, 78, 0):
      bpy.context.user_preferences.system.compute_device_type = 'CUDA'
      bpy.context.user_preferences.system.compute_device = 'CUDA_0'
    else:
      cycles_prefs = bpy.context.user_preferences.addons['cycles'].preferences
      cycles_prefs.compute_device_type = 'CUDA'

  # Some CYCLES-specific stuff
  bpy.data.worlds['World'].cycles.sample_as_light = True
  bpy.context.scene.cycles.blur_glossy = 2.0
  bpy.context.scene.cycles.samples = args.render_num_samples
  bpy.context.scene.cycles.transparent_min_bounces = args.render_min_bounces
  bpy.context.scene.cycles.transparent_max_bounces = args.render_max_bounces
  if args.use_gpu == 1:
    bpy.context.scene.cycles.device = 'GPU'

  # This will give ground-truth information about the scene and its objects
  scene_struct = {
      'split': output_split,
      'objects': [],
      'directions': {},
  }

  # Put a plane on the ground so we can compute cardinal directions
  bpy.ops.mesh.primitive_plane_add(radius=5)
  plane = bpy.context.object

  def rand(L):
    return 2.0 * L * (random.random() - 0.5)

  # Add random jitter to camera position
  if args.camera_jitter > 0:
    for i in range(3):
      bpy.data.objects['Camera'].location[i] += rand(args.camera_jitter)

  # Figure out the left, up, and behind directions along the plane and record
  # them in the scene structure
  camera = bpy.data.objects['Camera']
  plane_normal = plane.data.vertices[0].normal
  cam_behind = camera.matrix_world.to_quaternion() * Vector((0, 0, -1))
  cam_left = camera.matrix_world.to_quaternion() * Vector((-1, 0, 0))
  cam_up = camera.matrix_world.to_quaternion() * Vector((0, 1, 0))
  plane_behind = (cam_behind - cam_behind.project(plane_normal)).normalized()
  plane_left = (cam_left - cam_left.project(plane_normal)).normalized()
  plane_up = cam_up.project(plane_normal).normalized()

  # Delete the plane; we only used it for normals anyway. The base scene file
  # contains the actual ground plane.
  utils.delete_object(plane)

  # Save all six axis-aligned directions in the scene struct
  scene_struct['directions']['behind'] = tuple(plane_behind)
  scene_struct['directions']['front'] = tuple(-plane_behind)
  scene_struct['directions']['left'] = tuple(plane_left)
  scene_struct['directions']['right'] = tuple(-plane_left)
  scene_struct['directions']['above'] = tuple(plane_up)
  scene_struct['directions']['below'] = tuple(-plane_up)

  # Add random jitter to lamp positions
  if args.key_light_jitter > 0:
    for i in range(3):
      bpy.data.objects['Lamp_Key'].location[i] += rand(args.key_light_jitter)
  if args.back_light_jitter > 0:
    for i in range(3):
      bpy.data.objects['Lamp_Back'].location[i] += rand(args.back_light_jitter)
  if args.fill_light_jitter > 0:
    for i in range(3):
      bpy.data.objects['Lamp_Fill'].location[i] += rand(args.fill_light_jitter)


  objects = []
  blender_objects = []
  direction_vec = []
  traj = []

  for scene_idx in range(num_images):

    image_path = image_template % (scene_idx + args.start_idx)
    render_args.filepath = image_path
  
    scene_path = scene_template % (scene_idx + args.start_idx)
    arr_path = arr_template % (scene_idx + args.start_idx)

    if scene_idx == 0:

      init_positions = []
      # ref_obj_loc = np.array([0, -1, 0])
      ref_obj_loc = np.array([0, 0, 0])
      init_positions.append(ref_obj_loc)
      sizes = [('large', 0.6)]
      # sizes = [('small', 0.3)]
      inout=False



      for obj_idx in range(1, args.max_objects):
        init_position = []
        for axis, movement in directions.items():
          # X
          if axis == 1:
            if movement != ['no']:
              if movement[0] == 'front':
                init_position.append(-3)
              else:
                init_position.append(2)
            else:
              tmp = random.choice(np.linspace(-2, 2, 10, endpoint=True))
              while np.array([abs(tmp - posit[1]) < args.margin for posit in init_positions]).any():
                tmp = random.choice(np.linspace(-2, 2, 10, endpoint=True))
              init_position.append(tmp)
          
          # Y
          if axis == 0:
            if movement != ['no']:
              if movement[0] == 'left':
                init_position.append(-2)
              else:
                init_position.append(2)
            else:
              tmp = random.choice(np.linspace(-2, 2, 10, endpoint=True))
              while np.array([abs(tmp - posit[0]) < args.margin for posit in init_positions]).any():
                tmp = random.choice(np.linspace(-2, 2, 10, endpoint=True))
              init_position.append(tmp)

          # Z
          if axis == 2:
            if movement != ['no']:
              if movement[0] == 'below':
                init_position.append(0)
              else:
                init_position.append(2)
            else:
              tmp = random.choice(np.linspace(0, 2, 10, endpoint=True))
              # while np.array([abs(tmp - posit[2]) < args.margin for posit in init_positions]).any():
              while abs(tmp - init_positions[0][2]) < args.margin:
                tmp = random.choice(np.linspace(0, 2, 10, endpoint=True))
              init_position.append(tmp)

          # CLOSE/FAR
          close_far_thresh = 3
          if axis == 3:
            if movement != ['no']:
              far_sample = []
              close_sample = []
              while far_sample == [] or \
                  np.linalg.norm(far_sample - ref_obj_loc) < close_far_thresh or \
                  np.array([np.linalg.norm(far_sample - posit) < args.min_dist for posit in init_positions]).any():

                    x = random.choice(np.linspace(-2, 2, 10, endpoint=True))
                    y = random.choice(np.linspace(-2, 2, 10, endpoint=True))
                    z = random.choice(np.linspace(0.6, 2, 10, endpoint=True))
                    far_sample = np.array([x, y, z])

              while close_sample == [] or \
                  np.linalg.norm(close_sample - ref_obj_loc) > close_far_thresh or \
                  np.linalg.norm(close_sample - ref_obj_loc) < 1:

                    x = random.choice(np.linspace(-2, 2, 10, endpoint=True))
                    y = random.choice(np.linspace(-2, 2, 10, endpoint=True))
                    z = random.choice(np.linspace(0.6, 2, 10, endpoint=True))
                    close_sample = np.array([x, y, z])

              if movement[0] == 'far':
                init_position = far_sample

              else:
                init_position = close_sample
            else:
              pass

          # ON/OFF
          close_far_thresh = 1
          if axis == 4:
            if movement != ['no']:
              # size_mapping = [('small', 0.35), ('large', 0.7)]
              size_mapping = [('small', 0.5)]
              off_sample = []
              on_sample = []
              while off_sample == [] or \
                  np.linalg.norm(off_sample - ref_obj_loc) < close_far_thresh or \
                  np.array([np.linalg.norm(off_sample - posit) < args.min_dist for posit in init_positions]).any():

                    x = random.choice(np.linspace(-2, 2, 10, endpoint=True))
                    y = random.choice(np.linspace(-2, 2, 10, endpoint=True))
                    # z = random.choice(np.linspace(0.6, 2, 10, endpoint=True))
                    z = 0
                    off_sample = np.array([x, y, z])

              x = init_positions[-1][0] + random.uniform(-0.2, 0.2)
              y = init_positions[-1][1] + random.uniform(-0.2, 0.2)
              size_name, r = random.choice(size_mapping)
              sizes.append((size_name, r))
              z = init_positions[-1][2] + sizes[-1][1] * 2

              on_sample = np.array([x, y, z])

              if movement[0] == 'off':
                init_position = off_sample

              else:
                init_position = on_sample
            else:
              pass

          # IN/OUT
          close_far_thresh = 1
          if axis == 5:
            if movement != ['no']:
              inout = True
              out_sample = []
              in_sample = []
              while out_sample == [] or \
                  np.linalg.norm(out_sample - ref_obj_loc) < close_far_thresh or \
                  np.array([np.linalg.norm(out_sample - posit) < args.min_dist for posit in init_positions]).any():

                    x = random.choice(np.linspace(-2, 2, 10, endpoint=True))
                    # y = random.choice(np.linspace(-2, 2, 10, endpoint=True))
                    y = -3 + random.uniform(-0.2, 0.2)
                    # z = random.choice(np.linspace(0.6, 2, 10, endpoint=True))
                    z = 0
                    out_sample = np.array([x, y, z])

              # if obj_idx == 1:
              #   offset = -1
              # else:
              #   offset = 1

              offsets = [[-1, -1], [-1, 1], [1, -1], [1, 1]]

              # x = init_positions[0][0] + offset
              # y = init_positions[0][1] + random.choice(np.linspace(-0.2, 0.2, 2, endpoint=True))
              x, y = offsets[obj_idx - 1]
              x += random.uniform(-0.1, 0.1)
              y += random.uniform(-0.1, 0.1)

              sizes.append(('small', 0.3))
              z = init_positions[0][2]

              in_sample = np.array([x, y, z])

              if movement[0] == 'out':
                init_position = out_sample

              else:
                init_position = in_sample
            else:
              pass

        init_positions.append(init_position)

      # FACILITATE STACKING
      if directions[4][0] != 'no' and directions[4][0] == 'on':
        init_positions = init_positions[:1] + init_positions[1:][::-1]




      print(init_positions)
      # Now make some random objects
      objects, blender_objects = add_random_objects(scene_struct, num_objects, args, camera, \
                                                    init_positions, sizes=sizes, inout=inout)





      init_positions = []
      for obj in blender_objects:
        init_positions.append(np.array(obj.location))

      final_positions = []
      ref_obj_loc = init_positions[0]
      final_positions.append(ref_obj_loc)

      curvy = False

      for obj_idx in range(1, args.max_objects):
        final_position = []
        for axis, movement in directions.items():
          # X
          if axis == 1:
            if movement != ['no']:
              if movement[0] == 'front':
                final_position.append(2)
              else:
                final_position.append(-3)
            else:
              final_position.append(np.array(blender_objects[obj_idx].location[1]))
          
          # Y
          if axis == 0:
            if movement != ['no']:
              if movement[0] == 'left':
                final_position.append(2)
              else:
                final_position.append(-2)
            else:
              final_position.append(np.array(blender_objects[obj_idx].location[0]))

          # Z
          if axis == 2:
            if movement != ['no']:
              if movement[0] == 'below':
                final_position.append(2)
              else:
                final_position.append(objects[obj]['r'])
            else:
              final_position.append(np.array(blender_objects[obj_idx].location[2]))

          # CLOSE/FAR
          close_far_thresh = 3
          if axis == 3:
            if movement != ['no']:
              far_sample = []
              close_sample = []
              while far_sample == [] or \
                  np.linalg.norm(far_sample - ref_obj_loc) < close_far_thresh or \
                  np.array([np.linalg.norm(far_sample - posit) < args.min_dist for posit in final_positions]).any():

                    x = random.choice(np.linspace(-2, 2, 10, endpoint=True))
                    y = random.choice(np.linspace(-2, 2, 10, endpoint=True))
                    z = random.choice(np.linspace(0.6, 2, 10, endpoint=True))
                    far_sample = np.array([x, y, z])

              while close_sample == [] or \
                  np.linalg.norm(close_sample - ref_obj_loc) > close_far_thresh or \
                  np.linalg.norm(close_sample - ref_obj_loc) < 1 or \
                  np.array([np.linalg.norm(close_sample - posit) < args.min_dist for posit in final_positions]).any():

                    x = random.choice(np.linspace(-2, 2, 10, endpoint=True))
                    y = random.choice(np.linspace(-2, 2, 10, endpoint=True))
                    z = random.choice(np.linspace(0.6, 2, 10, endpoint=True))
                    close_sample = np.array([x, y, z])

              if movement[0] == 'far':
                final_position = close_sample
              else:
                final_position = far_sample
            else:
              pass

          # ON/OFF
          close_far_thresh = 1
          if axis == 4:
            if movement != ['no']:
              curvy = True
              off_sample = []
              on_sample = []
              while off_sample == [] or \
                    np.linalg.norm(off_sample - ref_obj_loc) < close_far_thresh or \
                  np.array([np.linalg.norm(off_sample - posit) < args.min_dist for posit in final_positions]).any():

                    x = random.choice(np.linspace(-2, 2, 10, endpoint=True))
                    y = random.choice(np.linspace(-2, 2, 10, endpoint=True))
                    # z = random.choice(np.linspace(0.6, 2, 10, endpoint=True))
                    z = 0
                    off_sample = np.array([x, y, z])

              x = final_positions[-1][0] + random.uniform(-0.2, 0.2)
              y = final_positions[-1][1] + random.uniform(-0.2, 0.2)
              
              r_prev = objects[obj_idx-1]['r']
              r = objects[obj_idx]['r']
              z = final_positions[-1][2] + r_prev + r

              on_sample = np.array([x, y, z])

              if movement[0] == 'off':
                final_position = on_sample

              else:
                final_position = off_sample
            else:
              pass

          # IN/OUT
          close_far_thresh = 1
          if axis == 5:
            if movement != ['no']:
              curvy = True
              out_sample = []
              in_sample = []
              while out_sample == [] or \
                  np.linalg.norm(out_sample - ref_obj_loc) < close_far_thresh or \
                  np.array([np.linalg.norm(out_sample - posit) < args.min_dist for posit in final_positions]).any():

                    x = random.choice(np.linspace(-2, 2, 10, endpoint=True))
                    # y = random.choice(np.linspace(-2, 2, 10, endpoint=True))
                    y = -3 + random.uniform(-0.2, 0.2)
                    # z = random.choice(np.linspace(0.6, 2, 10, endpoint=True))
                    z = 0
                    out_sample = np.array([x, y, z])

              # if obj_idx == 1:
              #   offset = -1
              # else:
              #   offset = 1
              # x = final_positions[0][0] + offset
              # y = final_positions[0][1] + random.choice(np.linspace(-0.2, 0.2, 2, endpoint=True))

              #offsets = [[-1, -1], [-1, 1], [1, -1], [1, 1]]
              offsets = [[-0.5, -0.5], [-0.5, 0.5], [0.5, -0.5], [0.5, 0.5]]

              x, y = offsets[obj_idx - 1]
              # x, y = [0, 0]
              x += random.uniform(-0.1, 0.1)
              y += random.uniform(-0.1, 0.1)

              r = objects[obj_idx]['r']
              z = final_positions[0][2] + r

              in_sample = np.array([x, y, z])

              if movement[0] == 'out':
                final_position = in_sample

              else:
                final_position = out_sample
            else:
              pass

        final_positions.append(final_position)

      traj = calculate_trajectory(init_positions, final_positions, args, curvy=curvy)

    else:
      move_obj_idx, pos = traj[scene_idx-1]

      move_object(blender_objects[move_obj_idx], pos)
      
      pixel_coords = utils.get_camera_coords(camera, blender_objects[move_obj_idx].location)
      objects[move_obj_idx]['pixel_coords'] = pixel_coords

      # <Vector (-1.6002, -1.5445, 1.9500)>
      objects[move_obj_idx]['3d_coords'] = list(blender_objects[move_obj_idx].location)
      
      # <Euler (x=0.0000, y=0.0000, z=139.0579), order='XYZ'>
      objects[move_obj_idx]['rotation'] = blender_objects[move_obj_idx].rotation_euler[2]






    ### get b_box
    box_dict = get_b_box.main(bpy.context, blender_objects)
    for _id in box_dict:
      objects[_id]['bbox'] = box_dict[_id]

    # Render the scene and dump the scene data structure
    scene_struct['objects'] = objects
    scene_struct['relationships'] = compute_all_relationships(scene_struct)


    tree = bpy.context.scene.node_tree
    links = tree.links
    rl = tree.nodes['Render Layers']
    v = tree.nodes['Viewer']

    links.new(rl.outputs[0], v.inputs[0])
    while True:
      try:
        bpy.ops.render.render(write_still=True)
        break
      except Exception as e:
        print(e)
    links.remove(links[0])

    # get viewer pixels
    rgb_pixels = bpy.data.images['Viewer Node'].pixels
    rgb_pixels = np.array(rgb_pixels[:])
    rgb_pixels = np.power(rgb_pixels, 1/2.2)
    rgb_pixels[rgb_pixels > 1] = 1
    rgb_pixels = rgb_pixels.reshape(args.height, args.width, 4)[...,:3]

    links.new(rl.outputs[2], v.inputs[0])
    render_shadeless(blender_objects, lights_off=False)
    links.remove(links[0])

    # get viewer pixels
    depth_pixels = bpy.data.images['Viewer Node'].pixels
    depth_pixels = np.array(depth_pixels[:])
    depth_pixels = depth_pixels.reshape(args.height, args.width, 4)[...,0, None]


    links.new(rl.outputs[0], v.inputs[0])
    render_shadeless(blender_objects)
    links.remove(links[0])

    # get viewer pixels
    mask_pixels = bpy.data.images['Viewer Node'].pixels
    mask_pixels = np.array(mask_pixels[:])
    mask_pixels = mask_pixels.reshape(args.height, args.width, 4)[...,:3]

    pixels = np.concatenate((rgb_pixels, depth_pixels, mask_pixels), axis=2)
    pixels = np.flipud(pixels)

    utils.save_arr(pixels, arr_path)

    with open(scene_path, 'w') as f:
      json.dump(scene_struct, f, indent=2)
Ejemplo n.º 8
0
def replace_random_object(scene_struct, blender_objects, camera, args):

    num_objs = len(blender_objects)
    n_rand = int(random.uniform(0, 1) * num_objs)

    obj = blender_objects[n_rand]
    x, y, r = obj.location
    size_name = scene_struct['objects'][n_rand]['size']
    old_shape = scene_struct['objects'][n_rand]['shape']
    old_color = scene_struct['objects'][n_rand]['color']
    utils.delete_object(obj)

    scene_struct['objects'].pop(n_rand)
    blender_objects.pop(n_rand)
    objects = scene_struct['objects']
    positions = [obj.location for obj in blender_objects]

    # Load the property file
    with open(args.properties_json, 'r') as f:
        properties = json.load(f)
        color_name_to_rgba = {}
        for name, rgb in properties['colors'].items():
            rgba = [float(c) / 255.0 for c in rgb] + [1.0]
            color_name_to_rgba[name] = rgba
        material_mapping = [(v, k) for k, v in properties['materials'].items()]
        object_mapping = [(v, k) for k, v in properties['shapes'].items()]
        size_mapping = list(properties['sizes'].items())

    shape_color_combos = None
    if args.shape_color_combos_json is not None:
        with open(args.shape_color_combos_json, 'r') as f:
            shape_color_combos = list(json.load(f).items())

    # Choose random color and shape
    if shape_color_combos is None:
        obj_name_out = old_shape
        color_name = old_color
        while obj_name_out == old_shape:
            obj_name, obj_name_out = random.choice(object_mapping)
        while color_name == old_color:
            color_name, rgba = random.choice(list(color_name_to_rgba.items()))
    else:
        obj_name_out = old_shape
        color_name = old_color
        while obj_name_out == old_shape:
            obj_name_out, color_choices = random.choice(shape_color_combos)
        while color_name == old_color:
            color_name = random.choice(color_choices)
        obj_name = [k for k, v in object_mapping if v == obj_name_out][0]
        rgba = color_name_to_rgba[color_name]

    # For cube, adjust the size a bit
    if obj_name == 'Cube':
        r /= math.sqrt(2)

    # Choose random orientation for the object.
    theta = 360.0 * random.random()

    # Actually add the object to the scene
    utils.add_object(args.shape_dir, obj_name, r, (x, y), theta=theta)
    obj = bpy.context.active_object
    blender_objects.append(obj)
    positions.append((x, y, r))

    # Attach a random material
    mat_name, mat_name_out = random.choice(material_mapping)
    utils.add_material(mat_name, Color=rgba)

    # Record data about the object in the scene data structure
    pixel_coords = utils.get_camera_coords(camera, obj.location)
    bbox = camera_view_bounds_2d(bpy.context.scene, camera, obj)

    objects.append({
        'shape': obj_name_out,
        'size': size_name,
        'material': mat_name_out,
        '3d_coords': tuple(obj.location),
        'rotation': theta,
        'pixel_coords': pixel_coords,
        'bbox': bbox.to_tuple(),
        'color': color_name,
    })
    scene_struct['objects'] = objects
    return blender_objects, scene_struct
Ejemplo n.º 9
0
def add_objects(scene_struct, blender_objects, camera, args):

    num_objects = 1
    # Load the property file
    with open(args.properties_json, 'r') as f:
        properties = json.load(f)
        color_name_to_rgba = {}
        for name, rgb in properties['colors'].items():
            rgba = [float(c) / 255.0 for c in rgb] + [1.0]
            color_name_to_rgba[name] = rgba
        material_mapping = [(v, k) for k, v in properties['materials'].items()]
        object_mapping = [(v, k) for k, v in properties['shapes'].items()]
        size_mapping = list(properties['sizes'].items())

    shape_color_combos = None
    if args.shape_color_combos_json is not None:
        with open(args.shape_color_combos_json, 'r') as f:
            shape_color_combos = list(json.load(f).items())

    objects = scene_struct['objects']
    positions = [obj.location for obj in blender_objects]

    for i in range(num_objects):
        # Choose a random size
        size_name, r = random.choice(size_mapping)

        # Try to place the object, ensuring that we don't intersect any existing
        # objects and that we are more than the desired margin away from all existing
        # objects along all cardinal directions.
        num_tries = 0
        while True:
            # If we try and fail to place an object too many times, then delete all
            # the objects in the scene and start over.
            num_tries += 1
            if num_tries > args.max_retries:
                print("*" * 20, " Num tries reached!!")
                #for obj in blender_objects:
                #  utils.delete_object(obj)
                #return add_random_objects(scene_struct, num_objects, args, camera)
            x = random.uniform(-3, 3)
            y = random.uniform(-3, 3)
            # Check to make sure the new object is further than min_dist from all
            # other objects, and further than margin along the four cardinal directions
            dists_good = True
            margins_good = True
            for (xx, yy, rr) in positions:
                dx, dy = x - xx, y - yy
                dist = math.sqrt(dx * dx + dy * dy)
                if dist - r - rr < args.min_dist:
                    dists_good = False
                    break
                for direction_name in ['left', 'right', 'front', 'behind']:
                    direction_vec = scene_struct['directions'][direction_name]
                    assert direction_vec[2] == 0
                    margin = dx * direction_vec[0] + dy * direction_vec[1]
                    if 0 < margin < args.margin:
                        print(margin, args.margin, direction_name)
                        print('BROKEN MARGIN!')
                        margins_good = False
                        break
                if not margins_good:
                    break

            if dists_good and margins_good:
                break

        # Choose random color and shape
        if shape_color_combos is None:
            obj_name, obj_name_out = random.choice(object_mapping)
            color_name, rgba = random.choice(list(color_name_to_rgba.items()))
        else:
            obj_name_out, color_choices = random.choice(shape_color_combos)
            color_name = random.choice(color_choices)
            obj_name = [k for k, v in object_mapping if v == obj_name_out][0]
            rgba = color_name_to_rgba[color_name]

        # For cube, adjust the size a bit
        if obj_name == 'Cube':
            r /= math.sqrt(2)

        # Choose random orientation for the object.
        theta = 360.0 * random.random()

        # Actually add the object to the scene
        utils.add_object(args.shape_dir, obj_name, r, (x, y), theta=theta)
        obj = bpy.context.object
        blender_objects.append(obj)
        positions.append((x, y, r))

        # Attach a random material
        mat_name, mat_name_out = random.choice(material_mapping)
        utils.add_material(mat_name, Color=rgba)

        # Record data about the object in the scene data structure
        pixel_coords = utils.get_camera_coords(camera, obj.location)
        bbox = camera_view_bounds_2d(
            bpy.context.scene, camera, obj
        )  #bpy_extras.object_utils.world_to_camera_view(scene, obj, coord)
        #print("*"* 10, b2, pixel_coords)
        #break
        objects.append({
            'shape': obj_name_out,
            'size': size_name,
            'material': mat_name_out,
            '3d_coords': tuple(obj.location),
            'rotation': theta,
            'pixel_coords': pixel_coords,
            'bbox': bbox.to_tuple(),
            'color': color_name,
        })

    scene_struct['objects'] = objects
    return blender_objects, scene_struct
Ejemplo n.º 10
0
def add_random_objects(scene_struct, num_objects, args, camera, attempts=0):
  """
  Add random objects to the current blender scene
  """
  if attempts > 10:
      print ("Tried 10 times to place {} objects and failed.  Giving up hope and moving on.".format(num_objects))
      return None, None
  # Load the property file
  with open(args.properties_json, 'r') as f:
    properties = json.load(f)
    color_name_to_rgba = {}
    for name, rgb in properties['colors'].items():
      rgba = [float(c) / 255.0 for c in rgb] + [1.0]
      color_name_to_rgba[name] = rgba
    material_mapping = [(v, k) for k, v in properties['materials'].items()]
    object_mapping = [(v, k) for k, v in properties['shapes'].items()]
    size_mapping = list(properties['sizes'].items())

  num_objects = [["duck",args.num_ducks],["sphere",args.num_balls]]

  objects_to_place = []
  for obj_name, num in num_objects:
      for i in range(num):
          objects_to_place.append(obj_name)

  shape_color_combos = None
  if args.shape_color_combos_json is not None:
    with open(args.shape_color_combos_json, 'r') as f:
      shape_color_combos = list(json.load(f).items())

  positions = []
  objects = []
  blender_objects = []
  x_range = [-2.5,2.5]
  y_range = [-2.5,2.5]
  corners = [[x_range[0], y_range[0]],
             [x_range[0], y_range[1]],
             [x_range[1], y_range[0]],
             [x_range[1], y_range[1]],]
  i=-1
  while len(objects_to_place) > 0:
    i+=1
  #for i in range(num_objects):
    # Choose a random size
    size_name, r = random.choice(size_mapping)

    # Try to place the object, ensuring that we don't intersect any existing
    # objects and that we are more than the desired margin away from all existing
    # objects along all cardinal directions.
    num_tries = 0
    while True:
      # If we try and fail to place an object too many times, then delete all
      # the objects in the scene and start over.
      num_tries += 1
      if num_tries > args.max_retries:
        for obj in blender_objects:
          utils.delete_object(obj)
        return add_random_objects(scene_struct, num_objects, args, camera, attempts=attempts+1)

      #x = corners[i][0]
      #y = corners[i][1]

      #print (x, y, "POSITION")


      x = random.uniform(*x_range)
      y = random.uniform(*y_range)


      # Check to make sure the new object is further than min_dist from all
      # other objects, and further than margin along the four cardinal directions
      dists_good = True
      margins_good = True
      for (xx, yy, rr) in positions:
        dx, dy = x - xx, y - yy
        dist = math.sqrt(dx * dx + dy * dy)
        if dist - r - rr < args.min_dist:
          dists_good = False
          break
        for direction_name in ['left', 'right', 'front', 'behind']:
          direction_vec = scene_struct['directions'][direction_name]
          assert direction_vec[2] == 0
          margin = dx * direction_vec[0] + dy * direction_vec[1]
          if 0 < margin < args.margin:
            print(margin, args.margin, direction_name)
            print('BROKEN MARGIN!')
            margins_good = False
            break
        if not margins_good:
          break

      if dists_good and margins_good:
        break

    # Choose random color and shape
    if shape_color_combos is None:
      obj_name_out = objects_to_place.pop()
      #obj_name = object_mapping[obj_name_out]
      obj_name = properties["shapes"][obj_name_out]
      #obj_name, obj_name_out = random.choice(object_mapping)
      color_name, rgba = random.choice(list(color_name_to_rgba.items()))
    else:
      obj_name_out, color_choices = random.choice(shape_color_combos)
      color_name = random.choice(color_choices)
      obj_name = [k for k, v in object_mapping if v == obj_name_out][0]
      rgba = color_name_to_rgba[color_name]


    r *= args.width / 256. / 1.2
    zshift=0.0
    # For cube, adjust the size a bit
    if obj_name == 'Cube':
      r /= math.sqrt(2)

    if obj_name=="Sphere":
        zshift = -0.25*r

    if obj_name == 'Rubber Duck':
        r /= math.sqrt(2)
        zshift=-1.15

    # Choose random orientation for the object.
    theta = 360.0 * random.random()

    # Actually add the object to the scene
    utils.add_object(args.shape_dir, obj_name, r, (x, y), theta=theta, zshift=zshift)
    obj = bpy.context.object
    blender_objects.append(obj)
    positions.append((x, y, r))

    # Attach a random material
    if obj_name != 'Rubber Duck':
        mat_name, mat_name_out = random.choice(material_mapping)
        utils.add_material(mat_name, Color=rgba)

    # Record data about the object in the scene data structure
    pixel_coords = utils.get_camera_coords(camera, obj.location)
    objects.append({
      'shape': obj_name_out,
      'size': size_name,
      #'material': mat_name_out,
      '3d_coords': tuple(obj.location),
      'rotation': theta,
      'pixel_coords': pixel_coords,
      'color': color_name,
    })

  # Check that all objects are at least partially visible in the rendered image
  all_visible = check_visibility(blender_objects, args.min_pixels_per_object*(args.width/256)**2)
  if not all_visible:
    # If any of the objects are fully occluded then start over; delete all
    # objects from the scene and place them all again.
    print('Some objects are occluded; replacing objects')
    for obj in blender_objects:
      utils.delete_object(obj)
    return add_random_objects(scene_struct, num_objects, args, camera, attempts=attempts+1)

  return objects, blender_objects
Ejemplo n.º 11
0
def add_random_objects(scene_struct, num_objects, args, camera, gen_list):
    """
  Add random objects to the current blender scene
  """

    # Load the property file
    with open(args.properties_json, 'r') as f:
        properties = json.load(f)
        color_name_to_rgba = {}
        for name, rgb in properties['colors'].items():
            rgba = [float(c) / 255.0 for c in rgb] + [1.0]
            color_name_to_rgba[name] = rgba
        material_mapping = [(v, k) for k, v in properties['materials'].items()]
        object_mapping = [(v, k) for k, v in properties['shapes'].items()]
        size_mapping = list(properties['sizes'].items())

    shape_color_combos = None
    if args.shape_color_combos_json is not None:
        with open(args.shape_color_combos_json, 'r') as f:
            shape_color_combos = list(json.load(f).items())

    positions = []
    objects = []
    blender_objects = []
    assert num_objects == 1, "Only Generate Single"
    gen_config = gen_list.split('.')
    gen_config = [k.split('_') for k in gen_config]
    for i in range(num_objects):
        # Choose a random size
        size_name, r = random.choice(size_mapping)

        # Try to place the object, ensuring that we don't intersect any existing
        # objects and that we are more than the desired margin away from all existing
        # objects along all cardinal directions.
        num_tries = 0
        while True:
            # If we try and fail to place an object too many times, then delete all
            # the objects in the scene and start over.
            num_tries += 1
            if num_tries > args.max_retries:
                for obj in blender_objects:
                    utils.delete_object(obj)
                return add_random_objects(scene_struct, num_objects, args,
                                          camera, gen_list)
            # if i == 0:
            #   x = random.uniform(-2.5, -0.3)
            # else:
            #   x = random.uniform(0.3, 2.5)
            x = random.uniform(-1.5, 1.5)

            # x = random.uniform(-3, 3)
            y = x  #random.uniform(-0.2, 0.2)#random.uniform(-3, 3)
            rn = random.uniform(0.5 * (np.abs(x) - 0.3) - 2.1, 0.1)
            y += rn
            x -= rn
            # Check to make sure the new object is further than min_dist from all
            # other objects, and further than margin along the four cardinal directions
            dists_good = True
            margins_good = True
            for (xx, yy, rr) in positions:
                dx, dy = x - xx, y - yy
                dist = math.sqrt(dx * dx + dy * dy)
                if dist - r - rr < args.min_dist:
                    dists_good = False
                    break
                for direction_name in ['left', 'right', 'front', 'behind']:
                    direction_vec = scene_struct['directions'][direction_name]
                    assert direction_vec[2] == 0
                    margin = dx * direction_vec[0] + dy * direction_vec[1]
                    if 0 < margin < args.margin:
                        print(margin, args.margin, direction_name)
                        print('BROKEN MARGIN!')
                        margins_good = False
                        break
                if not margins_good:
                    break

            if dists_good and margins_good:
                break

        # Choose random color and shape
        if shape_color_combos is None:
            obj_name, obj_name_out = random.choice(object_mapping)
            color_name, rgba = random.choice(list(color_name_to_rgba.items()))
        else:
            obj_name_out, color_choices = random.choice(shape_color_combos)
            color_name = random.choice(color_choices)
            obj_name = [k for k, v in object_mapping if v == obj_name_out][0]
            rgba = color_name_to_rgba[color_name]

        # print (obj_name, obj_name_out, color_name, rgba)
        # abc
        color_name = gen_config[i][0]
        obj_name = properties['shapes'][gen_config[i][1]]
        obj_name_out = gen_config[i][1]
        rgba = color_name_to_rgba[color_name]

        print(color_name, obj_name)
        # abc

        # For cube, adjust the size a bit
        if obj_name == 'cube':
            assert False
            r /= math.sqrt(2)

        # Choose random orientation for the object.
        theta = 45.  #360.0 * random.random()

        if obj_name == 'Trunk':
            theta = 134.

        # Actually add the object to the scene
        utils.add_object(args.shape_dir, obj_name, r, (x, y), theta=theta)
        obj = bpy.context.object
        blender_objects.append(obj)
        positions.append((x, y, r))

        # Attach a random material
        mat_name, mat_name_out = random.choice(material_mapping)
        utils.add_material(mat_name, Color=rgba)

        # Record data about the object in the scene data structure
        pixel_coords = utils.get_camera_coords(camera, obj.location)
        objects.append({
            'shape': obj_name_out,
            'size': size_name,
            'material': mat_name_out,
            '3d_coords': tuple(obj.location),
            'rotation': theta,
            'pixel_coords': pixel_coords,
            'color': color_name,
        })

    # Check that all objects are at least partially visible in the rendered image
    all_visible = check_visibility(blender_objects, args.min_pixels_per_object)
    if not all_visible:
        # If any of the objects are fully occluded then start over; delete all
        # objects from the scene and place them all again.
        print('Some objects are occluded; replacing objects')
        for obj in blender_objects:
            utils.delete_object(obj)
        return add_random_objects(scene_struct, num_objects, args, camera,
                                  gen_list)

    return objects, blender_objects
Ejemplo n.º 12
0
def add_random_objects(scene_struct, num_objects, args, camera):
    """
  Add random objects to the current blender scene
  """

    # Load the property file
    with open(args.properties_json, 'r') as f:
        properties = json.load(f)
        color_name_to_rgba = {}
        for name, rgb in properties['colors'].items():
            rgba = [float(c) / 255.0 for c in rgb] + [1.0]
            color_name_to_rgba[name] = rgba
        material_mapping = [(v, k) for k, v in properties['materials'].items()]
        object_mapping = [(v, k) for k, v in properties['shapes'].items()]
        size_mapping = list(properties['sizes'].items())

    shape_color_combos = None
    if args.shape_color_combos_json is not None:
        with open(args.shape_color_combos_json, 'r') as f:
            shape_color_combos = list(json.load(f).items())

    positions = []
    objects = []
    blender_objects = []
    for i in range(num_objects):
        # Choose a random size
        size_name, r = random.choice(size_mapping)

        # Try to place the object, ensuring that we don't intersect any existing
        # objects and that we are more than the desired margin away from all existing
        # objects along all cardinal directions.
        num_tries = 0
        while True:
            # If we try and fail to place an object too many times, then delete all
            # the objects in the scene and start over.
            num_tries += 1
            if num_tries > args.max_retries:
                for obj in blender_objects:
                    utils.delete_object(obj)
                return add_random_objects(scene_struct, num_objects, args,
                                          camera)
            x = random.uniform(-2.5, 2.5)
            y = random.uniform(-2.5, 2.5)
            # Check to make sure the new object is further than min_dist from all
            # other objects, and further than margin along the four cardinal directions
            dists_good = True
            margins_good = True
            for (xx, yy, rr) in positions:
                dx, dy = x - xx, y - yy
                dist = math.sqrt(dx * dx + dy * dy)
                if dist <= 0.5 and random.random() <= 0.5:
                    x = xx
                    y = yy
                dx, dy = x - xx, y - yy
                dist = math.sqrt(dx * dx + dy * dy)
                if dist >= 0.1 and dist - r - rr < args.min_dist:
                    dists_good = False
                    break
                for direction_name in [
                        'left', 'right', 'front', 'behind', 'above', 'below'
                ]:
                    direction_vec = scene_struct['directions'][direction_name]
                    # assert direction_vec[2] == 0
                    margin = dx * direction_vec[0] + dy * direction_vec[1]
                    if dist >= 0.1 and 0 < margin < args.margin:
                        print(dist, margin, args.margin, direction_name)
                        print('BROKEN MARGIN!')
                        margins_good = False
                        break
                if not margins_good:
                    break

            num, z = height(objects, (x, y))
            if dists_good and margins_good and num <= 2:
                break

        # Choose random color and shape
        if shape_color_combos is None:
            obj_name, obj_name_out = random.choice(object_mapping)
            color_name, rgba = random.choice(list(color_name_to_rgba.items()))
        else:
            obj_name_out, color_choices = random.choice(shape_color_combos)
            color_name = random.choice(color_choices)
            obj_name = [k for k, v in object_mapping if v == obj_name_out][0]
            rgba = color_name_to_rgba[color_name]

        # For cube, adjust the size a bit
        if obj_name == 'Cube':
            r /= math.sqrt(2)

        # Choose random orientation for the object.
        theta = 360.0 * random.random()

        # Actually add the object to the scene
        utils.add_object(args.shape_dir,
                         obj_name,
                         r, (x, y, z + r),
                         theta=theta)
        obj = bpy.context.object
        blender_objects.append(obj)
        positions.append((x, y, z + r))

        # Attach a random material
        mat_name, mat_name_out = random.choice(material_mapping)
        utils.add_material(mat_name, Color=rgba)

        # Record data about the object in the scene data structure
        pixel_coords = utils.get_camera_coords(camera, obj.location)

        import numpy as np
        bobj = bpy.context.object
        loc = np.array(bobj.location)
        dim = np.array(bobj.dimensions)
        half = dim / 2
        corners = []
        corners.append(loc + half * [1, 1, 1])
        corners.append(loc + half * [1, 1, -1])
        corners.append(loc + half * [1, -1, 1])
        corners.append(loc + half * [1, -1, -1])
        corners.append(loc + half * [-1, 1, 1])
        corners.append(loc + half * [-1, 1, -1])
        corners.append(loc + half * [-1, -1, 1])
        corners.append(loc + half * [-1, -1, -1])

        import mathutils
        corners_camera_coords = np.array([
            utils.get_camera_coords(camera, mathutils.Vector(tuple(corner)))
            for corner in corners
        ])
        xmax = np.amax(corners_camera_coords[:, 0])
        ymax = np.amax(corners_camera_coords[:, 1])
        xmin = np.amin(corners_camera_coords[:, 0])
        ymin = np.amin(corners_camera_coords[:, 1])

        objects.append({
            'shape': obj_name_out,
            'r': r,
            'size': size_name,
            'material': mat_name_out,
            '3d_coords': tuple(obj.location),
            'rotation': theta,
            'pixel_coords': pixel_coords,
            'color': color_name,
            'xmin': xmin,
            'ymin': ymin,
            'xmax': xmax,
            'ymax': ymax
        })

    # Check that all objects are at least partially visible in the rendered image
    all_visible = check_visibility(blender_objects, args.min_pixels_per_object)
    if not all_visible:
        # If any of the objects are fully occluded then start over; delete all
        # objects from the scene and place them all again.
        print('Some objects are occluded; replacing objects')
        for obj in blender_objects:
            utils.delete_object(obj)
        return add_random_objects(scene_struct, num_objects, args, camera)

    for obj in objects:
        print(obj['shape'], obj['color'])
    return objects, blender_objects
Ejemplo n.º 13
0
def add_random_objects(view_struct, num_objects, args, cams):
    """
  Add random objects to the current blender scene
  """

    # Load the property file
    with open(args.properties_json, 'r') as f:
        properties = json.load(f)
        color_name_to_rgba = {}
        for name, rgb in properties['colors'].items():
            rgba = [float(c) / 255.0 for c in rgb] + [1.0]
            color_name_to_rgba[name] = rgba
        material_mapping = [(v, k) for k, v in properties['materials'].items()]
        object_mapping = [(v, k) for k, v in properties['shapes'].items()]
        size_mapping = list(properties['sizes'].items())

    shape_color_combos = None
    if args.shape_color_combos_json is not None:
        with open(args.shape_color_combos_json, 'r') as f:
            shape_color_combos = list(json.load(f).items())

    positions = []
    objects = {cam.name: [] for cam in cams}
    blender_objects = []
    texts = []
    blender_texts = []
    all_chars = []
    for i in range(num_objects):
        # Choose a random size
        size_name, r = ('large', 0.7)  #random.choice(size_mapping)

        # Try to place the object, ensuring that we don't intersect any existing
        # objects and that we are more than the desired margin away from all existing
        # objects along all cardinal directions.
        num_tries = 0
        while True:
            # If we try and fail to place an object too many times, then delete all
            # the objects in the scene and start over.
            num_tries += 1
            if num_tries > args.max_retries:
                for obj in blender_objects:
                    utils.delete_object(obj)
                for text in blender_texts:
                    utils.delete_object(text)
                return add_random_objects(view_struct, num_objects, args, cams)
            x = uniform(-3, 3)
            y = uniform(-3, 3)
            # Check to make sure the new object is further than min_dist from all
            # other objects, and further than margin along the four cardinal directions
            dists_good = True
            margins_good = True
            for (xx, yy, rr) in positions:
                dx, dy = x - xx, y - yy
                dist = math.sqrt(dx * dx + dy * dy)
                if dist - r - rr < args.min_dist:
                    dists_good = False
                    break
                for direction_name in ['left', 'right', 'front', 'behind']:
                    direction_vec = view_struct['cc']['directions'][
                        direction_name]
                    assert direction_vec[2] == 0
                    margin = dx * direction_vec[0] + dy * direction_vec[1]
                    if 0 < margin < args.margin:
                        __builtin__.print(margin, args.margin, direction_name)
                        __builtin__.print('BROKEN MARGIN!')
                        margins_good = False
                        break
                if not margins_good:
                    break

            if dists_good and margins_good:
                break

        # Choose random color and shape
        if shape_color_combos is None:
            obj_name, obj_name_out = choice(object_mapping)
            color_name, rgba = choice(list(color_name_to_rgba.items()))
        else:
            obj_name_out, color_choices = choice(shape_color_combos)
            color_name = choice(color_choices)
            obj_name = [k for k, v in object_mapping if v == obj_name_out][0]
            rgba = color_name_to_rgba[color_name]

        # For cube, adjust the size a bit
        if obj_name == 'Cube':
            r /= math.sqrt(2)

        # Choose random orientation for the object.
        theta = 360.0 * random()

        # Actually add the object to the scene
        utils.add_object(args.shape_dir, obj_name, r, (x, y), theta=theta)
        obj = bpy.context.object
        blender_objects.append(obj)
        positions.append((x, y, r))
        __builtin__.print("added random object " + str(i))

        # Attach a random material
        mat_name, mat_name_out = choice(material_mapping)
        utils.add_material(mat_name, Color=rgba)

        # Record data about the object in the scene data structure
        for cam in cams:
            pixel_coords = utils.get_camera_coords(cam, obj.location)
            objects[cam.name].append({
                'shape': obj_name_out,
                'size': size_name,
                'material': mat_name_out,
                '3d_coords': tuple(obj.location),
                'rotation': theta,
                'pixel_coords': pixel_coords,
                'color': color_name,
            })

        # Generate Text
        num_chars = 1  # random.choice(range(1, 7))
        chars = choice(
            string.ascii_lowercase
        )  # "".join([random.choice(string.printable[:36]) for _ in range(num_chars)])

        # Add text to Blender
        if args.text:
            try:
                word_bboxes, char_bboxes, chars = utils.add_text(
                    chars, args.random_text_rotation, cams)
                all_chars.extend(chars)
            except Exception as e:
                return purge(blender_objects, blender_texts, view_struct,
                             num_objects, args, cams)

            # Select material and color for text
            text = bpy.context.scene.objects.active
            temp_dict = color_name_to_rgba.copy()
            del temp_dict[color_name]
            mat_name, mat_name_out = choice(material_mapping)
            color_name, rgba = choice(list(temp_dict.items()))
            utils.add_material(mat_name, Color=rgba)

            for char in chars:
                bpy.context.scene.objects.active = char
                utils.add_material(mat_name, Color=rgba)

            blender_texts.append(text)
            __builtin__.print("added text to object " + str(i))

            # Check that all objects are at least partially visible in the rendered image
            for cam in cams:
                bpy.context.scene.camera = cam
                all_objects_visible, visible_chars = check_visibility(
                    blender_objects + all_chars, args.min_pixels_per_object,
                    cams)
                for textid, visible_pixels in visible_chars.items():
                    for char_bbox in char_bboxes[cam.name]:
                        if char_bbox['id'] == textid:
                            char_bbox['visible_pixels'] = visible_pixels
            all_chars_visible = [
                c['visible_pixels'] > args.min_char_pixels
                for c in char_bboxes['cc']
            ]
            if args.all_chars_visible and not all(all_chars_visible):
                __builtin__.print(
                    "not all characters were visible, purging and retrying...")
                return purge(blender_objects, blender_texts, view_struct,
                             num_objects, args, cams)

            for cam in cams:
                x, y, _ = utils.get_camera_coords(cam, text.location)
                objects[cam.name][-1]['text'] = {
                    "font":
                    text.data.font.name,
                    "body":
                    text.data.body,
                    "3d_coords":
                    tuple(text.location),
                    "pixel_coords":
                    (x / bpy.context.scene.render.resolution_x,
                     y / bpy.context.scene.render.resolution_y),
                    "color":
                    color_name,
                    "char_bboxes":
                    char_bboxes,
                    "word_bboxes":
                    word_bboxes
                }
        else:
            all_objects_visible, visible_chars = check_visibility(
                blender_objects + all_chars, args.min_pixels_per_object, cams)

    if args.enforce_obj_visibility and not all_objects_visible:
        __builtin__.print(
            "not all objects were visible, purging and retrying...")
        return purge(blender_objects, blender_texts, view_struct, num_objects,
                     args, cams)

    return texts, blender_texts, objects, blender_objects
Ejemplo n.º 14
0
def add_random_objects(scene_struct, num_objects, args, camera, scene_idx=0):
    """
  Add random objects to the current blender scene
  """

    # Load the property file
    with open(args.properties_json, 'r') as f:
        properties = json.load(f)
        color_name_to_rgba = {}
        for name, rgb in properties['colors'].items():
            rgba = [float(c) / 255.0 for c in rgb] + [1.0]
            color_name_to_rgba[name] = rgba
        material_mapping = [(v, k) for k, v in properties['materials'].items()]
        object_mapping = [(v, k) for k, v in properties['shapes'].items()]
        size_mapping = list(properties['sizes'].items())

    shape_color_combos = None
    if args.shape_color_combos_json is not None:
        with open(args.shape_color_combos_json, 'r') as f:
            shape_color_combos = list(json.load(f).items())

    positions = []
    objects = []
    blender_objects = []

    last_obj_params = []

    for i in range(num_objects):

        # Choose random color and shape
        obj_name, obj_name_out = random.choice(object_mapping)

        while i != 0 and obj_name_out == "tray":
            obj_name, obj_name_out = random.choice(object_mapping)

        if i == 0:
            if np.random.rand() > 0.5:
                obj_name, obj_name_out = ("Tray", "tray")

        if obj_name_out == "tray":
            color_name, rgba = "gray", [0.66, 0.66, 0.66, 1]
        else:
            color_name, rgba = random.choice(list(color_name_to_rgba.items()))

        # Choose a random size
        if obj_name_out == "tray":
            size_name, r = "large", 0.6
        else:
            size_name, r = random.choice(size_mapping)

        # Attach a random material
        mat_name, mat_name_out = random.choice(material_mapping)

        # Try to place the object, ensuring that we don't intersect any existing
        # objects and that we are more than the desired margin away from all existing
        # objects along all cardinal directions.
        num_tries = 0
        while True:
            # If we try and fail to place an object too many times, then delete all
            # the objects in the scene and start over.
            num_tries += 1
            if num_tries > args.max_retries:
                for obj in blender_objects:
                    utils.delete_object(obj)
                return add_random_objects(scene_struct, num_objects, args,
                                          camera)

            if np.random.rand() > 0.5 and \
               last_obj_params != [] and \
               ("Cube" in last_obj_params[4] or "Cylinder" in last_obj_params[4]) and \
               last_obj_params[2] < 1:

                x = last_obj_params[0] + random.uniform(-0.3, 0.3)
                y = last_obj_params[1] + random.uniform(-0.3, 0.3)
                z = last_obj_params[2] + (2 * last_obj_params[3])

                min_dist = 0
                directions_to_check = []

            elif np.random.rand() > 0 and \
               last_obj_params != [] and \
               ("Tray" in last_obj_params[4]):

                x = last_obj_params[0] + random.uniform(-0.3, 0.3)
                y = last_obj_params[1] + random.uniform(-0.3, 0.3)
                z = last_obj_params[2]

                min_dist = -10
                directions_to_check = []

            else:
                x = random.choice(np.linspace(-2, 2, 25, endpoint=True))
                y = random.choice(np.linspace(-2, 2, 25, endpoint=True))
                z = random.choice(np.linspace(0, 2, 25, endpoint=True))

                if obj_name_out == "tray":
                    z = random.choice(np.linspace(0, 1, 25, endpoint=True))

                # x = 0
                # y = 0
                # z = 0

                min_dist = args.min_dist
                directions_to_check = [
                    x for x in scene_struct['directions'].keys()
                ]

            # Check to make sure the new object is further than min_dist from all
            # other objects, and further than margin along the four cardinal directions
            dists_good = True
            margins_good = True
            for (xx, yy, zz, rr) in positions:
                dx, dy, dz = x - xx, y - yy, z - zz
                dist = math.sqrt(dx * dx + dy * dy + dz * dz)
                if dist - r - rr < min_dist:
                    # print('BROKEN DISTANCE!', dist - r - rr, min_dist)
                    dists_good = False
                    break
                for direction_name in directions_to_check:
                    direction_vec = scene_struct['directions'][direction_name]
                    margin = dx * direction_vec[0] + dy * direction_vec[
                        1] + dz * direction_vec[2]
                    if 0 < margin < args.margin:
                        # print(margin, args.margin, direction_name)
                        # print('BROKEN MARGIN!')
                        margins_good = False
                        break
                if not margins_good:
                    break

            if dists_good and margins_good:
                break

        # For cube, adjust the size a bit
        if obj_name == 'Cube':
            r /= math.sqrt(2)

        # Choose random orientation for the object.
        # theta = 360.0 * random.random()
        theta = 0

        # Actually add the object to the scene
        utils.add_object(args.shape_dir, obj_name, r, (x, y, z), theta=theta)
        last_obj_params = [x, y, z, r, obj_name]

        utils.add_material(mat_name, Color=rgba)

        obj = bpy.context.object
        blender_objects.append(obj)

        # if obj_name_out != "tray":
        positions.append((x, y, z, r))

        # Record data about the object in the scene data structure
        pixel_coords = utils.get_camera_coords(camera, obj.location)
        objects.append({
            'shape': obj_name_out,
            'size': size_name,
            'r': r,
            'material': mat_name_out,
            '3d_coords': tuple(obj.location),
            'rotation': theta,
            'pixel_coords': pixel_coords,
            'color': color_name,
        })

        if obj_name_out == "tray":
            objects[-1]["mask_color"] = [0.66, 0.66, 0.66]

    # Check that all objects are at least partially visible in the rendered image
    all_visible = check_visibility(blender_objects, objects,
                                   args.min_pixels_per_object)
    if not all_visible:
        # If any of the objects are fully occluded then start over; delete all
        # objects from the scene and place them all again.
        print('Some objects are occluded or too small; replacing objects')
        for obj in blender_objects:
            utils.delete_object(obj)
        return add_random_objects(scene_struct, num_objects, args, camera)

    return objects, blender_objects
def add_random_objects(scene_struct, num_objects, args, camera):
    """
  Add random objects to the current blender scene
  """

    # Load the property file
    with open(args.properties_json, 'r') as f:
        properties = json.load(f)
        color_name_to_rgba = {}
        for name, rgb in properties['colors'].items():
            rgba = [float(c) / 255.0 for c in rgb] + [1.0]
            color_name_to_rgba[name] = rgba
        material_mapping = [(v, k) for k, v in properties['materials'].items()]
        object_mapping = [(v, k) for k, v in properties['shapes'].items()]

        # Choose between disks.blend and leaf.obj
        leaf_disk = False
        leaf_properties = properties['shapes'].copy()
        leaf_properties.pop('sphere')
        leaf_obj_mapping = [(v, k) for k, v in leaf_properties.items()]
        size_mapping = list(properties['sizes'].items())
        print("size mapping: ", size_mapping)

    shape_color_combos = None
    if args.shape_color_combos_json is not None:
        with open(args.shape_color_combos_json, 'r') as f:
            shape_color_combos = list(json.load(f).items())

    positions = []
    objects = []
    blender_objects = []

    init_rot = 0
    size_name, r = random.choice(size_mapping)
    color_name, rgba = random.choice(list(color_name_to_rgba.items()))
    '''
  WORKFLOW: First select nb of rows - 1 being bottom-most
  For each row, select nb of leaves - each row has a tilt angle that's a function of the row
  For each leaf, select angular position of leaf around z-axis. ensure leaves don't fully overlap
  '''
    nb_rows = random.randint(1, 3)

    # TEST CASE:
    # nb_rows = 4

    size_map_sorted = sorted(size_mapping, key=lambda x: x[1])
    size_map_sorted.reverse()

    # Position of leaves
    x = 0.0
    y = 0.0

    for row in range(nb_rows):
        # For each row pick nb of leaves
        nb_leaves_per_row = random.randint(3, 7)

        # TEST CASE:
        #nb_leaves_per_row = 4  # nb_leaves + 1 (coz sphere) --> change

        for i in range(nb_leaves_per_row):

            theta = math.pi * (random.choice(
                list(np.arange(row * 20, (row + 1) * 20,
                               0.5)))) / 180  # lower leaves are less tilted

            # Pick largest leaves for lowest rows, and decrease leaf size as rows increase (may need to be modified for more randomness)
            #size_name, r = size_map_sorted[row]
            size_name, r = random.choice(size_mapping)
            color_name, rgba = random.choice(list(color_name_to_rgba.items()))
            if not positions:
                z = r
                obj_name_out = str('sphere')
                obj_name = properties['shapes']['sphere']
            else:
                z = 0.0
                if leaf_disk == True:
                    obj_name, obj_name_out = random.choice(leaf_obj_mapping)
                else:
                    obj_name_out = str('leaf')
                    obj_name = str('leaf')
            # Actually add the object to the scene
            utils.add_object(args.shape_dir,
                             obj_name,
                             r, (x, y, z),
                             theta=theta)
            obj = bpy.context.object
            blender_objects.append(obj)
            positions.append((x, y, r))

            # TEST CASE: CHECK ORIENTATION
            print("theta: ", theta, " for obj: ", obj)

            # Attach a random material
            mat_name, mat_name_out = random.choice(material_mapping)
            utils.add_material(mat_name, Color=rgba)
            # Attach a random material
            mat_name, mat_name_out = random.choice(material_mapping)
            utils.add_material(mat_name, Color=rgba)

            # Record data about the object in the scene data structure
            pixel_coords = utils.get_camera_coords(camera, obj.location)
            objects.append({
                'shape': obj_name_out,
                'size': size_name,
                'material': mat_name_out,
                '3d_coords': tuple(obj.location),
                'rotation': theta,
                'pixel_coords': pixel_coords,
                'color': color_name,
            })

            # Rotate objects on axis of central sphere before placing next object
            # Create a parent and add children
            parent_object = blender_objects[0]
            bpy.context.object.rotation_mode = 'XYZ'

            if (len(positions) > 1 and obj.type == "MESH"):
                obj.select = True
                parent_object.select = True
                obj.parent = parent_object
                obj.matrix_parent_inverse = parent_object.matrix_world.inverted(
                )

            rot_angle_deg = 360.0 / (float(nb_leaves_per_row - 1)
                                     )  # to have some overlap between objects
            rot_angle = (3.14159 * rot_angle_deg / 180)
            # print("Rotated by: ", rot_angle - init_rot, " & rotation angle was: ", rot_angle)
            init_rot = rot_angle

            # Info note: The axis of interest is indexed by bpy.data.objects['ObjName'].rotation_euler[2]
            bpy.context.scene.objects.active = bpy.data.objects[
                parent_object.name]
            bpy.context.object.rotation_euler[
                2] = bpy.context.object.rotation_euler[2] + rot_angle
            parent_object.select = False
            obj.select = False
            bpy.ops.object.select_all(action='DESELECT')

    # Check that all objects are at least partially visible in the rendered image
    all_visible = check_visibility(blender_objects, args.min_pixels_per_object)

    return objects, blender_objects
def add_objects_from_json(scene_struct, args, camera):
    """
  Read json created by our unity simulation tool and read object properties to add objects
  """

    # Load the property file
    with open(args.properties_json, 'r') as f:
        properties = json.load(f)
        color_name_to_rgba = {}
        for name, rgb in properties['colors'].items():
            rgba = [float(c) / 255.0 for c in rgb] + [1.0]
            color_name_to_rgba[name] = rgba
        material_mapping = sorted([
            (v, k) for k, v in properties['materials'].items()
        ])
        object_mapping = sorted([(v, k)
                                 for k, v in properties['shapes'].items()])
        size_mapping = sorted(list(properties['sizes'].items()), reverse=True)

    with open(args.reconstructed_json, 'r') as f:
        scene = json.load(f)

    print(len(scene['objectStates']))

    shape_color_combos = None
    if args.shape_color_combos_json is not None:
        with open(args.shape_color_combos_json, 'r') as f:
            shape_color_combos = list(json.load(f).items())

    num_objects = len(scene['objectStates'])
    positions = []
    objects = []
    blender_objects = []
    for i in range(num_objects):

        object_representation = json.loads(scene['objectStates'][i])

        #get object size
        size_name, r = get_object_size(object_representation, size_mapping)

        #get object position
        x, y, z = get_object_position(object_representation)

        #get color and shape
        obj_name, obj_name_out, color_name, rgba = get_shape_and_color(
            object_representation, object_mapping,
            sorted(list(color_name_to_rgba.items())))

        # fix this calculate orientation from Quaternion
        # Choose random orientation for the object.
        theta = 360.0 * random.random()

        # Actually add the object to the scene
        utils.add_object_to_3d(args.shape_dir,
                               obj_name,
                               r, (x, y, z),
                               theta=theta)
        obj = bpy.context.object
        blender_objects.append(obj)
        positions.append((x, y, r))

        # Attach a random material
        mat_name, mat_name_out = get_material(object_representation,
                                              material_mapping)

        print(mat_name)
        print(mat_name_out)

        utils.add_material(mat_name, Color=rgba)

        # Record data about the object in the scene data structure
        pixel_coords = utils.get_camera_coords(camera, obj.location)
        objects.append({
            'shape': obj_name_out,
            'size': size_name,
            'material': mat_name_out,
            '3d_coords': tuple(obj.location),
            'rotation': theta,
            'pixel_coords': pixel_coords,
            'color': color_name,
        })
    return objects, blender_objects
Ejemplo n.º 17
0
def add_random_objects(scene_struct,
                       num_objects,
                       args,
                       camera,
                       output_mask="mask.png"):
    """
  Add random objects to the current blender scene
  """

    # Load the property file
    with open(args.properties_json, "r") as f:
        properties = json.load(f)
        color_name_to_rgba = {}
        for name, rgb in properties["colors"].items():
            rgba = [float(c) / 255.0 for c in rgb] + [1.0]
            color_name_to_rgba[name] = rgba
        material_mapping = [(v, k) for k, v in properties["materials"].items()]
        object_mapping = [(v, k) for k, v in properties["shapes"].items()]
        size_mapping = list(properties["sizes"].items())

    shape_color_combos = None
    if args.shape_color_combos_json is not None:
        with open(args.shape_color_combos_json, "r") as f:
            shape_color_combos = list(json.load(f).items())

    positions = []
    objects = []
    blender_objects = []
    for i in range(num_objects):
        # Choose a random size
        size_name, r = random.choice(size_mapping)

        # Try to place the object, ensuring that we don't intersect any existing
        # objects and that we are more than the desired margin away from all existing
        # objects along all cardinal directions.
        num_tries = 0
        while True:
            # If we try and fail to place an object too many times, then delete all
            # the objects in the scene and start over.
            num_tries += 1
            if num_tries > args.max_retries:
                for obj in blender_objects:
                    utils.delete_object(obj)
                return add_random_objects(scene_struct,
                                          num_objects,
                                          args,
                                          camera,
                                          output_mask=output_mask)
            x = random.uniform(-3, 3)
            y = random.uniform(-3, 3)
            # Check to make sure the new object is further than min_dist from all
            # other objects, and further than margin along the four cardinal directions
            dists_good = True
            margins_good = True
            for (xx, yy, rr) in positions:
                dx, dy = x - xx, y - yy
                dist = math.sqrt(dx * dx + dy * dy)
                if dist - r - rr < args.min_dist:
                    dists_good = False
                    break
                for direction_name in ["left", "right", "front", "behind"]:
                    direction_vec = scene_struct["directions"][direction_name]
                    assert direction_vec[2] == 0
                    margin = dx * direction_vec[0] + dy * direction_vec[1]
                    if 0 < margin < args.margin:
                        print(margin, args.margin, direction_name)
                        print("BROKEN MARGIN!")
                        margins_good = False
                        break
                if not margins_good:
                    break

            if dists_good and margins_good:
                break

        # Choose random color and shape
        if shape_color_combos is None:
            obj_name, obj_name_out = random.choice(object_mapping)
            color_name, rgba = random.choice(list(color_name_to_rgba.items()))
        else:
            obj_name_out, color_choices = random.choice(shape_color_combos)
            color_name = random.choice(color_choices)
            obj_name = [k for k, v in object_mapping if v == obj_name_out][0]
            rgba = color_name_to_rgba[color_name]

        # For cube, adjust the size a bit
        if obj_name == "Cube":
            r /= math.sqrt(2)

        # Choose random orientation for the object.
        theta = 360.0 * random.random()

        # Actually add the object to the scene
        utils.add_object(args.shape_dir, obj_name, r, (x, y), theta=theta)
        obj = bpy.context.object
        blender_objects.append(obj)
        positions.append((x, y, r))

        # Attach a random material
        mat_name, mat_name_out = random.choice(material_mapping)
        utils.add_material(mat_name, Color=rgba)

        # Record data about the object in the scene data structure
        pixel_coords = utils.get_camera_coords(camera, obj.location)
        objects.append({
            "shape": obj_name_out,
            "size": size_name,
            "material": mat_name_out,
            "3d_coords": tuple(obj.location),
            "rotation": theta,
            "pixel_coords": pixel_coords,
            "color": color_name,
            "mask_color": tuple(),
        })

    # Check that all objects are at least partially visible in the rendered image
    all_visible = check_visibility(blender_objects,
                                   objects,
                                   args.min_pixels_per_object,
                                   output_mask=output_mask)
    if not all_visible:
        # If any of the objects are fully occluded then start over; delete all
        # objects from the scene and place them all again.
        print("Some objects are occluded; replacing objects")
        for obj in blender_objects:
            utils.delete_object(obj)
        return add_random_objects(scene_struct,
                                  num_objects,
                                  args,
                                  camera,
                                  output_mask=output_mask)

    return objects, blender_objects
Ejemplo n.º 18
0
def relchange_random(scene_struct, blender_objects, camera, args):

    num_objs = len(blender_objects)
    n_rand = int(random.uniform(0, 1) * num_objs)

    obj = blender_objects[n_rand]
    loc = obj.location
    r = loc[2]
    size_name = scene_struct['objects'][n_rand]['size']
    shape = scene_struct['objects'][n_rand]['shape']
    color = scene_struct['objects'][n_rand]['color']
    mat_name = scene_struct['objects'][n_rand]['material']
    theta = scene_struct['objects'][n_rand]['rotation']
    utils.delete_object(obj)

    scene_struct['objects'].pop(n_rand)
    blender_objects.pop(n_rand)
    objects = scene_struct['objects']
    positions = [obj.location for obj in blender_objects]

    num_tries = 0
    while True:
        num_tries += 1
        dists_good = True
        margins_good = True
        x = random.uniform(-3, 3)
        y = random.uniform(-3, 3)
        dx_s, dy_s = x - loc[0], y - loc[1]
        dist = math.sqrt(dx_s * dx_s + dy_s * dy_s)
        if dist < 4:
            dists_good = False
            continue

        for (xx, yy, rr) in positions:
            dx, dy = x - xx, y - yy
            dist = math.sqrt(dx * dx + dy * dy)
            if dist - r - rr < args.min_dist:
                #print(dist - r - rr)
                dists_good = False
                break
            for direction_name in ['left', 'right', 'front', 'behind']:
                direction_vec = scene_struct['directions'][direction_name]
                assert direction_vec[2] == 0
                margin = dx * direction_vec[0] + dy * direction_vec[1]
                if 0 < margin < args.margin:
                    margins_good = False
                    break

        if num_tries > 10 and not (dists_good and margins_good):
            n_rand = int(random.uniform(0, num_objs - 1))
            obj = blender_objects[n_rand]
            loc = obj.location
            r = loc[2]
            num_tries = 0
        if dists_good and margins_good:
            break

    # Load the property file
    with open(args.properties_json, 'r') as f:
        properties = json.load(f)
        color_name_to_rgba = {}
        for name, rgb in properties['colors'].items():
            rgba = [float(c) / 255.0 for c in rgb] + [1.0]
            color_name_to_rgba[name] = rgba
        material_mapping = [(v, k) for k, v in properties['materials'].items()]
        object_mapping = [(v, k) for k, v in properties['shapes'].items()]
        size_mapping = list(properties['sizes'].items())

    shape_color_combos = None
    if args.shape_color_combos_json is not None:
        with open(args.shape_color_combos_json, 'r') as f:
            shape_color_combos = list(json.load(f).items())

    shape_name = properties['shapes'][shape]
    rgba = color_name_to_rgba[color]
    # Actually add the object to the scene
    utils.add_object(args.shape_dir, shape_name, r, (x, y), theta=theta)
    obj = bpy.context.active_object
    blender_objects.append(obj)
    positions.append((x, y, r))

    utils.add_material(properties['materials'][mat_name], Color=rgba)

    # Record data about the object in the scene data structure
    pixel_coords = utils.get_camera_coords(camera, obj.location)
    bbox = camera_view_bounds_2d(bpy.context.scene, camera, obj)

    objects.append({
        'shape': shape,  #obj_name_out
        'size': size_name,
        'material': mat_name,  #_out
        '3d_coords': tuple(obj.location),
        'rotation': theta,
        'pixel_coords': pixel_coords,
        'bbox': bbox.to_tuple(),
        'color': color,  #_name
    })
    scene_struct['objects'] = objects
    return blender_objects, scene_struct
Ejemplo n.º 19
0
def add_random_objects(scene_struct, num_objects, args, camera):
    """
  Add random objects to the current blender scene
  """

    # Load the property file
    with open(args.properties_json, 'r') as f:
        properties = json.load(f)
        color_name_to_rgba = {}
        for name, rgb in properties['colors'].items():
            rgba = [float(c) / 255.0 for c in rgb] + [1.0]
            color_name_to_rgba[name] = rgba
        material_mapping = [(v, k) for k, v in properties['materials'].items()]
        object_mapping = [(v, k) for k, v in properties['shapes'].items()]
        size_mapping = list(properties['sizes'].items())

    shape_color_combos = None
    if args.shape_color_combos_json is not None:
        with open(args.shape_color_combos_json, 'r') as f:
            shape_color_combos = list(json.load(f).items())

    positions = []
    objects = []
    blender_objects = []

    if balanced_num_shapes_flag:
        chosen_objects = [
            object_mapping[j] for j in range(NUM_SHAPES)
            for _ in range(num_objects[j])
        ]
        range_num = sum(num_objects)
    else:
        range_num = num_objects

    for i in range(range_num):
        # Choose a random size
        size_name, r = random.choice(size_mapping)

        # Try to place the object, ensuring that we don't intersect any existing
        # objects and that we are more than the desired margin away from all existing
        # objects along all cardinal directions.
        num_tries = 0
        while True:
            # If we try and fail to place an object too many times, then delete all
            # the objects in the scene and start over.
            num_tries += 1
            if num_tries > args.max_retries:
                for obj in blender_objects:
                    utils.delete_object(obj)
                return add_random_objects(scene_struct, num_objects, args,
                                          camera)
            x = random.uniform(-3, 3)
            y = random.uniform(-3, 3)
            # Check to make sure the new object is further than min_dist from all
            # other objects, and further than margin along the four cardinal directions
            dists_good = True
            margins_good = True
            for (xx, yy, rr) in positions:
                dx, dy = x - xx, y - yy
                dist = math.sqrt(dx * dx + dy * dy)
                if dist - r - rr < args.min_dist:
                    dists_good = False
                    break
                for direction_name in ['left', 'right', 'front', 'behind']:
                    direction_vec = scene_struct['directions'][direction_name]
                    assert direction_vec[2] == 0
                    margin = dx * direction_vec[0] + dy * direction_vec[1]
                    if 0 < margin < args.margin:
                        print(margin, args.margin, direction_name)
                        print('BROKEN MARGIN!')
                        margins_good = False
                        break
                if not margins_good:
                    break

            if dists_good and margins_good:
                break

        # Choose random color and shape
        if shape_color_combos is None:
            # Need to change this line to just choose one of the pre-chosen shapes.
            # obj_name, obj_name_out = random.choice(object_mapping)
            # Here, obj_name_out is "cube", "sphere", or "cylinder"
            if balanced_num_shapes_flag:
                obj_name, obj_name_out = chosen_objects[i]
            else:
                obj_name, obj_name_out = random.choice(object_mapping)
            color_name, rgba = random.choice(list(color_name_to_rgba.items()))
        else:
            obj_name_out, color_choices = random.choice(shape_color_combos)
            color_name = random.choice(color_choices)
            obj_name = [k for k, v in object_mapping if v == obj_name_out][0]
            rgba = color_name_to_rgba[color_name]

        # Get a random material
        mat_name, mat_name_out = random.choice(material_mapping)

        # Here, check if any of the chosen properties are disallowed.
        # If so, then keep randomly selecting again until no pair is disallowed.
        # Unfortunately, this will remove any guarantees about the distribution of labels.
        while obj_has_conflict(size_name, obj_name_out, mat_name_out,
                               color_name):
            size_name, r = random.choice(size_mapping)
            obj_name, obj_name_out = random.choice(object_mapping)
            mat_name, mat_name_out = random.choice(material_mapping)
            color_name, rgba = random.choice(list(color_name_to_rgba.items()))

        # For cube, adjust the size a bit
        if obj_name == 'Cube':
            r /= math.sqrt(2)

        # Choose random orientation for the object.
        theta = 360.0 * random.random()

        # Actually add the object to the scene
        utils.add_object(args.shape_dir, obj_name, r, (x, y), theta=theta)
        obj = bpy.context.object
        blender_objects.append(obj)
        positions.append((x, y, r))

        # Attach the chosen material and color.
        utils.add_material(mat_name, Color=rgba)

        # Record data about the object in the scene data structure
        pixel_coords = utils.get_camera_coords(camera, obj.location)
        objects.append({
            'shape': obj_name_out,
            'size': size_name,
            'material': mat_name_out,
            '3d_coords': tuple(obj.location),
            'rotation': theta,
            'pixel_coords': pixel_coords,
            'color': color_name,
        })

    # Check that all objects are at least partially visible in the rendered image
    all_visible = check_visibility(blender_objects, args.min_pixels_per_object)
    if not all_visible:
        # If any of the objects are fully occluded then start over; delete all
        # objects from the scene and place them all again.
        print('Some objects are occluded; replacing objects')
        for obj in blender_objects:
            utils.delete_object(obj)
        return add_random_objects(scene_struct, num_objects, args, camera)

    return objects, blender_objects
Ejemplo n.º 20
0
def add_specific_objects(scene_struct, object_dict, num_objects, args, camera):
    """
  Add specific objects to the current blender scene
  """

    # Load the property file
    with open(args.properties_json, 'r') as f:
        properties = json.load(f)
        color_name_to_rgba = {}
        for name, rgb in properties['colors'].items():
            rgba = [float(c) / 255.0 for c in rgb] + [1.0]
            color_name_to_rgba[name] = rgba
        material_mapping = [(v, k) for k, v in properties['materials'].items()]
        object_mapping = [(v, k) for k, v in properties['shapes'].items()]
        size_mapping = list(properties['sizes'].items())

    shape_color_combos = None
    if args.shape_color_combos_json is not None:
        with open(args.shape_color_combos_json, 'r') as f:
            shape_color_combos = list(json.load(f).items())

    positions = []
    objects = []
    blender_objects = []
    for i in range(num_objects):
        specific_object = object_dict[str(i)]
        size_idx = specific_object["size"]
        colour_idx = specific_object["colour"]
        material_idx = specific_object["material"]
        object_type_idx = specific_object["object_type"]
        orientation_spec = specific_object["orientation"]
        x_spec = specific_object["x"]
        y_spec = specific_object["y"]

        size_name, r = size_idx

        # Try to place the object, ensuring that we don't intersect any existing
        # objects and that we are more than the desired margin away from all existing
        # objects along all cardinal directions.
        num_tries = 0
        while True:
            # If we try and fail to place an object too many times, then delete all
            # the objects in the scene and start over.
            num_tries += 1
            if num_tries > args.max_retries:
                for obj in blender_objects:
                    utils.delete_object(obj)
                #return add_random_objects(scene_struct, num_objects, args, camera)
                return None, None
            x = x_spec
            y = y_spec
            # Check to make sure the new object is further than min_dist from all
            # other objects, and further than margin along the four cardinal directions
            dists_good = True
            margins_good = True
            for (xx, yy, rr) in positions:
                dx, dy = x - xx, y - yy
                dist = math.sqrt(dx * dx + dy * dy)
                if dist - r - rr < args.min_dist:
                    dists_good = False
                    break
                for direction_name in ['left', 'right', 'front', 'behind']:
                    direction_vec = scene_struct['directions'][direction_name]
                    assert direction_vec[2] == 0
                    margin = dx * direction_vec[0] + dy * direction_vec[1]
                    if 0 < margin < args.margin:
                        print(margin, args.margin, direction_name)
                        print('BROKEN MARGIN!')
                        margins_good = False
                        break
                if not margins_good:
                    break

            if dists_good and margins_good:
                break

        # Choose random color and shape
        if shape_color_combos is None:
            obj_name, obj_name_out = object_type_idx
            color_name, rgba = colour_idx
        else:
            fdhkfhddfh  # TODO: fail gracefully
            # obj_name_out, color_choices = random.choice(shape_color_combos)
            # color_name = random.choice(color_choices)
            # obj_name = [k for k, v in object_mapping if v == obj_name_out][0]
            # rgba = color_name_to_rgba[color_name]

        # For cube, adjust the size a bit
        if obj_name == 'Cube':
            r /= math.sqrt(2)

        # Choose random orientation for the object.
        theta = 360.0 * orientation_spec

        # Actually add the object to the scene
        utils.add_object(args.shape_dir, obj_name, r, (x, y), theta=theta)
        obj = bpy.context.object
        blender_objects.append(obj)
        positions.append((x, y, r))

        # Attach a random material
        mat_name, mat_name_out = material_idx
        utils.add_material(mat_name, Color=rgba)

        # Record data about the object in the scene data structure
        pixel_coords = utils.get_camera_coords(camera, obj.location)
        objects.append({
            'shape': obj_name_out,
            'size': size_name,
            'material': mat_name_out,
            '3d_coords': tuple(obj.location),
            'rotation': theta,
            'pixel_coords': pixel_coords,
            'color': color_name,
        })

    # Check that all objects are at least partially visible in the rendered image
    all_visible = check_visibility(blender_objects, args.min_pixels_per_object)
    if not all_visible:
        # If any of the objects are fully occluded then start over; delete all
        # objects from the scene and place them all again.
        print('Some objects are occluded; replacing objects')
        for obj in blender_objects:
            utils.delete_object(obj)
        #return add_random_objects(scene_struct, num_objects, args, camera)
        return None, None
    return objects, blender_objects
Ejemplo n.º 21
0
def add_random_objects(scene_struct, num_objects, args, camera, frame):
    """
  Add random objects to the current blender scene
  """
    flag = 0
    # Load the property file
    with open(args.properties_json, 'r') as f:
        properties = json.load(f)
        color_name_to_rgba = {}
        for name, rgb in properties['colors'].items():
            rgba = [float(c) / 255.0 for c in rgb] + [1.0]
            color_name_to_rgba[name] = rgba
        material_mapping = [(v, k) for k, v in properties['materials'].items()]
        object_mapping = [(v, k) for k, v in properties['shapes'].items()]
        size_mapping = list(properties['sizes'].items())

    shape_color_combos = None
    if args.shape_color_combos_json is not None:
        with open(args.shape_color_combos_json, 'r') as f:
            shape_color_combos = list(json.load(f).items())

    positions = []
    objects = []
    blender_objects = []
    for i in range(num_objects):
        # Choose a random size
        # size_name, r = random.choice(size_mapping)
        # yuji_size

        # size_name = "small"
        # r = 0.35
        size_name = "big"
        r = args.Objsize
        # Try to place the object, ensuring that we don't intersect any existing
        # objects and that we are more than the desired margin away from all existing
        # objects along all cardinal directions.
        num_tries = 0
        while True:
            # If we try and fail to place an object too many times, then delete all
            # the objects in the scene and start over.
            num_tries += 1
            if num_tries > args.max_retries:
                for obj in blender_objects:
                    utils.delete_object(obj)
                return add_random_objects(scene_struct, num_objects, args, camera)
            # shana_position
            # x = random.uniform(-3, 3)
            # y = random.uniform(-3, 3)
            x = pos[frame][0]
            y = pos[frame][1]
            # print("(x,y) = ("+str(x)+","+str(y)+")")
            # Check to make sure the new object is further than min_dist from all
            # other objects, and further than margin along the four cardinal directions
            dists_good = True
            margins_good = True
            for (xx, yy, rr) in positions:
                dx, dy = x - xx, y - yy
                dist = math.sqrt(dx * dx + dy * dy)
                if dist - r - rr < args.min_dist:
                    dists_good = False
                    break
                for direction_name in ['left', 'right', 'front', 'behind']:
                    direction_vec = scene_struct['directions'][direction_name]
                    assert direction_vec[2] == 0
                    margin = dx * direction_vec[0] + dy * direction_vec[1]
                    if 0 < margin < args.margin:
                        print(margin, args.margin, direction_name)
                        print('BROKEN MARGIN!')
                        margins_good = False
                        break
                if not margins_good:
                    break

            if dists_good and margins_good:
                break

        # Choose random color and shape
        if shape_color_combos is None:
            # yuji
            # print("shana")
            obj_name, obj_name_out = random.choice(object_mapping)
            obj_name = "SmoothCube_v2"
            obj_name = args.Objname
            obj_name_out = "cube"
            # obj_name = "Sphere"
            # obj_name_out = "sphere"

            # print(obj_name)
            # print(obj_name_out)
            color_name, rgba = random.choice(list(color_name_to_rgba.items()))
            # color_name = "red"
            #
            color_name = "yellow"
            col = (args.Objco).split(",")
            rgba = []
            for sh in range(0, 4):
                rgba.append(float(col[sh]))
            # if args.Objco == 0: #Red
            #     rgba = [0.6784313725490196, 0.13725490196078433, 0.13725490196078433, 1.0]
            # elif args.Objco == 1: #Gray
            #     rgba = [0.341176, 0.341176, 0.341176, 1.0]
            # elif args.Objco == 2: #Blue
            #     rgba = [0.164705, 0.294117, 0.84313, 1.0]
            # elif args.Objco ==
            # else:#Yellow
            #     rgba = [1.0,0.933333,0.2,1.0]
            # print(color_name)
            # print(rgba)
        else:
            obj_name_out, color_choices = random.choice(shape_color_combos)
            color_name = random.choice(color_choices)
            obj_name = [k for k, v in object_mapping if v == obj_name_out][0]
            rgba = color_name_to_rgba[color_name]

        # For cube, adjust the size a bit
        if obj_name == 'Cube':
            r /= math.sqrt(2)

        # Choose random orientation for the object.
        # theta = 360.0 * random.random()
        theta = 348.20058907697677
        # print(theta)
        # Actually add the object to the scene
        utils.add_object(args.shape_dir, obj_name, r, (x, y), theta=theta)
        obj = bpy.context.object
        blender_objects.append(obj)
        positions.append((x, y, r))

        # Attach a random material
        # mat_name, mat_name_out = random.choice(material_mapping)
        mat_name = "Rubber"
        mat_name_out = "rubber"
        # print(mat_name)
        # print(mat_name_out)
        utils.add_material(mat_name, Color=rgba)

        # Record data about the object in the scene data structure
        pixel_coords = utils.get_camera_coords(camera, obj.location)
        objects.append({
            'shape': obj_name_out,
            'size': size_name,
            'material': mat_name_out,
            '3d_coords': tuple(obj.location),
            'rotation': theta,
            'pixel_coords': pixel_coords,
            'color': color_name,
        })

    # Check that all objects are at least partially visible in the rendered image
    # all_visible = check_visibility(blender_objects, args.min_pixels_per_object)
    # if not all_visible:
    #     flag = 1
    #     # # If any of the objects are fully occluded then start over; delete all
    #     # # objects from the scene and place them all again.
    #     # print('Some objects are occluded; replacing objects')
    #     # for obj in blender_objects:
    #     #     utils.delete_object(obj)
    #     # return add_random_objects(scene_struct, num_objects, args, camera)

    return objects, blender_objects , flag
Ejemplo n.º 22
0
def add_random_objects(scene_struct, parameters, args, camera):
    """
  Add random objects to the current blender scene
  """
    #TODO: changed sigature, num_objects changed to parameters
    # Load the property file
    with open(args.properties_json, 'r') as f:
        properties = json.load(f)
        color_name_to_rgba = {}
        for name, rgb in properties['colors'].items():
            rgba = [float(c) / 255.0 for c in rgb] + [1.0]
            color_name_to_rgba[name] = rgba
        material_mapping = [(v, k) for k, v in properties['materials'].items()]
        object_mapping = [(v, k) for k, v in properties['shapes'].items()]
        size_mapping = list(properties['sizes'].items())

    # shape_color_combos = None
    # if args.shape_color_combos_json is not None:
    #     with open(args.shape_color_combos_json, 'r') as f:
    #         shape_color_combos = list(json.load(f).items())

    positions = []
    objects = []
    blender_objects = []

    for i in range(len(parameters)):
        # # Choose a random size
        # size_name, r = random.choice(size_mapping)
        #
        # # Try to place the object, ensuring that we don't intersect any existing
        # # objects and that we are more than the desired margin away from all existing
        # # objects along all cardinal directions.
        # num_tries = 0
        # while True:
        #     # If we try and fail to place an object too many times, then delete all
        #     # the objects in the scene and start over.
        #     num_tries += 1
        #     if num_tries > args.max_retries:
        #         for obj in blender_objects:
        #             utils.delete_object(obj)
        #         return add_random_objects(scene_struct, num_objects, args, camera)
        #     x = random.uniform(-3, 3)
        #     y = random.uniform(-3, 3)
        #     # Check to make sure the new object is further than min_dist from all
        #     # other objects, and further than margin along the four cardinal directions
        #     dists_good = True
        #     margins_good = True
        #     for (xx, yy, rr) in positions:
        #         dx, dy = x - xx, y - yy
        #         dist = math.sqrt(dx * dx + dy * dy)
        #         if dist - r - rr < args.min_dist:
        #             dists_good = False
        #             break
        #         for direction_name in ['left', 'right', 'front', 'behind']:
        #             direction_vec = scene_struct['directions'][direction_name]
        #             assert direction_vec[2] == 0
        #             margin = dx * direction_vec[0] + dy * direction_vec[1]
        #             if 0 < margin < args.margin:
        #                 print(margin, args.margin, direction_name)
        #                 print('BROKEN MARGIN!')
        #                 margins_good = False
        #                 break
        #         if not margins_good:
        #             break
        #
        #     if dists_good and margins_good:
        #         break
        #
        # # Choose random color and shape
        # if shape_color_combos is None:
        #     obj_name, obj_name_out = random.choice(object_mapping)
        #     color_name, rgba = random.choice(list(color_name_to_rgba.items()))
        # else:
        #     obj_name_out, color_choices = random.choice(shape_color_combos)
        #     color_name = random.choice(color_choices)
        #     obj_name = [k for k, v in object_mapping if v == obj_name_out][0]
        #     rgba = color_name_to_rgba[color_name]
        #
        # # For cube, adjust the size a bit
        # if obj_name == 'Cube':
        #     r /= math.sqrt(2)
        objct = parameters[i]
        size_name = objct["size_name"]
        x, y, r = objct["position"]
        obj_name = objct["obj_name"]
        obj_name_out = objct["obj_name_out"]
        color_name = objct["color_name"]
        rgba = objct["rgba"]
        mat_name = objct["mat_name"]
        mat_name_out = objct["mat_name_out"]
        theta = objct["theta"]

        # obj = {"size_name": size_name, "position": [x, y, y], "obj_name": obj_name, "obj_name_out": obj_name_out,
        #        "color_name": color_name, "rgba": rgba, "mat_name": mat_name, "mat_name_out": mat_name_out}
        # Choose random orientation for the object.
        #theta = 360.0 * random.random()

        # Actually add the object to the scene
        utils.add_object(args.shape_dir, obj_name, r, (x, y), theta=theta)
        obj = bpy.context.object
        blender_objects.append(obj)
        positions.append((x, y, r))

        # Attach a random material
        # mat_name, mat_name_out = random.choice(material_mapping)
        utils.add_material(mat_name, Color=rgba)

        # Record data about the object in the scene data structure
        pixel_coords = utils.get_camera_coords(camera, obj.location)
        objects.append({
            'shape': obj_name_out,
            'size': size_name,
            'material': mat_name_out,
            '3d_coords': tuple(obj.location),
            'rotation': theta,
            'pixel_coords': pixel_coords,
            'color': color_name,
        })

    # Check that all objects are at least partially visible in the rendered image
    all_visible = check_visibility(blender_objects, args.min_pixels_per_object)
    if not all_visible:
        # If any of the objects are fully occluded then start over; delete all
        # objects from the scene and place them all again.
        # print('Some objects are occluded; replacing objects')
        # for obj in blender_objects:
        #     utils.delete_object(obj)
        # return add_random_objects(scene_struct, num_objects, args, camera)
        print("not all visible")
        return [], [], False

    return objects, blender_objects, True
Ejemplo n.º 23
0
def add_random_objects(scene_struct, num_objects, args, inp, img_config,
                       camera):
    """
  Add random objects to the current blender scene
  """

    # Load the property file
    with open(args.properties_json, 'r') as f:
        properties = json.load(f)
        color_name_to_rgba = {}
        for name, rgb in properties['colors'].items():
            rgba = [float(c) / 255.0 for c in rgb] + [1.0]
            color_name_to_rgba[name] = rgba
        material_mapping = [(v, k) for k, v in properties['materials'].items()]
        object_mapping = [(v, k) for k, v in properties['shapes'].items()]
        size_mapping = list(properties['sizes'].items())

    shape_color_combos = None
    if args.shape_color_combos_json is not None:
        with open(args.shape_color_combos_json, 'r') as f:
            shape_color_combos = list(json.load(f).items())

    positions = []
    objects = []
    blender_objects = []
    for i in range(num_objects):
        # Choose a random size
        user_obj = img_config.objects[i]
        size_name = user_obj['size']
        assert size_name in properties[
            'sizes'], "Size not defined in properties.json"
        r = properties['sizes'][size_name]
        # size_name, r = random.choice(size_mapping)

        # Try to place the object, ensuring that we don't intersect any existing
        # objects and that we are more than the desired margin away from all existing
        # objects along all cardinal directions.
        num_tries = 0
        while True:
            # If we try and fail to place an object too many times, then delete all
            # the objects in the scene and start over.
            num_tries += 1
            if num_tries > args.max_retries:
                for obj in blender_objects:
                    utils.delete_object(obj)
                print("Failed to place objects")
                print(dists_good, margins_good)
                sys.exit(
                    "Failed to place objects. Check `user_config.py` for image {image_index}, object {i}"
                    .format(image_index=image_index, i=i))

            dy = lambda: random.uniform(-0.45, 0.45)
            clamp = lambda x: min(2.95, max(-2.95, x))

            x = clamp(user_obj['x'])
            y = clamp(user_obj['y'])
            z = user_obj['z']

            # Check to make sure the new object is further than min_dist from all
            # other objects, and further than margin along the four cardinal directions
            dists_good = True
            margins_good = True
            for (xx, yy, rr) in positions:
                dx, dy = x - xx, y - yy
                dist = math.sqrt(dx * dx + dy * dy)
                if dist - r - rr < args.min_dist:
                    dists_good = False
                    break
                for direction_name in ['left', 'right', 'front', 'behind']:
                    direction_vec = scene_struct['directions'][direction_name]
                    assert direction_vec[2] == 0
                    margin = dx * direction_vec[0] + dy * direction_vec[1]
                    if 0 < margin < args.margin:
                        print(margin, args.margin, direction_name)
                        print('BROKEN MARGIN!')
                        margins_good = False
                        break
                if not margins_good:
                    break

            if dists_good and margins_good:
                break

        # Choose random color and shape
        if shape_color_combos is None:
            # obj_name, obj_name_out = random.choice(object_mapping)
            # color_name, rgba = random.choice(list(color_name_to_rgba.items()))
            obj_name_out = user_obj['shape']
            color_name = user_obj['color']
            assert obj_name_out in properties[
                'shapes'], "Shape not defined in properties.json"
            assert color_name in color_name_to_rgba, "Color not defined in properties.json"
            obj_name = properties['shapes'][obj_name_out]
            rgba = color_name_to_rgba[color_name]

        else:
            obj_name_out, color_choices = random.choice(shape_color_combos)
            color_name = random.choice(color_choices)
            obj_name = [k for k, v in object_mapping if v == obj_name_out][0]
            rgba = color_name_to_rgba[color_name]

        # For cube, adjust the size a bit
        if obj_name == 'Cube':
            r /= math.sqrt(2)

        # Choose random orientation for the object.
        theta = user_obj[
            'orientation'] if 'orientation' in user_obj else 360.0 * random.random(
            )

        # Actually add the object to the scene
        utils.add_object(args.shape_dir, obj_name, r, (x, y, z), theta=theta)
        obj = bpy.context.object
        blender_objects.append(obj)
        positions.append((x, y, r))

        # Attach a random material
        # mat_name, mat_name_out = random.choice(material_mapping)
        mat_name_out = user_obj['material']
        assert mat_name_out in properties[
            'materials'], "Material not defined in properties.json"
        mat_name = properties['materials'][mat_name_out]
        utils.add_material(mat_name, Color=rgba)

        # Record data about the object in the scene data structure
        pixel_coords = utils.get_camera_coords(camera, obj.location)
        objects.append({
            'shape': obj_name_out,
            'size': size_name,
            'material': mat_name_out,
            '3d_coords': tuple(obj.location),
            'rotation': theta,
            'pixel_coords': pixel_coords,
            'color': color_name,
        })

    # Check that all objects are at least partially visible in the rendered image
    all_visible = check_visibility(blender_objects, args.min_pixels_per_object)
    if not all_visible:
        # If any of the objects are fully occluded then start over; delete all
        # objects from the scene and place them all again.
        print('Some objects are occluded; replacing objects')
        for obj in blender_objects:
            utils.delete_object(obj)
        return add_random_objects(scene_struct, num_objects, args, inp,
                                  img_config, camera)

    return objects, blender_objects
Ejemplo n.º 24
0
def add_random_objects(scene_struct, num_objects, args, camera):
    """
    Add random objects to the current blender scene
    """

    # Load the property file
    with open(args.properties_json, 'r') as f:
        properties = json.load(f)
        color_name_to_rgba = {}
        for name, rgb in properties['colors'].items():
            rgba = [float(c) / 255.0 for c in rgb] + [1.0]
            color_name_to_rgba[name] = rgba
        material_mapping = [(v, k) for k, v in properties['materials'].items()]
        object_mapping = [(v, k) for k, v in properties['shapes'].items()]
        size_mapping = list(properties['sizes'].items())

    shape_color_combos = None
    if args.shape_color_combos_json is not None:
        with open(args.shape_color_combos_json, 'r') as f:
            shape_color_combos = list(json.load(f).items())

    positions = []
    objects = []
    blender_objects = []
    for i in range(num_objects):
        if i == 0:
            # first element is the small shiny gold "snitch"!
            size_name, r = "small", 0.3  # slightly larger than small
            obj_name, obj_name_out = 'Spl', 'spl'
            color_name = "gold"
            rgba = [1.0, 0.843, 0.0, 1.0]
            mat_name, mat_name_out = "MyMetal", "metal"
        elif i == 1:
            # second element is a medium cone
            size_name, r = "medium", 0.5
            obj_name, obj_name_out = 'Cone', 'cone'
            color_name, rgba = random.choice(list(color_name_to_rgba.items()))
            mat_name, mat_name_out = random.choice(material_mapping)
        elif i == 2:
            # third element is a large cone
            size_name, r = "large", 0.75
            obj_name, obj_name_out = 'Cone', 'cone'
            color_name, rgba = random.choice(list(color_name_to_rgba.items()))
            mat_name, mat_name_out = random.choice(material_mapping)
        else:
            # Choose a random size
            size_name, r = random.choice(size_mapping)
            # Choose random color and shape
            if shape_color_combos is None:
                obj_name, obj_name_out = random.choice(object_mapping)
                color_name, rgba = random.choice(
                    list(color_name_to_rgba.items()))
            else:
                obj_name_out, color_choices = random.choice(shape_color_combos)
                color_name = random.choice(color_choices)
                obj_name = [k for k, v in object_mapping
                            if v == obj_name_out][0]
                rgba = color_name_to_rgba[color_name]
            # Choose a random material
            mat_name, mat_name_out = random.choice(material_mapping)

        # Try to place the object, ensuring that we don't intersect any
        # existing objects and that we are more than the desired margin away
        # from all existing objects along all cardinal directions.
        num_tries = 0
        while True:
            # If we try and fail to place an object too many times, then
            # delete all the objects in the scene and start over.
            num_tries += 1
            if num_tries > args.max_retries:
                for obj in blender_objects:
                    utils.delete_object(obj)
                return add_random_objects(scene_struct, num_objects, args,
                                          camera)
            x = random.uniform(-3, 3)
            y = random.uniform(-3, 3)
            # Check to make sure the new object is further than min_dist from
            # all other objects, and further than margin along the four
            # cardinal directions
            dists_good = True
            margins_good = True
            for (xx, yy, rr) in positions:
                dx, dy = x - xx, y - yy
                dist = math.sqrt(dx * dx + dy * dy)
                if dist - r - rr < args.min_dist:
                    dists_good = False
                    break
                for direction_name in ['left', 'right', 'front', 'behind']:
                    direction_vec = scene_struct['directions'][direction_name]
                    assert direction_vec[2] == 0
                    margin = dx * direction_vec[0] + dy * direction_vec[1]
                    if 0 < margin < args.margin:
                        logging.debug('{} {} {}'.format(
                            margin, args.margin, direction_name))
                        logging.debug('BROKEN MARGIN!')
                        margins_good = False
                        break
                if not margins_good:
                    break
            if dists_good and margins_good:
                break

        # For cube, adjust the size a bit
        if obj_name == 'Cube':
            r /= math.sqrt(2)

        # Choose random orientation for the object.
        # theta = 360.0 * random.random()
        theta = 2 * np.pi * random.random()

        # Actually add the object to the scene
        utils.add_object(args.shape_dir, obj_name, r, (x, y), theta=theta)
        obj = bpy.context.object
        blender_objects.append(obj)
        positions.append((x, y, r))

        # Actually add material
        utils.add_material(mat_name, Color=rgba)

        # get bbox corners in world coord
        bbox_corners_world = np.array([
            obj.matrix_world * Vector(corner) for corner in obj.bound_box
        ])  # 8 x 3 array

        T = np.average(bbox_corners_world,
                       axis=0)  # len-3, xyz coord in world system

        # try to create lrt
        l = [obj.dimensions.x, obj.dimensions.y, obj.dimensions.z]

        # R = eul2rot((0, 0, theta), degrees=True)
        # lx, ly, lz = l
        # xs = np.array([-lx/2., -lx/2., -lx/2., -lx/2., lx/2., lx/2., lx/2., lx/2.])[None, :] # 1 x 8
        # ys = np.array([-ly/2., -ly/2., ly/2., ly/2., -ly/2., -ly/2., ly/2., ly/2.])[None, :]
        # zs = np.array([-lz/2., lz/2., -lz/2., lz/2., -lz/2., lz/2., -lz/2., lz/2.])[None, :]
        # xyzs_obj = np.concatenate([xs, ys, zs], axis=0) # 3 x 8
        # xyzs_world = np.dot(R, xyzs) + T[:, None]

        # Record data about the object in the scene data structure
        pixel_coords = utils.get_camera_coords(camera, obj.location)
        objects.append({
            'shape': obj_name_out,
            'size': size_name,
            'sized': r,
            'material': mat_name_out,
            '3d_coords': tuple(obj.location),
            '3d_bbox': bbox_corners_world.tolist(),
            '3d_size': l,
            '3d_bbox_center': T.tolist(),
            'rotation': theta,
            'pixel_coords': pixel_coords,
            'color': color_name,
            'instance': obj.name,
        })
    return objects, blender_objects
Ejemplo n.º 25
0
def add_random_objects(scene_struct, num_objects, args, camera):
    """
  Add random objects to the current blender scene
  """

    # Load the property file
    with open(args.properties_json, 'r') as f:
        properties = json.load(f)
        color_name_to_rgba = {}
        for name, rgb in properties['colors'].items():
            rgba = [float(c) / 255.0 for c in rgb] + [1.0]
            color_name_to_rgba[name] = rgba
        material_mapping = [(v, k) for k, v in properties['materials'].items()]
        object_mapping = [(v, k) for k, v in properties['shapes'].items()]
        size_mapping = list(properties['sizes'].items())

    shape_color_combos = None
    if args.shape_color_combos_json is not None:
        with open(args.shape_color_combos_json, 'r') as f:
            shape_color_combos = list(json.load(f).items())

    positions = []
    objects = []
    blender_objects = []
    for i in range(num_objects):
        # Choose a random size
        size_name, r = random.choice(size_mapping)

        # Try to place the object, ensuring that we don't intersect any existing
        # objects and that we are more than the desired margin away from all existing
        # objects along all cardinal directions.
        num_tries = 0
        while True:
            # If we try and fail to place an object too many times, then delete all
            # the objects in the scene and start over.
            num_tries += 1
            if num_tries > args.max_retries:
                for obj in blender_objects:
                    utils.delete_object(obj)
                return add_random_objects(scene_struct, num_objects, args,
                                          camera)

            x = random.uniform(-3, 3)
            y = random.uniform(-3, 3)

            # Info Comment: For first loop, (x,y) as position and r as radius initialized above are placed in positions list. The for loop
            # below exists to ensure min dist between objects.

            # Maybe add code to limit spacing if nb of objects is low? (so if fewer objs and/or smaller size(?), closer together)

            # For first object, have anchor position.
            if not positions:
                x = 0.0
                y = 0.0

            # Check to make sure the new object is further than min_dist and closer than max distance (2(r+rr)) from all
            # other objects, and further than margin along the four cardinal directions
            dists_good = True
            margins_good = True
            # print('positions: ',positions)
            for (xx, yy, rr) in positions:
                # print("r, rr: ", r, " , ", rr)
                dx, dy = x - xx, y - yy
                dist = math.sqrt(dx * dx + dy * dy)
                max_dist = 2 * (r + rr)
                # print("x_dist, min_dist, max_dist: ", dist - r -rr, " , ", args.min_dist, " , ", max_dist)
                if (dist - r - rr < args.min_dist) or (dist - r - rr >
                                                       (2 * (r + rr))):
                    dists_good = False
                    break
                for direction_name in ['left', 'right', 'front', 'behind']:
                    direction_vec = scene_struct['directions'][direction_name]
                    assert direction_vec[2] == 0
                    margin = dx * direction_vec[0] + dy * direction_vec[1]
                    if 0 < margin < args.margin:
                        print(margin, args.margin, direction_name)
                        print('BROKEN MARGIN!')
                        margins_good = False
                        break
                if not margins_good:
                    break

            if dists_good and margins_good:
                break

        # Choose random color and shape
        if shape_color_combos is None:
            obj_name, obj_name_out = random.choice(
                object_mapping)  # obj_name_out is the key and obj_name is val
            color_name, rgba = random.choice(list(color_name_to_rgba.items()))
        else:
            obj_name_out, color_choices = random.choice(shape_color_combos)
            color_name = random.choice(color_choices)
            obj_name = [k for k, v in object_mapping if v == obj_name_out][0]
            rgba = color_name_to_rgba[color_name]

        # For cube, adjust the size a bit
        if obj_name == 'Cube':
            r /= math.sqrt(2)

        # Choose random orientation for the object.
        theta = 360.0 * random.random()

        # Actually add the object to the scene
        utils.add_object(args.shape_dir, obj_name, r, (x, y), theta=theta)
        obj = bpy.context.object
        blender_objects.append(obj)
        positions.append((x, y, r))

        # Attach a random material
        mat_name, mat_name_out = random.choice(material_mapping)
        utils.add_material(mat_name, Color=rgba)

        # Record data about the object in the scene data structure
        pixel_coords = utils.get_camera_coords(camera, obj.location)
        objects.append({
            'shape': obj_name_out,
            'size': size_name,
            'material': mat_name_out,
            '3d_coords': tuple(obj.location),
            'rotation': theta,
            'pixel_coords': pixel_coords,
            'color': color_name,
        })

    # Check that all objects are at least partially visible in the rendered image
    all_visible = check_visibility(blender_objects, args.min_pixels_per_object)
    if not all_visible:
        # If any of the objects are fully occluded then start over; delete all
        # objects from the scene and place them all again.
        print('Some objects are occluded; replacing objects')
        for obj in blender_objects:
            utils.delete_object(obj)
        return add_random_objects(scene_struct, num_objects, args, camera)

    return objects, blender_objects
Ejemplo n.º 26
0
def relative_transform_objects(scene_struct, blender_objects, camera, args):

    num_objs = len(blender_objects)
    n_rand = int(random.uniform(0, 1) * num_objs)

    #objects = scene_struct['objects']
    positions = [obj.location for obj in blender_objects]

    #num_objs = len(objects)
    #curr_obj = 0#int(random.uniform(0, num_objs))
    obj = blender_objects[n_rand]
    #sc_obj = scene_struct['objects'].pop(n_rand)
    objects = scene_struct['objects']
    loc = obj.location
    r = loc[2]

    #loc_target = 2 * blender_objects[1].location
    #diff = loc_target - loc
    #print("diff: ", diff)
    #x_t = min(max(diff[0],-3),3)
    #y_t = min(max(diff[1],-3),3)

    num_tries = 0
    while True:
        num_tries += 1
        dists_good = True
        margins_good = True
        x = random.uniform(-3, 3)
        y = random.uniform(-3, 3)
        dx_s, dy_s = x - loc[0], y - loc[1]
        dist = math.sqrt(dx_s * dx_s + dy_s * dy_s)
        if dist < 4:
            dists_good = False
            continue

        for (xx, yy, rr) in positions:
            dx, dy = x - xx, y - yy
            dist = math.sqrt(dx * dx + dy * dy)
            if dist - r - rr < args.min_dist:
                #print(dist - r - rr)
                dists_good = False
                break
            for direction_name in ['left', 'right', 'front', 'behind']:
                direction_vec = scene_struct['directions'][direction_name]
                assert direction_vec[2] == 0
                margin = dx * direction_vec[0] + dy * direction_vec[1]
                if 0 < margin < args.margin:
                    margins_good = False
                    break

        if num_tries > 10 and not (dists_good and margins_good):
            n_rand = int(random.uniform(0, 1) * num_objs)
            obj = blender_objects[n_rand]
            loc = obj.location
            r = loc[2]
            num_tries = 0
        if dists_good and margins_good:
            break

    obj.location = Vector((x, y, r))
    blender_objects[n_rand] = obj
    # Render the scene
    bpy.ops.render.render(write_still=False)

    pixel_coords = utils.get_camera_coords(camera, obj.location)
    bbox = camera_view_bounds_2d(bpy.context.scene, camera, obj)
    #print(sc_obj)
    objects[n_rand]['3d_coords'] = tuple(obj.location)
    objects[n_rand]['pixel_coords'] = pixel_coords
    objects[n_rand]['bbox'] = bbox.to_tuple()
    #print(sc_obj)
    #input()
    #sc_obj['3d_coords'] = tuple(obj.location)
    #sc_obj['pixel_coords'] = pixel_coords
    #sc_obj['bbox'] = bbox.to_tuple()
    #objects.append(sc_obj)
    scene_struct['objects'] = objects
    return blender_objects, scene_struct
Ejemplo n.º 27
0
def add_cups(scene_struct, num_objects, args, camera):
    """
    Add random objects to the current blender scene
    """
    # Load the property file
    with open(args.properties_json, 'r') as f:
        properties = json.load(f)
        color_name_to_rgba = {}
        for name, rgb in properties['colors'].items():
            rgba = [float(c) / 255.0 for c in rgb] + [1.0]
            color_name_to_rgba[name] = rgba
        material_mapping = [(v, k) for k, v in properties['materials'].items()]
        object_mapping = [(v, k) for k, v in properties['shapes'].items()]
        size_mapping = list(properties['sizes'].items())

    # shape_color_combos = None
    # if args.shape_color_combos_json is not None:
    #     with open(args.shape_color_combos_json, 'r') as f:
    #         shape_color_combos = list(json.load(f).items())

    positions = []
    objects = []
    blender_objects = []

    # Choose a random size, same for all cups
    size_name, r = size_mapping[0]
    first_cup_x = 0
    first_cup_y = 0

    # obj_name, obj_name_out = random.choice(object_mapping)
    obj_name, obj_name_out = [
        el for el in object_mapping if el[1] == 'cylinder'
    ][0]
    color_name, rgba = random.choice(list(color_name_to_rgba.items()))

    # If using combos
    # obj_name_out, color_choices = random.choice(shape_color_combos)
    # color_name = random.choice(color_choices)
    # obj_name = [k for k, v in object_mapping if v == obj_name_out][0]
    # rgba = color_name_to_rgba[color_name]

    # Attach a random material
    mat_name, mat_name_out = random.choice(material_mapping)

    # For cube, adjust the size a bit
    if obj_name == 'Cube':
        r /= math.sqrt(2)

    # Choose random orientation for the object.
    # theta = 360.0 * random.random()
    theta = 0.0

    for i in range(num_objects):
        x = first_cup_x + i * 1.5
        y = first_cup_y

        # Actually add the object to the scene
        utils.add_object(args.shape_dir, obj_name, r, (x, y), theta=theta)
        obj = bpy.context.object
        blender_objects.append(obj)
        positions.append((x, y, r))
        utils.add_material(mat_name, Color=rgba)

        # Record data about the object in the scene data structure
        pixel_coords = utils.get_camera_coords(camera, obj.location)
        objects.append({
            'shape': obj_name_out,
            'size': size_name,
            'material': mat_name_out,
            '3d_coords': tuple(obj.location),
            'rotation': theta,
            'pixel_coords': pixel_coords,
            'color': color_name,
        })
    return objects, blender_objects
Ejemplo n.º 28
0
def render_scene(args,
                 num_objects=5,
                 num_images=0,
                 output_split='none',
                 image_template='render.png',
                 scene_template='render_json',
                 arr_template='arr',
                 output_blendfile=None,
                 directions={
                     1: 'no',
                     2: 'no',
                     3: 'no',
                     4: 'no',
                     5: 'no'
                 }):

    for object_name in bpy.data.objects.keys():
        if 'Sphere' in object_name or\
           'Cylinder' in object_name or\
           'Cube' in object_name or\
           'Duck' in object_name or\
           'Peg' in object_name or\
           'Disk' in object_name or\
           'Bowl' in object_name:
            utils.delete_object_by_name(object_name)

    # Load materials
    utils.load_materials(args.material_dir)

    # Set render arguments so we can get pixel coordinates later.
    # We use functionality specific to the CYCLES renderer so BLENDER_RENDER
    # cannot be used.
    render_args = bpy.context.scene.render
    render_args.engine = "CYCLES"
    render_args.resolution_x = args.width
    render_args.resolution_y = args.height
    render_args.resolution_percentage = 100
    render_args.tile_x = args.render_tile_size
    render_args.tile_y = args.render_tile_size
    if args.use_gpu == 1:
        # Blender changed the API for enabling CUDA at some point
        if bpy.app.version < (2, 78, 0):
            bpy.context.user_preferences.system.compute_device_type = 'CUDA'
            bpy.context.user_preferences.system.compute_device = 'CUDA_0'
        else:
            cycles_prefs = bpy.context.user_preferences.addons[
                'cycles'].preferences
            cycles_prefs.compute_device_type = 'CUDA'

    # Some CYCLES-specific stuff
    bpy.data.worlds['World'].cycles.sample_as_light = True
    bpy.context.scene.cycles.blur_glossy = 2.0
    bpy.context.scene.cycles.samples = args.render_num_samples
    bpy.context.scene.cycles.transparent_min_bounces = args.render_min_bounces
    bpy.context.scene.cycles.transparent_max_bounces = args.render_max_bounces
    if args.use_gpu == 1:
        bpy.context.scene.cycles.device = 'GPU'

    # This will give ground-truth information about the scene and its objects
    scene_struct = {
        'split': output_split,
        'objects': [],
        'directions': {},
    }

    # Put a plane on the ground so we can compute cardinal directions
    bpy.ops.mesh.primitive_plane_add(radius=5)
    plane = bpy.context.object

    def rand(L):
        return 2.0 * L * (random.random() - 0.5)

    # Add random jitter to camera position
    if args.camera_jitter > 0:
        for i in range(3):
            bpy.data.objects['Camera'].location[i] += rand(args.camera_jitter)

    # Figure out the left, up, and behind directions along the plane and record
    # them in the scene structure
    camera = bpy.data.objects['Camera']
    plane_normal = plane.data.vertices[0].normal
    cam_behind = camera.matrix_world.to_quaternion() * Vector((0, 0, -1))
    cam_left = camera.matrix_world.to_quaternion() * Vector((-1, 0, 0))
    cam_up = camera.matrix_world.to_quaternion() * Vector((0, 1, 0))
    plane_behind = (cam_behind - cam_behind.project(plane_normal)).normalized()
    plane_left = (cam_left - cam_left.project(plane_normal)).normalized()
    plane_up = cam_up.project(plane_normal).normalized()

    # Delete the plane; we only used it for normals anyway. The base scene file
    # contains the actual ground plane.
    utils.delete_object(plane)

    # Save all six axis-aligned directions in the scene struct
    scene_struct['directions']['behind'] = tuple(plane_behind)
    scene_struct['directions']['front'] = tuple(-plane_behind)
    scene_struct['directions']['left'] = tuple(plane_left)
    scene_struct['directions']['right'] = tuple(-plane_left)
    scene_struct['directions']['above'] = tuple(plane_up)
    scene_struct['directions']['below'] = tuple(-plane_up)

    # Add random jitter to lamp positions
    if args.key_light_jitter > 0:
        for i in range(3):
            bpy.data.objects['Lamp_Key'].location[i] += rand(
                args.key_light_jitter)
    if args.back_light_jitter > 0:
        for i in range(3):
            bpy.data.objects['Lamp_Back'].location[i] += rand(
                args.back_light_jitter)
    if args.fill_light_jitter > 0:
        for i in range(3):
            bpy.data.objects['Lamp_Fill'].location[i] += rand(
                args.fill_light_jitter)

    objects = []
    blender_objects = []
    direction_vec = []

    for scene_idx in range(num_images):

        image_path = image_template % (scene_idx + args.start_idx)
        render_args.filepath = image_path

        scene_path = scene_template % (scene_idx + args.start_idx)
        arr_path = arr_template % (scene_idx + args.start_idx)

        if scene_idx == 0:

            init_position = []
            final_position = []
            ref_obj_loc = np.array([0, 0, 1])

            for axis, movement in directions.items():
                # X
                if axis == 1:
                    if movement != ['no']:
                        if movement[0] == 'front':
                            init_position.append(-3)
                            final_position.append(2)
                        else:
                            init_position.append(2)
                            final_position.append(-3)
                    else:
                        tmp = random.choice(
                            np.linspace(-2, 2, 10, endpoint=True))
                        init_position.append(tmp)
                        final_position.append(tmp)

                # Y
                if axis == 0:
                    if movement != ['no']:
                        if movement[0] == 'left':
                            init_position.append(-2)
                            final_position.append(2)
                        else:
                            init_position.append(2)
                            final_position.append(-2)
                    else:
                        tmp = random.choice(
                            np.linspace(-2, 2, 10, endpoint=True))
                        init_position.append(tmp)
                        final_position.append(tmp)

                # Z
                if axis == 2:
                    if movement != ['no']:
                        if movement[0] == 'below':
                            init_position.append(0)
                            final_position.append(2)
                        else:
                            init_position.append(2)
                            final_position.append(0)
                    else:
                        tmp = random.choice(
                            np.linspace(0, 2, 10, endpoint=True))
                        init_position.append(tmp)
                        final_position.append(tmp)

                # CLOSE/FAR
                close_far_thresh = 3
                if axis == 3:
                    if movement != ['no']:
                        far_sample = []
                        close_sample = []
                        while far_sample == [] or \
                            np.linalg.norm(far_sample - ref_obj_loc) < close_far_thresh:

                            x = random.choice(
                                np.linspace(-2, 2, 10, endpoint=True))
                            y = random.choice(
                                np.linspace(-2, 2, 10, endpoint=True))
                            z = random.choice(
                                np.linspace(0.6, 2, 10, endpoint=True))
                            far_sample = np.array([x, y, z])

                        while close_sample == [] or \
                            np.linalg.norm(close_sample - ref_obj_loc) > close_far_thresh or \
                            np.linalg.norm(close_sample - ref_obj_loc) < 1:

                            x = random.choice(
                                np.linspace(-2, 2, 10, endpoint=True))
                            y = random.choice(
                                np.linspace(-2, 2, 10, endpoint=True))
                            z = random.choice(
                                np.linspace(0.6, 2, 10, endpoint=True))
                            close_sample = np.array([x, y, z])

                        if movement[0] == 'far':
                            init_position = far_sample
                            final_position = []
                            while final_position == [] or \
                                np.linalg.norm(final_position - ref_obj_loc) > close_far_thresh or \
                                np.linalg.norm(final_position - ref_obj_loc) < 1:
                                final_position = init_position + random.uniform(
                                    0.5, 1) * (ref_obj_loc - init_position)
                                print(final_position)
                        else:
                            init_position = close_sample
                            final_position = []
                            while final_position == [] or \
                                np.linalg.norm(final_position - ref_obj_loc) < close_far_thresh:
                                final_position = init_position + random.uniform(
                                    0.5, 1) * (init_position - ref_obj_loc)

                    else:
                        pass

            # init_position[1] = -3
            # init_position[2] = 0
            # final_position[2] = 0
            print(init_position)
            print(final_position)
            init_positions = []
            init_positions.append(init_position)
            init_positions.append(ref_obj_loc)
            for i in range(2, num_objects):
                x = random.choice(np.linspace(-2, 2, 10, endpoint=True))
                y = random.choice(np.linspace(-2, 2, 10, endpoint=True))
                z = random.choice(np.linspace(0, 2, 6, endpoint=True))
                init_positions.append([x, y, z])

            direction_vec = np.array(final_position) - np.array(init_position)

            # Now make some random objects
            objects, blender_objects = add_random_objects(
                scene_struct, num_objects, args, camera, init_positions)

            if scene_idx == 0:
                movement = directions[4]
                if movement != ['no']:
                    far_sample = []
                    while far_sample == [] or \
                        np.linalg.norm(far_sample - ref_obj_loc) < close_far_thresh:

                        x = random.choice(np.linspace(-2, 2, 10,
                                                      endpoint=True))
                        y = random.choice(np.linspace(-2, 2, 10,
                                                      endpoint=True))
                        z = random.choice(
                            np.linspace(0.6, 2, 10, endpoint=True))
                        far_sample = np.array([x, y, z])

                    if movement[0] == 'off':
                        init_position = far_sample
                        final_position = np.array(blender_objects[1].location)
                        final_position[0] += random.uniform(
                            -objects[1]['r'], objects[1]['r'])
                        final_position[1] += random.uniform(
                            -objects[1]['r'], objects[1]['r'])
                        final_position[2] += objects[0]['r'] + objects[1]['r']

                        blender_objects[0].location[0] = init_position[0]
                        blender_objects[0].location[1] = init_position[1]
                        blender_objects[0].location[2] = init_position[2]
                    else:
                        final_position = far_sample
                        init_position = np.array(blender_objects[1].location)
                        init_position[0] += random.uniform(
                            -objects[1]['r'], objects[1]['r'])
                        init_position[1] += random.uniform(
                            -objects[1]['r'], objects[1]['r'])
                        init_position[2] += objects[0]['r'] + objects[1]['r']

                        blender_objects[0].location[0] = init_position[0]
                        blender_objects[0].location[1] = init_position[1]
                        blender_objects[0].location[2] = init_position[2]

                else:
                    pass

            direction_vec = np.array(final_position) - np.array(init_position)

        else:
            move_obj_idxs = [0]

            step = direction_vec / args.num_images

            for move_obj_idx in move_obj_idxs:
                move_object(blender_objects[move_obj_idx], step)
                pixel_coords = utils.get_camera_coords(
                    camera, blender_objects[move_obj_idx].location)
                objects[move_obj_idx]['pixel_coords'] = pixel_coords

                # <Vector (-1.6002, -1.5445, 1.9500)>
                objects[move_obj_idx]['3d_coords'] = list(
                    blender_objects[move_obj_idx].location)

                # <Euler (x=0.0000, y=0.0000, z=139.0579), order='XYZ'>
                objects[move_obj_idx]['rotation'] = blender_objects[
                    move_obj_idx].rotation_euler[2]

        ### get b_box
        box_dict = get_b_box.main(bpy.context, blender_objects)
        for _id in box_dict:
            objects[_id]['bbox'] = box_dict[_id]

        # Render the scene and dump the scene data structure
        scene_struct['objects'] = objects
        scene_struct['relationships'] = compute_all_relationships(scene_struct)

        ############ ADDED ############
        tree = bpy.context.scene.node_tree
        links = tree.links
        rl = tree.nodes['Render Layers']
        v = tree.nodes['Viewer']

        links.new(rl.outputs[0], v.inputs[0])
        while True:
            try:
                bpy.ops.render.render(write_still=True)
                break
            except Exception as e:
                print(e)
        links.remove(links[0])

        # get viewer pixels
        rgb_pixels = bpy.data.images['Viewer Node'].pixels
        rgb_pixels = np.array(rgb_pixels[:])
        rgb_pixels = np.power(rgb_pixels, 1 / 2.2)
        rgb_pixels[rgb_pixels > 1] = 1
        rgb_pixels = rgb_pixels.reshape(args.height, args.width, 4)[..., :3]

        links.new(rl.outputs[2], v.inputs[0])
        render_shadeless(blender_objects, lights_off=False)
        links.remove(links[0])

        # get viewer pixels
        depth_pixels = bpy.data.images['Viewer Node'].pixels
        depth_pixels = np.array(depth_pixels[:])
        depth_pixels = depth_pixels.reshape(args.height, args.width, 4)[..., 0,
                                                                        None]

        links.new(rl.outputs[0], v.inputs[0])
        render_shadeless(blender_objects)
        links.remove(links[0])

        # get viewer pixels
        mask_pixels = bpy.data.images['Viewer Node'].pixels
        mask_pixels = np.array(mask_pixels[:])
        mask_pixels = mask_pixels.reshape(args.height, args.width, 4)[..., :3]

        pixels = np.concatenate((rgb_pixels, depth_pixels, mask_pixels),
                                axis=2)
        pixels = np.flipud(pixels)

        utils.save_arr(pixels, arr_path)
        ############ ADDED ############

        with open(scene_path, 'w') as f:
            json.dump(scene_struct, f, indent=2)
Ejemplo n.º 29
0
def add_random_objects(scene_struct, num_objects, args, camera):
    """
  Add random objects to the current blender scene
  """

    # Load the property file
    with open(args.properties_json, 'r') as f:
        properties = json.load(f)
        color_name_to_rgba = {}
        for name, rgb in properties['colors'].items():
            rgba = [float(c) / 255.0 for c in rgb] + [1.0]
            color_name_to_rgba[name] = rgba
        material_mapping = [(v, k) for k, v in properties['materials'].items()]
        object_mapping = [(v, k) for k, v in properties['shapes'].items()]
        size_mapping = list(properties['sizes'].items())

    shape_color_combos = None
    if args.shape_color_combos_json is not None:
        with open(args.shape_color_combos_json, 'r') as f:
            shape_color_combos = list(json.load(f).items())

    positions = []
    objects = []
    blender_objects = []
    for i in range(num_objects):
        # Choose a random size
        size_name, r = random.choice(size_mapping)

        # Try to place the object, ensuring that we don't intersect any existing
        # objects and that we are more than the desired margin away from all existing
        # objects along all cardinal directions.
        num_tries = 0
        while True:
            # If we try and fail to place an object too many times, then delete all
            # the objects in the scene and start over.
            num_tries += 1
            if num_tries > args.max_retries:
                for obj in blender_objects:
                    utils.delete_object(obj)
                return add_random_objects(scene_struct, num_objects, args,
                                          camera)
            x = random.uniform(-3, 3)
            y = random.uniform(-3, 3)
            # Check to make sure the new object is further than min_dist from all
            # other objects, and further than margin along the four cardinal directions
            dists_good = True
            margins_good = True
            for (xx, yy, rr) in positions:
                dx, dy = x - xx, y - yy
                dist = math.sqrt(dx * dx + dy * dy)
                if dist - r - rr < args.min_dist:
                    dists_good = False
                    break
                for direction_name in ['left', 'right', 'front', 'behind']:
                    direction_vec = scene_struct['directions'][direction_name]
                    assert direction_vec[2] == 0
                    margin = dx * direction_vec[0] + dy * direction_vec[1]
                    if 0 < margin < args.margin:
                        print(margin, args.margin, direction_name)
                        print('BROKEN MARGIN!')
                        margins_good = False
                        break
                if not margins_good:
                    break

            if dists_good and margins_good:
                break

        # Choose random color and shape
        if shape_color_combos is None:
            obj_name, obj_name_out = random.choice(object_mapping)
            color_name, rgba = random.choice(list(color_name_to_rgba.items()))
        else:
            obj_name_out, color_choices = random.choice(shape_color_combos)
            color_name = random.choice(color_choices)
            obj_name = [k for k, v in object_mapping if v == obj_name_out][0]
            rgba = color_name_to_rgba[color_name]

        # For cube, adjust the size a bit
        if obj_name == 'Cube':
            r /= math.sqrt(2)

        # Choose random orientation for the object.
        theta = 360.0 * random.random()

        # Actually add the object to the scene
        utils.add_object(args.shape_dir, obj_name, r, (x, y), theta=theta)
        obj = bpy.context.object
        blender_objects.append(obj)
        positions.append((x, y, r))

        # Attach a random material
        mat_name, mat_name_out = random.choice(material_mapping)
        utils.add_material(mat_name, Color=rgba)

        # Record data about the object in the scene data structure
        pixel_coords = utils.get_camera_coords(camera, obj.location)
        objects.append({
            'name': obj.name,
            'shape': obj_name_out,
            'size': size_name,
            'material': mat_name_out,
            '3d_coords': tuple(obj.location),
            'rotation': theta,
            'pixel_coords': pixel_coords,
            'color': color_name,
        })


#   # Check that all objects are at least partially visible in the rendered image
#   all_visible = check_visibility(blender_objects, args.min_pixels_per_object, args.height, args.width,
#                                  args.crop_up, args.crop_down, args.crop_left, args.crop_right)
#   if not all_visible:
#     # If any of the objects are fully occluded then start over; delete all
#     # objects from the scene and place them all again.
#     print('Some objects are occluded; replacing objects')
#     for obj in blender_objects:
#       utils.delete_object(obj)
#     return add_random_objects(scene_struct, num_objects, args, camera)

    indices = [
        n[0] for n in sorted(enumerate(objects),
                             key=lambda x: x[1]['pixel_coords'][2],
                             reverse=True)
    ]
    objects = [objects[idx] for idx in indices]
    blender_objects = [blender_objects[idx] for idx in indices]
    return objects, blender_objects
Ejemplo n.º 30
0
def add_random_objects(scene_struct, num_objects, args, camera,
                       init_positions):
    """
  Add random objects to the current blender scene
  """
    # Load the property file
    with open(args.properties_json, 'r') as f:
        properties = json.load(f)
        color_name_to_rgba = {}
        for name, rgb in properties['colors'].items():
            rgba = [float(c) / 255.0 for c in rgb] + [1.0]
            color_name_to_rgba[name] = rgba
        material_mapping = [(v, k) for k, v in properties['materials'].items()]
        object_mapping = [(v, k) for k, v in properties['shapes'].items()]
        size_mapping = list(properties['sizes'].items())

    shape_color_combos = None
    if args.shape_color_combos_json is not None:
        with open(args.shape_color_combos_json, 'r') as f:
            shape_color_combos = list(json.load(f).items())

    positions = []
    objects = []
    blender_objects = []
    for i in range(num_objects):
        # Choose a random size
        size_name, r = random.choice(size_mapping)
        # size_name, r = size_mapping[0]

        # x = random.choice(np.linspace(-2, 2, 3, endpoint=True))
        # y = random.choice(np.linspace(-2, 2, 3, endpoint=True))
        # z = random.choice(np.linspace(0, 2, 3, endpoint=True))
        # z = 0

        x, y, z = init_positions[i]

        # Choose random color and shape
        if shape_color_combos is None:
            obj_name, obj_name_out = random.choice(object_mapping)
            color_name, rgba = random.choice(list(color_name_to_rgba.items()))
            # obj_name, obj_name_out = object_mapping[i]
            # color_name, rgba = list(color_name_to_rgba.items())[i]
        else:
            obj_name_out, color_choices = random.choice(shape_color_combos)
            color_name = random.choice(color_choices)
            obj_name = [k for k, v in object_mapping if v == obj_name_out][0]
            rgba = color_name_to_rgba[color_name]

        # For cube, adjust the size a bit
        if obj_name == 'Cube':
            r /= math.sqrt(2)

        # Choose random orientation for the object.
        # theta = 360.0 * random.random()
        theta = 0

        # Actually add the object to the scene
        utils.add_object(args.shape_dir, obj_name, r, (x, y, z), theta=theta)
        obj = bpy.context.object
        blender_objects.append(obj)

        positions.append((x, y, z, r))

        # Attach a random material
        mat_name, mat_name_out = random.choice(material_mapping)
        utils.add_material(mat_name, Color=rgba)

        # Record data about the object in the scene data structure
        pixel_coords = utils.get_camera_coords(camera, obj.location)
        objects.append({
            'shape': obj_name_out,
            'size': size_name,
            'material': mat_name_out,
            '3d_coords': tuple(obj.location),
            'r': r,
            'rotation': theta,
            'pixel_coords': pixel_coords,
            'color': color_name,
        })

    # Check that all objects are at least partially visible in the rendered image
    all_visible = check_visibility(blender_objects, args.min_pixels_per_object)
    if not all_visible:
        # If any of the objects are fully occluded then start over; delete all
        # objects from the scene and place them all again.
        print('Some objects are occluded; replacing objects')
        for obj in blender_objects:
            utils.delete_object(obj)
        return add_random_objects(
            scene_struct, num_objects, args, camera,
            init_positions + np.random.uniform(low=-0.1, high=0.1, size=3))

    return objects, blender_objects