How to place a connector element on a specific face on imported AutoCAD element

How to place a connector element on a specific face on imported AutoCAD element

trane.brb
Explorer Explorer
778 Views
3 Replies
Message 1 of 4

How to place a connector element on a specific face on imported AutoCAD element

trane.brb
Explorer
Explorer

Hi,

 

I am trying to place a connector element (duct, pipe & electrical) on a specific Face after importing solid from a autocad file using the API. I have the coordinates (XYZ) of where I want to place it and the normal. Is there a way to identify a Face or PlanarFace using these two properties? Otherwise what strategies can I use to identify a Face uniquely on a solid ?

 

The code and a sample dwg file is attached.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Autodesk.Revit;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using Autodesk.Revit.Attributes;
using Autodesk.Revit.ApplicationServices;
using System.Xml;
using System.IO;
using Autodesk.Revit.DB.Mechanical;
namespace RevitFamilyCreator
{
    [TransactionAttribute(TransactionMode.Manual)]
    class CADBased : IExternalCommand
    {
        Application _rvtApp;
        Document _rvtDoc;
        public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
        {
            //GetUIDocument
            _rvtApp = commandData.Application.Application;


            //Get Document
            _rvtDoc = commandData.Application.ActiveUIDocument.Document;

            DWGImportOptions DIO = new DWGImportOptions();
            DIO.ColorMode = ImportColorMode.Preserved;
            //DIO.Unit = ImportUnit.Foot;
            DIO.CustomScale = 1.00;
            DIO.Placement = ImportPlacement.Origin;
            ElementId eleID = new ElementId(1234);
            string path = @"C:\Logan\BIM Dev\Reference Files\testVAV.dwg";
            View nv = _rvtDoc.ActiveView;

            using (Transaction trans = new Transaction(_rvtDoc, "CADB"))
            {
                trans.Start();
                _rvtDoc.Import(path, DIO, nv, out eleID);
                trans.Commit();
            }

            //XmlDataDocument xmldoc = new XmlDataDocument();
            //XmlNodeList nodeList;
            //int i = 0;
            //string strX = null;
            //string strY = null;
            //string strZ = null;
            //string strConnectionCount = null;
            //FileStream fs = new FileStream(@"C:\Logan\BIM Dev\Reference Files\VAV-info.xml", FileMode.Open, FileAccess.Read);
            //xmldoc.Load(fs);
            //nodeList = xmldoc.GetElementsByTagName("LOCATION");
            //for (i = 0; i <= nodeList.Count - 1; i++)
            //{

            //    strX = nodeList[i].ChildNodes.Item(0).InnerText.Trim();
            //    strY = nodeList[i].ChildNodes.Item(1).InnerText.Trim();
            //    strZ = nodeList[i].ChildNodes.Item(2).InnerText.Trim();
            //}


            //nodeList = xmldoc.GetElementsByTagName("CONNECTION_DATA");
            //foreach (XmlNode node in nodeList)
            //{
            //    strConnectionCount = node.SelectSingleNode("CONNECTIONS_COUNT").InnerText.Trim();
            //}

            //string strDuctCount = null;
            //string strPipeCount = null;
            //string strElecCount = null;

            //nodeList = xmldoc.GetElementsByTagName("DUCTS");
            //foreach (XmlNode node in nodeList)
            //{

            //    strDuctCount = node.SelectSingleNode("DUCT_COUNT").InnerText.Trim();
            //}

            //nodeList = xmldoc.GetElementsByTagName("PIPES");
            //foreach (XmlNode node in nodeList)
            //{
            //    strPipeCount = node.SelectSingleNode("PIPE_COUNT").InnerText.Trim();
            //}

            //nodeList = xmldoc.GetElementsByTagName("ELECS");
            //foreach (XmlNode node in nodeList)
            //{
            //    strElecCount = node.SelectSingleNode("ELEC_COUNT").InnerText.Trim();
            //}


            //Create Duct

            XYZ ptLocation = new XYZ(5.75, 18.13, 4.75);
            XYZ ptNormal = new XYZ(0, 1, 0);

            double conDiameter=4.0;
            int flowConfiguration=0;
            int flowDirection=1;
            int lossMethod=0;
            string conDescription = "Return Air_In";


            AddDuctConnectorToFamily(_rvtDoc, eleID, ptLocation, ptNormal, DuctSystemType.ReturnAir, ConnectorProfileType.Round, conDiameter,  flowConfiguration,  flowDirection,  lossMethod,  conDescription);

            return Result.Succeeded;
        }


       

