Example #1
0
def xform_from_matrix(matrix):
    """Creates a Transform instance from a matrix represented as a list
    of 12 float values.
    """
    transform = Transform(1.0)
    for i in range(0, len(matrix)):
        transform[i // 4, i % 4] = matrix[i]

    return transform
Example #2
0
    def get_frame_meshes(self, path, frame, ctx):
        """Retrieves all meshes required to render a specific frame of a path plan.

        Args:
            path (:obj:`list` of :class:`Configuration`): Represents a collision-free
                path to a goal pose. It is the output of the path planning generated
                by a :class:`Simulator` object.
            frame (:obj:`int`): Frame number to retrieve.
            ctx (:obj:`dict`): A dictionary to keep context. Within Grasshopper, this is
                normally the ``sc.sticky`` object.

        Returns:
            list: list of Rhino meshes that can be used to visualize the selected frame.
        """
        first_start = timer() if self.debug else None
        shape_handles = self.simulator.get_all_visible_handles()
        if self.debug:
            LOG.debug('Execution time: get_all_visible_handles=%.2f',
                      timer() - first_start)

        if 'rfl_meshes' not in ctx:
            ctx['rfl_meshes'] = self._get_rfl_meshes(shape_handles)

        frame_config = path[frame]

        start = timer() if self.debug else None
        self.simulator.set_robot_config(self.robot, frame_config)
        if self.debug:
            LOG.debug('Execution time: set_robot_config=%.2f', timer() - start)

        start = timer() if self.debug else None
        meshes = []
        mesh_matrices = self.simulator.get_object_matrices(shape_handles)
        for handle, mesh_matrix in mesh_matrices.iteritems():
            mesh = ctx['rfl_meshes'][handle].DuplicateShallow()
            mesh.Transform(xform_from_matrix(mesh_matrix))
            meshes.append(mesh)

        if self.building_member:
            gripping_config = self.building_member_pickup_config if self.building_member_pickup_config else path[
                0]
            info = self._get_building_member_info(gripping_config)
            mesh = info['mesh'].DuplicateShallow()
            parent_transform = xform_from_matrix(
                mesh_matrices[info['parent_handle']])
            relative_transform = info['relative_transform']

            mesh.Transform(
                Transform.Multiply(parent_transform, relative_transform))
            meshes.append(mesh)

        if self.debug:
            LOG.debug('Execution time: get all transformed meshes=%.2f',
                      timer() - start)
            LOG.debug('Execution time: total=%.2f', timer() - first_start)

        return meshes
Example #3
0
	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
Example #4
0
def xform_from_transformation(transformation):
    """Creates a Rhino Transform instance from a :class:`Transformation`.

    Args:
        transformation (:class:`Transformation`): the transformation.

    Returns:
        (:class:`Rhino.Geometry.Transform`)
    """
    transform = Transform(1.0)
    for i in range(0, 4):
        for j in range(0, 4):
            transform[i, j] = transformation[i, j]
    return transform
Example #5
0
def xform_from_transformation(transformation):
    """Creates a Rhino Transform instance from a transformation object.
    
    Args:
        transformation (Transformation): the transformation.
    
    Returns:
        Transform: a Rhino class.
    """
    transform = Transform(1.0)
    for i in range(0, 4):
        for j in range(0, 4):
            transform[i, j] = transformation[i, j]
    return transform
Example #6
0
def xform_from_transformation_matrix(transformation_matrix):
    """Creates a Rhino Transform instance from 4x4 transformation matrix.

    Args:
        transformation_matrix (:obj:`list` of :obj:`list` of :obj:`float`): The
            4x4 transformation matrix in row-major order.

    Returns:
        (:class:`Rhino.Geometry.Transform`)
    """
    transform = Transform(1.0)
    for i in range(0, 4):
        for j in range(0, 4):
            transform[i, j] = transformation_matrix[i][j]
    return transform
Example #7
0
	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)
