dwg.ru forum rss xml
| Правила | Регистрация | Пользователи | Поиск | Сообщения за день | Все разделы прочитаны |  Справка по форуму |

Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > Библиотека функций > Revit 2019. Делаем макрос для получения размеров пластин

Revit 2019. Делаем макрос для получения размеров пластин

Версия для печати
 
Ответ
Опции темы Поиск в этой теме
Непрочитано 23.04.2018, 19:41 1 |
Revit 2019. Делаем макрос для получения размеров пластин
YarUnderoaker
 
Негропроект, инженегр-конструктор
 
Черкассы
Регистрация: 16.02.2008
Сообщений: 720

YarUnderoaker вне форума Вставить имя

Как известно новый тип элементов в Revit 2019 - плистины, не имеет размеров кроме толщины.
Для того что-бы получить размеры минимального паралелепипеда в котрый вписана пластина надо имея солид пластины найти object oriented bounding box.
У меня пока не установлен Ревит 2019, поэтому желающим быстрее начать работать с новым функционалом предланаю код
Клас для получения OOBB

Код:
[Выделить все]
    class OOBB
    {
    	static XYZ Min(XYZ a, XYZ b)
    	{
    		double x, y, z;
    		if (a.X < b.X) { x = a.X; } else { x = b.X; }
    		if (a.Y < b.Y) { y = a.Y; } else { y = b.Y; }
    		if (a.Z < b.Z) { z = a.Z; } else { z = b.Z; }
    		return new XYZ(x, y, z);
    	}
    	
     	static XYZ Max(XYZ a, XYZ b)
    	{
    		double x, y, z;
    		if (a.X > b.X) { x = a.X; } else { x = b.X; }
    		if (a.Y > b.Y) { y = a.Y; } else { y = b.Y; }
    		if (a.Z > b.Z) { z = a.Z; } else { z = b.Z; }
    		return new XYZ(x, y, z);
    	}
     	
    	public static BoundingBoxXYZ GetOOBB(Element source)
    	{
			Autodesk.Revit.DB.Options options = new Options();
			GeometryElement geo = source.get_Geometry(options);        	
			if (geo == null) return null;
			
			IList<Solid> solids = new List<Solid>();
			foreach(GeometryObject obj in geo)
            {
            	Solid solid = obj as Solid;
            	if (solid != null) solids.Add(solid);
			}
			
			if (solids.Count == 0) return null;			
			
		    IList<XYZ> vertices = new List<XYZ>();
		    IList<PlanarFace> faces = new List<PlanarFace>();
		    
		    BoundingBoxXYZ AABB = new BoundingBoxXYZ();
				    
    		foreach(Solid sld in solids)
    		{
    			
    			foreach(Face face in sld.Faces)
    			{
    				// filter only planar faces
    				if (face is PlanarFace) { faces.Add(face as PlanarFace); }
    				
				    Mesh mesh = face.Triangulate();
				    
				    for (int i = 0; i < mesh.NumTriangles; i++)
				    {
				        MeshTriangle triangle = mesh.get_Triangle(i);
				        XYZ p = triangle.get_Vertex(0); vertices.Add(p);
				        XYZ q = triangle.get_Vertex(1); vertices.Add(q);
				        XYZ r = triangle.get_Vertex(2); vertices.Add(r);
				        
				        AABB.Min = Min(AABB.Min, p); AABB.Max = Max(AABB.Max, p);
				        AABB.Min = Min(AABB.Min, q); AABB.Max = Max(AABB.Max, q);
				        AABB.Min = Min(AABB.Min, r); AABB.Max = Max(AABB.Max, r);
				    }
    			}
    		}
    		
    		faces.OrderByDescending( f => f.Area );
    		
	
			BoundingBoxXYZ minBB = new BoundingBoxXYZ();
			
			int count = 0;
			XYZ sizes = AABB.Max - AABB.Min;
			double volume = sizes.X * sizes.Y * sizes.Z;
			bool lessAABB = false;
			
			foreach(Face face in faces)
			{
				// Some optimization
				if (count > 24) break;
				count++;
				
				Transform tf = face.ComputeDerivatives(new UV()).Inverse;
				
				BoundingBoxXYZ bb = new BoundingBoxXYZ();
				bb.Min = new XYZ(1e10, 1e10, 1e10);
				bb.Max = new XYZ(-1e10, -1e10, -1e10);
				
				foreach(XYZ v in vertices)
				{
					XYZ tv = tf.OfPoint(v);
					bb.Min = Min(bb.Min, tv); 
					bb.Max = Max(bb.Max, tv);
				}
				
				XYZ sizes_ = bb.Max - bb.Min;
				double volume_ = sizes_.X * sizes_.Y * sizes_.Z;
				
				if (volume_ < volume) 
				{
					volume = volume_;
					minBB = bb;
					lessAABB = true;
				}
			}
    	
			if (lessAABB) { return minBB; } else { return AABB; }
    	}
    }
