Beispiel #1
0
        /// <summary>
        /// Remember to check for con.IsConnected!
        /// </summary>
        /// <param name="con">Connector for which to get the correspoinding ref con.</param>
        /// <param name="elem">The host element of the original connector.</param>
        /// <returns>The corresponding reference connector.</returns>
        public static Connector GetRefConnnector(this Connector con, Element elem)
        {
            var allRefsNotFiltered = MepUtils.GetAllConnectorsFromConnectorSet(con.AllRefs);
            var correspondingCon   = allRefsNotFiltered
                                     .Where(x => x.Domain == Domain.DomainPiping)
                                     .Where(x => x.Owner.Id.IntegerValue != elem.Id.IntegerValue).FirstOrDefault();

            return(correspondingCon);
        }
Beispiel #2
0
        internal static XYZ OletP1Point(Cons cons)
        {
            XYZ endPointOriginOletPrimary   = cons.Primary.Origin;
            XYZ endPointOriginOletSecondary = cons.Secondary.Origin;

            //get reference elements
            var refCons = MepUtils.GetAllConnectorsFromConnectorSet(cons.Primary.AllRefs);

            Connector refCon = refCons.Where(x => x.Owner.IsType <Pipe>()).FirstOrDefault();

            if (refCon == null)
            {
                throw new Exception("refCon Owner cannot find a Pipe for element!");
            }
            Pipe refPipe = (Pipe)refCon.Owner;

            Cons refPipeCons = Shared.MepUtils.GetConnectors(refPipe);

            //Following code is ported from my python solution in Dynamo.
            //The olet geometry is analyzed with congruent rectangles to find the connection point on the pipe even for angled olets.
            XYZ    B = endPointOriginOletPrimary; XYZ D = endPointOriginOletSecondary; XYZ pipeEnd1 = refPipeCons.Primary.Origin; XYZ pipeEnd2 = refPipeCons.Secondary.Origin;
            XYZ    BDvector = D - B; XYZ ABvector = pipeEnd1 - pipeEnd2;
            double angle = Conversion.RadianToDegree(ABvector.AngleTo(BDvector));

            if (angle > 90)
            {
                ABvector = -ABvector;
                angle    = Conversion.RadianToDegree(ABvector.AngleTo(BDvector));
            }
            Line   refsLine = Line.CreateBound(pipeEnd1, pipeEnd2);
            XYZ    C        = refsLine.Project(B).XYZPoint;
            double L3       = B.DistanceTo(C);
            XYZ    E        = refsLine.Project(D).XYZPoint;
            double L4       = D.DistanceTo(E);
            double ratio    = L4 / L3;
            double L1       = E.DistanceTo(C);
            double L5       = L1 / (ratio - 1);
            XYZ    A;

            if (angle < 89)
            {
                XYZ ECvector = C - E;
                ECvector = ECvector.Normalize();
                double L = L1 + L5;
                ECvector = ECvector.Multiply(L);
                A        = E.Add(ECvector);
            }
            else
            {
                A = E;
            }
            return(A);
        }
Beispiel #3
0
        public static int OletRefOwnerIdAsInt(this Element e)
        {
            var       cons    = MepUtils.GetConnectors(e);
            var       refCons = MepUtils.GetAllConnectorsFromConnectorSet(cons.Primary.AllRefs);
            Connector refCon  = refCons.Where(x => x.Owner.IsType <Pipe>()).FirstOrDefault();

            if (refCon == null)
            {
                throw new Exception("Olet id " + e.Id.ToString() + " has no reference connector! Check connectivity.");
            }
            Element owner = refCon.Owner;

            return(owner.Id.IntegerValue);
        }
