/// <summary>
        /// Get information about the structural member axis, if possible.
        /// Here we will do the following:
        /// - Calculate the Axis LCS by using the Axis curve itself with the StartPoint of the curve to be the origin and the tangent of the curve at origin as the direction
        /// - The curve is then transformed to its LCS
        /// </summary>
        /// <param name="element">The structural member element.</param>
        /// <returns>The StructuralMemberAxisInfo structure, or null if the structural member has no axis, or it is not a Line or Arc.</returns>
        public static StructuralMemberAxisInfo GetStructuralMemberAxisTransform(Element element)
        {
            StructuralMemberAxisInfo axisInfo = null;
            Transform orientTrf = Transform.Identity;

            XYZ   structMemberDirection = null;
            XYZ   projDir = null;
            Curve curve   = null;

            LocationCurve locCurve      = element.Location as LocationCurve;
            bool          canExportAxis = (locCurve != null);

            if (canExportAxis)
            {
                // Here we are defining the Axis Curve LCS by using the start point (for line) as the origin.
                // For the Arc, the center is the origin
                // The Structural member direction is the X-Axis
                curve = locCurve.Curve;
                if (curve is Line)
                {
                    Line line = curve as Line;
                    XYZ  planeY;

                    XYZ LCSorigin = line.GetEndPoint(0);
                    structMemberDirection = line.Direction.Normalize();
                    if (Math.Abs(structMemberDirection.Z) < 0.707) // approx 1.0/sqrt(2.0)
                    {
                        planeY = XYZ.BasisZ.CrossProduct(structMemberDirection).Normalize();
                    }
                    else
                    {
                        planeY = XYZ.BasisX.CrossProduct(structMemberDirection).Normalize();
                    }
                    projDir          = structMemberDirection.CrossProduct(planeY);
                    orientTrf.BasisX = structMemberDirection; orientTrf.BasisY = planeY; orientTrf.BasisZ = projDir; orientTrf.Origin = LCSorigin;
                }
                else if (curve is Arc)
                {
                    XYZ yDir;
                    Arc arc = curve as Arc;
                    structMemberDirection = arc.XDirection.Normalize();
                    yDir    = arc.YDirection.Normalize();
                    projDir = arc.Normal;

                    XYZ center = arc.Center;

                    if (!MathUtil.IsAlmostZero(structMemberDirection.DotProduct(yDir)))
                    {
                        // ensure that beamDirection and yDir are orthogonal
                        yDir = projDir.CrossProduct(structMemberDirection);
                        yDir = yDir.Normalize();
                    }
                    orientTrf.BasisX = structMemberDirection; orientTrf.BasisY = yDir; orientTrf.BasisZ = projDir; orientTrf.Origin = center;
                }
                else
                {
                    canExportAxis = false;
                }
            }

            if (canExportAxis)
            {
                axisInfo                = new StructuralMemberAxisInfo();
                axisInfo.Axis           = curve.CreateTransformed(orientTrf.Inverse); // transform the curve into its LCS
                axisInfo.AxisDirection  = orientTrf.BasisX;                           // We define here the Axis Curve to be following the X-axis
                axisInfo.AxisNormal     = orientTrf.BasisZ;
                axisInfo.LCSAsTransform = orientTrf;
            }

            return(axisInfo);
        }
