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

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

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

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

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) );
Просмотров: 8785
 
Автор темы   Непрочитано 05.06.2018, 10:24
#41
YarUnderoaker

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


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


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


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
Сообщений: 55


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

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


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

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


Тут ошибка в имени параметра 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
Сообщений: 55


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

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

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


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


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

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

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

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

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

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


Цитата:
Сообщение от 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
Сообщений: 55


Спасибо большое за помощь. Постараюсь разобраться .
madragor вне форума вставить имя Обратить внимание модератора на это сообщение  
 
Непрочитано 06.07.2018, 11:34
#50
Nels

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


Цитата:
Сообщение от madragor Посмотреть сообщение
Проблему обнаружил. В самом семействе были добавлены линии для отображения граней и скрытых граней. Они не обрезались узлом. Удалил все стало на свои места правда исчезли скрытые грани.
Я про эти линии и говорил. Только скорее всего их не стоило удалять, надо было только концы линий привязать к торцам 3D тела.
Nels вне форума вставить имя Обратить внимание модератора на это сообщение  
 
Непрочитано 06.07.2018, 11:59
#51
madragor


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


Они были привязаны к торцам. Проблему невидимых граней решил тем что пользуюсь командой "показать невидимые линии". Так что особых проблем не обнаружил, все невидимые грани отображаются, правда только на средней детализации.
madragor вне форума вставить имя Обратить внимание модератора на это сообщение  
 
Непрочитано 09.08.2018, 16:41
#52
m.Mitya


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


Добрый день! Масса отдельной пластины и в составе соединения макросом подсчитывается по разному(в составе соединения не верная). Это возможно исправить?
m.Mitya вне форума вставить имя Обратить внимание модератора на это сообщение  
 
Автор темы   Непрочитано 16.08.2018, 10:43
#53
YarUnderoaker

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


Можно, но надо понять почему так происходит.
Еще есть отдельная проблема - масса считается по объему, а в объеме учитываются отверстия.

....

В коде надо подправить одну константу, в строке

double vol = pl.Volume / (1000000 * 29.504);

заменить на

double vol = pl.Volume / (1000000 * 28.317);

----- добавлено через ~27 мин. -----
Обновил архив в посте 28.
Заменил константу и добавил проверку материала на наличие физических параметров.

Последний раз редактировалось YarUnderoaker, 16.08.2018 в 16:09. Причина: добавлено
YarUnderoaker вне форума вставить имя Обратить внимание модератора на это сообщение  
Ответ
Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > Библиотека функций > Revit 2019. Делаем макрос для получения размеров пластин

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

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

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

Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Макрос 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 || Галерея ||
|| Библиотека || Кунсткамера || Каталог предприятий || Контакты || Файлообменник || Блоги ||