오류메세지

Starting a transaction from an external application running outside of API context is not allowed

 

원인

1. 모든 Revit API 호출은 "API context" 내에서 수행되어야
2.
 다른 thread에서 API 액세스하는 경우
3. 이러한 현상은 Form 만들고 Button.onclick 이벤트로 API 호출할 자주 발생한다.

 

해결방법

IExternalEventHandler 을 통해 외부에서 event 발생되게한다.

 

방법1. IExternalEventHandler 생성
방법2.  Execute method 시행한다.
(Execute method Revit API context에서 실행됨)

방법3. ExternalEvent 생성(방금 생성된 event handler사용)
방법4. Revit API context에서 작업을 수행해야 경우, external event 공지하기( my_external_event.Raise() 이용)

 

오류 해결방법 참고사이트

https://stackoverflow.com/questions/31490990/starting-a-transaction-from-an-external-application-running-outside-of-api-conte

 

Starting a transaction from an external application running outside of API context is not allowed

Starting a transaction from an external application running outside of API context is not allowed. cannot start transaction.

stackoverflow.com

IExternalEventHandler 생성 참고사이트

https://thebuildingcoder.typepad.com/blog/2015/12/external-event-and-10-year-forum-anniversary.html

 

External Events and 10 Year Forum Anniversary

Ten years ago today, on December 9, 2005, Jim Quanci posted the first thread on the Revit API discussion forum. This was pointed out by Revitalizer, one of the forum's chief contributors. Thank you very much for this, Revitalizer, and thank you even more f

thebuildingcoder.typepad.com

 

반응형

1) 창(window) 이 떠있어도 Revit의 다른 기능을 사용하고 싶은 경우

* show를 사용하여 window를 띄울경우, window 에서 실행하는 작업이 Revit 에 영향을 주지 못하기 때문에 ExternalEventHandler로 이벤트를 사용해주어야한다.

 

window.Show()

Revit_Window window = new Revit_Window();
WindowInteropHelper wi = new WindowInteropHelper(window);
wi.Owner = Autodesk.Windows.ComponentManager.ApplicationWindow;
window.Show();

 

 

2) 창(window) 가 열리고 닫히기 전까지 Revit 의 다른 기능을 사용하지 못하고 싶은 경우

 

window.ShowDialog()

Revit_Window window = new Revit_Window();
WindowInteropHelper wi = new WindowInteropHelper(window);
wi.Owner = Autodesk.Windows.ComponentManager.ApplicationWindow;
window.ShowDialog();

 

 

 

 

 

 

 

반응형

 

[ 목표 ]

projec() 활용하여 교차하는 point 찾기

 

[ 방법 ]

XYZ tray2Direction = ((ray2.Location as LocationCurve).Curve as Line).Direction;
Xyz tray2Origin = ((tray2.Location as LocationCurve).Curve as Line).Origin;
Xyz tray3Origin = ((tray3.Location as LocationCurve).Curve as Line).Origin;
var projectLine = Line.CreateBound( tray2Origin + tray2Direction * 100, tray2Origin - tray2Direction * 100);
XYZ projectPoint = projectLine.Project (tray3Origin).XYZPoint;

 

반응형

[ 목표 ]

Revit api 를 활용하여 line 선택시 자동으로 Duct Cross Fitting 하기

 

[ 방법 ]

1) UIdocument 에서 선택한 modelLine을 가져온다.

2) line에 맞춰 Duct 생성한다.

3) Duct 끼리 Intersect 되는 부분이 connector와 일치할 경우

- 원하는 elbowfitting시킨다.

- Newelbowfitting 메소드 사용

3) Duct 끼리 Intersect 되는 부분이 connector와 일치하지 않을 경우

교차점을 기준으로 파이프 자른다.

- intersecNewCrossFitting 메소드 이용한다.

원하는 crosses Fitting 시킨다.

