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
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()