예제 #1
0
 def mergeResult(self, row: int, path: Sequence[Sequence[Tuple[float,
                                                               float]]]):
     """Merge result function of dimensional synthesis."""
     result = self.DimensionalSynthesis.mechanism_data(row)
     # exp_symbol = ['A', 'B', 'C', 'D', 'E']
     exp_symbol = []
     for exp in result['Link_expr'].split(';'):
         for name in str_between(exp, '[', ']').split(','):
             if name not in exp_symbol:
                 exp_symbol.append(name)
     self.CommandStack.beginMacro(
         "Merge mechanism kit from {Dimensional Synthesis}")
     tmp_dict = {}
     for tag in sorted(exp_symbol):
         tmp_dict[tag] = self.addPoint(
             result[tag][0],
             result[tag][1],
             color=("Dark-Orange" if tag in result['Target'] else 'Green'))
     for i, exp in enumerate(result['Link_expr'].split(';')):
         self.addNormalLink(
             tuple(tmp_dict[name]
                   for name in str_between(exp, '[', ']').split(',')))
         if i == 0:
             self.constrainLink(self.EntitiesLink.rowCount() - 1)
     self.CommandStack.endMacro()
     # Add the path.
     i = 0
     while f"Algorithm_{i}" in self.InputsWidget.pathData():
         i += 1
     self.InputsWidget.addPath(f"Algorithm_{i}", path)
     self.MainCanvas.zoomToFit()
예제 #2
0
 def __symbols(self) -> Set[str]:
     """Return all symbols."""
     expr_list = set()
     for expr in self.expr_show.text().split(';'):
         param_list = str_between(expr, '[', ']').split(',')
         param_list.append(str_between(expr, '(', ')'))
         expr_list.update(param_list)
     return expr_list
예제 #3
0
    def __init__(
        self,
        mechanism: Dict[str, Any],
        path: Sequence[Sequence[Tuple[float, float]]],
        parent: QWidget
    ):
        """Input link and path data."""
        super(_DynamicCanvas, self).__init__(parent)
        self.mechanism = mechanism
        self.Path.path = path
        self.target_path = self.mechanism['Target']
        self.__index = 0
        self.__interval = 1
        self.__path_count = max(len(path) for path in self.Path.path) - 1
        self.pos: List[Tuple[float, float]] = []

        # exp_symbol = {'P1', 'P2', 'P3', ...}
        exp_symbol = set()
        self.links = []
        for exp in self.mechanism['Link_expr'].split(';'):
            names = str_between(exp, '[', ']').split(',')
            self.links.append(tuple(names))
            for name in names:
                exp_symbol.add(name)
        self.exp_symbol = sorted(exp_symbol, key=lambda e: int(e.replace('P', '')))
        # Error
        self.error = False
        self.__no_error = 0
        # Timer start.
        self.__timer = QTimer(self)
        self.__timer.timeout.connect(self.__change_index)
        self.__timer.start(18)
예제 #4
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())
예제 #5
0
 def __pop_expr(self):
     """Remove the last solution."""
     count = self.expression_list.count()
     if not count:
         return
     expr = self.expression_list.item(count - 1).text()
     self.expression_list.takeItem(count - 1)
     self.PreviewWindow.setStatus(str_between(expr, '(', ')'), False)
     self.__set_parm_bind()
예제 #6
0
파일: io.py 프로젝트: se-forex/Pyslvs-PyQt5
 def outputTo(self, format_name: str, format_choose: List[str]) -> str:
     """Simple to support multiple format."""
     file_name, suffix = QFileDialog.getSaveFileName(
         self, f"Save to {format_name}...",
         self.env + '/' + self.DatabaseWidget.file_name.baseName(),
         ';;'.join(format_choose))
     if file_name:
         suffix = str_between(suffix, '(', ')').split('*')[-1]
         print(f"Format: {suffix}")
         if QFileInfo(file_name).completeSuffix() != suffix[1:]:
             file_name += suffix
         self.setLocate(QFileInfo(file_name).absolutePath())
     return file_name
