Exemplo n.º 1
0
    def getGraph(self) -> List[Tuple[int, int]]:
        """Return edges data for NetworkX graph class.

        + VLinks will become graph nodes.
        """
        vpoints = self.EntitiesPoint.dataTuple()
        vlinks = self.EntitiesLink.dataTuple()
        graph = Graph([])
        # links name for RP joint.
        k = len(vlinks)
        used_point = set()
        # Link names will change to index number.
        for i, vlink in enumerate(vlinks):
            for p in vlink.points:
                if p in used_point:
                    continue
                for m, vlink_ in enumerate(vlinks):
                    if not ((i != m) and (p in vlink_.points)):
                        continue
                    if vpoints[p].type != VPoint.RP:
                        graph.add_edge(i, m)
                        continue
                    graph.add_edge(i, k)
                    graph.add_edge(k, m)
                    k += 1
                used_point.add(p)
        return [edge for n, edge in edges_view(graph)]
Exemplo n.º 2
0
def four_bar_loops(G):
    result = set([])
    vertexes = {v: k for k, v in edges_view(G)}
    for node in G.nodes:
        if node in result:
            continue
        nb1s = G.neighbors(node)
        #node not in nb1s
        for nb1 in nb1s:
            if nb1 in result:
                continue
            nb2s = G.neighbors(nb1)
            #node can not in nb2s
            for nb2 in nb2s:
                if (nb2 == node) or (nb2 in result):
                    continue
                nb3s = G.neighbors(nb2)
                #node can not in nb3s
                for nb3 in nb3s:
                    if (nb3 in (node, nb1)) or (nb3 in result):
                        continue
                    if node in G.neighbors(nb3):
                        result.update([node, nb1, nb2, nb3])
                        yield tuple(vertexes[tuple(sorted(e))]
                                    for e in [(node,
                                               nb1), (nb1,
                                                      nb2), (nb2,
                                                             nb3), (node,
                                                                    nb3)])
Exemplo n.º 3
0
def four_bar_loops(G: Graph) -> Tuple[int, int, int, int]:
    """A generator to find out the four bar loops."""
    result = set([])
    vertexes = {v: k for k, v in edges_view(G)}

    def loop_set(node: int, nb1: int, nb2: int,
                 nb3: int) -> Tuple[int, int, int, int]:
        """Return a loop set."""
        tmp_list = []
        for e in [(node, nb1), (nb1, nb2), (nb2, nb3), (node, nb3)]:
            tmp_list.append(vertexes[tuple(sorted(e))])
        return tuple(tmp_list)

    for node in G.nodes:
        if node in result:
            continue
        nb1s = G.neighbors(node)
        #node not in nb1s
        for nb1 in nb1s:
            if nb1 in result:
                continue
            nb2s = G.neighbors(nb1)
            #node can not in nb2s
            for nb2 in nb2s:
                if (nb2 == node) or (nb2 in result):
                    continue
                nb3s = G.neighbors(nb2)
                #node can not in nb3s
                for nb3 in nb3s:
                    if (nb3 in (node, nb1)) or (nb3 in result):
                        continue
                    if node in G.neighbors(nb3):
                        loop = [node, nb1, nb2, nb3]
                        result.update(loop)
                        yield loop_set(*loop)
Exemplo n.º 4
0
def getGraph(self) -> List[Tuple[int, int]]:
    """Return edges data for NetworkX graph class.

    + VLinks will become graph nodes.
    """
    joint_data = self.EntitiesPoint.dataTuple()
    link_data = self.EntitiesLink.dataTuple()
    G = Graph()
    # links name for RP joint.
    k = len(link_data)
    used_point = set()
    for i, vlink in enumerate(link_data):
        for p in vlink.points:
            if p in used_point:
                continue
            for m, vlink_ in enumerate(link_data):
                if not ((i != m) and (p in vlink_.points)):
                    continue
                if joint_data[p].type != 2:
                    G.add_edge(i, m)
                    continue
                G.add_edge(i, k)
                G.add_edge(k, m)
                k += 1
            used_point.add(p)
    return [edge for n, edge in edges_view(G)]
