| Правила | Регистрация | Пользователи | Поиск | Сообщения за день | Все разделы прочитаны |  Справка по форуму | Файлообменник |

Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > Как создать контуры по отрезкам

Как создать контуры по отрезкам

Ответ
Поиск в этой теме
Непрочитано 22.06.2016, 16:44
Как создать контуры по отрезкам
DEM
 
YngIngKllr
 
СПб
Регистрация: 29.03.2005
Сообщений: 12,968

Собсно по мотивам темы
Перевод формата STL в твердотельную геометрию (Rhino, Salome и другие программы)
Решено сделать программу, т.к. та сетка которая получалась в Salome, делалась довольно таки долго и с непредсказуемыми последствиями.
Файлы в Salome загружались очень долго и т.д.
В качестве программы в которой будет создаваться модель, принят FreeCad соответственно программирование будет на Python.
Сразу оговорюсь, Python принят в качестве языка программирования т.к. потом к нему собираемся через SWIG подключить библиотеку SCAD API на C++.
На данный момент столкнулся с задачкой которую в лоб решить не могу.
У меня есть список отрезков вот такого вида
Код:
[Выделить все]
1я плоскость ['6/41', '6/40', '4/35', '30/31', '5/36', '1/34', '4/30', '5/35', '32/33', '31/32', '33/34', '1/41', '37/38', '38/39', '36/37', '39/40']
2я плоскость
['19/86', '19/87', '102/103', '15/71', '15/70', '95/96', '85/86', '4/104', '3/29', '61/62', '82/83', '84/85', '83/84', '92/93', '65/66', '30/31', '3/101', '90/91', '72/73', '75/76', '71/72', '28/29', '22/99', '32/33', '54/55', '74/75', '24/99', '24/98', '22/100', '21/97', '79/80', '21/100', '73/74', '25/26', '76/77', '2/67', '10/101', '10/102', '59/60', '16/77', '16/78', '1/34', '13/56', '26/27', '1/54', '4/30', '18/82', '18/81', '14/96', '78/79', '103/104', '87/88', '57/58', '58/59', '2/25', '27/28', '88/89', '93/94', '11/66', '94/95', '69/70', '13/57', '55/56', '23/97', '17/80', '17/81', '23/98', '62/63', '20/92', '20/91', '68/69', '14/68', '60/61', '64/65', '11/67', '89/90', '33/34', '12/63', '12/64', '31/32']
3я плоскость
['10/52', '7/42', '10/53', '44/45', '43/44', '42/43', '45/46', '7/53', '48/49', '50/51', '8/47', '8/46', '9/48', '9/47', '51/52', '49/50']
Собсно надо получить списки замкнутых контуров с обходом точек по часовой стрелке....
Типа [19/87, 87/88, 88/89 (и т.д.)]

Координаты точек я так понимаю особо то и не потребуются....
Либо алгоритм нужен, либо код на Paython 2.7
Ну иль просто подсказка в какую сторону копать.....

Миниатюры
Нажмите на изображение для увеличения
Название: 0.jpg
Просмотров: 260
Размер:	161.1 Кб
ID:	172458  

Вложения
Тип файла: rar 0555.rar (8.7 Кб, 11 просмотров)

__________________
Работаю за еду.
Working for food.
Für Essen arbeiten.
العمل من أجل الغذاء
Працую за їжу.

Последний раз редактировалось DEM, 23.06.2016 в 12:09.
Просмотров: 6125
 
Непрочитано 23.06.2016, 11:27
#21
trir


 
Регистрация: 18.12.2010
Сообщений: 5,047


Цитата:
кратчайшее расстояние между вершинами
значит нет внутренних перемычек
если в цикле есть перемычка, то получаем два цикла, периметр которых < исходного
проблема выбрать нужный и избежать лишних действий
trir вне форума  
 
Автор темы   Непрочитано 23.06.2016, 11:33
#22
DEM

YngIngKllr
 
Регистрация: 29.03.2005
СПб
Сообщений: 12,968