Beispiel #4
0
        public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
        {
            UIApplication uiApp = commandData.Application;
            Document      doc   = commandData.Application.ActiveUIDocument.Document;
            UIDocument    uidoc = uiApp.ActiveUIDocument;

            try
            {
                using (Transaction tx = new Transaction(doc))
                {
                    var allAccessories = fi.GetElements <Element, BuiltInCategory>(doc, BuiltInCategory.OST_PipeAccessory);

                    tx.Start("Populate tilkoblet");
                    foreach (var el in allAccessories)
                    {
                        Cons cons = new Cons(el);

                        Connector firstSideCon = cons.Primary; Connector secondSideCon = cons.Secondary;

                        Connector refFirstCon = null; Connector refSecondCon = null;

                        if (firstSideCon != null && firstSideCon.IsConnected)
                        {
                            var refFirstCons = MepUtils.GetAllConnectorsFromConnectorSet(firstSideCon.AllRefs);
                            refFirstCon = refFirstCons.FirstOrDefault();
                        }
                        else if (firstSideCon != null)
                        {
                            refFirstCon = DetectUnconnectedConnector(doc, firstSideCon);
                        }

                        if (secondSideCon != null && secondSideCon.IsConnected)
                        {
                            var refSecondCons = MepUtils.GetAllConnectorsFromConnectorSet(secondSideCon.AllRefs);
                            refSecondCon = refSecondCons.FirstOrDefault();
                        }
                        else if (secondSideCon != null)
                        {
                            refSecondCon = DetectUnconnectedConnector(doc, secondSideCon);
                        }

                        Element firstSideOwner = null; Element secondSideOwner = null;
                        string  commentsContent    = string.Empty;
                        string  firstSideComments  = string.Empty;
                        string  secondSideComments = string.Empty;

                        if (refFirstCon != null)
                        {
                            firstSideOwner = refFirstCon.Owner;
                            Parameter tag1par = firstSideOwner.LookupParameter("TAG 1");
                            if (tag1par != null)
                            {
                                string tag1 = firstSideOwner.LookupParameter("TAG 1").AsString();
                                string tag2 = firstSideOwner.LookupParameter("TAG 2").AsString();
                                string tag3 = firstSideOwner.LookupParameter("TAG 3").AsString();
                                string tag4 = firstSideOwner.LookupParameter("TAG 4").AsString();

                                firstSideComments = string.Empty;

                                if (!string.IsNullOrEmpty(tag1))
                                {
                                    firstSideComments += tag1;
                                }
                                if (!string.IsNullOrEmpty(tag2))
                                {
                                    firstSideComments += "_" + tag2;
                                }
                                if (!string.IsNullOrEmpty(tag3))
                                {
                                    firstSideComments += "_" + tag3;
                                }
                                if (!string.IsNullOrEmpty(tag4))
                                {
                                    firstSideComments += "_" + tag4;
                                }
                            }
                        }
                        if (refSecondCon != null)
                        {
                            secondSideOwner = refSecondCon.Owner;
                            Parameter tag1par = secondSideOwner.LookupParameter("TAG 1");
                            if (tag1par != null)
                            {
                                string tag1 = secondSideOwner.LookupParameter("TAG 1").AsString();
                                string tag2 = secondSideOwner.LookupParameter("TAG 2").AsString();
                                string tag3 = secondSideOwner.LookupParameter("TAG 3").AsString();
                                string tag4 = secondSideOwner.LookupParameter("TAG 4").AsString();

                                secondSideComments = string.Empty;

                                if (!string.IsNullOrEmpty(tag1))
                                {
                                    secondSideComments += tag1;
                                }
                                if (!string.IsNullOrEmpty(tag2))
                                {
                                    secondSideComments += "_" + tag2;
                                }
                                if (!string.IsNullOrEmpty(tag3))
                                {
                                    secondSideComments += "_" + tag3;
                                }
                                if (!string.IsNullOrEmpty(tag4))
                                {
                                    secondSideComments += "_" + tag4;
                                }
                            }
                        }

                        if (string.IsNullOrEmpty(firstSideComments) && string.IsNullOrEmpty(secondSideComments))
                        {
                            continue;
                        }
                        else if (string.IsNullOrEmpty(firstSideComments) || string.IsNullOrEmpty(secondSideComments))
                        {
                            if (!string.IsNullOrEmpty(firstSideComments))
                            {
                                commentsContent = firstSideComments;
                            }
                            else if (!string.IsNullOrEmpty(secondSideComments))
                            {
                                commentsContent = secondSideComments;
                            }
                        }
                        else
                        {
                            commentsContent = $"{firstSideComments}; {secondSideComments}";
                        }

                        Parameter comments = el.get_Parameter(BuiltInParameter.ALL_MODEL_INSTANCE_COMMENTS);
                        comments.Set(commentsContent);
                    }

                    tx.Commit();
                    return(Result.Succeeded);
                }
            }

            catch (Autodesk.Revit.Exceptions.OperationCanceledException) { return(Result.Cancelled); }

            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
        }