Exemplo n.º 5
0
 def setGraph(self, G, pos):
     self.clear()
     self.PreviewWindow.setGraph(G, pos)
     for link in G.nodes:
         self.grounded_list.addItem("({})".format(", ".join(
             'P{}'.format(n) for n, edge in edges_view(G) if link in edge)))
     #Point name as (P1, P2, P3, ...).
     for node in pos:
         self.joint_name.addItem('P{}'.format(node))
Exemplo n.º 6
0
 def find_friends(node: int):
     """Find all the nodes that are same link with input node."""
     ev = dict(edges_view(self.PreviewWindow.G))
     link = set(ev[node])
     tmp_list = []
     for node_, link_ in ev.items():
         if node_ == node:
             continue
         if set(link_) & link:
             tmp_list.append(f'P{node_}')
     return tmp_list
Exemplo n.º 7
0
 def on_load_button_clicked(self):
     """Show up the dialog to load structure data."""
     dlg = CollectionsDialog(self)
     dlg.show()
     if not dlg.exec_():
         return
     self.profile_name = dlg.name_loaded
     params = dlg.mechanismParams
     mapping = params['name_dict']
     #Add customize joints.
     G = Graph(params['Graph'])
     self.setGraph(G, params['pos'])
     self.PreviewWindow.cus = params['cus']
     self.PreviewWindow.same = params['same']
     #Grounded setting.
     Driver = [mapping[e] for e in params['Driver']]
     Follower = [mapping[e] for e in params['Follower']]
     for row, link in enumerate(G.nodes):
         points = set('P{}'.format(n) for n, edge in edges_view(G)
                      if link in edge)
         if set(Driver + Follower) <= points:
             self.grounded_list.setCurrentRow(row)
             break
     #Driver, Follower, Target
     for row in reversed(range(self.Follower_list.count())):
         if self.Follower_list.item(row).text() in Driver:
             self.Follower_list.setCurrentRow(row)
             self.Driver_add.click()
     self.Target_list.addItems([mapping[e] for e in params['Target']])
     self.setWarning(self.Target_label, not self.Target_list.count() > 0)
     #Constraints
     self.constraint_list.addItems(
         [", ".join(mapping[e] for e in c) for c in params['constraint']])
     #Expression
     for expr in params['Expression'].split(';'):
         params = get_from_parenthesis(expr, '[', ']').split(',')
         target = get_from_parenthesis(expr, '(', ')')
         params.append(target)
         for p in params:
             try:
                 #Try to avoid replace function name.
                 expr = mapping[p].join(expr.rsplit(p, 1))
             except KeyError:
                 continue
         item = QListWidgetItem()
         self.Expression_list.addItem(item)
         item.setText(expr)
         self.PreviewWindow.setStatus(mapping[target], True)
     self.setWarning(self.Expression_list_label,
                     not self.PreviewWindow.isAllLock())
Exemplo n.º 8
0
 def __load_data_base(self):
     """Show up the dialog to load structure data."""
     dlg = CollectionsDialog(self.collections, self.getCollection, self)
     dlg.show()
     if not dlg.exec_():
         return
     self.profile_name = dlg.name()
     params = dlg.params()
     # Add customize joints.
     graph = Graph(params['Graph'])
     self.setGraph(graph, params['pos'])
     self.PreviewWindow.cus = params['cus']
     self.PreviewWindow.same = params['same']
     # Grounded setting.
     drivers = set(params['Driver'])
     followers = set(params['Follower'])
     for row, link in enumerate(graph.nodes):
         points = {f'P{n}' for n, edge in edges_view(graph) if link in edge}
         if (drivers | followers) <= points:
             self.__set_ground(row)
             break
     # Driver, Follower, Target
     for expr in params['Expression'].split(';'):
         if str_before(expr, '[') != 'PLAP':
             continue
         base = str_between(expr, '[', ']').split(',')[0]
         self.__find_follower_to_remove(base)
         rotator = str_between(expr, '(', ')')
         self.driver_list.addItem(f"({base}, {rotator})")
     _set_warning(self.driver_label, not self.driver_list.count())
     self.target_list.addItems(list(params['Target']))
     _set_warning(self.target_label, not self.target_list.count() > 0)
     # Constraints
     self.constraint_list.addItems(
         [", ".join(c) for c in params['constraints']])
     # Expression
     if params['Expression']:
         for expr in params['Expression'].split(';'):
             func = str_before(expr, '[')
             target = str_between(expr, '(', ')')
             params = str_between(expr, '[', ']').split(',')
             params.insert(0, func)
             params.append(target)
             self.__add_solution(*params)
             self.PreviewWindow.setStatus(target, True)
     _set_warning(self.expression_list_label,
                  not self.PreviewWindow.isAllLock())