Brandashmыg
Ты гнешь свою линию и всё...
Я говорю, что у меня гораздо быстрее сейчас все отрабатывается и безо всяких библиотек..
Сейчас делаю поиск пути по аналогу с графами, все это будет отрабатываться гораздо быстрее чем графические библиотеки.
У меня же не четырех угольники, у меня контур уже найден, его надо отсортировать по верштнам.
trir
В п. 3 должно получится 3 полигона....
Я сейчас взял за аналог работу с графами.
Обхожу смежные вершины.
Возможны и вот такие варианты(см рисунок)
Тогда надо создать 2 полигона....
Миниатюры
Нажмите на изображение для увеличения
Название: Безымянный.jpg
Просмотров: 14
Размер:	6.2 Кб
ID:	172499  
__________________
Работаю за еду.
Working for food.
Für Essen arbeiten.
العمل من أجل الغذاء
Працую за їжу.
DEM вне форума  
 
Непрочитано 23.06.2016, 11:35
#23
Brandashmыg


 
Регистрация: 15.10.2008
Ростов-на-Дону
Сообщений: 370
Отправить сообщение для Brandashmыg с помощью Skype™


Цитата:
Сообщение от DEM Посмотреть сообщение
Brandashmыg
Ты гнешь свою линию и всё...
Гну) Буду очень признателен, если покажете итоговый код для нахождения контура с помощью графов.
__________________
Archicad, Smath, VBA
Brandashmыg вне форума  
 
Автор темы   Непрочитано 23.06.2016, 11:38
#24
DEM

YngIngKllr
 
Регистрация: 29.03.2005
СПб
Сообщений: 12,968


Brandashmыg
Думаю сегодня получу....
__________________
Работаю за еду.
Working for food.
Für Essen arbeiten.
العمل من أجل الغذاء
Працую за їжу.
DEM вне форума  
 
Непрочитано 23.06.2016, 11:49
#25
trir


 
Регистрация: 18.12.2010
Сообщений: 5,047


Цитата:
В п. 3 должно получится 3 полигона....
это просто у тебя subdivision surface, а в общем случае их может быть сколько угодно, а может и не быть
trir вне форума  
 
Автор темы   Непрочитано 23.06.2016, 11:54
#26
DEM

YngIngKllr
 
Регистрация: 29.03.2005
СПб
Сообщений: 12,968


trir
Не замкнутых не будет.....
По крайней мере пока планирую так...


----- добавлено через ~2 ч. -----
У меня почему то с цифрами не срабатывает....
Ищу почему же.....
Код:
[Выделить все]
def find_all_paths(graph, start, end, path=[]):
    path = path + [start]
    if start == end:
        return [path]
    if not graph.has_key(start):
        return []

    paths = []
    for node in graph[start]:
        if node not in path:
            newpaths = find_all_paths(graph, node, end, path)
            for newpath in newpaths:
                paths.append(newpath)
    return paths


def find_path(graph, start, end, path=[]):
    path = path + [start]
    if start == end:
        return path
    if not graph.has_key(start):
        return None
    for node in graph[start]:
        if node not in path:
            newpath = find_path(graph, node, end, path)
            if newpath: return newpath
    return None
graf2={}
rr0=['6/41', '6/40', '4/35', '30/31', '5/36', '1/34', '4/30', '5/35', '32/33', '31/32', '33/34', '1/41', '37/38', '38/39', '36/37', '39/40']
rr=['19/86', '19/87', '102/103', '15/71', '15/70', '95/96', '85/86', '4/104', '3/29', '61/62', '82/83', '84/85', '83/84', '92/93', '65/66', '30/31', '3/101', '90/91', '72/73', '75/76', '71/72', '28/29', '22/99', '32/33', '54/55', '74/75', '24/99', '24/98', '22/100', '21/97', '79/80', '21/100', '73/74', '25/26', '76/77', '2/67', '10/101', '10/102', '59/60', '16/77', '16/78', '1/34', '13/56', '26/27', '1/54', '4/30', '18/82', '18/81', '14/96', '78/79', '103/104', '87/88', '57/58', '58/59', '2/25', '27/28', '88/89', '93/94', '11/66', '94/95', '69/70', '13/57', '55/56', '23/97', '17/80', '17/81', '23/98', '62/63', '20/92', '20/91', '68/69', '14/68', '60/61', '64/65', '11/67', '89/90', '33/34', '12/63', '12/64', '31/32']
for ff in rr:
    nnn = ff.split("/")
    if graf2.get(nnn[0])==None:
        graf2[nnn[0]]=[nnn[1]]
    else:
        graf2[nnn[0]] = graf2[nnn[0]]+[nnn[1]]
    if graf2.get(nnn[1]) == None:
        graf2[nnn[1]] = [nnn[0]]
    else:
        graf2[nnn[1]] = graf2[nnn[1]] + [nnn[0]]