4) line 삭제한다.

 

        public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
        {
            App.m_App = commandData.Application;
            UIApplication uiapp = commandData.Application;
            UIDocument uidoc = uiapp.ActiveUIDocument;
            Autodesk.Revit.ApplicationServices.Application app = uiapp.Application;
            Document document = uidoc.Document;

            // 선택한 Line 가져오기
            List<Element> elementList = GetDuctLine(uidoc, document);
            CreateDuct(uidoc, document, elementList);

            return Result.Succeeded;
        }
        
                //선택한 개체를 필터링할 수 있는 인터페이스 구현(= An interface that provides the ability to filter objects during a selection operation)
        public class PlanarFacesSelectionFilter : ISelectionFilter
        {
            Document doc = null;
            public PlanarFacesSelectionFilter(Document document)
            {
                doc = document;
            }

            public bool AllowElement(Element elem)
            {
                return true;
            }

            public bool AllowReference(Reference reference, XYZ position)
            {
                if (doc.GetElement(reference).GetGeometryObjectFromReference(reference) is PlanarFace)
                { return true; }
                return false;
            }
        }
        
                public List<Element> GetDuctLine(UIDocument uidoc, Document document)
        {
            ISelectionFilter selectionFilter = new PlanarFacesSelectionFilter(document);
            List<Element> elementList = new List<Element>();
            if (MessageBox.Show("Duct 생성하시려면 line 을 선택 후 \n좌측 하단의 Finsh 버튼을 클릭해주세요", "Duct 생성확인", MessageBoxButton.YesNo) == MessageBoxResult.Yes)
            {
                IList<Reference> references = uidoc.Selection.PickObjects(ObjectType.Element, selectionFilter, "Select Multiple planar faces");
                foreach (Reference reference in references)
                {
                    Element element = uidoc.Document.GetElement(reference);
                    elementList.Add(element);
                }               
            }

            return elementList;
        }

 

        public void CreateDuct(UIDocument uidoc, Document document, List<Element> elementList)
        {
            // (1) Duct 생성하기

            // 1-1) Duct 생성에 필요한 속성 임의로 가져오기

            DuctType ductType = new FilteredElementCollector(document).OfClass(typeof(DuctType)).Cast<DuctType>().Where(a => a.FamilyName.Contains("Oval")).FirstOrDefault();
            Level level = new FilteredElementCollector(document).OfClass(typeof(Level)).First() as Level;
            List<ElementId> DuctSystemTypelst = new FilteredElementCollector(document).OfCategory(BuiltInCategory.OST_DuctSystem).ToElementIds().ToList();
            ElementId systemTypeId = DuctSystemTypelst.FirstOrDefault();

            // 1-2) 변수선언

            Duct newduct = null;
            XYZ start = null;
            XYZ end = null;
            XYZ splitpoint = null;
            // 1-3) geometryElements 생성하기

            List<Line> lines = new List<Line>();
            foreach (Element element in elementList)
            {
                GeometryElement geometry = element.get_Geometry(new Options());
                foreach (GeometryObject geometryObject in geometry)
                {
                    Line line = geometryObject as Line;
                    lines.Add(line);
                }

            }

            // 1-4) Transaction 시작

            Transaction trans = new Transaction(document);
            trans.Start("Create Duct");

            // 1-5) Duct 생성 후 리스트 담기

            List<Duct> ducts = new List<Duct>();
            List<Element> eleDuct = new List<Element>();

            foreach (Line line in lines)
            {
                start = line.GetEndPoint(0);
                end = line.GetEndPoint(1);

                newduct = Duct.Create(document, systemTypeId, ductType.Id, level.Id, start, end);
                ducts.Add(newduct);
                Element element = document.GetElement(newduct.Id as ElementId);
                eleDuct.Add(element);

                // 1-6) fitting 할 elbow 굵기에 맞게 duct 굴기 설정하기

                Parameter width = element.LookupParameter("Width");
                width.Set(10 * 0.2);
                Parameter height = element.LookupParameter("Height");
                height.Set(10 * 0.2);
            }

            // 1-6) transaction 안에서 duct fitting종류 설정했으므로 중간에 새로고침하여 값 적용되도록 하기
            document.Regenerate();

            // (2) Duct 연결시키기 ( NewElbowFitting 메소드 사용)
            for (int i = 0; i < ducts.Count(); i++)
            {

                // 교차점이 있는지 확인하기
                int num = 0;
                List<int> numlist = new List<int>();
                IntersectionResultArray result = null;
                List<IntersectionResultArray> results = new List<IntersectionResultArray>();

                for (int j = i + 1; j < lines.Count; j++)
                {
                    Line line1 = lines[i];
                    Line line2 = lines[j];

                    line1.Intersect(line2, out result);
                    if (result != null)
                    {
                        results.Add(result);
                        num = j;
                        numlist.Add(num);
                        result = null;
                    }
                }

                if (results != null)
                {
                    for (int k = 0; k < results.Count; k++)
                    {
                        IntersectionResult iResult = results[k].get_Item(0);
                        XYZ IntersectPoint = iResult.XYZPoint;

                        // 2-2) 연결시킬 덕트 connector 가져오기위해 connectmanager로 connectors 뽑아내기
                        ConnectorManager duct_connectorManager1 = ducts[i].ConnectorManager;
                        ConnectorSet duct_connectorSet1 = duct_connectorManager1.Connectors;
                        //ConnectorManager duct_connectorManager2 = ducts[i + 1].ConnectorManager;
                        ConnectorManager duct_connectorManager2 = ducts[numlist[k]].ConnectorManager;
                        ConnectorSet duct_connectorSet2 = duct_connectorManager2.Connectors;

                        // 2-3) duct 가 가지고 있는 connector 중에서 가장 가까운 connector 뽑아내기
                        Connector connector1 = null;
                        Connector connector2 = null;
                        double minDist = double.MaxValue;
                        bool iscross = false;

                        foreach (Connector conn1 in duct_connectorSet1)
                        {
                            foreach (Connector conn2 in duct_connectorSet2)
                            {
                                double distance = conn1.Origin.DistanceTo(conn2.Origin);
                                if (distance < minDist)
                                {
                                    connector1 = conn1;
                                    connector2 = conn2;
                                    minDist = distance;
                                }
                            }
                        }

                        // 2-4) crossfitting 여부확인을 위해, 교차점이 있는지 & 교차점이 connector 와 일치하는지 확인
                        if (connector1.Origin.DistanceTo(IntersectPoint) > 0.001)
                        {
                            iscross = true;
                        }

                        // (3) 파이프끼리 크로스되지 않고 연결되있을때
                        if (iscross == false)
                        {
                            try
                            {
                                // 3-1) Duct 연결할 elbow Type 지정하기
                                ElementType elementType = new FilteredElementCollector(document).OfCategory(BuiltInCategory.OST_DuctFitting).OfClass(typeof(ElementType)).Cast<ElementType>().Where(x => x.FamilyName.Equals("M_Oval Elbow - Gored")).FirstOrDefault();
                                RoutingPreferenceManager rpm = newduct.DuctType.RoutingPreferenceManager;
                                rpm.AddRule(RoutingPreferenceRuleGroupType.Elbows, new RoutingPreferenceRule(elementType.Id, "Duct Fitting"));
                                int routingPerenceGroupCnt = rpm.GetNumberOfRules(RoutingPreferenceRuleGroupType.Elbows);
                                if (routingPerenceGroupCnt > 1)
                                {
                                    for (int t = 0; t < routingPerenceGroupCnt - 1; t++)
                                    {
                                        rpm.RemoveRule(RoutingPreferenceRuleGroupType.Elbows, 0);
                                    }
                                }

                                document.Create.NewElbowFitting(connector1, connector2);
                            }
                            catch (Exception ex)
                            {
                                if (ex.Message.Contains("them is too small or too large"))
                                {
                                    TaskDialog.Show("오류창", "Duct 간의 각도가 너무 크거나 작습니다.\n조정후다시 시도해주세요");
                                }
                                else
                                {
                                    TaskDialog.Show("오류창", "Duct fitting 에 실패했습니다.\n\n [ 자세한 오류 메세지 ] \n " + ex.Message);
                                }
                               
                            }
                        }

                        // (3)파이프끼리 크로스되어 있을때
                        else
                        {
                            // 3-1) 파이프 자르기
                            ElementId newDuctId1 = Autodesk.Revit.DB.Mechanical.MechanicalUtils.BreakCurve(document, ducts[i].Id, IntersectPoint);
                            ElementId newDuctId2 = Autodesk.Revit.DB.Mechanical.MechanicalUtils.BreakCurve(document, ducts[numlist[k]].Id, IntersectPoint);
                            Duct splitduct1 = document.GetElement(newDuctId1) as Duct;
                            Duct splitduct2 = document.GetElement(newDuctId2) as Duct;

                            document.Regenerate();
                            // 3-2) 연결시킬 덕트 connector 가져오기위해 connectmanager로 connectors 뽑아내기

                            ConnectorManager duct_connectorManager3 = splitduct1.ConnectorManager;
                            ConnectorSet duct_connectorSet3 = duct_connectorManager3.Connectors;
                            ConnectorManager duct_connectorManager4 = splitduct2.ConnectorManager;
                            ConnectorSet duct_connectorSet4 = duct_connectorManager4.Connectors;

                            //// 3-3) duct 가 가지고 있는 connector 중에서 가장 가까운 connector 뽑아내기
                            Connector connector3 = null;
                            Connector connector4 = null;

                            double minDist2 = double.MaxValue;
                            foreach (Connector conn3 in duct_connectorSet3)
                            {
                                foreach (Connector conn4 in duct_connectorSet4)
                                {
                                    double distance2 = conn3.Origin.DistanceTo(conn4.Origin);
                                    if (distance2 < minDist2)
                                    {
                                        connector3 = conn3;
                                        connector4 = conn4;
                                        minDist2 = distance2;
                                    }
                                }
                            }
                            // 3-4) duct 연결시키기
                            try
                            {
                                // 3-5) Duct 연결할 elbow Type 지정하기
                                ElementType elementType = new FilteredElementCollector(document).OfCategory(BuiltInCategory.OST_DuctFitting).OfClass(typeof(ElementType)).Cast<ElementType>().Where(x => x.FamilyName.Equals("M_Oval Cross - Straight")).FirstOrDefault();
                                RoutingPreferenceManager rpm = newduct.DuctType.RoutingPreferenceManager;
                                rpm.AddRule(RoutingPreferenceRuleGroupType.Crosses, new RoutingPreferenceRule(elementType.Id, "Duct Fitting"));
                                int routingPerenceGroupCnt = rpm.GetNumberOfRules(RoutingPreferenceRuleGroupType.Crosses);
                                if (routingPerenceGroupCnt > 1)
                                {
                                    for (int t = 0; t < routingPerenceGroupCnt - 1; t++)
                                    {
                                        rpm.RemoveRule(RoutingPreferenceRuleGroupType.Crosses, 0);
                                    }
                                }
                                
                                document.Create.NewCrossFitting(connector1, connector3, connector2, connector4);                               
                            }
                            catch (Exception ex)
                            {
                                if (ex.Message.Contains("them is too small or too large"))
                                {
                                    TaskDialog.Show("오류창", "Duct 간의 각도가 너무 크거나 작습니다.\n조정후다시 시도해주세요");
                                }
                                else
                                {
                                    TaskDialog.Show("오류창", "Duct fitting 에 실패했습니다.\n\n [ 자세한 오류 메세지 ] \n " + ex.Message);
                                }
                            }
                        }
                    }
                }
            }
            //// (4) duct 와 겹치는 line 삭제하기
            foreach (Element element in elementList)
            {
                ElementId elementId = element.Id;
                document.Delete(elementId);
            }
            trans.Commit();
        }

 

 