예제 #7
0
 def __init__(
     self,
     mechanism: Dict[str, Any],
     path: Sequence[Sequence[Tuple[float, float]]],
     parent: QWidget
 ):
     """Show the information of results, and setup the preview canvas."""
     super(PreviewDialog, self).__init__(parent)
     self.setupUi(self)
     self.setWindowTitle(
         f"Preview: {mechanism['Algorithm']} "
         f"(max {mechanism['last_gen']} generations)"
     )
     self.setWindowFlags(self.windowFlags() | Qt.WindowMaximizeButtonHint)
     self.main_splitter.setSizes([800, 100])
     self.splitter.setSizes([100, 100, 100])
     preview_widget = _DynamicCanvas(mechanism, path, self)
     self.left_layout.insertWidget(0, preview_widget)
     # Basic information
     link_tags = []
     for expr in mechanism['Expression'].split(';'):
         for p in str_between(expr, '[', ']').split(','):
             if ('L' in p) and (p not in link_tags):
                 link_tags.append(p)
     self.basic_label.setText("\n".join([f"{tag}: {mechanism[tag]}" for tag in chain(
         ('Algorithm', 'time'),
         mechanism['Driver'],
         mechanism['Follower'],
         sorted(link_tags)
     )]))
     # Algorithm information
     if mechanism['interrupted'] == 'False':
         interrupt_icon = "task_completed.png"
     elif mechanism['interrupted'] == 'N/A':
         interrupt_icon = "question.png"
     else:
         interrupt_icon = "interrupted.png"
     text_list = [
         f"Max generation: {mechanism['last_gen']}",
         f"<img src=\":/icons/{interrupt_icon}\" width=\"15\"/>"
         f"Interrupted at: {mechanism['interrupted']}"
     ]
     for k, v in mechanism['settings'].items():
         text_list.append(f"{k}: {v}")
     text = "<br/>".join(text_list)
     self.algorithm_label.setText(f"<html><head/><body><p>{text}</p></body></html>")
     # Hardware information
     self.hardware_label.setText("\n".join([
         f"{tag}: {mechanism['hardware_info'][tag]}" for tag in ('os', 'memory', 'cpu')
     ]))
예제 #8
0
파일: io.py 프로젝트: se-forex/Pyslvs-PyQt5
 def inputFrom(self,
               format_name: str,
               format_choose: List[str],
               multiple: bool = False) -> str:
     """Get file name(s)."""
     args = (f"Open {format_name} file{'s' if multiple else ''}...",
             self.env, ';;'.join(format_choose))
     if multiple:
         file_name_s, suffix = QFileDialog.getOpenFileNames(self, *args)
     else:
         file_name_s, suffix = QFileDialog.getOpenFileName(self, *args)
     if file_name_s:
         suffix = str_between(suffix, '(', ')').split('*')[-1]
         print(f"Format: {suffix}")
         if type(file_name_s) == str:
             self.setLocate(QFileInfo(file_name_s).absolutePath())
         else:
             self.setLocate(QFileInfo(file_name_s[0]).absolutePath())
     return file_name_s
예제 #9
0
 def from_profile(self, params: Dict[str, Any]):
     """Simple load by dict object."""
     # Add customize joints.
     graph = Graph(params['Graph'])
     self.setGraph(graph, params['pos'])
     self.cus = params['cus']
     self.same = params['same']
     # Grounded setting.
     driver = set(params['Driver'])
     follower = set(params['Follower'])
     for row, link in enumerate(graph.nodes):
         points = set(f'P{n}' for n, edge in edges_view(graph) if link in edge)
         if (driver | follower) <= points:
             self.setGrounded(row)
             break
     # Expression
     if params['Expression']:
         for expr in params['Expression'].split(';'):
             self.setStatus(io.str_between(expr, '(', ')'), True)
     self.update()
