示例#1
0
 def add_house(self,
               house,
               no_walls=False,
               no_ceil=False,
               no_floor=False,
               use_separate_walls=False,
               static=False):
     for node in house.nodes:
         if not node.valid:
             continue
         if not hasattr(node, 'body'):
             node.body = None
         if node.type == 'Object':
             node.body = self.add_object(node, static=static)
         if node.type == 'Room':
             ceil = False if no_ceil else not (hasattr(node, 'hideCeiling')
                                               and node.hideCeiling == 1)
             wall = False if (no_walls or use_separate_walls) else not (
                 hasattr(node, 'hideWalls') and node.hideWalls == 1)
             floor = False if no_floor else not (hasattr(node, 'hideFloor')
                                                 and node.hideFloor == 1)
             node.body = self.add_room(node,
                                       wall=wall,
                                       floor=floor,
                                       ceiling=ceil)
         if node.type == 'Box':
             half_widths = list(map(lambda x: 0.5 * x, node.dimensions))
             node.body = self.add_box(obj_id=node.id,
                                      half_extents=half_widths,
                                      transform=Transform.from_node(node),
                                      static=static)
     if use_separate_walls and not no_walls:
         for wall in house.walls:
             wall['body'] = self.add_wall(wall)
示例#2
0
    def get_render_obb(self):
        o = Obj(self.modelId)

        bbox_dims = o.bbox_max - o.bbox_min
        model_matrix = Transform(scale=bbox_dims[:3],
                                 translation=o.bbox_min[:3]).as_mat4()
        full_matrix = np.matmul(np.transpose(self.get_transformation()),
                                model_matrix)
        obb = OBB.from_local2world_transform(full_matrix)
        obb_tris = np.asarray(obb.get_triangles(), dtype=np.float32)
        rendered_obb = torch.from_numpy(
            TopDownView.render_object_full_size_helper(obb_tris,
                                                       self.room.size))
        return rendered_obb
示例#3
0
 def add_wall(self, node):
     h = node['height']
     p0 = np.transpose(np.matrix(node['points'][0]))
     p1 = np.transpose(np.matrix(node['points'][1]))
     c = (p0 + p1) * 0.5
     c[1] = h * 0.5
     dp = p1 - p0
     dp_l = np.linalg.norm(dp)
     dp = dp / dp_l
     angle = np.arccos(dp[0])
     rot_q = Quaternion(axis=[0, 1, 0], radians=angle)
     half_extents = np.array([dp_l, h, node['depth']]) * 0.5
     return self.add_box(obj_id=node['id'],
                         half_extents=half_extents,
                         transform=Transform(translation=c, rotation=rot_q),
                         static=True)
示例#4
0
    def add_house_room_only(self,
                            house,
                            room,
                            no_walls=False,
                            no_ceil=True,
                            no_floor=False,
                            use_separate_walls=False,
                            only_architecture=False,
                            static=False):
        #walls, ceil, floor logic not fleshed out due to current limited use case
        room_node = [node for node in house.nodes if node.id == room.id]
        if len(room_node) < 1:
            raise Exception("Missing Room")
        if only_architecture:
            house.nodes = room_node
        else:
            house.nodes = [node for node in room.nodes]
            house.nodes.append(room_node[0])

        for node in house.nodes:
            if not node.valid:
                continue
            if not hasattr(node, 'body'):
                node.body = None
            if node.type == 'Object':
                node.body = self.add_object(node, static=static)
            if node.type == 'Room':
                ceil = False if no_ceil else not (hasattr(node, 'hideCeiling')
                                                  and node.hideCeiling == 1)
                wall = False if (no_walls or use_separate_walls) else not (
                    hasattr(node, 'hideWalls') and node.hideWalls == 1)
                floor = False if no_floor else not (hasattr(node, 'hideFloor')
                                                    and node.hideFloor == 1)
                node.body = self.add_room(node,
                                          wall=wall,
                                          floor=floor,
                                          ceiling=ceil)
            if node.type == 'Box':
                half_widths = list(map(lambda x: 0.5 * x, node.dimensions))
                node.body = self.add_box(obj_id=node.id,
                                         half_extents=half_widths,
                                         transform=Transform.from_node(node),
                                         static=static)
        if use_separate_walls and not no_walls:
            for wall in house.walls:
                wall['body'] = self.add_wall(wall)
示例#5
0
 def add_object(self, node, create_vis_mesh=False, static=False):
     model_id = node.modelId.replace(
         '_mirror', '')  # TODO: need to otherwise account for mirror?
     object_dir = os.path.join(self._data_dir_base, 'object')
     basename = f'{object_dir}/{model_id}/{model_id}'
     vis_obj_filename = f'{basename}.obj' if create_vis_mesh else None
     col_obj_filename = f'{basename}.vhacd.obj'
     if not os.path.exists(col_obj_filename):
         print(
             'WARNING: collision mesh {col_obj_filename} unavailable, using visual mesh instead.'
         )
         col_obj_filename = f'{basename}.obj'
     return self.add_mesh(obj_id=node.id,
                          obj_file=col_obj_filename,
                          transform=Transform.from_node(node),
                          vis_mesh_file=vis_obj_filename,
                          static=static)
示例#6
0
 def get_candidate_transform(self, node, max_iterations=100):
     num_checks = 0
     zmin = self._objects.room.zmin
     while True:
         num_checks += 1
         p = self._objects.room.obb.sample()
         ray_from = [p[0], zmin - .5, p[2]]
         ray_to = [p[0], zmin + .5, p[2]]
         intersection = ags._objects.simulator.ray_test(ray_from, ray_to)
         if intersection.id == self.room_id + 'f' or num_checks > max_iterations:
             break
     xform = Transform()
     xform.set_translation([p[0], zmin + .1, p[2]])
     angle = random() * 2 * math.pi
     angular_resolution = 2 * math.pi / self._num_angle_divisions
     angle = round(angle / angular_resolution) * angular_resolution
     xform.set_rotation(radians=angle)
     return xform