[ 주의할점 ]

1. Line 그리는 순서에 상관없이 fitting이 될 수 있도록 logic 구성해야한다.

2. Elbow fitting을 할지 creoss fitting을 할지는 connector와 일치하는지 방법 등등으로 확인하여 진행한다.

반응형

[ 목표 ]

Revit api 를 활용하여 line 선택시 교차점을 중심으로 line split 한 뒤 Duct 생성하기

 

[ 방법 ]

1)    Line 가져오기

2)    교차점을 중심으로 line 자르기

3)    Line 잘라졌는지 확인하기 위해 Detail Line 그리기 ( 선택사항 )

4)    파이프 생성

 

            ISelectionFilter selectionFilter = new PlanarFacesSelectionFilter(document);
            IList<Reference> references = uidoc.Selection.PickObjects(ObjectType.Element, selectionFilter, "Select Multiple planar faces");
            List<Element> elementList = new List<Element>();
            
            foreach (Reference reference in references)
                {
                    Element element = uidoc.Document.GetElement(reference);
                    elementList.Add(element);
                } 
                                             
            // 1-3) geometryElements 생성하기

            List<Line> lines = new List<Line>();
            foreach (Element element in elementList)
            {
                GeometryElement geometry = element.get_Geometry(new Options());
                foreach (GeometryObject geometryObject in geometry)
                {
                    Line line = geometryObject as Line;
                    lines.Add(line);
                }
            }

           // 교차점이 있는지 확인하기
            IntersectionResultArray results = null;
            Line line1 = lines[0];
            Line line2 = lines[1];
            line1.Intersect(line2, out results);
            IntersectionResult iResult = results.get_Item(0);
            var IntersectPoint = iResult.XYZPoint;

            if (IntersectPoint != null)
            {
                List<Line> splitLines = new List<Line>();
                DetailLine detailLine1 = null;
                DetailLine detailLine2 = null;
                // 교차점 기준으로 라인 자르기
                for (int i = 0; i < lines.Count; i++)
                {
                    Curve curve = lines[i];

                    double paraIntersection = curve.Project(IntersectPoint).Parameter;
                    double startpam = curve.GetEndParameter(0);
                    double endpam = curve.GetEndParameter(1);
                    Curve curve1 = curve.Clone();
                    Curve curve2 = curve.Clone();
                    curve1.MakeBound(startpam, paraIntersection);
                    curve2.MakeBound(paraIntersection, endpam);

                    splitLines.Add(curve1 as Line);
                    splitLines.Add(curve2 as Line);


                    // 평면도에서 교차점 기준으로 잘라낸 선분이 보일 수 있도록 DETAILLINE 생성하기 
                    detailLine1 = document.Create.NewDetailCurve(document.ActiveView, curve1) as DetailLine;
                    detailLine2 = document.Create.NewDetailCurve(document.ActiveView, curve2) as DetailLine;
                }

                lines.Clear();
                lines = splitLines;

            }

 

