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({
            '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 all_visible is False:
        # 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, all_visible, positions
示例#2
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
  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 sizes == []:
      # Choose a random size
      size_name, r = random.choice(size_mapping)
    else:
      size_name, r = sizes[i]

    if i == 0:
      size_name, r = ('large', 0.6)

    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])
      
    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, 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.02, high=0.02, size=3), sizes=sizes, inout=inout)

  return objects, blender_objects
def add_random_objects_closure(scene_struct, args, camera):
  # 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 = []

  # We first randomly determine how many groups we want to have
  num_groups = random.randint(2, 3)
  generated_pos = pg.pos_by_closure(num_groups)
  # pg.position_visualizer(generated_pos)
  for group_index in range(num_groups):
    group = generated_pos[group_index]
    for position in group:
      x = position[0]
      y = position[1]

      # Choose a random size
      size_name, r = random.choice(size_mapping)
      # choose random color and object
      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)

      theta = 360.0 * random.random()

      # Actually add the object to the scene
      print(args.shape_dir)
      print(obj_name)
      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))

      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,
        'group': group
      })

      # -------------end pos one obj

  #all_visible = check_visibility(blender_objects, 1)
  all_visible= True
  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_closure(scene_struct, args, camera)

  return objects, blender_objects
def add_random_objects_groups(scene_struct, num_groups, args, camera,num_objects):
  # If we have just one group, it's the "normal" case so just call the normal function
  if num_groups == 1:
    return add_random_objects(scene_struct,num_objects,args,camera)



  #We read the properties and do smth=======================================
  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 = []
  group_center_positions=get_center_positions_spatial_grouping(num_groups)



  for i in range(num_groups):
    #Choose a random size of the group. A group contains between 1-5 elements
    num_elements=random.randint(1,5)

    for element in range(num_elements):

      r=0
      while r<0.3:
      # 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
        print("Try to place object.")
        if num_tries > args.max_retries:
          print("Too many tries. Delete All and Start over.")
          for obj in blender_objects:
            utils.delete_object(obj)
          return add_random_objects_groups(scene_struct, num_groups, args, camera,num_objects)

        x=group_center_positions[i][0]+random.uniform(args.within_group_distance_min+r,args.within_group_distance_max+r)
        y=group_center_positions[i][1]+random.uniform(args.within_group_distance_min+r,args.within_group_distance_max+r)
        # 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.within_group_distance_min:
            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]
            print(margin)
            print("Args margin: "+str(args.margin))
            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
      print(args.shape_dir)
      print(obj_name)
      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,
        'group':i,
      })
    print("Check visibility")
    # Check that all objects are at least partially visible in the rendered image
    all_visible = check_visibility(blender_objects, 1)
    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_groups(scene_struct, num_groups, args, camera,num_objects)

  return objects, blender_objects
