def _costPrior(self, m):
        surface = self.surface
        m_bb_corners = cf._getWorldBoundingBox(m)
        m_parent_bb_corners = cf._getWorldBoundingBox(m.parent)

        model_top = cf._getTopSurface(m_bb_corners)
        parent_top = cf._getTopSurface(m_parent_bb_corners)

        name = m.name + "_" + m.parent.name
        # calculate c
        c = cf._calculateCenterPoint(m_bb_corners, model_top)

        total_cost = np.inf
        for s in self.data.objects[name].spatial:
            #### find the nearest surface
            parent_point = self._getSamePoint(parent_top, surface[s.s1_p])
            parent_point2 = self._getSamePoint(parent_top, surface[s.s2_p])
            model_point = self._getSamePoint(model_top, surface[s.s1_o])

            # calculate d1
            d1 = cf._calculateDistanceOfLineAndPoint(
                m_parent_bb_corners[parent_point[0]],
                m_parent_bb_corners[parent_point[1]], c)

            # calculate d2
            d2 = cf._calculateDistanceOfLineAndPoint(
                m_parent_bb_corners[parent_point2[0]],
                m_parent_bb_corners[parent_point2[1]], c)

            # calculate theta1
            theta1 = cf._calculateTheta([
                m_parent_bb_corners[parent_point[0]][0:2],
                m_parent_bb_corners[parent_point[1]][0:2]
            ], [
                m_bb_corners[model_point[0]][0:2],
                m_bb_corners[model_point[1]][0:2]
            ])

            temp_d1 = np.abs(d1 - s.d1) * self.Wpr_d1
            temp_d2 = np.abs(d2 - s.d2) * self.Wpr_d2
            temp_theta1 = np.abs(theta1 - s.theta1) * self.Wpr_theta1
            temp_cost = temp_d1 + temp_d2 + temp_theta1

            if (total_cost > temp_cost):
                total_cost = temp_cost
                cost_d1 = temp_d1
                cost_d2 = temp_d2
                cost_theta1 = temp_theta1

        return (cost_d1, cost_d2, cost_theta1)
    def _costAccessibility(self, m):
        # accessibility
        cost = 0
        for f in m.parent.children:
            if (f.name == m.name):
                continue
            if (cf._checkAccessCollision(f, m)):
                m_bb_corners = cf._getWorldBoundingBox(m)
                m_top = cf._getTopSurface(m_bb_corners)
                data_p = cf._calculateCenterPoint(m_bb_corners, m_top)
                data_b = cf._calculateL2Distance(data_p, m_bb_corners[0][0:2])

                box_min = np.min(m_bb_corners, axis=0)
                box_max = np.max(m_bb_corners, axis=0)
                if (np.abs(box_max[0] - box_min[0]) >
                        np.abs(box_max[1] - box_min[1])):
                    # y
                    data_a = [data_p[0], data_p[1] - box_min[1]]
                    data_pa = np.abs(data_p[1] - box_min[1]) / 2
                    data_ad = cf._calculateL2Distance(
                        data_a, [box_min[0], box_min[1] - 0.05])
                else:
                    # x
                    data_a = [data_p[0] - box_min[0], data_p[1]]
                    data_pa = np.abs(data_p[0] - box_min[0]) / 2
                    data_ad = cf._calculateL2Distance(
                        [box_min[0] - 0.05, box_min[1]], data_a)
                cost += (1 - (data_pa / (data_b + data_ad)))

        return cost * self.Wa
    def _costVisibility(self, m):
        cost = 0
        for obj in m.parent.children:
            if (obj.name == m.name):
                continue
            for vf in m.children:
                if (cf._checkCollision(vf, obj)):
                    m_bb_corners = cf._getWorldBoundingBox(obj)
                    m_top = cf._getTopSurface(m_bb_corners)
                    v = cf._calculateCenterPoint(m_bb_corners, m_top)
                    vd = cf._calculateL2Distance(v, m_bb_corners[m_top[0]])
                    # calculate c (center)
                    data_c = cf._calculateCenterPoint(m_bb_corners, m_top)
                    # calculate b (diagonal)
                    data_b = cf._calculateL2Distance(data_c,
                                                     m_bb_corners[0][0:2])
                    cost += np.max([
                        0,
                        1 - cf._calculateL2Distance(data_c, v) / (data_b + vd)
                    ])

        return cost * self.Wv