print graf2
print find_all_paths(graf2, '24', '99')
__________________
Работаю за еду.
Working for food.
Für Essen arbeiten.
العمل من أجل الغذاء
Працую за їжу.

Последний раз редактировалось DEM, 23.06.2016 в 15:14.
DEM вне форума  
 
Непрочитано 23.06.2016, 16:31
#27
Brandashmыg


 
Регистрация: 15.10.2008
Ростов-на-Дону
Сообщений: 370
Отправить сообщение для Brandashmыg с помощью Skype™


Мой вариант. line = rezult[0].exterior - наружная граница.

Код:
[Выделить все]
import numpy as np
import shapely.geometry as sh
import shapely.ops as sho

class msh(object):
    def __init__(self, filename):
        self.__read_asf(filename)
    def __parse_string(self, string, start_string, end_string):
        out = string.split(start_string)[1].split(end_string)[0]
        out = out.strip().split("\n")[1:]
        return out
    def __get_index_node(self, node):
        """ 
        Индекс точки в массиве data по её номеру
        """
        index = int(np.where(self.nodes[:,[0]] == node)[0][0])
        return index
    def __get_index_element(self, element):
        """
        Индекс элемента в массиве data по его номеру
        """
        key = self.n_elements[element]
        index = int(np.where(self.elements[key][:,[0]] == element)[0][0])
        return key, index 
    def __get_coordinates_node(self,node):
        """
        Координаты точки по её номеру
        """
        index = self.__get_index_node(node)
        coordinates = self.nodes[index,1:]
        return coordinates
    def get_node(self,node):
        """
        Получить точку в виде объекта shapely
        """
        coordinates = self.__get_coordinates_node(node)
        return sh.Point(coordinates) 
    def get_list_element_by_type(self, type_element):
        element_list = []
        for element in self.elements[type_element]:
            element_list.append(element[0])    
        return element_list
    def get_element(self,element):
        """
        Полигон в виде объекта shapely по его номеру
        """
        key, index = self.__get_index_element(element)
        nodes = self.elements[key][index][3:]
        for i, node in enumerate(nodes):
            if i == 0:
                coordinates = self.__get_coordinates_node(node)
            else:
                coordinates = np.vstack((coordinates, self.__get_coordinates_node(node)))        
        if key == 1:
            elements = sh.LineString(coordinates)
        elif key == 2:
            elements = sh.Polygon(coordinates)
        elif key == 3:
            elements = sh.Polygon(coordinates)
        return elements
    def axis_surf(self, polygon):
        x = polygon.exterior.coords[0][0]
        y = polygon.exterior.coords[0][1]
        z = polygon.exterior.coords[0][2]
        xx = 1
        yy = 1
        zz = 1
        for coord in polygon.exterior.coords[1:]:
            if x != coord[0]:
                xx = 0
            if y != coord[1]:
                yy = 0
            if z != coord[2]:
                yy = 0
        if xx == 0:
            axis = 0
        elif yy == 0:
            axis = 1
        elif zz == 0:
            axis = 2
        return axis
    def __read_asf(self,filename):
        """
        Читает файл
        """
        msh = open(filename, 'r').read().split('$EndMeshFormat')[1]
        #Получаем два массива - с точками и элементами
        nodes_str = self.__parse_string(msh, '$Nodes', '$EndNodes')
        elements_str = self.__parse_string(msh, '$Elements', '$EndElements')
        
        #Создаём массив с точками
        self.nodes = np.fromstring(nodes_str[0], dtype=float, sep=' ')
        for node in nodes_str[1:]:
            a = np.fromstring(node, dtype=float, sep=' ')
            self.nodes =  np.vstack((self.nodes, a))
        #Теперь - элементы
        #Для каждого типа элемента пропишем количество вершин в словарь и рассортируем элементы по номеру
        self.elements = {1:2, 2:3, 3:4, 4:4, 5:8}
        #Итак далее, в примере только типы 1 и 3, на них пока и остановимся.
        self.n_elements = {} #словарь для быстрого поиска типа элемента по его номеру
        for i, element in enumerate(elements_str):
            a = np.fromstring(element, dtype=float, sep=' ')
            number_element = int(a[0]) 
            elm_type = int(a[1])
            self.n_elements[number_element] = elm_type
            if type(self.elements[elm_type]) == int:
               self.elements[elm_type] = a
            else:
                self.elements[elm_type] = np.vstack((self.elements[elm_type], a))
          
               