        public bool AddDuctConnectorToFamily(Document famDoc, ElementId importedId, XYZ ptLocation, XYZ ptNormal, DuctSystemType ductSysType, ConnectorProfileType conProfType,double conDiameter,int flowConfiguration,int flowDirection,int lossMethod,string conDescription)
        {


            PlanarFace pf = null;

            Options opts = famDoc.Application.Create.NewGeometryOptions();
            opts.DetailLevel = ViewDetailLevel.Fine;
            opts.ComputeReferences = true;


            Element e = famDoc.GetElement(importedId);
            ImportInstance impInst = e as ImportInstance;

            //To access the Geometry of the Imported DWG block
            //We need to dig into it a little bit.
            GeometryElement impGeo = e.get_Geometry(opts);

            using (Transaction trans = new Transaction(famDoc))
            {
                IEnumerator<GeometryObject> geoObjectIter = impGeo.GetEnumerator();

                trans.Start("InsertConnector");

                while (geoObjectIter.MoveNext())
                {
                    GeometryInstance symInst = geoObjectIter.Current as GeometryInstance;
                    GeometryElement symEle = symInst.SymbolGeometry;

                    foreach (GeometryObject symObj in symEle)
                    {
                        Solid solid = symObj as Solid;

                        if (solid != null)
                        {

                            foreach (Face face in solid.Faces)
                            {
                                pf = face as PlanarFace;

                                if ((pf != null) && pf.FaceNormal.IsAlmostEqualTo(ptNormal)) // we found the face
                                {
                                    //if (pf.Origin.IsAlmostEqualTo(ptLocation))
                                    //{
                                    using (SubTransaction refTrans = new SubTransaction(famDoc))
                                    {
                                        refTrans.Start();


                                        ConnectorElement connDuct = ConnectorElement.CreateDuctConnector(famDoc, DuctSystemType.ReturnAir, ConnectorProfileType.Round, pf.Reference, pf.EdgeLoops.get_Item(0).get_Item(0));


                                        Parameter param;


                                        //param = connDuct.get_Parameter(BuiltInParameter.CONNECTOR_HEIGHT);
                                        //param.Set(0);

                                        // param = connDuct.get_Parameter(BuiltInParameter.CONNECTOR_WIDTH);
                                        //param.Set(0);



                                        param = connDuct.get_Parameter(BuiltInParameter.CONNECTOR_DIAMETER);
                                        param.Set(conDiameter);


                                        param = connDuct.get_Parameter(BuiltInParameter.RBS_DUCT_FLOW_CONFIGURATION_PARAM);
                                        param.Set(flowConfiguration);

                                        param = connDuct.get_Parameter(BuiltInParameter.RBS_DUCT_FLOW_DIRECTION_PARAM);
                                        param.Set(flowDirection);


                                        param = connDuct.get_Parameter(BuiltInParameter.RBS_DUCT_FITTING_LOSS_METHOD_PARAM);
                                        param.Set(lossMethod);


                                        param = connDuct.get_Parameter(BuiltInParameter.RBS_CONNECTOR_DESCRIPTION);
                                        param.Set(conDescription);


                                        refTrans.Commit();

                                    }
                                    //}
                                }
                            }
                        }

                    }

                    //famDoc.Save();

                }
                trans.Commit();
            }
            return true;
        }


    }
}

 

 

0 Likes
779 Views
3 Replies
Replies (3)
Message 2 of 4

Noetie.nibi
Participant
Participant

Did you find a solution?

0 Likes
Message 3 of 4

jeremy_tammik
Alumni
Alumni

Yes, sure. Take a look at the Revit SDK FamilyCreation CreateAirHandler sample. That should help you too, @Noetie.nibi 

  

Jeremy Tammik Developer Advocacy and Support + The Building Coder + Autodesk Developer Network + ADN Open
Message 4 of 4

Noetie.nibi
Participant
Participant

thanks @jeremy_tammik 😀

0 Likes