From ea742b26d7d756321e2c9a95265961ac82e85df3 Mon Sep 17 00:00:00 2001 From: IDONTSUDO Date: Thu, 13 Jul 2023 19:55:18 +0000 Subject: [PATCH] =?UTF-8?q?=D0=90=D0=BB=D0=B3=D0=BE=D1=80=D0=B8=D1=82?= =?UTF-8?q?=D0=BC=20=D0=BF=D0=BE=D0=B8=D1=81=D0=BA=D0=B0=20=D0=B2=D1=81?= =?UTF-8?q?=D0=B5=D1=85=20=D0=BF=D0=BE=D1=81=D0=BB=D0=B5=D0=B4=D0=BE=D0=B2?= =?UTF-8?q?=D0=B0=D1=82=D0=B5=D0=BB=D1=8C=D0=BD=D0=BE=D1=81=D1=82=D0=B5?= =?UTF-8?q?=D0=B9=20=D0=BC=D0=B0=D1=82=D1=80=D0=B8=D1=86=D1=8B=20=D1=81?= =?UTF-8?q?=D0=BC=D0=B5=D0=B6=D0=BD=D0=BE=D1=81=D1=82=D0=B8=20=D1=87=D0=B5?= =?UTF-8?q?=D1=80=D0=B5=D0=B7=20Depth=20First=20Search=20(DFS)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- geometric_feasibility_predicate/env.json | 4 +- geometric_feasibility_predicate/main.py | 136 +++++++++++++++++++++-- 2 files changed, 126 insertions(+), 14 deletions(-) diff --git a/geometric_feasibility_predicate/env.json b/geometric_feasibility_predicate/env.json index 2375211..4bc2d96 100644 --- a/geometric_feasibility_predicate/env.json +++ b/geometric_feasibility_predicate/env.json @@ -1,4 +1,4 @@ { - "cadFilePath":"", - "outPath":"" + "cadFilePath":"/home/idontsudo/framework/geometric_feasibility_predicate/cubes.FCStd", + "outPath":"/home/idontsudo/framework/geometric_feasibility_predicate/out/" } \ No newline at end of file diff --git a/geometric_feasibility_predicate/main.py b/geometric_feasibility_predicate/main.py index f77dedf..7e717fa 100644 --- a/geometric_feasibility_predicate/main.py +++ b/geometric_feasibility_predicate/main.py @@ -1,11 +1,112 @@ -# Алгоритм генерации графа И/ИЛИ c помощью вычисления матрицы смежности import FreeCAD as App import uuid import os import json from typing import List, Dict, Any, TypeVar, Callable, Type, cast +from itertools import repeat + + +def isInListRange(listIn, index): + try: + listIn[index] + return False + except: + return True + + +class AllSequences: + all_sequences = None + adj_matrix = None + topologyIds = None + adj_matrix_names = None + + def __init__(self, adj_matrix) -> None: + self.adj_matrix = adj_matrix + self.all_possible_sequences(self.adj_matrix) + self.matrix_by_name() + pass + + def matrix_by_name(self): + result = self.all_sequences + inc = 0 + for matrix in self.all_sequences: + for index in range(len(matrix)): + result[inc][index] = list(filter(lambda el: el.get( + 'number') == matrix[index]+1, self.topologyIds))[0].get('name') + inc += 1 + self.adj_matrix_names = result + pass + + def find_all_sequences(self, adj_matrix): + sequences = [] + num_vertices = len(adj_matrix) + + def dfs(vertex, sequence): + sequence.append(vertex) + + if len(sequence) == num_vertices: + sequences.append(sequence) + return + + for i in range(num_vertices): + if adj_matrix[vertex][i] == 1 and i not in sequence: + dfs(i, sequence.copy()) + + for i in range(num_vertices): + dfs(i, []) + + self.all_sequences = sequences + + def findId(self, listMatrix, id): + def filter_odd_num(in_num): + if in_num['name'] == id: + return True + else: + return False + return list(filter(filter_odd_num, listMatrix))[0]['number'] + + def iter_paths(self, adj, min_length=6, path=None): + if not path: + for start_node in range(len(adj)): + yield from self.iter_paths(adj, min_length, [start_node]) + else: + if len(path) >= min_length: + yield path + if path[-1] in path[:-1]: + return + current_node = path[-1] + for next_node in range(len(adj[current_node])): + if adj[current_node][next_node] == 1: + yield from self.iter_paths(adj, min_length, path + [next_node]) + + def allUnique(self, x): + seen = set() + return not any(i in seen or seen.add(i) for i in x) + + def all_possible_sequences(self, matrix): + topologyIds = [] + topologyMatrixNumber = {} + inc = 0 + for k, v in matrix.items(): + inc += 1 + topologyIds.append({"name": k, "number": inc}) + inc = 0 + for k, v in matrix.items(): + inc += 1 + topologyMatrixNumber[inc] = list( + map(lambda el: self.findId(topologyIds, el), v)) + self.topologyIds = topologyIds + adj = [] + matrixSize = matrix.keys().__len__() + inc = 0 + for k, v in topologyMatrixNumber.items(): + adj.append(list(repeat(0, matrixSize))) + for el in v: + adj[inc][el-1] = 1 + inc += 1 + return self.find_all_sequences(adj) + -# вспомогательный класс для работы с FreeCad API class FreeCadRepository: _solids = [] @@ -59,8 +160,10 @@ def to_class(c: Type[T], x: Any) -> dict: return cast(Any, x).to_dict() # Вспомогательный класс который делает генрацию JSON на основе пайтон обьектов + + class AdjacencyMatrix: - matrixError: Dict[str,str] = {} + matrixError: Dict[str, str] = {} all_parts: List[str] first_detail: str matrix: Dict[str, List[str]] @@ -77,17 +180,19 @@ class AdjacencyMatrix: if el == self.first_detail: return i i = +1 + def validateMatrix(self): for el in self.all_parts: - if(self.matrix.get(el) == None): + if (self.matrix.get(el) == None): self.matrixError[el] = 'Not found adjacency ' + el + @staticmethod def from_dict(obj: Any) -> 'AdjacencyMatrix': assert isinstance(obj, dict) all_pars = from_list(from_str, obj.get("allPars")) first_detail = from_str(obj.get("firstDetail")) matrix = from_dict(lambda x: from_list(from_str, x), obj.get("matrix")) - + return AdjacencyMatrix(all_pars, first_detail, matrix) def to_dict(self) -> dict: @@ -96,7 +201,7 @@ class AdjacencyMatrix: result["firstDetail"] = from_str(self.first_detail) result["matrix"] = from_dict( lambda x: from_list(from_str, x), self.matrix) - if(self.matrixError.values().__len__() == 0): + if (self.matrixError.values().__len__() == 0): result['matrixError'] = None else: result['matrixError'] = self.matrixError @@ -120,7 +225,9 @@ def adjacency_matrix_from_dict(s: Any) -> AdjacencyMatrix: def adjacency_matrix_to_dict(x: AdjacencyMatrix) -> Any: return to_class(AdjacencyMatrix, x) -# Вспомогательный класс для работы с Freecad +# Вспомогательный класс для работы с Freecad + + class FreeCadMetaModel(object): def __init__(self, label, vertex) -> None: @@ -329,7 +436,8 @@ class CadAdjacencyMatrix: first_detail=GetFirstDetailUseCase().call(), matrix=matrix, ) - # Матрица основанная на соприкосновении обьектов + # Матрица основанная на соприкосновении обьектов + def matrixBySurfaces(self): matrix = {} for part in FreeCadRepository().getAllSolids(): @@ -347,6 +455,7 @@ class CadAdjacencyMatrix: matrix=matrix ) + def main(): env = FS.readJSON('env.json') cadFile = env['cadFilePath'] @@ -354,12 +463,15 @@ def main(): if (cadFile == None): return TypeError('CadFile not found env.json') App.open(u'' + cadFile) - + # Получение матрицы - matrixOut = CadAdjacencyMatrix().primitiveMatrix().to_dict() + topologyMatrix = CadAdjacencyMatrix().primitiveMatrix() import json - # Запись результата - FS.writeFile(json.dumps(matrixOut, ensure_ascii=False, indent=4), outPath,'out.json') + sequences = json.dumps({"sequences": AllSequences( + topologyMatrix.matrix).adj_matrix_names}, ensure_ascii=False, indent=4) + FS.writeFile(sequences, outPath, 'sequences.json') + FS.writeFile(json.dumps(topologyMatrix.to_dict(), + ensure_ascii=False, indent=4), outPath, 'adjacency_matrix.json') main()