public StringBuilder Export(string pipeLineGroupingKey, HashSet <Element> elements, Document doc)
        {
            var pipeList = elements;
            var sbPipes  = new StringBuilder();
            var key      = pipeLineGroupingKey;

            foreach (Element element in pipeList)
            {
                sbPipes.AppendLine(element.get_Parameter(new plst().PCF_ELEM_TYPE.Guid).AsString());
                sbPipes.AppendLine("    COMPONENT-IDENTIFIER " + element.get_Parameter(new plst().PCF_ELEM_COMPID.Guid).AsInteger());

                //Write Plant3DIso entries if turned on
                if (InputVars.ExportToPlant3DIso)
                {
                    sbPipes.Append(Composer.Plant3DIsoWriter(element, doc));
                }

                Pipe pipe = (Pipe)element;
                //Get connector set for the pipes
                ConnectorSet connectorSet = pipe.ConnectorManager.Connectors;
                //Filter out non-end types of connectors
                IList <Connector> connectorEnd = (from Connector connector in connectorSet
                                                  where connector.ConnectorType.ToString().Equals("End")
                                                  select connector).ToList();

                sbPipes.Append(EndWriter.WriteEP1(element, connectorEnd.First()));
                sbPipes.Append(EndWriter.WriteEP2(element, connectorEnd.Last()));

                Composer elemParameterComposer = new Composer();
                sbPipes.Append(elemParameterComposer.ElemParameterWriter(element));

                #region CII export

                if (InputVars.ExportToCII)
                {
                    sbPipes.Append(Composer.CIIWriter(doc, key));
                }
                #endregion

                sbPipes.Append("    UNIQUE-COMPONENT-IDENTIFIER ");
                sbPipes.Append(element.UniqueId);
                sbPipes.AppendLine();
            }

            return(sbPipes);

            //// Clear the output file
            //System.IO.File.WriteAllBytes(InputVars.OutputDirectoryFilePath + "Pipes.pcf", new byte[0]);

            //// Write to output file
            //using (StreamWriter w = File.AppendText(InputVars.OutputDirectoryFilePath + "Pipes.pcf"))
            //{
            //    w.Write(sbPipes);
            //    w.Close();
            //}
        }