Exemplo n.º 9
0
 def on_load_button_clicked(self):
     """Show up the dialog to load structure data."""
     dlg = CollectionsDialog(self)
     dlg.show()
     if not dlg.exec_():
         return
     self.profile_name = dlg.name_loaded
     params = dlg.mech_params
     #Add customize joints.
     G = Graph(params['Graph'])
     self.setGraph(G, params['pos'])
     self.PreviewWindow.cus = params['cus']
     self.PreviewWindow.same = params['same']
     #Grounded setting.
     drivers = set(params['Driver'])
     followers = set(params['Follower'])
     for row, link in enumerate(G.nodes):
         points = set('P{}'.format(n) for n, edge in edges_view(G)
                      if link in edge)
         if (drivers | followers) <= points:
             self.grounded_list.setCurrentRow(row)
             break
     #Driver, Follower, Target
     for expr in params['Expression'].split(';'):
         if strbefore(expr, '[') != 'PLAP':
             continue
         base = strbetween(expr, '[', ']').split(',')[0]
         self.__find_follower_to_remove(base)
         rotator = strbetween(expr, '(', ')')
         self.driver_list.addItem("({}, {})".format(base, rotator))
     self.__setWarning(self.driver_label, not self.driver_list.count())
     self.target_list.addItems(list(params['Target']))
     self.__setWarning(self.target_label, not self.target_list.count() > 0)
     #Constraints
     self.constraint_list.addItems(
         [", ".join(c) for c in params['constraint']])
     #Expression
     for expr in params['Expression'].split(';'):
         func = strbefore(expr, '[')
         target = strbetween(expr, '(', ')')
         params = strbetween(expr, '[', ']').split(',')
         params.insert(0, func)
         params.append(target)
         self.__addSolution(*params)
         self.PreviewWindow.setStatus(target, True)
     self.__setWarning(self.expression_list_label,
                       not self.PreviewWindow.isAllLock())
Exemplo n.º 10
0
def addPointsByGraph(self, G: Graph, pos: Dict[int, Tuple[float, float]],
                     ground_link: int):
    """Add points by networkx graph and position dict."""
    base_count = self.EntitiesPoint.rowCount()
    self.CommandStack.beginMacro(
        "Merge mechanism kit from {Number and Type Synthesis}")
    for i in range(len(pos)):
        self.addPoint(*pos[i])
    for link in G.nodes:
        self.addLink(
            _getLinkSerialNumber(self), 'Blue',
            [base_count + n for n, edge in edges_view(G) if (link in edge)])
        if link == ground_link:
            ground = self.EntitiesLink.rowCount() - 1
    self.CommandStack.endMacro()
    if ground_link is not None:
        self.constrainLink(ground)
Exemplo n.º 11
0
 def setGraph(self, G: Graph, pos: Dict[int, Tuple[float, float]]):
     """Set the graph to preview canvas."""
     self.clear()
     self.PreviewWindow.setGraph(G, pos)
     ev = dict(edges_view(G))
     joints_count = set()
     for l1, l2 in ev.values():
         joints_count.update({l1, l2})
     links = [[] for i in range(len(joints_count))]
     for joint, link in ev.items():
         for node in link:
             links[node].append(joint)
     for link in links:
         self.grounded_list.addItem("({})".format(", ".join(
             'P{}'.format(node) for node in link)))
     #Point name as (P1, P2, P3, ...).
     for node in pos:
         self.joint_name.addItem('P{}'.format(node))