Beispiel #2
0
        /// <summary>
        /// Exports an element to IfcPile.
        /// </summary>
        /// <param name="exporterIFC">The ExporterIFC object.</param>
        /// <param name="element">The element.</param>
        /// <param name="geometryElement">The geometry element.</param>
        /// <param name="ifcEnumType">The string value represents the IFC type.</param>
        /// <param name="productWrapper">The ProductWrapper.</param>
        public static void ExportPile(ExporterIFC exporterIFC, Element element, GeometryElement geometryElement,
                                      string ifcEnumType, ProductWrapper productWrapper)
        {
            // NOTE: We expect to incorporate this code into the generic FamilyInstanceExporter at some point.
            // export parts or not
            bool exportParts = PartExporter.CanExportParts(element);

            if (exportParts && !PartExporter.CanExportElementInPartExport(element, element.LevelId, false))
            {
                return;
            }

            IFCFile file = exporterIFC.GetFile();

            using (IFCTransaction tr = new IFCTransaction(file))
            {
                // Check for containment override
                IFCAnyHandle overrideContainerHnd = null;
                ElementId    overrideContainerId  = ParameterUtil.OverrideContainmentParameter(exporterIFC, element, out overrideContainerHnd);

                using (PlacementSetter setter = PlacementSetter.Create(exporterIFC, element, null, null, overrideContainerId, overrideContainerHnd))
                {
                    using (IFCExtrusionCreationData ecData = new IFCExtrusionCreationData())
                    {
                        ecData.SetLocalPlacement(setter.LocalPlacement);

                        IFCAnyHandle prodRep = null;
                        ElementId    matId   = ElementId.InvalidElementId;
                        if (!exportParts)
                        {
                            ElementId catId = CategoryUtil.GetSafeCategoryId(element);


                            matId = BodyExporter.GetBestMaterialIdFromGeometryOrParameter(geometryElement, exporterIFC, element);
                            BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true, ExportOptionsCache.ExportTessellationLevel.ExtraLow);

                            StructuralMemberAxisInfo axisInfo = StructuralMemberExporter.GetStructuralMemberAxisTransform(element);
                            if (axisInfo != null)
                            {
                                ecData.CustomAxis            = axisInfo.AxisDirection;
                                ecData.PossibleExtrusionAxes = IFCExtrusionAxes.TryCustom;
                            }
                            else
                            {
                                ecData.PossibleExtrusionAxes = IFCExtrusionAxes.TryZ;
                            }

                            prodRep = RepresentationUtil.CreateAppropriateProductDefinitionShape(exporterIFC,
                                                                                                 element, catId, geometryElement, bodyExporterOptions, null, ecData, true);
                            if (IFCAnyHandleUtil.IsNullOrHasNoValue(prodRep))
                            {
                                ecData.ClearOpenings();
                                return;
                            }
                        }

                        string            instanceGUID = GUIDUtil.CreateGUID(element);
                        IFCExportInfoPair exportInfo   = new IFCExportInfoPair(Common.Enums.IFCEntityType.IfcPile, ifcEnumType);

                        IFCAnyHandle pile = IFCInstanceExporter.CreatePile(exporterIFC, element, instanceGUID, ExporterCacheManager.OwnerHistoryHandle,
                                                                           ecData.GetLocalPlacement(), prodRep, ifcEnumType, null);

                        // TODO: to allow shared geometry for Piles. For now, Pile export will not use shared geometry
                        if (exportInfo.ExportType != Common.Enums.IFCEntityType.UnKnown)
                        {
                            IFCAnyHandle type = ExporterUtil.CreateGenericTypeFromElement(element, exportInfo, file, ExporterCacheManager.OwnerHistoryHandle, exportInfo.ValidatedPredefinedType, productWrapper);
                            ExporterCacheManager.TypeRelationsCache.Add(type, pile);
                        }
                        if (exportParts)
                        {
                            PartExporter.ExportHostPart(exporterIFC, element, pile, productWrapper, setter, setter.LocalPlacement, null);
                        }
                        else
                        {
                            if (matId != ElementId.InvalidElementId)
                            {
                                CategoryUtil.CreateMaterialAssociation(exporterIFC, pile, matId);
                            }
                        }

                        productWrapper.AddElement(element, pile, setter, ecData, true, exportInfo);

                        OpeningUtil.CreateOpeningsIfNecessary(pile, element, ecData, null,
                                                              exporterIFC, ecData.GetLocalPlacement(), setter, productWrapper);
                    }
                }

                tr.Commit();
            }
        }
        /// <summary>
        /// Create the handle corresponding to the "Axis" IfcRepresentation for a structural member objects, if possible.
        /// </summary>
        /// <param name="exporterIFC">The ExporterIFC class.</param>
        /// <param name="element">The structural member element.</param>
        /// <param name="catId">The structural member category id.</param>
        /// <param name="axisInfo">The optional structural member axis information.</param>
        /// <param name="offsetTransform">The optional offset transform applied to the "Body" representation.</param>
        /// <returns>The handle, or null if not created.</returns>
        public static IFCAnyHandle CreateStructuralMemberAxis(ExporterIFC exporterIFC, Element element, ElementId catId, StructuralMemberAxisInfo axisInfo, Transform newTransformLCS)
        {
            if (axisInfo == null)
            {
                return(null);
            }

            // This Axis should have been transformed into its ECS position previously (in GetStructuralMemberAxisTransform())
            Curve     curve  = axisInfo.Axis;
            Transform offset = Transform.Identity;

            if (newTransformLCS != null)
            {
                // We need to flip the Left-handed transform to the right-hand one as IFC only support right-handed coordinate system
                if (newTransformLCS.Determinant < 0)
                {
                    XYZ orig = newTransformLCS.Origin;
                    newTransformLCS.Origin = XYZ.Zero;
                    offset        = FlipYTrf().Multiply(newTransformLCS);
                    offset.Origin = orig;
                }
                else
                {
                    offset = newTransformLCS;
                }
            }

            // Calculate the transformation matrix to tranform the original Axis Curve at its ECS into the new ECS assigned in the offset
            curve = curve.CreateTransformed(offset.Inverse.Multiply(axisInfo.LCSAsTransform));

            IDictionary <IFCFuzzyXYZ, IFCAnyHandle> cachePoints = new Dictionary <IFCFuzzyXYZ, IFCAnyHandle>();
            IFCAnyHandle         ifcCurveHnd = GeometryUtil.CreateIFCCurveFromRevitCurve(exporterIFC.GetFile(), exporterIFC, curve, true, cachePoints);
            IList <IFCAnyHandle> axis_items  = new List <IFCAnyHandle>();

            if (!(IFCAnyHandleUtil.IsNullOrHasNoValue(ifcCurveHnd)))
            {
                axis_items.Add(ifcCurveHnd);
            }

            if (axis_items.Count > 0)
            {
                string       identifierOpt         = "Axis";    // This is by IFC2x2+ convention.
                string       representationTypeOpt = "Curve3D"; // This is by IFC2x2+ convention.
                IFCAnyHandle axisRep = RepresentationUtil.CreateShapeRepresentation(exporterIFC, element, catId, exporterIFC.Get3DContextHandle(identifierOpt),
                                                                                    identifierOpt, representationTypeOpt, axis_items);
                return(axisRep);
            }

            return(null);
        }