Beispiel #4
0
    def _getSpatial(self):
        def _isNeighbor(a, b):
            for i in a:
                for j in b:
                    if (i == j):
                        return True

            return False

        for m in self.model:
            # model
            model = self.model[m]

            # skip when object is a room or furniture
            if (model.parent == "None" or model.parent == "room"):
                continue

            # parent of model
            model_parent = self.model[model.parent]

            # Z
            Z = np.min(model.bb_corners, axis=0)[2]
            rot = model.rot

            # find the top surface of model
            model_top = cf._getTopSurface(model.bb_corners)
            # find the top surface of model's parent
            parent_top = cf._getTopSurface(model_parent.bb_corners)

            # calculate c (center)
            c = cf._calculateCenterPoint(model.bb_corners, model_top)
            # calculate b (diagonal)
            b = cf._calculateL2Distance(c, model.bb_corners[0][0:2])

            # Distinguish diagonals
            diags = cf._seperateDiagonalsRect(model.bb_corners, model_top)
            diags_parent = cf._seperateDiagonalsRect(model_parent.bb_corners,
                                                     parent_top)

            # Calculate the distances for each surfaces
            parent_point = []
            for i in diags_parent[0]:
                for j in diags_parent[1]:
                    distance = cf._calculateDistanceOfLineAndPoint(
                        model_parent.bb_corners[i], model_parent.bb_corners[j],
                        c)
                    parent_point.append(([i, j], distance))

            # Sort distance
            sorted_distance = sorted(parent_point, key=lambda x: x[1])
            nearest_parent_point = sorted_distance[0][0]

            ### calculate d1 (from center(c) to the nearest parent's surface)
            ### calculate d2 (from center(c) to the second nearest parent's surface and neighbor)
            d1 = sorted_distance[0][1]
            if (_isNeighbor(sorted_distance[0][0], sorted_distance[1][0])):
                nearest_parent_point2 = sorted_distance[1][0]
                d2 = sorted_distance[1][1]
            else:
                nearest_parent_point2 = sorted_distance[2][0]
                d2 = sorted_distance[2][1]

            # get Back_surface
            h = cf._calculateFootofPerpendicular(
                model_parent.bb_corners[nearest_parent_point[0]],
                model_parent.bb_corners[nearest_parent_point[1]], c)
            for i in diags[0]:
                for j in diags[1]:
                    if (cf._checkCross(c, h, model.bb_corners[i],
                                       model.bb_corners[j])):
                        s1_o = cf._getSurfaceLabel(
                            cf._getSurfacePoint(model.bb_corners, i, j),
                            self.surface)
                        backSurface_point = [i, j]

            # get Parent_surface
            s1_p = cf._getSurfaceLabel(
                cf._getSurfacePoint(model_parent.bb_corners,
                                    nearest_parent_point[0],
                                    nearest_parent_point[1]), self.surface)
            s2_p = cf._getSurfaceLabel(
                cf._getSurfacePoint(model_parent.bb_corners,
                                    nearest_parent_point2[0],
                                    nearest_parent_point2[1]), self.surface)

            # calculate theta1
            theta1 = cf._calculateTheta([
                model_parent.bb_corners[nearest_parent_point[0]][0:2],
                model_parent.bb_corners[nearest_parent_point[1]][0:2]
            ], [
                model.bb_corners[backSurface_point[0]][0:2],
                model.bb_corners[backSurface_point[1]][0:2]
            ])

            model.spatial = Spatial(Z, rot, d1, d2, s1_o, s1_p, s2_p, theta1)
    def _initializedLocation(self):
        def check_axis(points, bb_corner):
            if (np.abs(bb_corner[points[0]][0] - bb_corner[points[1]][0]) <=
                    0.01):
                return 1
            else:
                return 0

        for m in bpy.data.objects:
            model_name = m.name

            if (model_name == "room" or model_name.split('.')[0] == "viewing"
                    or model_name == "Camera" or model_name == "Lamp"
                    or m.parent.name == "room"):
                continue
            if model_name in self.unfeasibleObjects:
                continue

            surface = self.surface
            m_bb_corners = cf._getWorldBoundingBox(m)
            m_parent_bb_corners = cf._getWorldBoundingBox(m.parent)

            model_top = cf._getTopSurface(m_bb_corners)
            parent_top = cf._getTopSurface(m_parent_bb_corners)

            name = m.name + "_" + m.parent.name

            s = self.data.objects[name].spatial[0]

            #### find the nearest surface
            parent_point = self._getSamePoint(parent_top, surface[s.s1_p])
            parent_point2 = self._getSamePoint(parent_top, surface[s.s2_p])
            model_point = self._getSamePoint(model_top, surface[s.s1_o])

            common_point = list(
                set(parent_point).intersection(parent_point2))[0]
            uncommon_point = list(
                set(list(set(parent_top).difference(
                    set(parent_point)))).difference(set(parent_point2)))[0]

            if (check_axis(parent_point, m_parent_bb_corners) == 0):
                # parent_point y axis
                if (m_parent_bb_corners[common_point][1] >
                        m_parent_bb_corners[uncommon_point][1]):
                    m.location[1] = m_parent_bb_corners[common_point][1] - s.d1
                else:
                    m.location[1] = m_parent_bb_corners[common_point][1] + s.d1
            else:
                # parent_point x axis
                if (m_parent_bb_corners[common_point][0] >
                        m_parent_bb_corners[uncommon_point][0]):
                    m.location[0] = m_parent_bb_corners[common_point][0] - s.d1
                else:
                    m.location[0] = m_parent_bb_corners[common_point][0] + s.d1

            if (check_axis(parent_point2, m_parent_bb_corners) == 0):
                # parent_point y axis
                if (m_parent_bb_corners[common_point][1] >
                        m_parent_bb_corners[uncommon_point][1]):
                    m.location[1] = m_parent_bb_corners[common_point][1] - s.d2
                else:
                    m.location[1] = m_parent_bb_corners[common_point][1] + s.d2
            else:
                # parent_point x axis
                if (m_parent_bb_corners[common_point][0] >
                        m_parent_bb_corners[uncommon_point][0]):
                    m.location[0] = m_parent_bb_corners[common_point][0] - s.d2
                else:
                    m.location[0] = m_parent_bb_corners[common_point][0] + s.d2

            if (m.parent.parent.name != "room"):
                temp_parent = m.parent
                self._changeParent(m, bpy.data.objects['room'])
                m.location[0] = m.parent.location[0]
                m.location[1] = m.parent.location[1]
                self._changeParent(m, temp_parent)

        bpy.context.scene.update()