/// <summary> /// Implement this method as an external command for Revit. /// </summary> /// <param name="commandData">An object that is passed to the external application /// which contains data related to the command, /// such as the application object and active view.</param> /// <param name="message">A message that can be set by the external application /// which will be displayed if a failure or cancellation is returned by /// the external command.</param> /// <param name="elements">A set of elements to which the external application /// can add elements that are to be highlighted in case of failure or cancellation.</param> /// <returns>Return the status of the external command. /// A result of Succeeded means that the API external method functioned as expected. /// Cancelled can be used to signify that the user cancelled the external operation /// at some point. Failure should be returned if the application is unable to proceed with /// the operation.</returns> public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements) { UIDocument activeDoc = commandData.Application.ActiveUIDocument; Autodesk.Revit.DB.Document doc = activeDoc.Document; using (Transaction trans = new Transaction(doc, "ContextualAnalyticalModel.UpdateRelation")) { trans.Start(); //select object for which we want to break the relation Reference eRef = activeDoc.Selection.PickObject(ObjectType.Element, "Please select the element for which you want to break relation"); ElementId selectedElementId = null; if (eRef != null && eRef.ElementId != ElementId.InvalidElementId) { selectedElementId = eRef.ElementId; } // Gets the AnalyticalToPhysicalAssociationManager for this Revit document AnalyticalToPhysicalAssociationManager analyticalToPhysicalmanager = AnalyticalToPhysicalAssociationManager.GetAnalyticalToPhysicalAssociationManager(doc); if (analyticalToPhysicalmanager == null) { return(Result.Failed); } //break relation analyticalToPhysicalmanager.RemoveAssociation(selectedElementId); trans.Commit(); } return(Result.Succeeded); }
/// <summary> /// Implement this method as an external command for Revit. /// </summary> /// <param name="commandData">An object that is passed to the external application /// which contains data related to the command, /// such as the application object and active view.</param> /// <param name="message">A message that can be set by the external application /// which will be displayed if a failure or cancellation is returned by /// the external command.</param> /// <param name="elements">A set of elements to which the external application /// can add elements that are to be highlighted in case of failure or cancellation.</param> /// <returns>Return the status of the external command. /// A result of Succeeded means that the API external method functioned as expected. /// Cancelled can be used to signify that the user cancelled the external operation /// at some point. Failure should be returned if the application is unable to proceed with /// the operation.</returns> public virtual Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements) { UIDocument activeDoc = commandData.Application.ActiveUIDocument; Autodesk.Revit.DB.Document doc = activeDoc.Document; if (null == doc) { return(Result.Failed); } using (Transaction trans = new Transaction(doc, "Revit.SDK.Samples.AddRelationBetweenPhysicalAndAnalyticalElements")) { trans.Start(); ElementId analyticalElementId = ContextualAnalyticalModel.Utilities.GetSelectedObject(activeDoc, "Please select analytical element"); ElementId physicalElementId = ContextualAnalyticalModel.Utilities.GetSelectedObject(activeDoc, "Please select physical element"); //gets the AnalyticalToPhysicalAssociationManager for the current document AnalyticalToPhysicalAssociationManager analyticalToPhysicalmanager = AnalyticalToPhysicalAssociationManager.GetAnalyticalToPhysicalAssociationManager(doc); if (analyticalToPhysicalmanager == null) { return(Result.Failed); } //creates a new relation between physical and analytical selected elements analyticalToPhysicalmanager.AddAssociation(analyticalElementId, physicalElementId); trans.Commit(); } return(Result.Succeeded); }
/// <summary> /// Generate a Transform instance which as Transform property of BoundingBoxXYZ, /// when the user select a floor, this method will be called /// </summary> /// <returns>the reference of Transform, return null if it can't be generated</returns> Transform GenerateFloorTransform() { Transform transform = null; Floor floor = m_currentComponent as Floor; // First get the Analytical Model lines AnalyticalPanel model = null; Document document = floor.Document; AnalyticalToPhysicalAssociationManager assocManager = AnalyticalToPhysicalAssociationManager.GetAnalyticalToPhysicalAssociationManager(document); if (assocManager != null) { ElementId associatedElementId = assocManager.GetAssociatedElementId(floor.Id); if (associatedElementId != ElementId.InvalidElementId) { Element associatedElement = document.GetElement(associatedElementId); if (associatedElement != null && associatedElement is AnalyticalPanel) { model = associatedElement as AnalyticalPanel; } } } if (null == model) { m_errorInformation = "Please select a structural floor."; return(transform); } CurveArray curves = m_project.Document.Application.Create.NewCurveArray(); IList <Curve> curveList = model.GetOuterContour().ToList(); foreach (Curve curve in curveList) { curves.Append(curve); } if (null == curves || true == curves.IsEmpty) { m_errorInformation = "The program should never go here."; return(transform); } // Now I am sure I can create a transform instance. transform = Transform.Identity; // Third find the middle point of the floor and set it as Origin property. Autodesk.Revit.DB.XYZ midPoint = XYZMath.FindMiddlePoint(curves); transform.Origin = midPoint; // At last find out the directions of the created view, and set it as Basis property. Autodesk.Revit.DB.XYZ basisZ = XYZMath.FindFloorViewDirection(curves); Autodesk.Revit.DB.XYZ basisX = XYZMath.FindRightDirection(basisZ); Autodesk.Revit.DB.XYZ basisY = XYZMath.FindUpDirection(basisZ); transform.set_Basis(0, basisX); transform.set_Basis(1, basisY); transform.set_Basis(2, basisZ); return(transform); }
/// <summary> /// get necessary data when create AreaReinforcement on a horizontal floor /// </summary> /// <param name="floor">floor on which to create AreaReinforcemen</param> /// <param name="refer">reference of the horizontal face on the floor</param> /// <param name="curves">curves compose the horizontal face of the floor</param> /// <returns>is successful</returns> public bool GetFloorGeom(Floor floor, ref Reference refer, ref IList <Curve> curves) { //get horizontal face reference FaceArray faces = GeomUtil.GetFaces(floor); foreach (Face face in faces) { if (GeomUtil.IsHorizontalFace(face)) { refer = face.Reference; break; } } //no proper reference if (null == refer) { return(false); } //check the analytical model profile is rectangular //check the analytical model profile is rectangular Document document = floor.Document; AnalyticalToPhysicalAssociationManager assocManager = AnalyticalToPhysicalAssociationManager.GetAnalyticalToPhysicalAssociationManager(document); AnalyticalPanel model = null; if (assocManager != null) { ElementId associatedElementId = assocManager.GetAssociatedElementId(floor.Id); if (associatedElementId != ElementId.InvalidElementId) { Element associatedElement = document.GetElement(associatedElementId); if (associatedElement != null && associatedElement is AnalyticalPanel) { model = associatedElement as AnalyticalPanel; } } } if (null == model) { return(false); } curves = model.GetOuterContour().ToList(); if (!GeomUtil.IsRectangular(curves)) { return(false); } return(true); }
/// <summary> /// Search for the In-Place family instance's properties data to be listed /// and graphics data to be drawn. /// </summary> /// <param name="inPlaceMember">properties data to be listed</param> /// <param name="model">graphics data to be draw</param> /// <returns>Returns true if retrieved this data</returns> private bool PrepareData(ref FamilyInstance inPlaceMember, ref AnalyticalElement model) { ElementSet selected = new ElementSet(); foreach (ElementId elementId in m_commandData.Application.ActiveUIDocument.Selection.GetElementIds()) { selected.Insert(m_commandData.Application.ActiveUIDocument.Document.GetElement(elementId)); } if (selected.Size != 1) { return(false); } foreach (object o in selected) { inPlaceMember = o as FamilyInstance; if (null == inPlaceMember) { return(false); } } Document document = inPlaceMember.Document; AnalyticalToPhysicalAssociationManager relManager = AnalyticalToPhysicalAssociationManager.GetAnalyticalToPhysicalAssociationManager(document); if (relManager != null) { ElementId associatedElementId = relManager.GetAssociatedElementId(inPlaceMember.Id); if (associatedElementId != ElementId.InvalidElementId) { Element associatedElement = document.GetElement(associatedElementId); if (associatedElement != null && associatedElement is AnalyticalElement) { model = associatedElement as AnalyticalElement; } } } if (null == model) { return(false); } return(true); }
/// <summary> /// Get the analytical model object from an element. /// </summary> /// <param name="element">The selected element maybe has analytical model lines</param> /// <returns>Return analytical model object, or else return null.</returns> private AnalyticalElement GetAnalyticalElement(Element element) { Document document = element.Document; AnalyticalElement analyticalElement = null; AnalyticalToPhysicalAssociationManager assocManager = AnalyticalToPhysicalAssociationManager.GetAnalyticalToPhysicalAssociationManager(document); if (assocManager != null) { ElementId associatedElementId = assocManager.GetAssociatedElementId(element.Id); if (associatedElementId != ElementId.InvalidElementId) { Element associatedElement = document.GetElement(associatedElementId); if (associatedElement != null && associatedElement is AnalyticalElement) { analyticalElement = associatedElement as AnalyticalElement; } } } return(analyticalElement); }
AnalyticalElement GetAnalyticalElement(Autodesk.Revit.DB.Element element) { AnalyticalElement analyticalModel = null; Document document = element.Document; AnalyticalToPhysicalAssociationManager assocManager = AnalyticalToPhysicalAssociationManager.GetAnalyticalToPhysicalAssociationManager(document); if (assocManager != null) { ElementId associatedElementId = assocManager.GetAssociatedElementId(element.Id); if (associatedElementId != ElementId.InvalidElementId) { Element associatedElement = document.GetElement(associatedElementId); if (associatedElement != null && associatedElement is AnalyticalElement) { analyticalModel = associatedElement as AnalyticalElement; } } } return(analyticalModel); }
/// <summary> /// the selected element must be a structural Column/brace/Beam/Wall/Wall Foundation/Slab/Foundation Slab. /// </summary> /// <returns></returns> private bool IsExpectedElement(Element element) { // judge the element's type. If it is any type of FamilyInstance, Wall, Floor or // WallFoundation, then get judge if it has a AnalyticalModel. AnalyticalToPhysicalAssociationManager assocManager = AnalyticalToPhysicalAssociationManager.GetAnalyticalToPhysicalAssociationManager(element.Document); AnalyticalElement elemAnalytical = null; if (assocManager != null) { ElementId associatedElementId = assocManager.GetAssociatedElementId(element.Id); if (associatedElementId != ElementId.InvalidElementId) { Element associatedElement = element.Document.GetElement(associatedElementId); if (associatedElement != null && associatedElement is AnalyticalElement) { elemAnalytical = associatedElement as AnalyticalElement; } } } if (null == elemAnalytical) { return(false); } FamilyInstance familyInstance = element as FamilyInstance; if ((null != familyInstance) && (StructuralType.Footing == familyInstance.StructuralType)) { return(false); // if selected a isolated foundation not create BC } if (element is FamilyInstance || element is Wall || element is Floor || element is WallFoundation) { return(true); } return(false); }
/// <summary> /// get necessary data when create AreaReinforcement on a straight wall /// </summary> /// <param name="wall">wall on which to create AreaReinforcemen</param> /// <param name="refer">reference of the vertical straight face on the wall</param> /// <param name="curves">curves compose the vertical face of the wall</param> /// <returns>is successful</returns> public bool GetWallGeom(Wall wall, ref Reference refer, ref IList <Curve> curves) { FaceArray faces = GeomUtil.GetFaces(wall); LocationCurve locCurve = wall.Location as LocationCurve; //unless API has bug, locCurve can't be null if (null == locCurve) { return(false); } //check the location is line Line locLine = locCurve.Curve as Line; if (null == locLine) { return(false); } //get the face reference foreach (Face face in faces) { if (GeomUtil.IsParallel(face, locLine)) { refer = face.Reference; break; } } //can't find proper reference if (null == refer) { return(false); } //check the analytical model profile is rectangular Document document = wall.Document; AnalyticalToPhysicalAssociationManager assocManager = AnalyticalToPhysicalAssociationManager.GetAnalyticalToPhysicalAssociationManager(document); AnalyticalPanel model = null; if (assocManager != null) { ElementId associatedElementId = assocManager.GetAssociatedElementId(wall.Id); if (associatedElementId != ElementId.InvalidElementId) { Element associatedElement = document.GetElement(associatedElementId); if (associatedElement != null && associatedElement is AnalyticalPanel) { model = associatedElement as AnalyticalPanel; } } } if (null == model) { return(false); } curves = model.GetOuterContour().ToList(); if (!GeomUtil.IsRectangular(curves)) { return(false); } return(true); }
/// <summary> /// get all the required information of selected elements and store them in a data table /// </summary> /// <param name="selectedElements"> /// all selected elements in Revit main program /// </param> /// <returns> /// a data table which store all the required information /// </returns> private DataTable StoreInformationInDataTable(ElementSet selectedElements) { DataTable informationTable = CreatDataTable(); foreach (Element element in selectedElements) { // Get AnalyticalElement analyticalModel = null; Document document = element.Document; AnalyticalToPhysicalAssociationManager assocManager = AnalyticalToPhysicalAssociationManager.GetAnalyticalToPhysicalAssociationManager(document); if (assocManager != null) { ElementId associatedElementId = assocManager.GetAssociatedElementId(element.Id); if (associatedElementId != ElementId.InvalidElementId) { Element associatedElement = document.GetElement(associatedElementId); if (associatedElement != null && associatedElement is AnalyticalElement) { analyticalModel = associatedElement as AnalyticalElement; } } } if (null == analyticalModel) // skip no AnalyticalModel element { continue; } DataRow newRow = informationTable.NewRow(); string idValue = element.Id.ToString(); // store element Id value string typeName = ""; // store element type name string[] supportInformation = GetSupportInformation(analyticalModel); // store support information // get element type information switch (element.GetType().Name) { case "WallFoundation": WallFoundation wallFound = element as WallFoundation; ElementType wallFootSymbol = m_revit.Application.ActiveUIDocument.Document.GetElement(wallFound.GetTypeId()) as ElementType;// get element Type typeName = wallFootSymbol.Category.Name + ": " + wallFootSymbol.Name; break; case "FamilyInstance": FamilyInstance familyInstance = element as FamilyInstance; FamilySymbol symbol = m_revit.Application.ActiveUIDocument.Document.GetElement(familyInstance.GetTypeId()) as FamilySymbol; typeName = symbol.Family.Name + ": " + symbol.Name; break; case "Floor": Floor slab = element as Floor; FloorType slabType = m_revit.Application.ActiveUIDocument.Document.GetElement(slab.GetTypeId()) as FloorType; // get element type typeName = slabType.Category.Name + ": " + slabType.Name; break; case "Wall": Wall wall = element as Wall; WallType wallType = m_revit.Application.ActiveUIDocument.Document.GetElement(wall.GetTypeId()) as WallType; // get element type typeName = wallType.Kind.ToString() + ": " + wallType.Name; break; default: break; } // set the relative information of current element into the table. newRow["Id"] = idValue; newRow["Element Type"] = typeName; newRow["Support Type"] = supportInformation[0]; newRow["Remark"] = supportInformation[1]; informationTable.Rows.Add(newRow); } return(informationTable); }
/// <summary> /// Exports a CeilingAndFloor element to IFC. /// </summary> /// <param name="exporterIFC">The ExporterIFC object.</param> /// <param name="floor">The floor element.</param> /// <param name="geometryElement">The geometry element.</param> /// <param name="productWrapper">The ProductWrapper.</param> public static void ExportCeilingAndFloorElement(ExporterIFC exporterIFC, CeilingAndFloor floorElement, ref GeometryElement geometryElement, ProductWrapper productWrapper) { if (geometryElement == null) { return; } IFCFile file = exporterIFC.GetFile(); string ifcEnumType; IFCExportInfoPair exportType = ExporterUtil.GetProductExportType(exporterIFC, floorElement, out ifcEnumType); if (!ElementFilteringUtil.IsElementVisible(floorElement)) { return; } // Check the intended IFC entity or type name is in the exclude list specified in the UI IFCEntityType elementClassTypeEnum; if (Enum.TryParse(exportType.ExportInstance.ToString(), out elementClassTypeEnum) || Enum.TryParse(exportType.ExportType.ToString(), out elementClassTypeEnum)) { if (ExporterCacheManager.ExportOptionsCache.IsElementInExcludeList(elementClassTypeEnum)) { return; } } Document doc = floorElement.Document; using (SubTransaction tempPartTransaction = new SubTransaction(doc)) { MaterialLayerSetInfo layersetInfo = new MaterialLayerSetInfo(exporterIFC, floorElement, productWrapper); // For IFC4RV export, Element will be split into its parts(temporarily) in order to export the wall by its parts // If Parts are created by code and not by user then their names should be equal to Material names. bool setMaterialNameToPartName = ExporterUtil.CreateParts(floorElement, layersetInfo.MaterialIds.Count, ref geometryElement); ExporterUtil.ExportPartAs exportPartAs = ExporterUtil.CanExportByComponentsOrParts(floorElement); bool exportByComponents = exportPartAs == ExporterUtil.ExportPartAs.ShapeAspect; bool exportParts = exportPartAs == ExporterUtil.ExportPartAs.Part; if (exportParts && !PartExporter.CanExportElementInPartExport(floorElement, floorElement.LevelId, false)) { return; } using (IFCTransaction tr = new IFCTransaction(file)) { bool canExportAsContainerOrWithExtrusionAnalyzer = (!exportParts && (floorElement is Floor)); if (canExportAsContainerOrWithExtrusionAnalyzer) { // Try to export the Floor slab as a container. If that succeeds, we are done. // If we do export the floor as a container, it will take care of the local placement and transform there, so we need to leave // this out of the IFCTransformSetter and PlacementSetter scopes below, or else we'll get double transforms. IFCAnyHandle floorHnd = RoofExporter.ExportRoofOrFloorAsContainer(exporterIFC, floorElement, geometryElement, productWrapper); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(floorHnd)) { tr.Commit(); return; } } IList <IFCAnyHandle> slabHnds = new List <IFCAnyHandle>(); IList <IFCAnyHandle> brepSlabHnds = new List <IFCAnyHandle>(); IList <IFCAnyHandle> nonBrepSlabHnds = new List <IFCAnyHandle>(); IFCAnyHandle ownerHistory = ExporterCacheManager.OwnerHistoryHandle; IFCAnyHandle typeHandle = null; using (IFCTransformSetter transformSetter = IFCTransformSetter.Create()) { // Check for containment override IFCAnyHandle overrideContainerHnd = null; ElementId overrideContainerId = ParameterUtil.OverrideContainmentParameter(exporterIFC, floorElement, out overrideContainerHnd); using (PlacementSetter placementSetter = PlacementSetter.Create(exporterIFC, floorElement, null, null, overrideContainerId, overrideContainerHnd)) { IFCAnyHandle localPlacement = placementSetter.LocalPlacement; // The routine ExportExtrudedSlabOpenings is called if exportedAsInternalExtrusion is true, and it requires having a valid level association. // Disable calling ExportSlabAsExtrusion if we can't handle potential openings. bool canExportAsInternalExtrusion = placementSetter.LevelInfo != null && !ExporterCacheManager.ExportOptionsCache.ExportAs4ReferenceView; bool exportedAsInternalExtrusion = false; ElementId catId = CategoryUtil.GetSafeCategoryId(floorElement); IList <IFCAnyHandle> prodReps = new List <IFCAnyHandle>(); IList <ShapeRepresentationType> repTypes = new List <ShapeRepresentationType>(); IList <IList <CurveLoop> > extrusionLoops = new List <IList <CurveLoop> >(); IList <IFCExtrusionCreationData> loopExtraParams = new List <IFCExtrusionCreationData>(); Plane floorPlane = GeometryUtil.CreateDefaultPlane(); IFCExtrusionCreationData ecData = new IFCExtrusionCreationData(); IList <IFCAnyHandle> localPlacements = new List <IFCAnyHandle>(); if (!exportParts) { if (canExportAsContainerOrWithExtrusionAnalyzer) { Floor floor = floorElement as Floor; // Next, try to use the ExtrusionAnalyzer for the limited cases it handles - 1 solid, no openings, end clippings only. // Also limited to cases with line and arc boundaries. // SolidMeshGeometryInfo solidMeshInfo = GeometryUtil.GetSplitSolidMeshGeometry(geometryElement); IList <Solid> solids = solidMeshInfo.GetSolids(); IList <Mesh> meshes = solidMeshInfo.GetMeshes(); IList <GeometryObject> gObjs = FamilyExporterUtil.RemoveInvisibleSolidsAndMeshes(floorElement.Document, exporterIFC, ref solids, ref meshes); if (solids.Count == 1 && meshes.Count == 0) { // floorExtrusionDirection is set to (0, 0, -1) because extrusionAnalyzerFloorPlane is computed from the top face of the floor XYZ floorExtrusionDirection = new XYZ(0, 0, -1); XYZ modelOrigin = XYZ.Zero; XYZ floorOrigin = floor.GetVerticalProjectionPoint(modelOrigin, FloorFace.Top); if (floorOrigin == null) { // GetVerticalProjectionPoint may return null if FloorFace.Top is an edited face that doesn't // go through the Revit model origin. We'll try the midpoint of the bounding box instead. BoundingBoxXYZ boundingBox = floorElement.get_BoundingBox(null); modelOrigin = (boundingBox.Min + boundingBox.Max) / 2.0; floorOrigin = floor.GetVerticalProjectionPoint(modelOrigin, FloorFace.Top); } if (floorOrigin != null) { XYZ floorDir = floor.GetNormalAtVerticalProjectionPoint(floorOrigin, FloorFace.Top); Plane extrusionAnalyzerFloorBasePlane = GeometryUtil.CreatePlaneByNormalAtOrigin(floorDir); GenerateAdditionalInfo additionalInfo = GenerateAdditionalInfo.GenerateBody; additionalInfo |= ExporterCacheManager.ExportOptionsCache.ExportAs4 ? GenerateAdditionalInfo.GenerateFootprint : GenerateAdditionalInfo.None; // Skip generate body item for IFC4RV. It will be handled later in PartExporter.ExportHostPartAsShapeAspects() if (exportByComponents) { additionalInfo &= ~GenerateAdditionalInfo.GenerateBody; } ExtrusionExporter.ExtraClippingData extraClippingData = null; HandleAndData floorAndProperties = ExtrusionExporter.CreateExtrusionWithClippingAndProperties(exporterIFC, floorElement, false, catId, solids[0], extrusionAnalyzerFloorBasePlane, floorOrigin, floorExtrusionDirection, null, out extraClippingData, addInfo: additionalInfo); if (extraClippingData.CompletelyClipped) { return; } IList <IFCAnyHandle> representations = new List <IFCAnyHandle>(); if (floorAndProperties.Handle != null) { representations.Add(floorAndProperties.Handle); repTypes.Add(ShapeRepresentationType.SweptSolid); } // Footprint representation will only be exported in export to IFC4 if (((additionalInfo & GenerateAdditionalInfo.GenerateFootprint) != 0) && (floorAndProperties.FootprintInfo != null)) { IFCAnyHandle footprintShapeRep = floorAndProperties.FootprintInfo.CreateFootprintShapeRepresentation(exporterIFC); representations.Add(footprintShapeRep); } if (exportByComponents) { IFCAnyHandle prodRep = RepresentationUtil.CreateProductDefinitionShapeWithoutBodyRep(exporterIFC, floorElement, catId, geometryElement, representations); prodReps.Add(prodRep); } else if (representations.Count > 0 && floorAndProperties.Handle != null) // Only when at least the body rep exists will come here { IFCAnyHandle prodRep = IFCInstanceExporter.CreateProductDefinitionShape(file, null, null, representations); prodReps.Add(prodRep); } if (floorAndProperties.Data != null) { loopExtraParams.Add(floorAndProperties.Data); } } } } // Use internal routine as backup that handles openings. if (prodReps.Count == 0 && canExportAsInternalExtrusion && !exportByComponents) { exportedAsInternalExtrusion = ExporterIFCUtils.ExportSlabAsExtrusion(exporterIFC, floorElement, geometryElement, transformSetter, localPlacement, out localPlacements, out prodReps, out extrusionLoops, out loopExtraParams, floorPlane); if (exportedAsInternalExtrusion) { AugmentHandleInformation(exporterIFC, floorElement, geometryElement, prodReps); for (int ii = 0; ii < prodReps.Count; ii++) { // all are extrusions repTypes.Add(ShapeRepresentationType.SweptSolid); // Footprint representation will only be exported in export to IFC4 if (ExporterCacheManager.ExportOptionsCache.ExportAs4) { if (extrusionLoops.Count > ii) { if (extrusionLoops[ii].Count > 0) { // Get the extrusion footprint using the first Curveloop. Transform needs to be obtained from the returned local placement Transform lcs = ExporterIFCUtils.GetUnscaledTransform(exporterIFC, localPlacements[ii]); IFCAnyHandle footprintGeomRepItem = GeometryUtil.CreateIFCCurveFromCurveLoop(exporterIFC, extrusionLoops[ii][0], lcs, floorPlane.Normal); IFCAnyHandle contextOfItemsFootprint = exporterIFC.Get3DContextHandle("FootPrint"); ISet <IFCAnyHandle> repItem = new HashSet <IFCAnyHandle>(); repItem.Add(footprintGeomRepItem); IFCAnyHandle footprintShapeRepresentation = RepresentationUtil.CreateBaseShapeRepresentation(exporterIFC, contextOfItemsFootprint, "FootPrint", "Curve2D", repItem); IList <IFCAnyHandle> reps = new List <IFCAnyHandle>(); reps.Add(footprintShapeRepresentation); IFCAnyHandleUtil.AddRepresentations(prodReps[ii], reps); } } } } } } IFCAnyHandle prodDefHnd; if (prodReps.Count == 0) { if (exportByComponents) { prodDefHnd = RepresentationUtil.CreateProductDefinitionShapeWithoutBodyRep(exporterIFC, floorElement, catId, geometryElement, null); prodReps.Add(prodDefHnd); } else { // Brep representation using tesellation after ExportSlabAsExtrusion does not return prodReps BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true, ExportOptionsCache.ExportTessellationLevel.Medium); BodyData bodyData; prodDefHnd = RepresentationUtil.CreateAppropriateProductDefinitionShape(exporterIFC, floorElement, catId, geometryElement, bodyExporterOptions, null, ecData, out bodyData); if (IFCAnyHandleUtil.IsNullOrHasNoValue(prodDefHnd)) { ecData.ClearOpenings(); return; } prodReps.Add(prodDefHnd); repTypes.Add(bodyData.ShapeRepresentationType); } } } // Create the slab from either the extrusion or the BRep information. string ifcGUID = GUIDUtil.CreateGUID(floorElement); int numReps = exportParts ? 1 : prodReps.Count; // Deal with a couple of cases that have non-standard defaults. switch (exportType.ExportInstance) { case IFCEntityType.IfcCovering: exportType.ValidatedPredefinedType = IFCValidateEntry.GetValidIFCType <IFCCoveringType>(floorElement, ifcEnumType, "FLOORING"); break; case IFCEntityType.IfcSlab: { bool isBaseSlab = false; AnalyticalToPhysicalAssociationManager manager = AnalyticalToPhysicalAssociationManager.GetAnalyticalToPhysicalAssociationManager(doc); if (manager != null) { ElementId counterPartId = manager.GetAssociatedElementId(floorElement.Id); if (counterPartId != ElementId.InvalidElementId) { Element counterpartElem = doc.GetElement(counterPartId); if (counterpartElem != null && counterpartElem is AnalyticalElement) { AnalyzeAs slabAnalyzeAs = (counterpartElem as AnalyticalElement).AnalyzeAs; isBaseSlab = (slabAnalyzeAs == AnalyzeAs.SlabOnGrade) || (slabAnalyzeAs == AnalyzeAs.Mat); } } } exportType.ValidatedPredefinedType = IFCValidateEntry.GetValidIFCType <IFCSlabType>(floorElement, ifcEnumType, isBaseSlab ? "BASESLAB" : "FLOOR"); } break; } for (int ii = 0; ii < numReps; ii++) { string ifcName = NamingUtil.GetNameOverride(floorElement, NamingUtil.GetIFCNamePlusIndex(floorElement, ii == 0 ? -1 : ii + 1)); string currentGUID = (ii == 0) ? ifcGUID : GUIDUtil.GenerateIFCGuidFrom(floorElement, "Slab Copy " + ii.ToString()); IFCAnyHandle localPlacementHnd = exportedAsInternalExtrusion ? localPlacements[ii] : localPlacement; IFCAnyHandle slabHnd = null; slabHnd = IFCInstanceExporter.CreateGenericIFCEntity(exportType, exporterIFC, floorElement, currentGUID, ownerHistory, localPlacementHnd, exportParts ? null : prodReps[ii]); if (IFCAnyHandleUtil.IsNullOrHasNoValue(slabHnd)) { return; } if (!string.IsNullOrEmpty(ifcName)) { IFCAnyHandleUtil.OverrideNameAttribute(slabHnd, ifcName); } // Pre IFC4 Slab does not have PredefinedType if (!string.IsNullOrEmpty(exportType.ValidatedPredefinedType) && !ExporterCacheManager.ExportOptionsCache.ExportAsOlderThanIFC4) { IFCAnyHandleUtil.SetAttribute(slabHnd, "PredefinedType", exportType.ValidatedPredefinedType, true); } if (exportParts) { PartExporter.ExportHostPart(exporterIFC, floorElement, slabHnd, productWrapper, placementSetter, localPlacementHnd, null, setMaterialNameToPartName); } else if (exportByComponents) { IFCExtrusionCreationData partECData = new IFCExtrusionCreationData(); IFCAnyHandle hostShapeRepFromParts = PartExporter.ExportHostPartAsShapeAspects(exporterIFC, floorElement, prodReps[ii], productWrapper, placementSetter, localPlacement, ElementId.InvalidElementId, layersetInfo, partECData); loopExtraParams.Add(partECData); } slabHnds.Add(slabHnd); // For IFC4RV, export of the geometry is already handled in PartExporter.ExportHostPartAsShapeAspects() if (!exportParts && !exportByComponents) { if (repTypes[ii] == ShapeRepresentationType.Brep || repTypes[ii] == ShapeRepresentationType.Tessellation) { brepSlabHnds.Add(slabHnd); } else { nonBrepSlabHnds.Add(slabHnd); } } OpeningUtil.CreateOpeningsIfNecessary(slabHnd, floorElement, ecData, null, exporterIFC, localPlacement, placementSetter, productWrapper); } typeHandle = ExporterUtil.CreateGenericTypeFromElement(floorElement, exportType, file, ownerHistory, exportType.ValidatedPredefinedType, productWrapper); for (int ii = 0; ii < numReps; ii++) { IFCExtrusionCreationData loopExtraParam = ii < loopExtraParams.Count ? loopExtraParams[ii] : null; productWrapper.AddElement(floorElement, slabHnds[ii], placementSetter, loopExtraParam, true, exportType); ExporterCacheManager.TypeRelationsCache.Add(typeHandle, slabHnds[ii]); ExporterUtil.AddIntoComplexPropertyCache(slabHnds[ii], layersetInfo); } // This call to the native function appears to create Brep opening also when appropriate. But the creation of the IFC instances is not // controllable from the managed code. Therefore in some cases BRep geometry for Opening will still be exported even in the Reference View if (exportedAsInternalExtrusion) { ISet <IFCAnyHandle> oldCreatedObjects = productWrapper.GetAllObjects(); ExporterIFCUtils.ExportExtrudedSlabOpenings(exporterIFC, floorElement, placementSetter.LevelInfo, localPlacements[0], slabHnds, extrusionLoops, floorPlane, productWrapper.ToNative()); ISet <IFCAnyHandle> newCreatedObjects = productWrapper.GetAllObjects(); newCreatedObjects.ExceptWith(oldCreatedObjects); AugmentHandleInformation(exporterIFC, floorElement, geometryElement, newCreatedObjects); } } if (!exportParts) { if (ExporterCacheManager.ExportOptionsCache.ExportAs4ReferenceView) { HostObjectExporter.ExportHostObjectMaterials(exporterIFC, floorElement, productWrapper.GetAnElement(), geometryElement, productWrapper, ElementId.InvalidElementId, IFCLayerSetDirection.Axis3, false, typeHandle); } else { if (nonBrepSlabHnds.Count > 0) { HostObjectExporter.ExportHostObjectMaterials(exporterIFC, floorElement, nonBrepSlabHnds, geometryElement, productWrapper, ElementId.InvalidElementId, IFCLayerSetDirection.Axis3, false, typeHandle); } if (brepSlabHnds.Count > 0) { HostObjectExporter.ExportHostObjectMaterials(exporterIFC, floorElement, brepSlabHnds, geometryElement, productWrapper, ElementId.InvalidElementId, IFCLayerSetDirection.Axis3, true, typeHandle); } } } } tr.Commit(); return; } } }
/// <summary> /// find out every wall in the selection and add a dimension from the start of the wall to its end /// </summary> /// <returns>if add successfully, true will be returned, else false will be returned</returns> public bool AddDimension() { if (!initialize()) { return false; } Transaction transaction = new Transaction(m_revit.Application.ActiveUIDocument.Document, "Add Dimensions"); transaction.Start(); //get out all the walls in this array, and create a dimension from its start to its end for (int i = 0; i < m_walls.Count; i++) { Wall wallTemp = m_walls[i] as Wall; if (null == wallTemp) { continue; } //get location curve Location location = wallTemp.Location; LocationCurve locationline = location as LocationCurve; if (null == locationline) { continue; } //New Line Line newLine = null; //get reference ReferenceArray referenceArray = new ReferenceArray(); AnalyticalPanel analyticalModel = null; Document document = wallTemp.Document; AnalyticalToPhysicalAssociationManager assocManager = AnalyticalToPhysicalAssociationManager.GetAnalyticalToPhysicalAssociationManager(document); if (assocManager != null) { ElementId associatedElementId = assocManager.GetAssociatedElementId(wallTemp.Id); if (associatedElementId != ElementId.InvalidElementId) { Element associatedElement = document.GetElement(associatedElementId); if (associatedElement != null && associatedElement is AnalyticalPanel) { analyticalModel = associatedElement as AnalyticalPanel; } } } IList<Curve> activeCurveList = analyticalModel.GetOuterContour().ToList(); foreach (Curve aCurve in activeCurveList) { // find non-vertical curve from analytical model if (aCurve.GetEndPoint(0).Z == aCurve.GetEndPoint(1).Z) newLine = aCurve as Line; if (aCurve.GetEndPoint(0).Z != aCurve.GetEndPoint(1).Z) { AnalyticalModelSelector amSelector = new AnalyticalModelSelector(aCurve); amSelector.CurveSelector = AnalyticalCurveSelector.StartPoint; referenceArray.Append(analyticalModel.GetReference(amSelector)); } if (2 == referenceArray.Size) break; } if (referenceArray.Size != 2) { m_errorMessage += "Did not find two references"; return false; } try { //try to add new a dimension Autodesk.Revit.UI.UIApplication app = m_revit.Application; Document doc = app.ActiveUIDocument.Document; Autodesk.Revit.DB.XYZ p1 = new XYZ( newLine.GetEndPoint(0).X + 5, newLine.GetEndPoint(0).Y + 5, newLine.GetEndPoint(0).Z); Autodesk.Revit.DB.XYZ p2 = new XYZ( newLine.GetEndPoint(1).X + 5, newLine.GetEndPoint(1).Y + 5, newLine.GetEndPoint(1).Z); Line newLine2 = Line.CreateBound(p1, p2); Dimension newDimension = doc.Create.NewDimension( doc.ActiveView, newLine2, referenceArray); } // catch the exceptions catch (Exception ex) { m_errorMessage += ex.ToString(); return false; } } transaction.Commit(); return true; }
/// <summary> /// Get a floor's profile. /// </summary> /// <param name="floor">The floor whose profile you want to get.</param> /// <returns>The profile of the floor.</returns> private CurveArray GetFloorProfile(Floor floor) { CurveArray floorProfile = new CurveArray(); // Structural slab's profile can be found in it's analytical element. Document document = floor.Document; AnalyticalPanel analyticalModel = null; AnalyticalToPhysicalAssociationManager relManager = AnalyticalToPhysicalAssociationManager.GetAnalyticalToPhysicalAssociationManager(document); if (relManager != null) { ElementId associatedElementId = relManager.GetAssociatedElementId(floor.Id); if (associatedElementId != ElementId.InvalidElementId) { Element associatedElement = document.GetElement(associatedElementId); if (associatedElement != null && associatedElement is AnalyticalPanel) { analyticalModel = associatedElement as AnalyticalPanel; } } } if (null != analyticalModel) { IList <Curve> curveList = analyticalModel.GetOuterContour().ToList(); for (int i = 0; i < curveList.Count; i++) { floorProfile.Append(curveList[i]); } return(floorProfile); } // Nonstructural floor's profile can be formed through it's Geometry. Options aOptions = m_revit.Application.Create.NewGeometryOptions(); Autodesk.Revit.DB.GeometryElement aElementOfGeometry = floor.get_Geometry(aOptions); //GeometryObjectArray geometryObjects = aElementOfGeometry.Objects; IEnumerator <GeometryObject> Objects = aElementOfGeometry.GetEnumerator(); //foreach (GeometryObject o in geometryObjects) while (Objects.MoveNext()) { GeometryObject o = Objects.Current; Solid solid = o as Solid; if (null == solid) { continue; } // Form the floor's profile through solid's edges. EdgeArray edges = solid.Edges; for (int i = 0; i < (edges.Size) / 3; i++) { Edge edge = edges.get_Item(i); List <XYZ> xyzArray = edge.Tessellate() as List <XYZ>; // A set of points. for (int j = 0; j < (xyzArray.Count - 1); j++) { Autodesk.Revit.DB.XYZ startPoint = xyzArray[j]; Autodesk.Revit.DB.XYZ endPoint = xyzArray[j + 1]; Line line = Line.CreateBound(startPoint, endPoint); floorProfile.Append(line); } } } return(floorProfile); }