Example #8
0
def xform_from_transformation_matrix(transformation_matrix):
    """Creates a Rhino Transform instance from 4x4 transformation matrix.

    Parameters
    ----------
    transformation_matrix : :obj:`list` of :obj:`list` of :obj:`float`
        The 4x4 transformation matrix in row-major order.

    Returns
    -------
    :class:`Rhino.Geometry.Transform`
        RhinoCommon Transform object
    """
    transform = Transform(1.0)
    for i in range(0, 4):
        for j in range(0, 4):
            transform[i, j] = transformation_matrix[i][j]
    return transform
Example #9
0
def xform_from_transformation(transformation):
    """Creates a Rhino Transform instance from a :class:`Transformation`.

    Parameters
    ----------
    transformation (:class:`Transformation`):
        Compas transformation object

    Returns
    -------
    :class:`Rhino.Geometry.Transform`
        RhinoCommon Transform object
    """
    transform = Transform(1.0)
    for i in range(0, 4):
        for j in range(0, 4):
            transform[i, j] = transformation[i, j]
    return transform
Example #10
0
def xform_from_transformation(transformation):
    """Creates a Rhino transformation from a COMPAS transformation.

    Parameters
    ----------
    transformation : :class:`compas.geometry.Transformation`
        COMPAS transformation.

    Returns
    -------
    :rhino:`Rhino.Geometry.Transform`

    """
    transform = Transform(1.0)
    for i in range(0, 4):
        for j in range(0, 4):
            transform[i, j] = transformation[i, j]
    return transform
Example #11
0
def xform_from_transformation_matrix(matrix):
    """Creates a Rhino transformation from a 4x4 transformation matrix.

    Parameters
    ----------
    matrix : list[list[float]]
        The 4x4 transformation matrix in row-major order.

    Returns
    -------
    :rhino:`Rhino.Geometry.Transform`

    """
    transform = Transform(1.0)
    for i in range(0, 4):
        for j in range(0, 4):
            transform[i, j] = matrix[i][j]
    return transform
Example #12
0
    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
Example #13
0
    def aggregate_field(self, num):

        added = 0
        loops = 0
        while added < num:
            ## avoid endless loops
            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 and self.prev_num == 0:
                first_part = self.parts[random.choice(self.parts.keys())]
                start_point = None
                if self.multiple_fields:
                    f_name = first_part.field
                    if (self.mode == 2 or self.mode
                            == 3) and len(self.global_constraints) > 0:
                        start_point = self.field[f_name].return_highest_pt(
                            constraints=self.global_constraints)
                    else:
                        start_point = self.field[f_name].return_highest_pt()
                else:
                    if (self.mode == 2 or self.mode
                            == 3) and len(self.global_constraints) > 0:
                        start_point = self.field.return_highest_pt(
                            constraints=self.global_constraints)
                    else:
                        start_point = self.field.return_highest_pt()

                mov_vec = Vector3d.Subtract(Vector3d(start_point),
                                            Vector3d(first_part.center))
                move_transform = Transform.Translation(mov_vec.X, mov_vec.Y,
                                                       mov_vec.Z)
                first_part_trans = first_part.transform(move_transform)

                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)

                ## compute all possible next parts and append to list
                self.compute_next_w_field(first_part_trans)
                added += 1

            else:
                ## if no part is available, exit the aggregation routine and return an error message
                if self.queue_count == 0:
                    msg = "Could not place " + str(num - added) + " parts"
                    return msg

                next_data = self.aggregation_queue[self.queue_count - 1]
                next_part = self.parts[next_data[0]]
                next_center = Point3d(next_part.center)
                orientTransform = next_data[2]

                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 conn in next_part_trans.connections:
                        conn.generate_rules_table(self.rules)

                    next_part_trans.id = len(self.aggregated_parts)
                    self.aggregated_parts[next_data[1]].children.append(
                        next_part_trans.id)
                    next_part_trans.parent = self.aggregated_parts[
                        next_data[1]].id
                    self.aggregated_parts.append(next_part_trans)

                    ## compute all possible next parts and append to list
                    self.compute_next_w_field(next_part_trans)
                    added += 1

                ## TO FIX --> do not remove rules when only caused by missing supports
                self.aggregation_queue.pop()
                self.queue_values.pop()
                self.queue_count -= 1
Example #14
0
    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
Example #15
0
    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