Пример использования
Код:
[Выделить все]
        private XYZ GetSizes(BoundingBoxXYZ bb)
        {
                        double x = bb.Max.X - bb.Min.X;
 	 		double y = bb.Max.Y - bb.Min.Y;
 	 		double z = bb.Max.Z - bb.Min.Z;
 	 		double e;
 	 		if (z > y) { e = z; z = y; y = e;}
 	 		if (y > x) { e = y; y = x; x = e;}
 	 		if (z > y) { e = z; z = y; y = e;}
 	 		return new XYZ(x, y, z);
        }
//-----------------------------------------------------------------------------
        BoundingBoxXYZ bb = OOBB.GetOOBB( plate);
     
         XYZ sizes = GetSizes(bb);
         double thikness = Math.Round( UnitUtils.Convert(sizes.Z, DisplayUnitType.DUT_FEET_FRACTIONAL_INCHES, DisplayUnitType.DUT_MILLIMETERS) );
         double width = Math.Round( UnitUtils.Convert(sizes.Y, DisplayUnitType.DUT_FEET_FRACTIONAL_INCHES, DisplayUnitType.DUT_MILLIMETERS) );
         double length = Math.Round( UnitUtils.Convert(sizes.X, DisplayUnitType.DUT_FEET_FRACTIONAL_INCHES, DisplayUnitType.DUT_MILLIMETERS) );
Просмотров: 5037
 
Автор темы   Непрочитано 05.06.2018, 10:24
#41
YarUnderoaker

Негропроект, инженегр-конструктор
 
Регистрация: 16.02.2008
Черкассы
Сообщений: 720


С отдельными пластинами не входящими в узлы работает (в том же примере есть такие). Но может случиласть какая-то нестандартная ситуация, все эти узлы, чесно говоря, сделаны через одно место - кусок кода эдванс стила прикрутили к ревиту.
Давайте какой-нибудь файл для теста, попробую решить проблему.
YarUnderoaker вне форума вставить имя Обратить внимание модератора на это сообщение  
 
Непрочитано 05.06.2018, 11:18
#42
madragor


 
Регистрация: 06.07.2012
Сообщений: 54


https://drive.google.com/open?id=1AI...szjMI0QR9yvdlI - Ссылка на файл с Которым работал, уменьшил размер как мог, ниже 13,4 МБ так и не смог уменьшить, потому ссылка и на гугл драйв
https://drive.google.com/open?id=1a_...KDCvaHhPMh8oMb - Ссылка на мой измененный макрос.
madragor вне форума вставить имя Обратить внимание модератора на это сообщение  
 
Непрочитано 05.06.2018, 17:25
#43
madragor


 
Регистрация: 06.07.2012
Сообщений: 54


Хотел спросить про один забавный момент. В прикрепленных 2 картинки, узел в 3Д, и тот же узел в 2Д, на том что в 2Д почему то связи из трубы не обрезались по узлу крепления к фасонке. Это такой баг?
Нажмите на изображение для увеличения
Название: 3D.png
Просмотров: 33
Размер:	34.3 Кб
ID:	203138 Нажмите на изображение для увеличения
Название: 2D.png
Просмотров: 34
Размер:	28.7 Кб
ID:	203139
madragor вне форума вставить имя Обратить внимание модератора на это сообщение  
 
Непрочитано 05.06.2018, 21:16
#44
Nels

конструктор, строитель
 
Регистрация: 08.10.2006
Уфа
Сообщений: 417
Отправить сообщение для Nels с помощью ICQ


Возможно надо проверить линии (сплошную и пунктир) в семействе трубы. Их блокировку на торец 3д тела. Возможно линии привязаны к плоскости и не укоротились вслед за торцом трубы.
Nels вне форума вставить имя Обратить внимание модератора на это сообщение  
 
Автор темы   Непрочитано 05.06.2018, 23:20
#45
YarUnderoaker

Негропроект, инженегр-конструктор
 
Регистрация: 16.02.2008
Черкассы
Сообщений: 720


Тут ошибка в имени параметра pij.proxy.LookupParameter("Мрк.МаркаКонструкций").Set(pij.number.ToString());

Желательно взять в перехват ошибок

Код:
[Выделить все]
 
						try 
						{
							pij.proxy.LookupParameter("Мрк.МаркаКонструкции").Set(pij.number.ToString());
							continue;
						}
						catch (Exception)	
						{
							t.RollBack();
							MessageBox.Show("У пластин отсутсвует параметр Мрк.МаркаКонструкции");
							return;
						}
YarUnderoaker вне форума вставить имя Обратить внимание модератора на это сообщение  
 
Непрочитано 06.06.2018, 09:13
#46
madragor


 
Регистрация: 06.07.2012
Сообщений: 54