Beispiel #5
0
        public static StringBuilder DetectAndWriteEndsAndConnections(
            string key, HashSet <Element> pipes, HashSet <Element> fittings, HashSet <Element> accessories, Document doc)
        {
            StringBuilder sb = new StringBuilder();

            HashSet <Element> all = new HashSet <Element>(pipes);

            all.UnionWith(fittings);
            all.UnionWith(accessories);

            //Iterate over all elements and check their connected counterparts
            //If they satisfy certain conditions -> write end continuation property
            //Cases for connected connectors:
            //1) In different PipingSystem -> Pipeline continuation
            //1.1) If Selection and connector belongs to an element not in selection -> Pipeline continuation
            //2) Belongs to MechanicalEquipment -> Equipment continuation -> write tags
            //3) Free end -> Null connection

            foreach (Element elem in all)
            {
                HashSet <Connector> cons = new HashSet <Connector>();

                switch (elem)
                {
                case Pipe pipe:
                    var consPipe = new Cons(elem);
                    cons.Add(consPipe.Primary);
                    cons.Add(consPipe.Secondary);
                    break;

                case FamilyInstance fi:
                    cons = MepUtils.GetALLConnectorsFromElements(elem);
                    break;

                default:
                    continue;
                }

                foreach (Connector con in cons)
                {
                    //This if should also filter out free ends...
                    if (con.IsConnected)
                    {
                        var allRefsNotFiltered = MepUtils.GetAllConnectorsFromConnectorSet(con.AllRefs);
                        var correspondingCon   = allRefsNotFiltered
                                                 .Where(x => x.Domain == Domain.DomainPiping)
                                                 .Where(x => x.Owner.Id.IntegerValue != elem.Id.IntegerValue).FirstOrDefault();

                        //CASE: Free end -> Do nothing yet, for simplicity
                        //This also catches empty cons on multicons accessories
                        //Example: pressure take outs on filters.
                        if (correspondingCon == null)
                        {
                            continue;
                        }

                        //CASE: If selection is exported, continuation for elements not in selection
                        //Even if same pipeline
                        if (iv.ExportSelection)
                        {
                            bool inElementsList = !all.Any(x => x.Id.IntegerValue == correspondingCon.Owner.Id.IntegerValue);
                            //bool inDiscardedPipes = !discardedPipes.Any(x => x.Id.IntegerValue == correspondingCon.Owner.Id.IntegerValue);

                            if (inElementsList)// && inDiscardedPipes)
                            {
                                //CASE: Con belongs to MechanicalEquipment
                                if (correspondingCon.Owner.Category.Id.IntegerValue == (int)BuiltInCategory.OST_MechanicalEquipment)
                                {
                                    sb.AppendLine("END-CONNECTION-EQUIPMENT");
                                    sb.Append(PCF_Functions.EndWriter.WriteCO(correspondingCon.Origin));
                                    sb.Append(PCF_Functions.ParameterDataWriter
                                              .ParameterValue("CONNECTION-REFERENCE", new[] { "TAG 1", "TAG 2", "TAG 3", "TAG 4" }, correspondingCon.Owner));

                                    continue;
                                }
                                //CASE: Any other component
                                else
                                {
                                    sb.AppendLine("END-CONNECTION-PIPELINE");
                                    sb.Append(PCF_Functions.EndWriter.WriteCO(correspondingCon.Origin));
                                    sb.AppendLine("    PIPELINE-REFERENCE " + correspondingCon.MEPSystemAbbreviation(doc));

                                    continue;
                                }
                            }
                            //CASE: None of the above hit -> continue with loop execution
                            //To prevent from falling through to non selection cases.
                            continue;
                        }

                        //CASE: Con belongs to MechanicalEquipment
                        else if (correspondingCon.Owner.Category.Id.IntegerValue == (int)BuiltInCategory.OST_MechanicalEquipment)
                        {
                            sb.AppendLine("END-CONNECTION-EQUIPMENT");
                            sb.Append(PCF_Functions.EndWriter.WriteCO(correspondingCon.Origin));
                            sb.Append(PCF_Functions.ParameterDataWriter
                                      .ParameterValue("CONNECTION-REFERENCE", new[] { "TAG 1", "TAG 2", "TAG 3", "TAG 4" }, correspondingCon.Owner));

                            continue;
                        }
                        //CASE: If corrCon belongs to different Pipeline -> unconditional end
                        //MechanicalEquipment cons should belong to the same Piping System, else...
                        else if (correspondingCon.MEPSystemAbbreviation(doc) != key)
                        {
                            sb.AppendLine("END-CONNECTION-PIPELINE");
                            sb.Append(PCF_Functions.EndWriter.WriteCO(correspondingCon.Origin));
                            sb.AppendLine("    PIPELINE-REFERENCE " + correspondingCon.MEPSystemAbbreviation(doc));

                            continue;
                        }
                        //CASE: If corrCon belongs to EXISTING component
                        //Write PIPELINE-REFERENCE -> EXISTING
                        Element hostElement = correspondingCon.Owner;
                        //GUID is for PCF_ELEM_SPEC
                        Parameter existingParameter = hostElement.get_Parameter(new Guid("90be8246-25f7-487d-b352-554f810fcaa7"));
                        if (existingParameter.AsString() == "EXISTING")
                        {
                            sb.AppendLine("END-CONNECTION-PIPELINE");
                            sb.Append(PCF_Functions.EndWriter.WriteCO(correspondingCon.Origin));
                            sb.AppendLine("    PIPELINE-REFERENCE EKSISTERENDE");
                        }
                    }
                }
            }

            return(sb);
        }