Exemplo n.º 12
0
 def setGraph(self, graph: Graph, pos: Dict[int, Tuple[float, float]]):
     """Set the graph to preview canvas."""
     self.__clear_panel()
     self.PreviewWindow.setGraph(graph, pos)
     ev = dict(edges_view(graph))
     joints_count = set()
     for l1, l2 in ev.values():
         joints_count.update({l1, l2})
     links = []
     for i in range(len(joints_count)):
         links.append([])
     for joint, link in ev.items():
         for node in link:
             links[node].append(joint)
     for link in links:
         points_text = ", ".join(f'P{node}' for node in link)
         self.grounded_list.addItem(f"({points_text})")
     # Point name as (P1, P2, P3, ...).
     for node in pos:
         self.joint_name.addItem(f'P{node}')
Exemplo n.º 13
0
    def addPointsByGraph(self, graph: Graph, pos: Dict[int, Tuple[float,
                                                                  float]],
                         ground_link: Optional[int]):
        """Add points by NetworkX graph and position dict."""
        base_count = self.EntitiesPoint.rowCount()
        self.CommandStack.beginMacro(
            "Merge mechanism kit from {Number and Type Synthesis}")

        for i in range(len(pos)):
            x, y = pos[i]
            self.addPoint(x, y)

        ground: Optional[int] = None
        for link in graph.nodes:
            self.addLink(self.__get_link_serial_number(), 'Blue', [
                base_count + n for n, edge in edges_view(graph) if link in edge
            ])
            if link == ground_link:
                ground = self.EntitiesLink.rowCount() - 1
        self.CommandStack.endMacro()
        if ground_link is not None:
            self.constrainLink(ground)
Exemplo n.º 14
0
def _four_bar_loops(graph: Graph) -> Iterator[Tuple[int, int, int, int]]:
    """A generator to find out the four bar loops."""
    result = set()
    vertexes = {v: k for k, v in edges_view(graph)}

    def loop_set(n: int, n1: int, n2: int,
                 n3: int) -> Tuple[int, int, int, int]:
        """Return a loop set."""
        return (
            vertexes[tuple(sorted((n, n1)))],
            vertexes[tuple(sorted((n1, n2)))],
            vertexes[tuple(sorted((n2, n3)))],
            vertexes[tuple(sorted((n, n3)))],
        )

    for node in graph.nodes:
        if node in result:
            continue
        nb1s = graph.neighbors(node)
        # node not in nb1s
        for nb1 in nb1s:
            if nb1 in result:
                continue
            nb2s = graph.neighbors(nb1)
            # node can not in nb2s
            for nb2 in nb2s:
                if (nb2 == node) or (nb2 in result):
                    continue
                nb3s = graph.neighbors(nb2)
                # node can not in nb3s
                for nb3 in nb3s:
                    if (nb3 in (node, nb1)) or (nb3 in result):
                        continue
                    if node in graph.neighbors(nb3):
                        loop = [node, nb1, nb2, nb3]
                        result.update(loop)
                        yield loop_set(*loop)
Exemplo n.º 15
0
 def friends(self, node1: int, reliable: bool = False) -> int:
     """Return a generator yield the nodes
     that has solution on the same link.
     """
     #All edges of all nodes.
     edges = dict(edges_view(self.G))
     for n, l in self.cus.items():
         edges[int(n.replace('P', ''))] = (l, )
     #Reverse dict of 'self.same'.
     same_r = {v: k for k, v in self.same.items()}
     #for all link of node1.
     links1 = set(edges[node1])
     if node1 in same_r:
         links1.update(edges[same_r[node1]])
     #for all link.
     for node2 in edges:
         if (node1 == node2) or (node2 in self.same):
             continue
         links2 = set(edges[node2])
         if node2 in same_r:
             links2.update(edges[same_r[node2]])
         #Reference by intersection and status.
         if (links1 & links2) and (not self.getStatus(node2) != reliable):
             yield node2