Цитата:
Сообщение от YarUnderoaker Посмотреть сообщение
Желательно взять в перехват ошибок
Вот с этого места по подробнее.
Я уже разобрался как добавить в этот макрос внесение целого числа в нужные мне параметры. Могли бы вы мне подсказать как можно назначить материал в нужном мне параметре?
Программирование начинает интересовать

Спасибо что нашли ошибку, все работает.

Последний раз редактировалось madragor, 06.06.2018 в 09:23.
madragor вне форума вставить имя Обратить внимание модератора на это сообщение  
 
Непрочитано 06.06.2018, 09:21
#47
madragor


 
Регистрация: 06.07.2012
Сообщений: 54


Цитата:
Сообщение от Nels Посмотреть сообщение
Возможно надо проверить линии (сплошную и пунктир) в семействе трубы. Их блокировку на торец 3д тела. Возможно линии привязаны к плоскости и не укоротились вслед за торцом трубы.
Не нашел таких данных. Единственное что может подходить это "модификаторы" в "Соединениях несущих конструкций" но они у меня включены. Да и есть на одном плане , где одна связь приходит нормально, а вторая так же заходит, прогоны не доходят до узла.

Нажмите на изображение для увеличения
Название: 2D.1.png
Просмотров: 11
Размер:	9.8 Кб
ID:	203160

Это все тот же узел только сделан из плана, и главная балка с связями просто под углом к плоскости вида.

Проблему обнаружил. В самом семействе были добавлены линии для отображения граней и скрытых граней. Они не обрезались узлом. Удалил все стало на свои места правда исчезли скрытые грани.

Последний раз редактировалось madragor, 06.06.2018 в 10:05.
madragor вне форума вставить имя Обратить внимание модератора на это сообщение  
 
Автор темы   Непрочитано 08.06.2018, 15:51
#48
YarUnderoaker

Негропроект, инженегр-конструктор
 
Регистрация: 16.02.2008
Черкассы
Сообщений: 720


Цитата:
Сообщение от madragor Посмотреть сообщение
Могли бы вы мне подсказать как можно назначить материал в нужном мне параметре?
Вот для примера код для изменения параметра типа материал
Код:
[Выделить все]
 
public void SetMaterialParam()
{
	RVTDocument doc = this.ActiveUIDocument.Document;
    FilteredElementCollector collector = new FilteredElementCollector(doc);
    IEnumerable<Material> collection = collector.OfClass(typeof(Material)).OfType<Material>();
    
    ICollection<ElementId> elementSet = this.ActiveUIDocument.Selection.GetElementIds();    

	using(RVTransaction t = new RVTransaction(doc))
	{		    
		t.Start("Set material");
			
        foreach(Material mtr in collection)
        {
        	if (string.Compare(mtr.Name, "Металл") == 0)
        	{
        		foreach(ElementId id in elementSet)
        		{
        			FamilyInstance fi = doc.GetElement(id) as FamilyInstance;
        			if (fi == null) continue;
        			
        			Parameter p = fi.get_Parameter(BuiltInParameter.STRUCTURAL_MATERIAL_PARAM);
        			if (p != null) { p.Set(mtr.Id); }
        		}
        		
        		t.Commit();
        		return;
        	}
        }
        
        t.RollBack();
    
	}

}
Описание в кратце - из всех материалов проекта выбираем с именем "Металл" и назначаем выбраным элементам если у них есть системный параметр "Материал конструкции"
YarUnderoaker вне форума вставить имя Обратить внимание модератора на это сообщение  
 
Непрочитано 11.06.2018, 14:41
#49
madragor


 
Регистрация: 06.07.2012
Сообщений: 54


Спасибо большое за помощь. Постараюсь разобраться .
madragor вне форума вставить имя Обратить внимание модератора на это сообщение  
Ответ
Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > Библиотека функций > Revit 2019. Делаем макрос для получения размеров пластин

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

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

Быстрый переход

Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Макрос VBA Excel для извлечения таблиц из линий, полилиний, текста из DWG файлов в Excel с помощью NanoCAD/AutoCAD JZY Готовые программы 8 14.07.2016 06:31
Использование Revit MEP для проектирования промышленных объектов. andr_g Revit 6 29.10.2015 20:59
Использование Revit Structure для конструирования мостов AlexYoung Revit 26 20.02.2012 20:21
Заменимость Revit Architecture Revit Structure'м cardinalus Revit 4 30.06.2011 10:58
Балки в Revit MEP. Revit и СПДС Минька Revit 1 25.04.2011 05:51

|| Главная || Каталог САПР || Тендеры || Публикации || Объявления || Биржа труда || Download || Галерея ||
|| Библиотека || Кунсткамера || Каталог предприятий || Контакты || Файлообменник || Блоги ||