예제 #10
0
 def __has_solution(self, index: Optional[int] = None):
     """Set buttons enable if there has solution."""
     if index is None:
         index = self.joint_name.currentIndex()
     if not index > -1:
         self.status_show.setText("N/A")
         self.PLAP_solution.setEnabled(False)
         self.PLLP_solution.setEnabled(False)
         return
     status = self.PreviewWindow.getStatus(index)
     if not status:
         status_str = "Not known."
     elif index in self.PreviewWindow.same:
         status_str = f"Same as P{self.PreviewWindow.same[index]}."
     else:
         status_str = "Grounded."
         for expr in list_texts(self.expression_list):
             if index == int(str_between(expr, '(', ')').replace('P', '')):
                 status_str = f"From {str_before(expr, '[')}."
     self.status_show.setText(status_str)
     self.PLAP_solution.setEnabled(not status)
     self.PLLP_solution.setEnabled(not status)
예제 #11
0
 def paintEvent(self, event):
     """Draw the structure."""
     width = self.width()
     height = self.height()
     if self.pos:
         x_right, x_left, y_top, y_bottom = self.__zoom_to_fit_limit()
         x_diff = x_left - x_right
         y_diff = y_top - y_bottom
         x_diff = x_diff if x_diff else 1
         y_diff = y_diff if y_diff else 1
         if width / x_diff < height / y_diff:
             factor = width / x_diff
         else:
             factor = height / y_diff
         self.zoom = factor * 0.95
         self.ox = width / 2 - (x_left + x_right) / 2 * self.zoom
         self.oy = height / 2 + (y_top + y_bottom) / 2 * self.zoom
     else:
         sq_w = 240
         self.zoom = (width / sq_w) if (width <= height) else (height / sq_w)
         self.ox = width / 2
         self.oy = height / 2
     super(PreviewCanvas, self).paintEvent(event)
     pen = QPen()
     pen.setWidth(self.joint_size)
     self.painter.setPen(pen)
     self.painter.setBrush(QBrush(QColor(226, 219, 190, 150)))
     # Links
     for link in self.G.nodes:
         if link == self.grounded:
             continue
         points = []
         # Points that is belong with the link.
         for num, edge in edges_view(self.G):
             if link in edge:
                 if num in self.same:
                     num = self.same[num]
                 x, y = self.pos[num]
                 points.append((x * self.zoom, y * -self.zoom))
         # Customize points.
         for name, link_ in self.cus.items():
             if link == link_:
                 x, y = self.pos[int(name.replace('P', ''))]
                 points.append((x * self.zoom, y * -self.zoom))
         self.painter.drawPolygon(*convex_hull(points, as_qpoint=True))
     # Nodes
     for node, (x, y) in self.pos.items():
         if node in self.same:
             continue
         x *= self.zoom
         y *= -self.zoom
         if node in (self.Driver, self.Target):
             if node == self.Driver:
                 pen.setColor(color_qt('Red'))
             elif node == self.Target:
                 pen.setColor(color_qt('Yellow'))
             self.painter.setPen(pen)
             self.painter.drawEllipse(QPointF(x, y), self.joint_size, self.joint_size)
         if self.getStatus(node):
             color = color_qt('Dark-Magenta')
         else:
             color = color_qt('Green')
         pen.setColor(color)
         self.painter.setPen(pen)
         self.painter.setBrush(QBrush(color))
         self.painter.drawEllipse(QPointF(x, y), self.joint_size, self.joint_size)
         pen.setColor(color_qt('Black'))
         self.painter.setPen(pen)
     # Solutions
     if self.showSolutions:
         solutions = self.get_solutions()
         if solutions:
             for expr in solutions.split(';'):
                 self.drawSolution(
                     io.str_before(expr, '['),
                     io.str_between(expr, '[', ']').split(','),
                     io.str_between(expr, '(', ')'),
                     self.pos
                 )
     # Text of node.
     pen.setColor(Qt.black)
     self.painter.setPen(pen)
     for node, (x, y) in self.pos.items():
         if node in self.same:
             continue
         x *= self.zoom
         x += 2 * self.joint_size
         y *= -self.zoom
         y -= 2 * self.joint_size
         self.painter.drawText(QPointF(x, y), f'P{node}')
     self.painter.end()