Message 1 of 4
How to place a connector element on a specific face on imported AutoCAD element
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
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; } } }