Beispiel #4
0
        /// <summary>
        /// Exports an element to IfcPile.
        /// </summary>
        /// <param name="exporterIFC">The ExporterIFC object.</param>
        /// <param name="element">The element.</param>
        /// <param name="geometryElement">The geometry element.</param>
        /// <param name="ifcEnumType">The string value represents the IFC type.</param>
        /// <param name="productWrapper">The ProductWrapper.</param>
        public static void ExportPile(ExporterIFC exporterIFC, Element element, GeometryElement geometryElement,
                                      string ifcEnumType, ProductWrapper productWrapper)
        {
            // export parts or not
            bool exportParts = PartExporter.CanExportParts(element);

            if (exportParts && !PartExporter.CanExportElementInPartExport(element, element.LevelId, false))
            {
                return;
            }

            IFCFile file = exporterIFC.GetFile();

            using (IFCTransaction tr = new IFCTransaction(file))
            {
                using (PlacementSetter setter = PlacementSetter.Create(exporterIFC, element))
                {
                    using (IFCExtrusionCreationData ecData = new IFCExtrusionCreationData())
                    {
                        ecData.SetLocalPlacement(setter.LocalPlacement);

                        IFCAnyHandle prodRep = null;
                        ElementId    matId   = ElementId.InvalidElementId;
                        if (!exportParts)
                        {
                            ElementId catId = CategoryUtil.GetSafeCategoryId(element);


                            matId = BodyExporter.GetBestMaterialIdFromGeometryOrParameter(geometryElement, exporterIFC, element);
                            BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true, ExportOptionsCache.ExportTessellationLevel.ExtraLow);

                            StructuralMemberAxisInfo axisInfo = StructuralMemberExporter.GetStructuralMemberAxisTransform(element);
                            if (axisInfo != null)
                            {
                                ecData.CustomAxis            = axisInfo.AxisDirection;
                                ecData.PossibleExtrusionAxes = IFCExtrusionAxes.TryCustom;
                            }
                            else
                            {
                                ecData.PossibleExtrusionAxes = IFCExtrusionAxes.TryZ;
                            }

                            prodRep = RepresentationUtil.CreateAppropriateProductDefinitionShape(exporterIFC,
                                                                                                 element, catId, geometryElement, bodyExporterOptions, null, ecData, true);
                            if (IFCAnyHandleUtil.IsNullOrHasNoValue(prodRep))
                            {
                                ecData.ClearOpenings();
                                return;
                            }
                        }

                        string instanceGUID = GUIDUtil.CreateGUID(element);
                        //string pileType = IFCValidateEntry.GetValidIFCPredefinedType(element, ifcEnumType);

                        IFCAnyHandle pile = IFCInstanceExporter.CreatePile(exporterIFC, element, instanceGUID, ExporterCacheManager.OwnerHistoryHandle,
                                                                           ecData.GetLocalPlacement(), prodRep, ifcEnumType, null);

                        if (exportParts)
                        {
                            PartExporter.ExportHostPart(exporterIFC, element, pile, productWrapper, setter, setter.LocalPlacement, null);
                        }
                        else
                        {
                            if (matId != ElementId.InvalidElementId)
                            {
                                CategoryUtil.CreateMaterialAssociation(exporterIFC, pile, matId);
                            }
                        }

                        productWrapper.AddElement(element, pile, setter, ecData, true);

                        OpeningUtil.CreateOpeningsIfNecessary(pile, element, ecData, null,
                                                              exporterIFC, ecData.GetLocalPlacement(), setter, productWrapper);
                    }
                }

                tr.Commit();
            }
        }