Beispiel #6
0
        public static void ConnectTheConnectors(ExternalCommandData commandData)
        {
            try
            {
                bool ctrl = false;
                bool shft = false;
                if ((int)Keyboard.Modifiers == 2)
                {
                    ctrl = true;
                }
                if ((int)Keyboard.Modifiers == 4)
                {
                    shft = true;
                }

                var app       = commandData.Application;
                var uiDoc     = app.ActiveUIDocument;
                var doc       = uiDoc.Document;
                var selection = uiDoc.Selection.GetElementIds();

                //If no elements selected, connect ALL connectors to ALL connectors
                //Or if more than two -- connect to each other
                if ((selection.Count == 0 || selection.Count > 2) && !ctrl)
                {
                    //Argh! It seems Revit2019 doesn't break when connecting pipes at angle!!!
                    ////To filter out PCF_ELEM_EXCL set to true
                    ////Collecting pipes, fittings, accessories
                    ////Filtering out those with "true" value
                    ////The Guid below is for PCF_ELEM_EXCL
                    //var exclFilter = fi.ParameterValueGenericFilter(doc, 0, new Guid("CC8EC292-226C-4677-A32D-10B9736BFC1A"));

                    //FilteredElementCollector col1 = new FilteredElementCollector(doc);
                    //col1.WherePasses(
                    //        new LogicalOrFilter(
                    //            new List<ElementFilter>
                    //            {
                    //                new ElementCategoryFilter(BuiltInCategory.OST_PipeFitting),
                    //                new ElementCategoryFilter(BuiltInCategory.OST_PipeAccessory),
                    //                new ElementClassFilter(typeof (Pipe))
                    //            }));//.WherePasses(exclFilter);
                    //var col2 = mp.GetElementsOfBuiltInCategory(doc, BuiltInCategory.OST_MechanicalEquipment);

                    //HashSet<Element> elements = new HashSet<Element>();
                    //elements.UnionWith(col1);
                    //elements.UnionWith(col2);

                    //When selection is 0
                    IList <Connector> allConnectors;
                    if (selection.Count == 0)
                    {
                        allConnectors = mp.GetALLConnectorsInDocument(doc, true)
                                        .Where(c => !c.IsConnected)
                                        .ExceptWhere(c => c.MEPSystemAbbreviation(doc, true) == "ARGD")
                                        .ToList();
                    }
                    //Selection is more than 2
                    else
                    {
                        allConnectors = mp.GetALLConnectorsFromElements((from ElementId id in selection select doc.GetElement(id)).ToHashSet()).ToList();
                    }


                    //Employ reverse iteration to be able to modify the collection while iterating over it
                    for (int i = allConnectors.Count - 1; i > 0; i--)
                    {
                        if (allConnectors.Count < 2)
                        {
                            break;
                        }
                        Connector c1 = allConnectors[i];
                        allConnectors.RemoveAt(i);
                        if (c1.IsConnected)
                        {
                            continue;                 //Need: connectors connected in this loop are still in collection
                        }
                        Connector c2 = (from Connector c in allConnectors where c.Equalz(c1, Extensions._1mmTol) select c).FirstOrDefault();
                        try
                        {
                            if (c1?.Owner.Id.IntegerValue == c2?.Owner.Id.IntegerValue)
                            {
                                continue;
                            }
                            c2?.ConnectTo(c1);
                        }
                        catch (Exception)
                        {
                            throw new Exception($"Element {c1.Owner.Id.ToString()} is already connected to element {c2.Owner.Id.ToString()}");
                        }
                    }

                    return;
                }

                else if (selection.Count == 1 && shft)
                {
                    ElementId hangerId = selection.First();
                    Element   hanger   = doc.GetElement(hangerId);
                    Cons      cons     = new Cons(hanger);

                    var allConnectors = mp.GetALLConnectorsInDocument(doc).ToList();

                    var query = allConnectors.Where(c => c.Equalz(cons.Primary, Extensions._1mmTol)).Where(c => c.Owner.Id.IntegerValue != hanger.Id.IntegerValue).ToList();

                    //Disconnect connectors of the existing components if the hanger was moved in place
                    Connector con1 = query.FirstOrDefault();
                    if (con1 == null)
                    {
                        throw new Exception("Detection of existing con1 failed!");
                    }
                    Connector con2 = query.LastOrDefault();
                    if (con2 == null)
                    {
                        throw new Exception("Detection of existing con2 failed!");
                    }

                    if (con1.IsConnectedTo(con2))
                    {
                        con1.DisconnectFrom(con2);
                    }

                    //If the hanger was created by placing on element and thus auto connected -> disconnect both connectors
                    //Dunno if this is needed and placing by auto connect does orient the connectors correctly
                    //Until it is proven true, both connectors are disconnected
                    if (cons.Primary.IsConnected)
                    {
                        var refCons = cons.Primary.AllRefs;
                        var refCon  = MepUtils.GetAllConnectorsFromConnectorSet(refCons)
                                      .Where(c => c.Owner.IsType <Pipe>() || c.Owner.IsType <FamilyInstance>()).FirstOrDefault();
                        if (refCon != null)
                        {
                            cons.Primary.DisconnectFrom(refCon);
                        }
                    }
                    if (cons.Secondary.IsConnected)
                    {
                        var refCons = cons.Secondary.AllRefs;
                        var refCon  = MepUtils.GetAllConnectorsFromConnectorSet(refCons)
                                      .Where(c => c.Owner.IsType <Pipe>() || c.Owner.IsType <FamilyInstance>()).FirstOrDefault();
                        if (refCon != null)
                        {
                            cons.Primary.DisconnectFrom(refCon);
                        }
                    }
                    doc.Regenerate();

                    //Start connecting hanger connectors
                    //https://stackoverflow.com/questions/7572640/how-do-i-know-if-two-vectors-are-near-parallel
                    var       detectOpposite1 = query.Where(c => cons.Primary.CoordinateSystem.BasisZ.DotProduct(c.CoordinateSystem.BasisZ) < -1 + Extensions._epx);
                    Connector opposite1       = detectOpposite1.FirstOrDefault();
                    if (opposite1 == null)
                    {
                        throw new Exception("Opposite primary detection failed!");
                    }
                    cons.Primary.ConnectTo(opposite1);

                    var       detectOpposite2 = query.Where(c => cons.Secondary.CoordinateSystem.BasisZ.DotProduct(c.CoordinateSystem.BasisZ) < -1 + Extensions._epx);
                    Connector opposite2       = detectOpposite2.FirstOrDefault();
                    if (opposite2 == null)
                    {
                        throw new Exception("Opposite secondary detection failed!");
                    }
                    cons.Secondary.ConnectTo(opposite2);

                    return;
                }

                else if (selection.Count == 1 && !ctrl) //If one and no CTRL key, connect the element
                {
                    var elements          = new HashSet <Element>(from ElementId id in selection select doc.GetElement(id));
                    var elementConnectors = mp.GetALLConnectorsFromElements(elements);
                    var allConnectors     = mp.GetALLConnectorsInDocument(doc, true).Where(c => !c.IsConnected).ToList();

                    IList <Connector> list1 = new List <Connector>();
                    IList <Connector> list2 = new List <Connector>();

                    foreach (var c1 in elementConnectors)
                    {
                        foreach (var c2 in allConnectors)
                        {
                            if (c1.Id != c2.Id && !c1.IsConnected && c1.Equalz(c2, Extensions._1mmTol))
                            {
                                list1.Add(c1);
                                list2.Add(c2);
                            }
                        }
                    }

                    if (list1.Count == 0 && list2.Count == 0)
                    {
                        throw new Exception("No matches found! Check alignment!");
                    }

                    foreach (var(c1, c2) in list1.Zip(list2, (x, y) => (c1: x, c2: y)))
                    {
                        c1.ConnectTo(c2);
                    }

                    return;
                }

                else if ((selection.Count == 1 || selection.Count > 2) && ctrl) //If one and CTRL key is pressed, disconnect the element
                {
                    var elements          = new HashSet <Element>(from ElementId id in selection select doc.GetElement(id));
                    var elementConnectors = mp.GetALLConnectorsFromElements(elements);

                    foreach (Connector c1 in elementConnectors)
                    {
                        if (c1.IsConnected)
                        {
                            var set = c1.AllRefs;
                            foreach (Connector c2 in set)
                            {
                                if (c1.IsConnectedTo(c2))
                                {
                                    c1.DisconnectFrom(c2);
                                }
                            }
                        }
                    }

                    return;
                }

                //Connect or disconnect the connectors of selection
                //Only works on selection of two adjacent elements
                //That means only two connectors get connected to or disconnected from each other
                else if (selection.Count == 2)
                {
                    var elements   = new HashSet <Element>(from ElementId id in selection select doc.GetElement(id));
                    var connectors = mp.GetALLConnectorsFromElements(elements).ToList();

                    for (int i = connectors.Count - 1; i > 0; i--)
                    {
                        if (connectors.Count < 2)
                        {
                            throw new Exception("No eligible connectors found! Check alignment.");
                        }
                        Connector c1 = connectors[i];
                        connectors.RemoveAt(i);
                        Connector c2 = (from Connector c in connectors where c.Equalz(c1, Extensions._1mmTol) select c).FirstOrDefault();
                        if (c2 != null)
                        {
                            if (c1.Owner.Id.IntegerValue == c2.Owner.Id.IntegerValue)
                            {
                                continue;
                            }
                            if (c1.IsConnected)
                            {
                                c2.DisconnectFrom(c1);
                            }
                            else
                            {
                                c2.ConnectTo(c1);
                            }
                        }
                    }

                    return;
                }
                else
                {
                    throw new Exception("Not correct amount of elements selected for the command! Choose none, one or two!");
                }
            }
            catch (Exception e)
            {
                throw new Exception(e.Message);
            }
        }