def add_random_objects_group_by_similarity(scene_struct, args, camera):
  #TODO Implemetn
  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())

  not_fixed = random.randint(0,3)
  #0=color
  #1=size
  #2=material
  #3=shape

  fixed_size_name, fixed_size = random.choice(size_mapping)
  fixed_color_name, fixed_rgba = random.choice(list(color_name_to_rgba.items()))

  fixed_mat_name, fixed_mat_name_out = random.choice(material_mapping)

  fixed_obj_name, fixed_obj_name_out = random.choice(object_mapping)

  num_objects=random.randint(4,10)
  postitions=get_positions(num_objects,-7,7,-7,7)

  groups = {}

  objects = []
  blender_objects = []


  for num_object_actual in range(num_objects):
    position=postitions[num_object_actual]
    print("Iteration: ",num_object_actual)
    print("Position: ",position)
    if not_fixed == 0:
      fixed_color_name, fixed_rgba = random.choice(list(color_name_to_rgba.items()))
      if len(groups) > 0:
        if fixed_color_name not in groups.keys():
          index = max(groups.values())
          groups[fixed_color_name]=index+1
          group=index+1
        else:
          group=groups[fixed_color_name]
      else:
        groups[fixed_color_name] = 0
        group=0

    if not_fixed == 1:
      fixed_size_name, fixed_size = random.choice(size_mapping)
      if len(groups) > 0:
        if fixed_size_name not in groups.keys():
          index = max(groups.values())
          groups[fixed_size_name] = index + 1
          group = index + 1
        else:
          group = groups[fixed_size_name]
      else:
        groups[fixed_size_name] = 0
        group = 0

    if not_fixed == 2:
      fixed_mat_name, fixed_mat_name_out = random.choice(material_mapping)
      if len(groups) > 0:
        if fixed_mat_name not in groups.keys():
          index = max(groups.values())
          groups[fixed_mat_name] = index + 1
          group = index + 1
        else:
          group = groups[fixed_mat_name]
      else:
        groups[fixed_mat_name] = 0
        group = 0

    if not_fixed == 3:
      fixed_obj_name, fixed_obj_name_out = random.choice(object_mapping)
      if len(groups) > 0:
        if fixed_obj_name not in groups.keys():
          index = max(groups.values())
          groups[fixed_obj_name] = index + 1
          group = index + 1
        else:
          group = groups[fixed_obj_name]
      else:
        groups[fixed_obj_name] = 0
        group = 0

    print("---------Group ", group)

    if fixed_obj_name == 'Cube':
      fixed_size /= math.sqrt(2)

    theta = 360.0 * random.random()

    # Actually add the object to the scene
    utils.add_object(args.shape_dir, fixed_obj_name, fixed_size, position, theta=theta)
    object = bpy.context.object
    blender_objects.append(object)
    utils.add_material(fixed_mat_name, Color=fixed_rgba)
    # Record data about the object in the scene data structure
    pixel_coords = utils.get_camera_coords(camera, object.location)
    objects.append({
      'shape': fixed_obj_name_out,
      'size': fixed_size_name,
      'material': fixed_mat_name_out,
      '3d_coords': tuple(object.location),
      'rotation': theta,
      'pixel_coords': pixel_coords,
      'color': fixed_color_name,
      'group': group
    })

    # 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 thing in blender_objects:
      utils.delete_object(thing)
    return add_random_objects_group_by_similarity(scene_struct, args, camera)

  return objects, blender_objects
def add_random_objects(scene_struct, num_objects, args, camera, pos_density):
    """
  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, pos_density)

            # Zi = density_to_prob(pos_density, MASK_COORDS)
            # x, y = sample_2d_pos(Zi,)

            x_low, x_high = (-11, 5)
            y_low, y_high = (-9, 9)
            # y_low, y_high = (3, 3)

            yrange_left = (y_low, -3.2)
            yrange_right = (y_high, 3.2)

            # fup = solve_equation((x_low, yrange_right[0]), (x_high, yrange_right[1]))
            # fdown = solve_equation((x_low, yrange_left[0]), (x_high, yrange_left[1]))
            # while True:
            #   x = random.uniform(x_low, x_high)
            #   y = random.uniform(y_low, y_high)
            #   if y >= fdown(x) and y <= fup(x):
            #       break

            # x = random.uniform(x_low, x_high)
            x = aphine_uniform(x_low, x_high, 1, 2.2)
            yrange = interpolate(x, x_low, x_high, *yrange_left), interpolate(
                x, x_low, x_high, *yrange_right)
            y = random.uniform(*yrange)
            # y = random.uniform(-2, 2)
            # x, y = zero_one_norm(x, 0, 320), zero_one_norm(y, 0, 480)
            # Borde inferior: 5
            # Borde inferior: (5,[-3.5,3.5])
            # Border superior: -12
            # Border superior izquierdo: (-12, -9)
            # Border superior derecho: (-12, 9.5)

            # x, y = rescale(x, -12, 5), rescale(y, *yrange)

            x, y = rotate(x, y, args.theta)
            # 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,
        })

    # 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 all_visible is False:
        # 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,
                                  pos_density)

    return objects, blender_objects, all_visible, positions