Beispiel #2
0
        public StringBuilder Export(string pipeLineAbbreviation, HashSet <Element> elements, Document document)
        {
            Document doc = document;
            string   key = pipeLineAbbreviation;
            //The list of fittings, sorted by TYPE then SKEY
            IList <Element> fittingsList = elements.
                                           OrderBy(e => e.get_Parameter(new plst().PCF_ELEM_TYPE.Guid).AsString()).
                                           ThenBy(e => e.get_Parameter(new plst().PCF_ELEM_SKEY.Guid).AsString()).ToList();

            StringBuilder sbFittings = new StringBuilder();

            foreach (Element element in fittingsList)
            {
                //If the Element Type field is empty -> ignore the component
                if (string.IsNullOrEmpty(element.get_Parameter(new plst().PCF_ELEM_TYPE.Guid).AsString()))
                {
                    continue;
                }

                sbFittings.AppendLine(element.get_Parameter(new plst().PCF_ELEM_TYPE.Guid).AsString());
                sbFittings.AppendLine("    COMPONENT-IDENTIFIER " + element.get_Parameter(new plst().PCF_ELEM_COMPID.Guid).AsInteger());

                //Write Plant3DIso entries if turned on
                if (iv.ExportToPlant3DIso)
                {
                    sbFittings.Append(Composer.Plant3DIsoWriter(element, doc));
                }

                //Cast the elements gathered by the collector to FamilyInstances
                FamilyInstance familyInstance = (FamilyInstance)element;
                Options        options        = new Options();
                //MEPModel of the elements is accessed
                MEPModel mepmodel = familyInstance.MEPModel;
                //Get connector set for the element
                ConnectorSet connectorSet = mepmodel.ConnectorManager.Connectors;

                //Switch to different element type configurations
                switch (element.get_Parameter(new plst().PCF_ELEM_TYPE.Guid).AsString())
                {
                case ("ELBOW"):
                    Connector primaryConnector = null; Connector secondaryConnector = null;

                    //Process endpoints of the component
                    foreach (Connector connector in connectorSet)
                    {
                        if (connector.GetMEPConnectorInfo().IsPrimary)
                        {
                            primaryConnector = connector;
                        }
                        if (connector.GetMEPConnectorInfo().IsSecondary)
                        {
                            secondaryConnector = connector;
                        }
                    }

                    sbFittings.Append(EndWriter.WriteEP1(element, primaryConnector));
                    sbFittings.Append(EndWriter.WriteEP2(element, secondaryConnector));
                    sbFittings.Append(EndWriter.WriteCP(familyInstance));

                    sbFittings.Append("    ANGLE ");
                    sbFittings.Append((Conversion.RadianToDegree(element.LookupParameter("Angle").AsDouble()) * 100).ToString("0"));
                    sbFittings.AppendLine();

                    break;

                case ("TEE"):
                    //Sort connectors to primary, secondary and none
                    primaryConnector = null; secondaryConnector = null; Connector tertiaryConnector = null;

                    foreach (Connector connector in connectorSet)
                    {
                        #region Debug
                        //Debug
                        //sbFittings.Append(connector.GetMEPConnectorInfo().IsPrimary);
                        //sbFittings.Append(connector.GetMEPConnectorInfo().IsSecondary);
                        //sbFittings.Append((connector.GetMEPConnectorInfo().IsPrimary == false) & (connector.GetMEPConnectorInfo().IsSecondary == false));
                        //sbFittings.AppendLine();
                        #endregion

                        if (connector.GetMEPConnectorInfo().IsPrimary)
                        {
                            primaryConnector = connector;
                        }
                        if (connector.GetMEPConnectorInfo().IsSecondary)
                        {
                            secondaryConnector = connector;
                        }
                        if ((connector.GetMEPConnectorInfo().IsPrimary == false) && (connector.GetMEPConnectorInfo().IsSecondary == false))
                        {
                            tertiaryConnector = connector;
                        }
                    }

                    //Process endpoints of the component
                    sbFittings.Append(EndWriter.WriteEP1(element, primaryConnector));
                    sbFittings.Append(EndWriter.WriteEP2(element, secondaryConnector));
                    sbFittings.Append(EndWriter.WriteCP(familyInstance));
                    sbFittings.Append(EndWriter.WriteBP1(element, tertiaryConnector));

                    break;

                case ("REDUCER-CONCENTRIC"):
                    //Process endpoints of the component
                    primaryConnector = null; secondaryConnector = null;

                    //Process endpoints of the component
                    foreach (Connector connector in connectorSet)
                    {
                        if (connector.GetMEPConnectorInfo().IsPrimary)
                        {
                            primaryConnector = connector;
                        }
                        if (connector.GetMEPConnectorInfo().IsSecondary)
                        {
                            secondaryConnector = connector;
                        }
                    }

                    sbFittings.Append(EndWriter.WriteEP1(element, primaryConnector));
                    sbFittings.Append(EndWriter.WriteEP2(element, secondaryConnector));

                    break;

                case ("REDUCER-ECCENTRIC"):
                    goto case ("REDUCER-CONCENTRIC");

                case ("FLANGE"):
                    primaryConnector = null; secondaryConnector = null; tertiaryConnector = null;

                    foreach (Connector connector in connectorSet)
                    {
                        if (connector.GetMEPConnectorInfo().IsPrimary)
                        {
                            primaryConnector = connector;
                        }
                        if (connector.GetMEPConnectorInfo().IsSecondary)
                        {
                            secondaryConnector = connector;
                        }
                    }

                    //Process endpoints of the component
                    //Secondary goes first because it is the weld neck point and the primary second because it is the flanged end
                    //(dunno if it is significant);

                    sbFittings.Append(EndWriter.WriteEP1(element, secondaryConnector));
                    sbFittings.Append(EndWriter.WriteEP2(element, primaryConnector));

                    break;

                case ("FLANGE-BLIND"):
                    primaryConnector = null;
                    foreach (Connector connector in connectorSet)
                    {
                        primaryConnector = connector;
                    }
                    //Connector information extraction

                    sbFittings.Append(EndWriter.WriteEP1(element, primaryConnector));

                    XYZ    endPointOriginFlangeBlind = primaryConnector.Origin;
                    double connectorSizeFlangeBlind  = primaryConnector.Radius;

                    //Analyses the geometry to obtain a point opposite the main connector.
                    //Extraction of the direction of the connector and reversing it
                    XYZ  reverseConnectorVector = -primaryConnector.CoordinateSystem.BasisZ;
                    Line detectorLine           = Line.CreateUnbound(endPointOriginFlangeBlind, reverseConnectorVector);
                    //Begin geometry analysis
                    GeometryElement geometryElement = familyInstance.get_Geometry(options);

                    //Prepare resulting point
                    XYZ endPointAnalyzed = null;

                    foreach (GeometryObject geometry in geometryElement)
                    {
                        GeometryInstance instance = geometry as GeometryInstance;
                        if (null != instance)
                        {
                            foreach (GeometryObject instObj in instance.GetInstanceGeometry())
                            {
                                Solid solid = instObj as Solid;
                                if (null == solid || 0 == solid.Faces.Size || 0 == solid.Edges.Size)
                                {
                                    continue;
                                }
                                // Get the faces
                                foreach (Face face in solid.Faces)
                                {
                                    IntersectionResultArray results = null;
                                    XYZ intersection           = null;
                                    SetComparisonResult result = face.Intersect(detectorLine, out results);
                                    if (result == SetComparisonResult.Overlap)
                                    {
                                        intersection = results.get_Item(0).XYZPoint;
                                        if (intersection.IsAlmostEqualTo(endPointOriginFlangeBlind) == false)
                                        {
                                            endPointAnalyzed = intersection;
                                        }
                                    }
                                }
                            }
                        }
                    }

                    sbFittings.Append(EndWriter.WriteEP2(element, endPointAnalyzed, connectorSizeFlangeBlind));

                    break;

                case ("CAP"):
                    goto case ("FLANGE-BLIND");

                case ("OLET"):
                    primaryConnector = null; secondaryConnector = null;

                    foreach (Connector connector in connectorSet)
                    {
                        if (connector.GetMEPConnectorInfo().IsPrimary)
                        {
                            primaryConnector = connector;
                        }
                        if (connector.GetMEPConnectorInfo().IsSecondary)
                        {
                            secondaryConnector = connector;
                        }
                    }

                    XYZ endPointOriginOletPrimary   = primaryConnector.Origin;
                    XYZ endPointOriginOletSecondary = secondaryConnector.Origin;

                    //get reference elements
                    ConnectorSet refConnectors = primaryConnector.AllRefs;
                    Element      refElement    = null;
                    foreach (Connector c in refConnectors)
                    {
                        refElement = c.Owner;
                    }
                    Pipe refPipe = (Pipe)refElement;
                    //Get connector set for the pipes
                    ConnectorSet refConnectorSet = refPipe.ConnectorManager.Connectors;
                    //Filter out non-end types of connectors
                    IEnumerable <Connector> connectorEnd = from Connector connector in refConnectorSet
                                                           where connector.ConnectorType.ToString() == "End"
                                                           select connector;

                    //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 = connectorEnd.First().Origin; XYZ pipeEnd2 = connectorEnd.Last().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);

                        #region Debug
                        //Debug
                        //Place family instance at points to debug the alorithm
                        //StructuralType strType = (StructuralType)4;
                        //FamilySymbol familySymbol = null;
                        //FilteredElementCollector collector = new FilteredElementCollector(doc);
                        //IEnumerable<Element> collection = collector.OfClass(typeof(FamilySymbol)).ToElements();
                        //FamilySymbol marker = null;
                        //foreach (Element e in collection)
                        //{
                        //    familySymbol = e as FamilySymbol;
                        //    if (null != familySymbol.Category)
                        //    {
                        //        if ("Structural Columns" == familySymbol.Category.Name)
                        //        {
                        //            break;
                        //        }
                        //    }
                        //}

                        //if (null != familySymbol)
                        //{
                        //    foreach (Element e in collection)
                        //    {
                        //        familySymbol = e as FamilySymbol;
                        //        if (familySymbol.FamilyName == "Marker")
                        //        {
                        //            marker = familySymbol;
                        //            Transaction trans = new Transaction(doc, "Place point markers");
                        //            trans.Start();
                        //            doc.Create.NewFamilyInstance(A, marker, strType);
                        //            doc.Create.NewFamilyInstance(B, marker, strType);
                        //            doc.Create.NewFamilyInstance(C, marker, strType);
                        //            doc.Create.NewFamilyInstance(D, marker, strType);
                        //            doc.Create.NewFamilyInstance(E, marker, strType);
                        //            trans.Commit();
                        //        }
                        //    }

                        //}
                        #endregion
                    }
                    else
                    {
                        A = E;
                    }
                    angle = Math.Round(angle * 100);

                    sbFittings.Append(EndWriter.WriteCP(A));

                    sbFittings.Append(EndWriter.WriteBP1(element, secondaryConnector));

                    sbFittings.Append("    ANGLE ");
                    sbFittings.Append(Conversion.AngleToPCF(angle));
                    sbFittings.AppendLine();

                    break;
                }

                Composer elemParameterComposer = new Composer();
                sbFittings.Append(elemParameterComposer.ElemParameterWriter(element));

                #region CII export
                if (iv.ExportToCII)
                {
                    sbFittings.Append(Composer.CIIWriter(doc, key));
                }
                #endregion

                sbFittings.Append("    UNIQUE-COMPONENT-IDENTIFIER ");
                sbFittings.Append(element.UniqueId);
                sbFittings.AppendLine();
            }

            //// Clear the output file
            //File.WriteAllBytes(InputVars.OutputDirectoryFilePath + "Fittings.pcf", new byte[0]);

            //// Write to output file
            //using (StreamWriter w = File.AppendText(InputVars.OutputDirectoryFilePath + "Fittings.pcf"))
            //{
            //    w.Write(sbFittings);
            //    w.Close();
            //}

            return(sbFittings);
        }