line split 전

 

line split 후

 

 

[ 주의할점 ]

1.     2개의 line 에 교차점이 존재할 경우, 교차점을 기준으로 Curve Class MakeBound를 이용하여 라인을 자른다. 이때, document 상에서는 4등분 된 line 이 보이지 않는다. 만약 document 상에서 split line을 확인하고 싶다면 detailline 혹은 modelline을 생성하여 제대로 잘라졌는지 확인하면된다.

2.     Datailline 을 그린 후 selection 할 시 3D 뷰에서는 선택되지 않는다. 따라서, level1과 같은 평면도에서 detail line을 선택해야한다.

반응형

[ 목표 ]

Revit api 를 활요하여 Duct 를 생성하고 Elbow를 이용하여 Duct Fitting 처리한다.

 

[ 방법 ] 

 

1) UIdocument 에서 선택한 modelLine을 가져온다.
2) line에 맞춰 Duct 생성한다. 
3) 생성된 Duct 끼리 elbow로 Fitting 시킨다.
4) line 삭제한다.

 

 public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
        {
            App.m_App = commandData.Application;
            UIApplication uiapp = commandData.Application;
            UIDocument uidoc = uiapp.ActiveUIDocument;
            Autodesk.Revit.ApplicationServices.Application app = uiapp.Application;
            Document document = uidoc.Document;

            // 선택한 Line 가져오기
            List<Element> elementList = GetDuctLine(uidoc, document);
            CreateDuct(uidoc, document, elementList);

            return Result.Succeeded;
        }

 

