def compute_possible_children(self, part_id, conn_id, check_constraints = False): possible_children = [] current_part = self.aggregated_parts[part_id] if conn_id in current_part.active_connections: current_conn = current_part.connections[conn_id] for rule_id in current_conn.active_rules: rule = current_conn.rules_table[rule_id] next_part = self.parts[rule.part2] orientTransform = Transform.PlaneToPlane(next_part.connections[rule.conn2].flip_pln, current_conn.pln) ## boolean checks for all constraints coll_check = False add_coll_check = False valid_connections = [] missing_sup_check = False global_const_check = False if check_constraints: ## collision check self.possible_collisions = [] coll_check = self.collision_check(next_part, orientTransform) ## constraints check if self.mode == 1: ## only local constraints mode if coll_check == False and next_part.is_constrained: add_coll_check = self.additional_collider_check(next_part, orientTransform) if add_coll_check == False: missing_sup_check = self.missing_supports_check(next_part, orientTransform) elif self.mode == 2: ## onyl global constraints mode if coll_check == False and len(self.global_constraints) > 0: global_const_check = self.global_constraints_check(next_part, orientTransform) elif self.mode == 3: ## local+global constraints mode if coll_check == False: if len(self.global_constraints) > 0: global_const_check = self.global_constraints_check(next_part, orientTransform) if global_const_check == False and next_part.is_constrained: add_coll_check = self.additional_collider_check(next_part, orientTransform) if add_coll_check == False: missing_sup_check = self.missing_supports_check(next_part, orientTransform) if coll_check == False and add_coll_check == False and missing_sup_check == False and global_const_check == False: next_part_trans = next_part.transform(orientTransform) possible_children.append(next_part_trans) return possible_children else: return -1
def check_all_connections(self): for part in self.aggregated_parts: if len(part.active_connections) > 0: for conn_id in part.active_connections: conn = part.connections[conn_id] if len(conn.active_rules) > 0: for rule_id in conn.active_rules: next_rule = conn.rules_table[rule_id] next_part = self.parts[next_rule.part2] orientTransform = Transform.PlaneToPlane(next_part.connections[next_rule.conn2].flip_pln, conn.pln) _, coll_check, _, _, _ = self.check_all_constraints(next_part, orientTransform) if coll_check: conn.active_rules.remove(rule_id) if len(conn.active_rules) == 0: part.active_connections.remove(conn_id)
def compute_next_w_field(self, part): for i in xrange(len(part.active_connections) - 1, -1, -1): conn_id = part.active_connections[i] conn = part.connections[conn_id] for i2 in xrange(len(conn.active_rules) - 1, -1, -1): rule_id = conn.active_rules[i2] rule = conn.rules_table[rule_id] next_part = self.parts[rule.part2] next_center = Point3d(next_part.center) orientTransform = Transform.PlaneToPlane( next_part.connections[rule.conn2].flip_pln, conn.pln) next_center.Transform(orientTransform) if self.multiple_fields: f_name = next_part.field if self.field[f_name].bbox.Contains(next_center) == True: field_val = self.field[f_name].return_pt_val( next_center) queue_index = bisect.bisect_left( self.queue_values, field_val) queue_entry = (next_part.name, part.id, orientTransform) self.queue_values.insert(queue_index, field_val) self.aggregation_queue.insert(queue_index, queue_entry) self.queue_count += 1 else: if self.field.bbox.Contains(next_center) == True: field_val = self.field.return_pt_val(next_center) queue_index = bisect.bisect_left( self.queue_values, field_val) queue_entry = (next_part.name, part.id, orientTransform) self.queue_values.insert(queue_index, field_val) self.aggregation_queue.insert(queue_index, queue_entry) self.queue_count += 1
def aggregate_rnd(self, num): added = 0 loops = 0 while added < num: loops += 1 if loops > num * 100: break ## if no part is present in the aggregation, add first random part if len(self.aggregated_parts) == 0: first_part = self.parts[random.choice(self.parts.keys())] first_part_trans = first_part.transform(Transform.Identity) for conn in first_part_trans.connections: conn.generate_rules_table(self.rules) first_part_trans.id = 0 self.aggregated_parts.append(first_part_trans) added += 1 ## otherwise add new random part else: next_rule = None part_01_id = -1 conn_01_id = -1 next_rule_id = -1 new_rule_attempts = 0 while new_rule_attempts < 10000: new_rule_attempts += 1 part_01_id = random.randint(0, len(self.aggregated_parts) - 1) part_01 = self.aggregated_parts[part_01_id] if len(part_01.active_connections) > 0: conn_01_id = part_01.active_connections[random.randint( 0, len(part_01.active_connections) - 1)] conn_01 = part_01.connections[conn_01_id] if len(conn_01.active_rules) > 0: next_rule_id = conn_01.active_rules[random.randint( 0, len(conn_01.active_rules) - 1)] next_rule = conn_01.rules_table[next_rule_id] break if next_rule is not None: next_part = self.parts[next_rule.part2] orientTransform = Transform.PlaneToPlane( next_part.connections[next_rule.conn2].flip_pln, conn_01.pln) global_check, coll_check, add_coll_check, missing_sup_check, global_const_check = self.check_all_constraints( next_part, orientTransform) if not global_check: next_part_trans = next_part.transform(orientTransform) next_part_trans.reset_part(self.rules) for i in range(len( next_part_trans.active_connections)): if next_part_trans.active_connections[ i] == next_rule.conn2: next_part_trans.active_connections.pop(i) break next_part_trans.id = len(self.aggregated_parts) ## parent-child tracking self.aggregated_parts[part_01_id].children.append( next_part_trans.id) next_part_trans.parent = self.aggregated_parts[ part_01_id].id self.aggregated_parts.append(next_part_trans) for i in range( len(self.aggregated_parts[part_01_id]. active_connections)): if self.aggregated_parts[ part_01_id].active_connections[ i] == conn_01_id: self.aggregated_parts[ part_01_id].active_connections.pop(i) break added += 1 ## TO FIX --> do not remove rules when only caused by missing supports else: ## remove rules if they cause collisions or overlappings for i in range( len(self.aggregated_parts[part_01_id]. connections[conn_01_id].active_rules)): if self.aggregated_parts[part_01_id].connections[ conn_01_id].active_rules[ i] == next_rule_id: self.aggregated_parts[part_01_id].connections[ conn_01_id].active_rules.pop(i) break ## check if the connection is still active (still active rules available) if len(self.aggregated_parts[part_01_id]. connections[conn_01_id].active_rules) == 0: for i in range( len(self.aggregated_parts[part_01_id]. active_connections)): if self.aggregated_parts[ part_01_id].active_connections[ i] == conn_01_id: self.aggregated_parts[ part_01_id].active_connections.pop(i) break else: ## if no part is available, exit the aggregation routine and return an error message msg = "Could not place " + str(num - added) + " parts" return msg
def aggregate_sequence(self, graph_rules): for rule in graph_rules: ## first part if len(self.aggregated_parts) == 0: aggr_rule = rule.split(">")[0] rule_parts = aggr_rule.split("_") part1 = str(rule_parts[0].split("|")[0]) conn1 = int(rule_parts[0].split("|")[1]) part2 = str(rule_parts[1].split("|")[0]) conn2 = int(rule_parts[1].split("|")[1]) rule_ids = rule.split(">")[1].split("_") first_part = self.parts[part1] first_part_trans = first_part.transform(Transform.Identity) first_part_trans.id = rule_ids[0] next_part = self.parts[part2] orientTransform = Transform.PlaneToPlane( next_part.connections[conn2].flip_pln, first_part.connections[conn1].pln) next_part_trans = next_part.transform(orientTransform) next_part_trans.id = rule_ids[1] ## check additional collider (for fabrication constraints) self.additional_collider_check(next_part, orientTransform) ## parent-child tracking first_part_trans.children.append(next_part_trans) next_part_trans.parent = first_part_trans self.aggregated_parts.append(first_part_trans) self.aggregated_parts.append(next_part_trans) first_part_trans.children.append(next_part_trans) else: aggr_rule = rule.split(">")[0] rule_parts = aggr_rule.split("_") part1_id = str(rule_parts[0].split("|")[0]) conn1 = int(rule_parts[0].split("|")[1]) part2 = str(rule_parts[1].split("|")[0]) conn2 = int(rule_parts[1].split("|")[1]) rule_ids = rule.split(">")[1].split("_") first_part = None for part in self.aggregated_parts: if part.id == part1_id: first_part = part break if first_part is not None: first_part.id = rule_ids[0] next_part = self.parts[part2] orientTransform = Transform.PlaneToPlane( next_part.connections[conn2].flip_pln, first_part.connections[conn1].pln) next_part_trans = next_part.transform(orientTransform) next_part_trans.id = rule_ids[1] ## parent-child tracking first_part.children.append(next_part_trans.id) next_part_trans.parent = first_part.id self.aggregated_parts.append(next_part_trans) else: pass ## implement error handling