filename = "G://0555.msh"
test = msh(filename)
poly_list = test.get_list_element_by_type(3)
poly_x = []
for polygon in poly_list:
    poly = test.get_element(polygon)
    if test.axis_surf(poly) == 0:
        if poly.is_valid:
            poly_x.append(poly)
        else:
            print("err")
rezult = sho.cascaded_union(poly_x)
line = rezult[0].exterior


Причём решение честное - я не использовал элементы 1-го типа, предполагая, что они идёт по контуру. Только 3-го типа.
Миниатюры
Нажмите на изображение для увеличения
Название: figure_1-1.jpg
Просмотров: 31
Размер:	30.6 Кб
ID:	172519  
__________________
Archicad, Smath, VBA

Последний раз редактировалось Brandashmыg, 23.06.2016 в 17:53.
Brandashmыg вне форума  
 
Автор темы   Непрочитано 23.06.2016, 18:28
#28
DEM

YngIngKllr
 
Регистрация: 29.03.2005
СПб
Сообщений: 12,968


А на 20 тысячах элементов не зависнет?
__________________
Работаю за еду.
Working for food.
Für Essen arbeiten.
العمل من أجل الغذاء
Працую за їжу.
DEM вне форума  
 
Непрочитано 23.06.2016, 18:48
#29
Brandashmыg


 
Регистрация: 15.10.2008
Ростов-на-Дону
Сообщений: 370
Отправить сообщение для Brandashmыg с помощью Skype™


Давай файл - проверим)
__________________
Archicad, Smath, VBA
Brandashmыg вне форума  
 
Автор темы   Непрочитано 23.06.2016, 20:53
#30
DEM

YngIngKllr
 
Регистрация: 29.03.2005
СПб
Сообщений: 12,968


Brandashmыg
Так в СКАДе же сейчас любой файл можно сохранить в msh...
__________________
Работаю за еду.
Working for food.
Für Essen arbeiten.
العمل من أجل الغذاء
Працую за їжу.
DEM вне форума  
 
Автор темы   Непрочитано 24.06.2016, 09:42
#31
DEM

YngIngKllr
 
Регистрация: 29.03.2005
СПб
Сообщений: 12,968


Цитата:
Сообщение от Brandashmыg Посмотреть сообщение
Давай файл - проверим)
Ну вот, надо все контуры создать....
PS. Опять проблемы с shapely не получается поставить на Анаконду2 и на FreeCad.
Вложения
Тип файла: rar 02.rar (1.06 Мб, 9 просмотров)
__________________
Работаю за еду.
Working for food.
Für Essen arbeiten.
العمل من أجل الغذاء
Працую за їжу.
DEM вне форума  
Ответ
Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > Как создать контуры по отрезкам

Размещение рекламы
Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Revit: как создать сварной арматурный каркас? extraneous Revit 42 28.12.2016 05:52
Solidworks 2014. Как создать выпадающий список? voverrr SolidWorks 1 18.02.2016 16:27
Как в SCAD создать группу нагружений из загружений? МишаИнженер SCAD 1 21.08.2011 05:30
найти пустые контуры АлексЮстасу Программирование 4 26.02.2011 02:54