示例#7
0
 def add_architecture(n, obj_file, suffix):
     return self.add_mesh(obj_id=n.id + suffix,
                          obj_file=obj_file,
                          transform=Transform(),
                          vis_mesh_file=None,
                          static=True)
示例#8
0
 def from_node(cls, node, aligned_dims):
     xform = Transform.from_mat4x4_flat_row_major(node.transform)
     return cls(center=xform.translation,
                half_widths=aligned_dims * xform.scale * 0.5,
                rotation_matrix=xform.rotation.rotation_matrix)
示例#9
0
 def from_local2world_transform(cls, transform):
     xform = Transform.from_mat4(transform)
     return cls(center=xform.translation,
                half_widths=xform.scale,
                rotation_matrix=xform.rotation.rotation_matrix)
示例#10
0
    def render(self, room):
        projection = self.pgen.get_projection(room)

        visualization = np.zeros((self.size, self.size))
        nodes = []

        for node in room.nodes:
            modelId = node.modelId  #Camelcase due to original json

            t = np.asarray(node.transform).reshape(4, 4)

            o = Obj(modelId)
            t = projection.to_2d(t)
            o.transform(t)

            save_t = t
            t = projection.to_2d()
            bbox_min = np.dot(np.asarray([node.xmin, node.zmin, node.ymin, 1]),
                              t)
            bbox_max = np.dot(np.asarray([node.xmax, node.zmax, node.ymax, 1]),
                              t)
            xmin = math.floor(bbox_min[0])
            ymin = math.floor(bbox_min[2])
            xsize = math.ceil(bbox_max[0]) - xmin + 1
            ysize = math.ceil(bbox_max[2]) - ymin + 1

            description = {}
            description["modelId"] = modelId
            description["transform"] = node.transform
            description["bbox_min"] = bbox_min
            description["bbox_max"] = bbox_max
            description["id"] = node.id
            description["child"] = [c.id for c in node.child
                                    ] if node.child else None
            description["parent"] = node.parent.id if isinstance(
                node.parent, Node) else node.parent
            #if description["parent"] is None or description["parent"] == "Ceiling":
            #    print(description["modelId"])
            #    print(description["parent"])
            #    print(node.zmin - room.zmin)
            #print("FATAL ERROR")

            #Since it is possible that the bounding box information of a room
            #Was calculated without some doors/windows
            #We need to handle these cases
            if ymin < 0:
                ymin = 0
            if xmin < 0:
                xmin = 0

            #xmin = 0
            #ymin = 0
            #xsize = 256
            #ysize = 256

            #print(list(bbox_min), list(bbox_max))
            #print(xmin, ymin, xsize, ysize)
            rendered = self.render_object(o, xmin, ymin, xsize, ysize,
                                          self.size)
            description["height_map"] = torch.from_numpy(rendered).float()

            #tmp = np.zeros((self.size, self.size))
            #tmp[xmin:xmin+rendered.shape[0],ymin:ymin+rendered.shape[1]] = rendered
            #visualization += tmp

            # Compute the pixel-space dimensions of the object before it has been
            #    transformed (i.e. in object space)
            objspace_bbox_min = np.dot(o.bbox_min, t)
            objspace_bbox_max = np.dot(o.bbox_max, t)
            description['objspace_dims'] = np.array([
                objspace_bbox_max[0] - objspace_bbox_min[0],
                objspace_bbox_max[2] - objspace_bbox_min[2]
            ])

            # Render an OBB height map as well
            bbox_dims = o.bbox_max - o.bbox_min
            model_matrix = Transform(scale=bbox_dims[:3],
                                     translation=o.bbox_min[:3]).as_mat4()
            full_matrix = np.matmul(np.transpose(save_t), model_matrix)
            obb = OBB.from_local2world_transform(full_matrix)
            obb_tris = np.asarray(obb.get_triangles(), dtype=np.float32)
            bbox_min = np.min(np.min(obb_tris, 0), 0)
            bbox_max = np.max(np.max(obb_tris, 0), 0)
            xmin, ymin = math.floor(bbox_min[0]), math.floor(bbox_min[2])
            xsize, ysize = math.ceil(bbox_max[0]) - xmin + 1, math.ceil(
                bbox_max[2]) - ymin + 1
            rendered_obb = self.render_object_helper(obb_tris, xmin, ymin,
                                                     xsize, ysize, self.size)
            description["height_map_obb"] = torch.from_numpy(
                rendered_obb).float()
            description['bbox_min_obb'] = bbox_min
            description['bbox_max_obb'] = bbox_max

            tmp = np.zeros((self.size, self.size))
            tmp[xmin:xmin + rendered.shape[0],
                ymin:ymin + rendered.shape[1]] = rendered
            visualization += tmp

            nodes.append(description)

        if hasattr(room, "transform"):
            t = projection.to_2d(np.asarray(room.transform).reshape(4, 4))
        else:
            t = projection.to_2d()
        #Render the floor
        o = Obj(room.modelId + "f", room.house_id, is_room=True)
        o.transform(t)
        floor = self.render_object(o, 0, 0, self.size, self.size, self.size)
        visualization += floor
        floor = torch.from_numpy(floor).float()

        #Render the walls
        o = Obj(room.modelId + "w", room.house_id, is_room=True)
        o.transform(t)
        wall = self.render_object(o, 0, 0, self.size, self.size, self.size)
        visualization += wall
        wall = torch.from_numpy(wall).float()
        return (visualization, (floor, wall, nodes))