Beispiel #3
0
        public StringBuilder Export(string pipeLineAbbreviation, HashSet <Element> elements, Document document)
        {
            Document doc = document;
            string   key = pipeLineAbbreviation;
            //The list of fittings, sorted by TYPE then SKEY
            IList <Element> fittingsList = elements.
                                           OrderBy(e => e.get_Parameter(new plst().PCF_ELEM_TYPE.Guid).AsString()).
                                           ThenBy(e => e.get_Parameter(new plst().PCF_ELEM_SKEY.Guid).AsString()).ToList();

            StringBuilder sbFittings = new StringBuilder();

            foreach (Element element in fittingsList)
            {
                sbFittings.AppendLine(element.get_Parameter(new plst().PCF_ELEM_TYPE.Guid).AsString());
                sbFittings.AppendLine("    COMPONENT-IDENTIFIER " + element.get_Parameter(new plst().PCF_ELEM_COMPID.Guid).AsString());

                if (element.get_Parameter(new plst().PCF_ELEM_SPEC.Guid).AsString() == "EXISTING-INCLUDE")
                {
                    sbFittings.AppendLine("    STATUS DOTTED-UNDIMENSIONED");
                    sbFittings.AppendLine("    MATERIAL-LIST EXCLUDE");
                }

                //Write Plant3DIso entries if turned on
                if (iv.ExportToIsogen)
                {
                    sbFittings.Append(Composer.Plant3DIsoWriter(element, doc));
                }

                //Cast the elements gathered by the collector to FamilyInstances
                FamilyInstance familyInstance = (FamilyInstance)element;
                Options        options        = new Options();

                //Gather connectors of the element
                var cons = mp.GetConnectors(element);

                //Switch to different element type configurations
                switch (element.get_Parameter(new plst().PCF_ELEM_TYPE.Guid).AsString())
                {
                case ("ELBOW"):
                    sbFittings.Append(EndWriter.WriteEP1(element, cons.Primary));
                    sbFittings.Append(EndWriter.WriteEP2(element, cons.Secondary));
                    sbFittings.Append(EndWriter.WriteCP(familyInstance));

                    sbFittings.Append("    ANGLE ");

                    Parameter par = element.LookupParameter("Angle");
                    if (par == null)
                    {
                        par = element.LookupParameter("angle");
                    }
                    if (par == null)
                    {
                        throw new Exception($"Angle parameter on elbow {element.Id.IntegerValue} does not exist or is named differently!");
                    }
                    sbFittings.Append((Conversion.RadianToDegree(par.AsDouble()) * 100).ToString("0"));
                    sbFittings.AppendLine();

                    break;
                //case ("BEND"):
                //    sbFittings.Append(EndWriter.WriteEP1(element, cons.Primary));
                //    sbFittings.Append(EndWriter.WriteEP2(element, cons.Secondary));
                //    sbFittings.Append(EndWriter.WriteCP(familyInstance));
                //    break;

                case ("TEE"):
                    //Process endpoints of the component
                    sbFittings.Append(EndWriter.WriteEP1(element, cons.Primary));
                    sbFittings.Append(EndWriter.WriteEP2(element, cons.Secondary));
                    sbFittings.Append(EndWriter.WriteCP(familyInstance));
                    sbFittings.Append(EndWriter.WriteBP1(element, cons.Tertiary));

                    break;

                case ("REDUCER-CONCENTRIC"):
                    sbFittings.Append(EndWriter.WriteEP1(element, cons.Primary));
                    sbFittings.Append(EndWriter.WriteEP2(element, cons.Secondary));

                    break;

                case ("REDUCER-ECCENTRIC"):
                    goto case ("REDUCER-CONCENTRIC");

                case ("COUPLING"):
                    goto case ("REDUCER-CONCENTRIC");

                case ("FLANGE"):
                    //Process endpoints of the component
                    //Secondary goes first because it is the weld neck point and the primary second because it is the flanged end
                    //(dunno if it is significant); It is not, it should be specified the type of end, BW, PL, FL etc. to work correctly.

                    sbFittings.Append(EndWriter.WriteEP1(element, cons.Secondary));
                    sbFittings.Append(EndWriter.WriteEP2(element, cons.Primary));

                    break;

                case ("FLANGE-BLIND"):
                    sbFittings.Append(EndWriter.WriteEP1(element, cons.Primary));

                    XYZ    endPointOriginFlangeBlind = cons.Primary.Origin;
                    double connectorSizeFlangeBlind  = cons.Primary.Radius;

                    //Analyses the geometry to obtain a point opposite the main connector.
                    //Extraction of the direction of the connector and reversing it
                    XYZ  reverseConnectorVector = -cons.Primary.CoordinateSystem.BasisZ;
                    Line detectorLine           = Line.CreateBound(endPointOriginFlangeBlind, endPointOriginFlangeBlind + reverseConnectorVector * 10);
                    //Begin geometry analysis
                    GeometryElement geometryElement = familyInstance.get_Geometry(options);

                    //Prepare resulting point
                    XYZ endPointAnalyzed = null;

                    foreach (GeometryObject geometry in geometryElement)
                    {
                        if (geometry is GeometryInstance instance)
                        {
                            foreach (GeometryObject instObj in instance.GetInstanceGeometry())
                            {
                                Solid solid = instObj as Solid;
                                if (null == solid || 0 == solid.Faces.Size || 0 == solid.Edges.Size)
                                {
                                    continue;
                                }
                                // Get the faces
                                foreach (Face face in solid.Faces)
                                {
                                    IntersectionResultArray results = null;
                                    XYZ intersection           = null;
                                    SetComparisonResult result = face.Intersect(detectorLine, out results);
                                    if (result == SetComparisonResult.Overlap)
                                    {
                                        intersection = results.get_Item(0).XYZPoint;
                                        if (intersection.IsAlmostEqualTo(endPointOriginFlangeBlind) == false)
                                        {
                                            endPointAnalyzed = intersection;
                                        }
                                    }
                                }
                            }
                        }
                    }

                    sbFittings.Append(EndWriter.WriteEP2(element, endPointAnalyzed, connectorSizeFlangeBlind));

                    break;

                case ("CAP"):
                    goto case ("FLANGE-BLIND");

                case ("OLET"):
                    XYZ endPointOriginOletPrimary   = cons.Primary.Origin;
                    XYZ endPointOriginOletSecondary = cons.Secondary.Origin;

                    //get reference elements
                    Pipe refPipe = null;
                    var  refCons = mp.GetAllConnectorsFromConnectorSet(cons.Primary.AllRefs);

                    Connector refCon = refCons.Where(x => x.Owner.IsType <Pipe>()).FirstOrDefault();
                    if (refCon == null)
                    {
                        //Find the target pipe
                        var filter               = new ElementClassFilter(typeof(Pipe));
                        var view3D               = Shared.Filter.Get3DView(doc);
                        var refIntersect         = new ReferenceIntersector(filter, FindReferenceTarget.Element, view3D);
                        ReferenceWithContext rwc = refIntersect.FindNearest(cons.Primary.Origin, cons.Primary.CoordinateSystem.BasisZ);
                        var refId = rwc.GetReference().ElementId;
                        refPipe = (Pipe)doc.GetElement(refId);

                        if (refPipe == null)
                        {
                            throw new Exception($"Olet {element.Id.IntegerValue} cannot find a reference Pipe!");
                        }
                    }
                    else
                    {
                        refPipe = (Pipe)refCon.Owner;
                    }

                    Cons refPipeCons = mp.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);

                        #region Debug
                        //Debug
                        //Place family instance at points to debug the alorithm
                        //StructuralType strType = (StructuralType)4;
                        //FamilySymbol familySymbol = null;
                        //FilteredElementCollector collector = new FilteredElementCollector(doc);
                        //IEnumerable<Element> collection = collector.OfClass(typeof(FamilySymbol)).ToElements();
                        //FamilySymbol marker = null;
                        //foreach (Element e in collection)
                        //{
                        //    familySymbol = e as FamilySymbol;
                        //    if (null != familySymbol.Category)
                        //    {
                        //        if ("Structural Columns" == familySymbol.Category.Name)
                        //        {
                        //            break;
                        //        }
                        //    }
                        //}

                        //if (null != familySymbol)
                        //{
                        //    foreach (Element e in collection)
                        //    {
                        //        familySymbol = e as FamilySymbol;
                        //        if (familySymbol.FamilyName == "Marker")
                        //        {
                        //            marker = familySymbol;
                        //            Transaction trans = new Transaction(doc, "Place point markers");
                        //            trans.Start();
                        //            doc.Create.NewFamilyInstance(A, marker, strType);
                        //            doc.Create.NewFamilyInstance(B, marker, strType);
                        //            doc.Create.NewFamilyInstance(C, marker, strType);
                        //            doc.Create.NewFamilyInstance(D, marker, strType);
                        //            doc.Create.NewFamilyInstance(E, marker, strType);
                        //            trans.Commit();
                        //        }
                        //    }

                        //}
                        #endregion
                    }
                    else
                    {
                        A = E;
                    }
                    angle = Math.Round(angle * 100);

                    sbFittings.Append(EndWriter.WriteCP(A));

                    sbFittings.Append(EndWriter.WriteBP1(element, cons.Secondary));

                    sbFittings.Append("    ANGLE ");
                    sbFittings.Append(Conversion.AngleToPCF(angle));
                    sbFittings.AppendLine();

                    break;
                }

                Composer elemParameterComposer = new Composer();
                sbFittings.Append(elemParameterComposer.ElemParameterWriter(element));

                #region CII export
                if (iv.ExportToCII)
                {
                    sbFittings.Append(Composer.CIIWriter(doc, key));
                }
                #endregion

                sbFittings.Append("    UNIQUE-COMPONENT-IDENTIFIER ");
                sbFittings.Append(element.UniqueId);
                sbFittings.AppendLine();
            }

            //// Clear the output file
            //File.WriteAllBytes(InputVars.OutputDirectoryFilePath + "Fittings.pcf", new byte[0]);

            //// Write to output file
            //using (StreamWriter w = File.AppendText(InputVars.OutputDirectoryFilePath + "Fittings.pcf"))
            //{
            //    w.Write(sbFittings);
            //    w.Close();
            //}

            return(sbFittings);
        }
        public StringBuilder Export(string pipeLineAbbreviation, HashSet <Element> elements, Document document)
        {
            Document doc   = document;
            string   key   = pipeLineAbbreviation;
            plst     pList = new plst();
            //paramList = new plst();
            //The list of fittings, sorted by TYPE then SKEY
            IList <Element> accessoriesList = elements.
                                              OrderBy(e => e.get_Parameter(pList.PCF_ELEM_TYPE.Guid).AsString()).
                                              ThenBy(e => e.get_Parameter(pList.PCF_ELEM_SKEY.Guid).AsString()).ToList();

            StringBuilder sbAccessories = new StringBuilder();

            //This is a workaround to try to determine what element caused an exception
            Element element = null;

            try
            {
                foreach (Element Element in accessoriesList)
                {
                    //This is a workaround to try to determine what element caused an exception
                    element = Element;
                    //If the Element Type field is empty -> ignore the component
                    if (string.IsNullOrEmpty(element.get_Parameter(pList.PCF_ELEM_TYPE.Guid).AsString()))
                    {
                        continue;
                    }

                    sbAccessories.AppendLine(element.get_Parameter(new plst().PCF_ELEM_TYPE.Guid).AsString());
                    sbAccessories.AppendLine("    COMPONENT-IDENTIFIER " + element.get_Parameter(new plst().PCF_ELEM_COMPID.Guid).AsInteger());

                    //Write Plant3DIso entries if turned on
                    if (InputVars.ExportToPlant3DIso)
                    {
                        sbAccessories.Append(Composer.Plant3DIsoWriter(element, doc));
                    }

                    //Cast the elements gathered by the collector to FamilyInstances
                    FamilyInstance familyInstance = (FamilyInstance)element;
                    Options        options        = new Options();
                    //MEPModel of the elements is accessed
                    MEPModel mepmodel = familyInstance.MEPModel;
                    //Get connector set for the element
                    ConnectorSet connectorSet = mepmodel.ConnectorManager.Connectors;

                    //Switch to different element type configurations
                    switch (element.get_Parameter(pList.PCF_ELEM_TYPE.Guid).AsString())
                    {
                    case ("FILTER"):
                        //Process endpoints of the component
                        Connector primaryConnector = null; Connector secondaryConnector = null;

                        foreach (Connector connector in connectorSet)
                        {
                            if (connector.GetMEPConnectorInfo().IsPrimary)
                            {
                                primaryConnector = connector;
                            }
                            if (connector.GetMEPConnectorInfo().IsSecondary)
                            {
                                secondaryConnector = connector;
                            }
                        }

                        //Process endpoints of the component
                        sbAccessories.Append(EndWriter.WriteEP1(element, primaryConnector));
                        sbAccessories.Append(EndWriter.WriteEP2(element, secondaryConnector));

                        break;

                    case ("INSTRUMENT"):
                        //Process endpoints of the component
                        primaryConnector = null; secondaryConnector = null;

                        foreach (Connector connector in connectorSet)
                        {
                            if (connector.GetMEPConnectorInfo().IsPrimary)
                            {
                                primaryConnector = connector;
                            }
                            if (connector.GetMEPConnectorInfo().IsSecondary)
                            {
                                secondaryConnector = connector;
                            }
                        }

                        //Process endpoints of the component
                        sbAccessories.Append(EndWriter.WriteEP1(element, primaryConnector));
                        sbAccessories.Append(EndWriter.WriteEP2(element, secondaryConnector));
                        sbAccessories.Append(EndWriter.WriteCP(familyInstance));

                        break;

                    case ("VALVE"):
                        goto case ("INSTRUMENT");

                    case ("VALVE-ANGLE"):
                        //Process endpoints of the component
                        primaryConnector = null; secondaryConnector = null;

                        foreach (Connector connector in connectorSet)
                        {
                            if (connector.GetMEPConnectorInfo().IsPrimary)
                            {
                                primaryConnector = connector;
                            }
                            if (connector.GetMEPConnectorInfo().IsSecondary)
                            {
                                secondaryConnector = connector;
                            }
                        }

                        //Process endpoints of the component
                        sbAccessories.Append(EndWriter.WriteEP1(element, primaryConnector));
                        sbAccessories.Append(EndWriter.WriteEP2(element, secondaryConnector));

                        //The centre point is obtained by creating an unbound line from primary connector and projecting the secondary point on the line.
                        XYZ  reverseConnectorVector = -primaryConnector.CoordinateSystem.BasisZ;
                        Line primaryLine            = Line.CreateUnbound(primaryConnector.Origin, reverseConnectorVector);
                        XYZ  centrePoint            = primaryLine.Project(secondaryConnector.Origin).XYZPoint;

                        sbAccessories.Append(EndWriter.WriteCP(centrePoint));

                        break;

                    case ("INSTRUMENT-DIAL"):
                        ////Process endpoints of the component
                        //primaryConnector = null;

                        //foreach (Connector connector in connectorSet) primaryConnector = connector;

                        ////Process endpoints of the component
                        //sbAccessories.Append(EndWriter.WriteEP1(element, primaryConnector));

                        ////The co-ords point is obtained by creating an unbound line from primary connector and taking an arbitrary point a long the line.
                        //reverseConnectorVector = -primaryConnector.CoordinateSystem.BasisZ.Multiply(0.656167979);
                        //XYZ coOrdsPoint = primaryConnector.Origin;
                        //Transform pointTranslation;
                        //pointTranslation = Transform.CreateTranslation(reverseConnectorVector);
                        //coOrdsPoint = pointTranslation.OfPoint(coOrdsPoint);

                        primaryConnector = null;
                        foreach (Connector connector in connectorSet)
                        {
                            primaryConnector = connector;
                        }
                        //Connector information extraction

                        sbAccessories.Append(EndWriter.WriteEP1(element, primaryConnector));

                        XYZ primConOrigin = primaryConnector.Origin;

                        //Analyses the geometry to obtain a point opposite the main connector.
                        //Extraction of the direction of the connector and reversing it
                        reverseConnectorVector = -primaryConnector.CoordinateSystem.BasisZ;
                        Line detectorLine = Line.CreateUnbound(primConOrigin, reverseConnectorVector);
                        //Begin geometry analysis
                        GeometryElement geometryElement = familyInstance.get_Geometry(options);

                        //Prepare resulting point
                        XYZ endPointAnalyzed = null;

                        foreach (GeometryObject geometry in geometryElement)
                        {
                            GeometryInstance instance = geometry as GeometryInstance;
                            if (null == instance)
                            {
                                continue;
                            }
                            foreach (GeometryObject instObj in instance.GetInstanceGeometry())
                            {
                                Solid solid = instObj as Solid;
                                if (null == solid || 0 == solid.Faces.Size || 0 == solid.Edges.Size)
                                {
                                    continue;
                                }
                                foreach (Face face in solid.Faces)
                                {
                                    IntersectionResultArray results = null;
                                    XYZ intersection           = null;
                                    SetComparisonResult result = face.Intersect(detectorLine, out results);
                                    if (result != SetComparisonResult.Overlap)
                                    {
                                        continue;
                                    }
                                    intersection = results.get_Item(0).XYZPoint;
                                    if (intersection.IsAlmostEqualTo(primConOrigin) == false)
                                    {
                                        endPointAnalyzed = intersection;
                                    }
                                }
                            }
                        }

                        sbAccessories.Append(EndWriter.WriteCO(endPointAnalyzed));

                        break;

                    case "SUPPORT":
                        primaryConnector = (from Connector c in connectorSet where c.GetMEPConnectorInfo().IsPrimary select c).FirstOrDefault();
                        sbAccessories.Append(EndWriter.WriteCO(familyInstance, primaryConnector));
                        break;

                    case "INSTRUMENT-3WAY":
                        //Sort connectors to primary, secondary and none
                        primaryConnector = null; secondaryConnector = null; Connector tertiaryConnector = null;

                        foreach (Connector connector in connectorSet)
                        {
                            if (connector.GetMEPConnectorInfo().IsPrimary)
                            {
                                primaryConnector = connector;
                            }
                            if (connector.GetMEPConnectorInfo().IsSecondary)
                            {
                                secondaryConnector = connector;
                            }
                            if ((connector.GetMEPConnectorInfo().IsPrimary == false) && (connector.GetMEPConnectorInfo().IsSecondary == false))
                            {
                                tertiaryConnector = connector;
                            }
                        }

                        //Process endpoints of the component
                        sbAccessories.Append(EndWriter.WriteEP1(element, primaryConnector));
                        sbAccessories.Append(EndWriter.WriteEP2(element, secondaryConnector));
                        sbAccessories.Append(EndWriter.WriteEP3(element, tertiaryConnector));
                        sbAccessories.Append(EndWriter.WriteCP(familyInstance));
                        break;
                    }

                    Composer elemParameterComposer = new Composer();
                    sbAccessories.Append(elemParameterComposer.ElemParameterWriter(element));

                    #region CII export
                    if (InputVars.ExportToCII && !string.Equals(element.get_Parameter(pList.PCF_ELEM_TYPE.Guid).AsString(), "SUPPORT"))
                    {
                        sbAccessories.Append(Composer.CIIWriter(doc, key));
                    }
                    #endregion

                    sbAccessories.Append("    UNIQUE-COMPONENT-IDENTIFIER ");
                    sbAccessories.Append(element.UniqueId);
                    sbAccessories.AppendLine();

                    //Process tap entries of the element if any
                    //Diameter Limit nullifies the tapsWriter output if the tap diameter is less than the limit so it doesn't get exported
                    if (string.IsNullOrEmpty(element.LookupParameter("PCF_ELEM_TAP1").AsString()) == false)
                    {
                        TapsWriter tapsWriter = new TapsWriter(element, "PCF_ELEM_TAP1", doc);
                        sbAccessories.Append(tapsWriter.tapsWriter);
                    }
                    if (string.IsNullOrEmpty(element.LookupParameter("PCF_ELEM_TAP2").AsString()) == false)
                    {
                        TapsWriter tapsWriter = new TapsWriter(element, "PCF_ELEM_TAP2", doc);
                        sbAccessories.Append(tapsWriter.tapsWriter);
                    }
                    if (string.IsNullOrEmpty(element.LookupParameter("PCF_ELEM_TAP3").AsString()) == false)
                    {
                        TapsWriter tapsWriter = new TapsWriter(element, "PCF_ELEM_TAP3", doc);
                        sbAccessories.Append(tapsWriter.tapsWriter);
                    }
                }
            }
            catch (Exception e)
            {
                throw new Exception("Element " + element.Id.IntegerValue.ToString() + " caused an exception: " + e.Message);
            }

            //// Clear the output file
            //System.IO.File.WriteAllBytes(InputVars.OutputDirectoryFilePath + "Accessories.pcf", new byte[0]);

            //// Write to output file
            //using (StreamWriter w = File.AppendText(InputVars.OutputDirectoryFilePath + "Accessories.pcf"))
            //{
            //    w.Write(sbAccessories);
            //    w.Close();
            //}
            return(sbAccessories);
        }
        public StringBuilder Export(string pipeLineAbbreviation, HashSet <Element> elements, Document document)
        {
            Document doc   = document;
            string   key   = pipeLineAbbreviation;
            plst     pList = new plst();
            //paramList = new plst();
            //The list of fittings, sorted by TYPE then SKEY
            IList <Element> accessoriesList = elements.
                                              OrderBy(e => e.get_Parameter(pList.PCF_ELEM_TYPE.Guid).AsString()).
                                              ThenBy(e => e.get_Parameter(pList.PCF_ELEM_SKEY.Guid).AsString()).ToList();

            StringBuilder sbAccessories = new StringBuilder();

            //This is a workaround to try to determine what element caused an exception
            Element element = null;

            try
            {
                foreach (Element Element in accessoriesList)
                {
                    //This is a workaround to try to determine what element caused an exception
                    element = Element;

                    sbAccessories.AppendLine(element.get_Parameter(new plst().PCF_ELEM_TYPE.Guid).AsString());
                    sbAccessories.AppendLine("    COMPONENT-IDENTIFIER " + element.get_Parameter(new plst().PCF_ELEM_COMPID.Guid).AsString());

                    if (element.get_Parameter(new plst().PCF_ELEM_SPEC.Guid).AsString() == "EXISTING-INCLUDE")
                    {
                        sbAccessories.AppendLine("    STATUS DOTTED-UNDIMENSIONED");
                        sbAccessories.AppendLine("    MATERIAL-LIST EXCLUDE");
                    }

                    //Write Plant3DIso entries if turned on
                    if (InputVars.ExportToIsogen)
                    {
                        sbAccessories.Append(Composer.Plant3DIsoWriter(element, doc));
                    }

                    //Cast the elements gathered by the collector to FamilyInstances
                    FamilyInstance familyInstance = (FamilyInstance)element;
                    Options        options        = new Options();

                    //Gather connectors of the element
                    var cons = mp.GetConnectors(element);

                    //Switch to different element type configurations
                    switch (element.get_Parameter(pList.PCF_ELEM_TYPE.Guid).AsString())
                    {
                    case ("FILTER"):
                        //Process endpoints of the component
                        sbAccessories.Append(EndWriter.WriteEP1(element, cons.Primary));
                        sbAccessories.Append(EndWriter.WriteEP2(element, cons.Secondary));
                        sbAccessories.Append(pdw.ParameterValue("TAG", new[] { "TAG 1", "TAG 2", "TAG 3" }, element));
                        break;

                    case ("INSTRUMENT"):
                        //Process endpoints of the component
                        sbAccessories.Append(EndWriter.WriteEP1(element, cons.Primary));
                        sbAccessories.Append(EndWriter.WriteEP2(element, cons.Secondary));
                        sbAccessories.Append(EndWriter.WriteCP(familyInstance));
                        sbAccessories.Append(pdw.ParameterValue("TAG", new[] { "TAG 1", "TAG 2", "TAG 3" }, element));

                        break;

                    case ("VALVE"):
                        goto case ("INSTRUMENT");

                    case ("VALVE-ANGLE"):
                        //Process endpoints of the component
                        sbAccessories.Append(EndWriter.WriteEP1(element, cons.Primary));
                        sbAccessories.Append(EndWriter.WriteEP2(element, cons.Secondary));

                        //The centre point is obtained by creating an bound line from primary connector and projecting the secondary point on the line.
                        XYZ  reverseConnectorVector = -cons.Primary.CoordinateSystem.BasisZ;
                        Line primaryLine            = Line.CreateBound(cons.Primary.Origin, cons.Primary.Origin + reverseConnectorVector * 10);
                        XYZ  centrePoint            = primaryLine.Project(cons.Secondary.Origin).XYZPoint;

                        sbAccessories.Append(EndWriter.WriteCP(centrePoint));

                        sbAccessories.Append(pdw.ParameterValue("TAG", new[] { "TAG 1", "TAG 2", "TAG 3" }, element));

                        break;

                    case ("INSTRUMENT-DIAL"):

                        //Connector information extraction
                        sbAccessories.Append(EndWriter.WriteEP1(element, cons.Primary));

                        XYZ primConOrigin = cons.Primary.Origin;

                        //Analyses the geometry to obtain a point opposite the main connector.
                        //Extraction of the direction of the connector and reversing it
                        reverseConnectorVector = -cons.Primary.CoordinateSystem.BasisZ;
                        Line detectorLine = Line.CreateBound(primConOrigin, primConOrigin + reverseConnectorVector * 10);
                        //Begin geometry analysis
                        GeometryElement geometryElement = familyInstance.get_Geometry(options);

                        //Prepare resulting point
                        XYZ endPointAnalyzed = null;

                        foreach (GeometryObject geometry in geometryElement)
                        {
                            GeometryInstance instance = geometry as GeometryInstance;
                            if (null == instance)
                            {
                                continue;
                            }
                            foreach (GeometryObject instObj in instance.GetInstanceGeometry())
                            {
                                Solid solid = instObj as Solid;
                                if (null == solid || 0 == solid.Faces.Size || 0 == solid.Edges.Size)
                                {
                                    continue;
                                }
                                foreach (Face face in solid.Faces)
                                {
                                    IntersectionResultArray results = null;
                                    XYZ intersection = null;
                                    try
                                    {
                                        SetComparisonResult result = face.Intersect(detectorLine, out results);
                                        if (result != SetComparisonResult.Overlap)
                                        {
                                            continue;
                                        }
                                        intersection = results.get_Item(0).XYZPoint;
                                        if (intersection.IsAlmostEqualTo(primConOrigin) == false)
                                        {
                                            endPointAnalyzed = intersection;
                                        }
                                    }
                                    catch (Exception)
                                    {
                                        continue;
                                    }
                                }
                            }
                        }

                        //If the point is still null after geometry intersection, it means the analysis failed
                        //Create an artificial point
                        if (endPointAnalyzed == null)
                        {
                            endPointAnalyzed = cons.Primary.Origin + reverseConnectorVector * 2;
                        }

                        sbAccessories.Append(EndWriter.WriteCO(endPointAnalyzed));
                        sbAccessories.Append(pdw.ParameterValue("TAG", new[] { "TAG 1", "TAG 2", "TAG 3" }, element));
                        break;

                    case "SUPPORT":
                        sbAccessories.Append(EndWriter.WriteCO(familyInstance, cons.Primary));
                        sbAccessories.Append(pdw.ParameterValue("TAG", new[] { "TAG 1", "TAG 2", "TAG 3" }, element));
                        break;

                    case "FLOOR-SYMBOL":
                        sbAccessories.Append(EndWriter.WriteCO(familyInstance));
                        break;

                    case "INSTRUMENT-3WAY":
                        //Process endpoints of the component
                        sbAccessories.Append(EndWriter.WriteEP1(element, cons.Primary));
                        sbAccessories.Append(EndWriter.WriteEP2(element, cons.Secondary));
                        sbAccessories.Append(EndWriter.WriteEP3(element, cons.Tertiary));
                        sbAccessories.Append(EndWriter.WriteCP(familyInstance));
                        break;
                    }

                    Composer elemParameterComposer = new Composer();
                    sbAccessories.Append(elemParameterComposer.ElemParameterWriter(element));

                    #region CII export
                    if (InputVars.ExportToCII && !string.Equals(element.get_Parameter(pList.PCF_ELEM_TYPE.Guid).AsString(), "SUPPORT"))
                    {
                        sbAccessories.Append(Composer.CIIWriter(doc, key));
                    }
                    #endregion

                    sbAccessories.Append("    UNIQUE-COMPONENT-IDENTIFIER ");
                    sbAccessories.Append(element.UniqueId);
                    sbAccessories.AppendLine();

                    //Process tap entries of the element if any
                    //Diameter Limit nullifies the tapsWriter output if the tap diameter is less than the limit so it doesn't get exported
                    if (string.IsNullOrEmpty(element.LookupParameter("PCF_ELEM_TAP1").AsString()) == false)
                    {
                        TapsWriter tapsWriter = new TapsWriter(element, "PCF_ELEM_TAP1", doc);
                        sbAccessories.Append(tapsWriter.tapsWriter);
                    }
                    if (string.IsNullOrEmpty(element.LookupParameter("PCF_ELEM_TAP2").AsString()) == false)
                    {
                        TapsWriter tapsWriter = new TapsWriter(element, "PCF_ELEM_TAP2", doc);
                        sbAccessories.Append(tapsWriter.tapsWriter);
                    }
                    if (string.IsNullOrEmpty(element.LookupParameter("PCF_ELEM_TAP3").AsString()) == false)
                    {
                        TapsWriter tapsWriter = new TapsWriter(element, "PCF_ELEM_TAP3", doc);
                        sbAccessories.Append(tapsWriter.tapsWriter);
                    }
                }
            }
            catch (Exception e)
            {
                throw new Exception("Element " + element.Id.IntegerValue.ToString() + " caused an exception: " + e.Message);
            }

            //// Clear the output file
            //System.IO.File.WriteAllBytes(InputVars.OutputDirectoryFilePath + "Accessories.pcf", new byte[0]);

            //// Write to output file
            //using (StreamWriter w = File.AppendText(InputVars.OutputDirectoryFilePath + "Accessories.pcf"))
            //{
            //    w.Write(sbAccessories);
            //    w.Close();
            //}
            return(sbAccessories);
        }