//선택한 개체를 필터링할 수 있는 인터페이스 구현(= An interface that provides the ability to filter objects during a selection operation)
        public class PlanarFacesSelectionFilter : ISelectionFilter
        {
            Document doc = null;
            public PlanarFacesSelectionFilter(Document document)
            {
                doc = document;
            }

            public bool AllowElement(Element elem)
            {
                return true;
            }

            public bool AllowReference(Reference reference, XYZ position)
            {
                if (doc.GetElement(reference).GetGeometryObjectFromReference(reference) is PlanarFace)
                { return true; }
                return false;
            }
        }

 

 public List<Element> GetDuctLine(UIDocument uidoc, Document document)
        {
            ISelectionFilter selectionFilter = new PlanarFacesSelectionFilter(document);
            IList<Reference> references = uidoc.Selection.PickObjects(ObjectType.Element, selectionFilter, "Select Multiple planar faces");
            List<Element> elementList = new List<Element>();

            foreach (Reference reference in references)
            {
                Element element = uidoc.Document.GetElement(reference);
                elementList.Add(element);
            }

            return elementList;
        }

 

 public void CreateDuct(UIDocument uidoc, Document document, List<Element> elementList)
        {
            // (1) Duct 생성하기

            // 1-1) Duct 생성에 필요한 속성 임의로 가져오기

            DuctType ductType = new FilteredElementCollector(document).OfClass(typeof(DuctType)).Cast<DuctType>().Where(a => a.FamilyName.Contains("Oval")).FirstOrDefault();
            Level level = new FilteredElementCollector(document).OfClass(typeof(Level)).First() as Level;
            List<ElementId> DuctSystemTypelst = new FilteredElementCollector(document).OfCategory(BuiltInCategory.OST_DuctSystem).ToElementIds().ToList();
            ElementId systemTypeId = DuctSystemTypelst.FirstOrDefault();

            // 1-2) 변수선언

            Duct newduct = null;
            XYZ start = null;
            XYZ end = null;

            // 1-3) geometryElements 생성하기

            List<GeometryElement> geometryElements = new List<GeometryElement>();

            foreach (Element element in elementList)
            {
                GeometryElement geometry = element.get_Geometry(new Options());
                geometryElements.Add(geometry);
            }

            // 1-4) Transaction 시작

            Transaction trans = new Transaction(document);
            trans.Start("Create Duct");

            // 1-5) Duct 생성 후 리스트 담기

            List<Line> lines = new List<Line>();
            List<Duct> ducts = new List<Duct>();
            List<Element> eleDuct = new List<Element>();
            foreach (GeometryElement geometry in geometryElements)
            {
                foreach (GeometryObject geometryObject in geometry)
                {
                    Line line = geometryObject as Line;
                    lines.Add(line);

                    start = line.GetEndPoint(0);
                    end = line.GetEndPoint(1);

                    newduct = Duct.Create(document, systemTypeId, ductType.Id, level.Id, start, end);
                    ducts.Add(newduct);
                    Element element = document.GetElement(newduct.Id as ElementId);
                    eleDuct.Add(element);

                    // 1-6) fitting 할 elbow 굵기에 맞게 duct 굴기 설정하기

                    Parameter width = element.LookupParameter("Width");
                    width.Set(10 * 0.09);
                    Parameter height = element.LookupParameter("Height");
                    height.Set(10 * 0.09);

                }
            }

            // 1-6) transaction 안에서 duct fitting종류 설정했으므로 중간에 새로고침하여 값 적용되도록 하기

            document.Regenerate();

            // (2) Duct 연결시키기 ( NewElbowFitting 메소드 사용)
                // 2-1) Duct 연결할 elbow Type 지정하기
                ElementType elementType = new FilteredElementCollector(document).OfCategory(BuiltInCategory.OST_DuctFitting).OfClass(typeof(ElementType)).Cast<ElementType>().Where(x => x.FamilyName.Equals("M_Oval Elbow - Gored")).FirstOrDefault();
                RoutingPreferenceManager rpm = newduct.DuctType.RoutingPreferenceManager;
                rpm.AddRule(RoutingPreferenceRuleGroupType.Elbows, new RoutingPreferenceRule(elementType.Id, "Duct Fitting"));
                int routingPerenceGroupCnt = rpm.GetNumberOfRules(RoutingPreferenceRuleGroupType.Elbows);
                if (routingPerenceGroupCnt > 1)
                {
                    for (int k = 0; k < routingPerenceGroupCnt - 1; k++)
                    {
                        rpm.RemoveRule(RoutingPreferenceRuleGroupType.Elbows, 0);
                    }
                }

                // 2-2) 연결시킬 덕트 connector 가져오기위해 connectmanager로 connectors 뽑아내기
                for (int i = 0; i < ducts.Count() - 1; i++)
                {
                    ConnectorManager duct_connectorManager1 = ducts[i].ConnectorManager;
                    ConnectorSet duct_connectorSet1 = duct_connectorManager1.Connectors;
                    ConnectorManager duct_connectorManager2 = ducts[i + 1].ConnectorManager;
                    ConnectorSet duct_connectorSet2 = duct_connectorManager2.Connectors;

                    // 2-3) duct 가 가지고 있는 connector 중에서 가장 가까운 connector 뽑아내기
                    Connector connector1 = null;
                    Connector connector2 = null;
                    double minDist = double.MaxValue;

                    foreach (Connector conn1 in duct_connectorSet1)
                    {
                        foreach (Connector conn2 in duct_connectorSet2)
                        {
                            double distance = conn1.Origin.DistanceTo(conn2.Origin);
                            if (distance < minDist)
                            {
                                connector1 = conn1;
                                connector2 = conn2;
                                minDist = distance;
                            }
                        }
                    }
                    try
                    {
                        document.Create.NewElbowFitting(connector1, connector2);
                    }
                    catch (Exception ex)
                    {
                        TaskDialog.Show("오류창", "Duct fitting 에 실패했습니다.\n파이프간의 각도가 너무 크거나 작지 않은지 확인해 주세요\n\n [ 자세한 오류 메세지 ] \n " + ex.Message);
                        trans.RollBack();
                    }
                }

                // (3) duct 와 겹치는 line 삭제하기
                foreach (Element element in elementList)
                {
                    ElementId elementId = element.Id;
                    document.Delete(elementId);
                }
                trans.Commit();
        }

 

 [ 주의할점 ]

 

Revit api 를 활용하여 Duct Fitting을 할 경우 Duct 끼리 이어질 Elbow 의 기본값이 None 으로 지정된다.

따라서, Duct 생성후 Routing Preferences 에서 어떤 Elbow와 Fitting시킬 것인지 RoutingPreferenceManager api 를 이용하여 elbowType 을 지정해준다.

 

반응형

오류원인: 

 

ElbowFitting 할때 , Routing Preference의 Elbow 종류가 설정되어 있지 않다.

 

해결방법 : 

 

Element 의 Type Edit > Routing Preferences Edit 클릭 >  Elbow Group에서 원하는 Fitting 종류를 지정한다.

 

반응형

오류원인: 

 

CrossFitting 할때 , Routing Preference가 Cross에 설정되어 있지 않다.

 

해결방법 : 

 

Element 의 Type Edit > Routing Preferences Edit 클릭 > Cross Group에서 원하는 Fitting 종류를 지정한다.

 

 

반응형

+ Recent posts