<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Re: Splitting ducts correctly with unions in Revit API Forum</title>
    <link>https://forums.autodesk.com/t5/revit-api-forum/splitting-ducts-correctly-with-unions/m-p/10320395#M26018</link>
    <description>&lt;P&gt;I ended up asking the user for the length (with 10mm default value in nothing is provided by the user). Could not find a way to determine it programmatically. I went over a few active models in the company and the union fitting differs from project to project.&lt;/P&gt;</description>
    <pubDate>Tue, 18 May 2021 10:00:12 GMT</pubDate>
    <dc:creator>Andrej.Licanin</dc:creator>
    <dc:date>2021-05-18T10:00:12Z</dc:date>
    <item>
      <title>Splitting ducts correctly with unions</title>
      <link>https://forums.autodesk.com/t5/revit-api-forum/splitting-ducts-correctly-with-unions/m-p/10308012#M26016</link>
      <description>&lt;P&gt;Hello, I made a command that splits ducts into chunks of maximum lengths 1500mm and 300 mm.&lt;BR /&gt;The problem I am faced with is that breaking the curve makes a&amp;nbsp; new curve that has the&amp;nbsp; correct length but when I add a union fitting between 2 ducts, the fitting width "eats a bit" out of my 1500mm duct and turns it into 1497 mm or something. I know this is because the union fitting has its own physical width, I am unsure how to tackle compensating for this width. Seeing as there can be may different families of unions with different widths.&lt;/P&gt;&lt;P&gt;I hard coded a value that have in the test project and used it&amp;nbsp; to compensate&amp;nbsp; , but that wont be the case in all projects...&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Any ideas on how to resolve this issue without asking the user for the union width or hardcoding it?&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Here is my code for the entire command (its called with one duct selected).&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;LI-CODE lang="csharp"&gt; [Transaction(TransactionMode.Manual)]
    class DuctSplitter : IExternalCommand

    {
        public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
        {
            UIDocument uiDoc = commandData.Application.ActiveUIDocument;
            Document doc = uiDoc.Document;



            using (Transaction trans = new Transaction(doc, "Trans1"))
            {
                trans.Start();

                Split1DuctMutlipleTimes(uiDoc, doc);

                trans.Commit();
            }

            return Result.Succeeded;
        }


        private void Split1DuctMutlipleTimes(UIDocument uiDoc, Document doc)
        {
            ICollection&amp;lt;ElementId&amp;gt; selectedIds = uiDoc.Selection.GetElementIds();
            Element duct = doc.GetElement((selectedIds.ToList())[0]);
            Element newDuct = null;
            LocationCurve lCurve = duct.Location as LocationCurve;
            Curve curve = lCurve.Curve;


            double totalLength = curve.Length;
            //convert length to mm
            double realLen = UnitUtils.ConvertFromInternalUnits(totalLength, DisplayUnitType.DUT_MILLIMETERS);

            double minLen = 300;
            double maxLen = 1500;
            //need to acount for union fitting width
            double unionSize = 7;
            //double internalLength = UnitUtils.ConvertToInternalUnits(maxLen, DisplayUnitType.DUT_MILLIMETERS);

            //calculate the number of splits
            int numOfSplits = (int)Math.Truncate(realLen / maxLen);

            // the length of the final piece, if this is 0, then it still needs to reduce the number of splits because unions have their own lengths
            double finalPiece = realLen - maxLen * numOfSplits;
            bool needsFinalPiece = false;
            //compensate for possible outcomes for final piece
            double maxLenWithUnion = maxLen + unionSize / 2;
            double minLenWithUnion = minLen + unionSize / 2;

            if (finalPiece &amp;lt; minLenWithUnion)
            {
                numOfSplits -= 1;
                needsFinalPiece = true;
            }

            for (int i = 0; i &amp;lt; numOfSplits; i++)
            {
                newDuct = SplitDuct(uiDoc, doc, duct, maxLenWithUnion);
            }

            placeFinalPiece(uiDoc, doc, duct, minLenWithUnion, maxLen, finalPiece, needsFinalPiece);

        }

        private void placeFinalPiece(UIDocument uiDoc, Document doc, Element duct, double minLen, double maxLen, double finalPiece, bool needsFinalPiece)
        {
            if (needsFinalPiece)
            {
                double len = (duct.Location as LocationCurve).Curve.Length;
                double extLen = UnitUtils.ConvertFromInternalUnits(len, DisplayUnitType.DUT_MILLIMETERS);
                // to cover for case when finalpiece = 0
                if (extLen &amp;lt; maxLen) return;

                finalPiece = extLen - minLen;
                SplitDuct(uiDoc, doc, duct, finalPiece);
            }
            return;
        }

        Element  SplitDuct(UIDocument uiDoc, Document doc, Element duct, double splitLen)
        {
            // get curve
            LocationCurve lCurve = duct.Location as LocationCurve;
            Curve curve = lCurve.Curve;

            // get endpoins and a vector betwen them
            XYZ pt0 = curve.GetEndPoint(0);
            XYZ pt1 = curve.GetEndPoint(1);
            XYZ vec = pt1.Subtract(pt0).Normalize();

            double lenght = UnitUtils.ConvertToInternalUnits(splitLen, DisplayUnitType.DUT_MILLIMETERS);
            // scale normalized vector
            XYZ breakPt = pt0.Add(vec.Multiply(lenght));
            // make new duct and get it
            ElementId newDuctId = Autodesk.Revit.DB.Mechanical.MechanicalUtils.BreakCurve(doc, duct.Id, breakPt);
            Element newDuct = doc.GetElement(newDuctId);

            //create a union
            Connector con1 = (duct as Autodesk.Revit.DB.Mechanical.Duct).ConnectorManager.Lookup(0);
            Connector con2 = (newDuct as Autodesk.Revit.DB.Mechanical.Duct).ConnectorManager.Lookup(1);

            doc.Create.NewUnionFitting(con1, con2);

            return newDuct;
        }

    }&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Wed, 12 May 2021 12:12:54 GMT</pubDate>
      <guid>https://forums.autodesk.com/t5/revit-api-forum/splitting-ducts-correctly-with-unions/m-p/10308012#M26016</guid>
      <dc:creator>Andrej.Licanin</dc:creator>
      <dc:date>2021-05-12T12:12:54Z</dc:date>
    </item>
    <item>
      <title>Re: Splitting ducts correctly with unions</title>
      <link>https://forums.autodesk.com/t5/revit-api-forum/splitting-ducts-correctly-with-unions/m-p/10310438#M26017</link>
      <description>&lt;P&gt;It sounds to me as if the task is impossible to solve unless you can somehow determine in advance how much of the duct will be replaced by the fitting. For that, you need to know which fitting will be used, or at least how long it is. I would assume that can be determined from the Revit routing preferences, and ultimately by you yourself and the end user. So, this boils down to a different question: which union fitting type do the Revit routing preferences specify for your specific duct?&lt;/P&gt;</description>
      <pubDate>Thu, 13 May 2021 11:55:59 GMT</pubDate>
      <guid>https://forums.autodesk.com/t5/revit-api-forum/splitting-ducts-correctly-with-unions/m-p/10310438#M26017</guid>
      <dc:creator>jeremy_tammik</dc:creator>
      <dc:date>2021-05-13T11:55:59Z</dc:date>
    </item>
    <item>
      <title>Re: Splitting ducts correctly with unions</title>
      <link>https://forums.autodesk.com/t5/revit-api-forum/splitting-ducts-correctly-with-unions/m-p/10320395#M26018</link>
      <description>&lt;P&gt;I ended up asking the user for the length (with 10mm default value in nothing is provided by the user). Could not find a way to determine it programmatically. I went over a few active models in the company and the union fitting differs from project to project.&lt;/P&gt;</description>
      <pubDate>Tue, 18 May 2021 10:00:12 GMT</pubDate>
      <guid>https://forums.autodesk.com/t5/revit-api-forum/splitting-ducts-correctly-with-unions/m-p/10320395#M26018</guid>
      <dc:creator>Andrej.Licanin</dc:creator>
      <dc:date>2021-05-18T10:00:12Z</dc:date>
    </item>
    <item>
      <title>Re: Splitting ducts correctly with unions</title>
      <link>https://forums.autodesk.com/t5/revit-api-forum/splitting-ducts-correctly-with-unions/m-p/10320978#M26019</link>
      <description>&lt;P&gt;why can't you move Union after you create it?&lt;/P&gt;</description>
      <pubDate>Tue, 18 May 2021 14:24:57 GMT</pubDate>
      <guid>https://forums.autodesk.com/t5/revit-api-forum/splitting-ducts-correctly-with-unions/m-p/10320978#M26019</guid>
      <dc:creator>MarryTookMyCoffe</dc:creator>
      <dc:date>2021-05-18T14:24:57Z</dc:date>
    </item>
    <item>
      <title>Re: Splitting ducts correctly with unions</title>
      <link>https://forums.autodesk.com/t5/revit-api-forum/splitting-ducts-correctly-with-unions/m-p/10323303#M26020</link>
      <description>&lt;P&gt;ONE DOES NOT SIMPLY MOVE A DUCT UNI....or does it. &lt;span class="lia-unicode-emoji" title=":grinning_face_with_smiling_eyes:"&gt;😄&lt;/span&gt;&lt;BR /&gt;that was it, dont know why i didnt think of it. Thank you.&lt;BR /&gt;&lt;BR /&gt;Added this function after the creation of the union duct to move it.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;LI-CODE lang="csharp"&gt;       private void moveDuctUnion(Element newduct, Element ductUnion, XYZ vec, XYZ breakPt, XYZ pt0)
        {
            
            double newLength = (newduct.Location as LocationCurve).Curve.Length;
            // moving the duct with the length of the original duct lenght and the created one with the combined duct union
            XYZ newVec = pt0.Add(vec.Multiply(newLength)); // created duct vecotr
            XYZ offsetVector = breakPt - newVec;// original duct -current duct
            ElementTransformUtils.MoveElement(doc,ductUnion.Id, offsetVector);

        }&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Wed, 19 May 2021 11:45:45 GMT</pubDate>
      <guid>https://forums.autodesk.com/t5/revit-api-forum/splitting-ducts-correctly-with-unions/m-p/10323303#M26020</guid>
      <dc:creator>Andrej.Licanin</dc:creator>
      <dc:date>2021-05-19T11:45:45Z</dc:date>
    </item>
  </channel>
</rss>

