Exemple #1
0
        /// <summary>
        /// Processes IfcSpace attributes.
        /// </summary>
        /// <param name="ifcSpace">The IfcSpace handle.</param>
        protected override void Process(IFCAnyHandle ifcSpace)
        {
            base.Process(ifcSpace);

            ElevationWithFlooring = IFCImportHandleUtil.GetOptionalScaledLengthAttribute(ifcSpace, "ElevationWithFlooring", 0.0);
        }
        /// <summary>
        /// Processes IfcRepresentation attributes.
        /// </summary>
        /// <param name="ifcRepresentation">The IfcRepresentation handle.</param>
        override protected void Process(IFCAnyHandle ifcRepresentation)
        {
            base.Process(ifcRepresentation);

            IFCAnyHandle representationContext = IFCImportHandleUtil.GetRequiredInstanceAttribute(ifcRepresentation, "ContextOfItems", false);

            if (representationContext != null)
            {
                Context = IFCRepresentationContext.ProcessIFCRepresentationContext(representationContext);
            }

            string identifier = IFCImportHandleUtil.GetOptionalStringAttribute(ifcRepresentation, "RepresentationIdentifier", null);

            Identifier = GetRepresentationIdentifier(identifier, ifcRepresentation);

            // Don't read in Box represenation unless options allow it.
            bool isBoundingBox = (Identifier == IFCRepresentationIdentifier.Box);

            if (isBoundingBox && !IFCImportFile.TheFile.Options.ProcessBoundingBoxGeometry)
            {
                throw new InvalidOperationException("BoundingBox not imported with ProcessBoundingBoxGeometry=false");
            }

            Type = IFCImportHandleUtil.GetOptionalStringAttribute(ifcRepresentation, "RepresentationType", null);

            HashSet <IFCAnyHandle> items =
                IFCAnyHandleUtil.GetAggregateInstanceAttribute <HashSet <IFCAnyHandle> >(ifcRepresentation, "Items");

            LayerAssignment = IFCPresentationLayerAssignment.GetTheLayerAssignment(ifcRepresentation, true);

            foreach (IFCAnyHandle item in items)
            {
                IFCRepresentationItem repItem = null;
                try
                {
                    if (NotAllowedInRepresentation(item))
                    {
                        IFCEntityType entityType = IFCAnyHandleUtil.GetEntityType(item);
                        Importer.TheLog.LogWarning(item.StepId, "Ignoring unhandled representation item of type " + entityType.ToString() + " in " +
                                                   Identifier.ToString() + " representation.", true);
                        continue;
                    }

                    // Special processing for bounding boxes - only IfcBoundingBox allowed.
                    if (isBoundingBox)
                    {
                        BoundingBox = ProcessBoundingBox(item);
                        if (BoundingBox != null)
                        {
                            break;
                        }
                    }
                    else
                    {
                        repItem = IFCRepresentationItem.ProcessIFCRepresentationItem(item);
                    }
                }
                catch (Exception ex)
                {
                    Importer.TheLog.LogError(item.StepId, ex.Message, false);
                }
                if (repItem != null)
                {
                    RepresentationItems.Add(repItem);
                }
            }
        }
        /// <summary>
        /// Processes IfcObjectDefinition attributes.
        /// </summary>
        /// <param name="ifcObjectDefinition">The IfcObjectDefinition handle.</param>
        protected override void Process(IFCAnyHandle ifcObjectDefinition)
        {
            base.Process(ifcObjectDefinition);

            PredefinedType = GetPredefinedType(ifcObjectDefinition);

            // If we aren't importing this category, skip processing.
            if (!IFCCategoryUtil.CanImport(EntityType, PredefinedType))
            {
                throw new InvalidOperationException("Don't Import");
            }

            // Before IFC2x3, IfcTypeObject did not have IsDecomposedBy.
            HashSet <IFCAnyHandle> elemSet = null;

            if (IFCImportFile.TheFile.SchemaVersion >= IFCSchemaVersion.IFC2x3 || !IFCAnyHandleUtil.IsSubTypeOf(ifcObjectDefinition, IFCEntityType.IfcTypeObject))
            {
                elemSet = IFCAnyHandleUtil.GetAggregateInstanceAttribute
                          <HashSet <IFCAnyHandle> >(ifcObjectDefinition, "IsDecomposedBy");
            }

            if (elemSet != null)
            {
                foreach (IFCAnyHandle elem in elemSet)
                {
                    ProcessIFCRelDecomposes(elem);
                }
            }

            HashSet <IFCAnyHandle> hasAssociations = IFCAnyHandleUtil.GetAggregateInstanceAttribute
                                                     <HashSet <IFCAnyHandle> >(ifcObjectDefinition, "HasAssociations");

            if (hasAssociations != null)
            {
                foreach (IFCAnyHandle hasAssociation in hasAssociations)
                {
                    if (IFCAnyHandleUtil.IsSubTypeOf(hasAssociation, IFCEntityType.IfcRelAssociatesMaterial))
                    {
                        ProcessIFCRelAssociatesMaterial(hasAssociation);
                    }
                    else if (IFCAnyHandleUtil.IsSubTypeOf(hasAssociation, IFCEntityType.IfcRelAssociatesClassification))
                    {
                        ProcessRelAssociatesClassification(hasAssociation);
                    }
                    else
                    {
                        Importer.TheLog.LogUnhandledSubTypeError(hasAssociation, IFCEntityType.IfcRelAssociates, false);
                    }
                }
            }

            // The default IFC2x3_TC1.exp file does not have this INVERSE attribute correctly set.  Encapsulate this function.
            ISet <IFCAnyHandle> hasAssignments = IFCImportHandleUtil.GetHasAssignments(ifcObjectDefinition);

            if (hasAssignments != null)
            {
                foreach (IFCAnyHandle hasAssignment in hasAssignments)
                {
                    ProcessIFCRelAssigns(hasAssignment);
                }
            }

            Importer.TheLog.AddToElementCount();
        }
Exemple #4
0
        /// <summary>
        /// Processes IfcBuildingStorey attributes.
        /// </summary>
        /// <param name="ifcIFCBuildingStorey">The IfcBuildingStorey handle.</param>
        protected override void Process(IFCAnyHandle ifcIFCBuildingStorey)
        {
            base.Process(ifcIFCBuildingStorey);

            Elevation = IFCImportHandleUtil.GetOptionalScaledLengthAttribute(ifcIFCBuildingStorey, "Elevation", 0.0);
        }
        override protected void Process(IFCAnyHandle item)
        {
            base.Process(item);

            Name = IFCImportHandleUtil.GetOptionalStringAttribute(item, "Name", null);
        }
Exemple #6
0
        /// <summary>
        /// Processes IfcGridAxis attributes.
        /// </summary>
        /// <param name="ifcGridAxis">The IfcGridAxis handle.</param>
        protected override void Process(IFCAnyHandle ifcGridAxis)
        {
            base.Process(ifcGridAxis);

            AxisTag = IFCImportHandleUtil.GetOptionalStringAttribute(ifcGridAxis, "AxisTag", null);
            if (AxisTag == null)
            {
                AxisTag = "Z"; // arbitrary; all Revit Grids have names.
            }
            IFCAnyHandle axisCurve = IFCImportHandleUtil.GetRequiredInstanceAttribute(ifcGridAxis, "AxisCurve", true);

            AxisCurve = IFCCurve.ProcessIFCCurve(axisCurve);

            bool found     = false;
            bool sameSense = IFCImportHandleUtil.GetRequiredBooleanAttribute(ifcGridAxis, "SameSense", out found);

            SameSense = found ? sameSense : true;

            // We are going to check if this grid axis is a vertical duplicate of any existing axis.
            // If so, we will throw an exception so that we don't create duplicate grids.
            // We will only initialize these values if we actually intend to use them below.
            IList <Curve> curves     = null;
            int           curveCount = 0;

            ElementId gridId = ElementId.InvalidElementId;

            if (Importer.TheCache.GridNameToElementMap.TryGetValue(AxisTag, out gridId))
            {
                Grid grid = IFCImportFile.TheFile.Document.GetElement(gridId) as Grid;
                if (grid != null)
                {
                    IList <Curve> otherCurves = new List <Curve>();
                    Curve         gridCurve   = grid.Curve;
                    if (gridCurve != null)
                    {
                        otherCurves.Add(gridCurve);
                        long matchingGridId = FindMatchingGrid(otherCurves, grid.Id.IntegerValue, ref curves, ref curveCount);

                        if (matchingGridId != -1)
                        {
                            Importer.TheCache.UseGrid(grid);
                            CreatedElementId = grid.Id;
                            return;
                        }
                    }
                }
            }

            IDictionary <string, IFCGridAxis> gridAxes = IFCImportFile.TheFile.IFCProject.GridAxes;
            IFCGridAxis gridAxis = null;

            if (gridAxes.TryGetValue(AxisTag, out gridAxis))
            {
                long matchingGridId = FindMatchingGrid(gridAxis, ref curves, ref curveCount);
                if (matchingGridId != -1)
                {
                    DuplicateAxisId = matchingGridId;
                    return;
                }
                else
                {
                    // Revit doesn't allow grid lines to have the same name.  If it isn't a duplicate, rename it.
                    // Note that this will mean that we may miss some "duplicate" grid lines because of the renaming.
                    AxisTag = MakeAxisTagUnique(AxisTag);
                }
            }

            gridAxes.Add(new KeyValuePair <string, IFCGridAxis>(AxisTag, this));
        }
Exemple #7
0
        protected override void Process(IFCAnyHandle ifcCurve)
        {
            base.Process(ifcCurve);

            bool found = false;

            bool sameSense = IFCImportHandleUtil.GetRequiredBooleanAttribute(ifcCurve, "SenseAgreement", out found);

            if (!found)
            {
                sameSense = true;
            }

            IFCAnyHandle basisCurve    = IFCImportHandleUtil.GetRequiredInstanceAttribute(ifcCurve, "BasisCurve", true);
            IFCCurve     ifcBasisCurve = IFCCurve.ProcessIFCCurve(basisCurve);

            if (ifcBasisCurve == null || (ifcBasisCurve.Curve == null && ifcBasisCurve.CurveLoop == null))
            {
                // LOG: ERROR: Error processing BasisCurve # for IfcTrimmedCurve #.
                return;
            }
            if (ifcBasisCurve.Curve == null)
            {
                // LOG: ERROR: Expected a single curve, not a curve loop for BasisCurve # for IfcTrimmedCurve #.
                return;
            }

            IFCData trim1 = ifcCurve.GetAttribute("Trim1");

            if (trim1.PrimitiveType != IFCDataPrimitiveType.Aggregate)
            {
                // LOG: ERROR: Invalid data type for Trim1 attribute for IfcTrimmedCurve #.
                return;
            }

            IFCData trim2 = ifcCurve.GetAttribute("Trim2");

            if (trim2.PrimitiveType != IFCDataPrimitiveType.Aggregate)
            {
                // LOG: ERROR: Invalid data type for Trim1 attribute for IfcTrimmedCurve #.
                return;
            }

            // Note that these are the "unprocessed" values.  These can be used for, e.g., adding up the IFC parameter length
            // of the file, to account for export errors.  The "processed" values can be determined from the Revit curves.
            Trim1 = GetRawTrimParameter(trim1);
            Trim2 = GetRawTrimParameter(trim2);

            IFCTrimmingPreference trimPreference = IFCEnums.GetSafeEnumerationAttribute <IFCTrimmingPreference>(ifcCurve, "MasterRepresentation", IFCTrimmingPreference.Parameter);

            double param1 = 0.0, param2 = 0.0;

            try
            {
                GetTrimParameters(trim1, trim2, ifcBasisCurve, trimPreference, out param1, out param2);
            }
            catch (Exception ex)
            {
                Importer.TheLog.LogError(ifcCurve.StepId, ex.Message, false);
                return;
            }

            Curve baseCurve = ifcBasisCurve.Curve;

            if (baseCurve.IsCyclic)
            {
                if (!sameSense)
                {
                    MathUtil.Swap(ref param1, ref param2);
                }

                if (param2 < param1)
                {
                    param2 = MathUtil.PutInRange(param2, param1 + Math.PI, 2 * Math.PI);
                }

                if (param2 - param1 > 2.0 * Math.PI - MathUtil.Eps())
                {
                    Importer.TheLog.LogWarning(ifcCurve.StepId, "IfcTrimmedCurve length is greater than 2*PI, leaving unbound.", false);
                    Curve = baseCurve;
                    return;
                }

                Curve = baseCurve.Clone();

                try
                {
                    Curve.MakeBound(param1, param2);
                }
                catch (Exception ex)
                {
                    if (ex.Message.Contains("too small"))
                    {
                        Curve = null;
                        Importer.TheLog.LogError(Id, "curve length is invalid, ignoring.", false);
                        return;
                    }
                    else
                    {
                        throw ex;
                    }
                }
            }
            else
            {
                if (MathUtil.IsAlmostEqual(param1, param2))
                {
                    Importer.TheLog.LogError(Id, "Param1 = Param2 for IfcTrimmedCurve #, ignoring.", false);
                    return;
                }

                if (param1 > param2 - MathUtil.Eps())
                {
                    Importer.TheLog.LogWarning(Id, "Param1 > Param2 for IfcTrimmedCurve #, reversing.", false);
                    MathUtil.Swap(ref param1, ref param2);
                    return;
                }

                Curve copyCurve = baseCurve.Clone();

                double length = param2 - param1;
                if (length <= IFCImportFile.TheFile.Document.Application.ShortCurveTolerance)
                {
                    string lengthAsString = IFCUnitUtil.FormatLengthAsString(length);
                    Importer.TheLog.LogError(Id, "curve length of " + lengthAsString + " is invalid, ignoring.", false);
                    return;
                }

                copyCurve.MakeBound(param1, param2);
                if (sameSense)
                {
                    Curve = copyCurve;
                }
                else
                {
                    Curve = copyCurve.CreateReversed();
                }
            }

            CurveLoop = new CurveLoop();
            CurveLoop.Append(Curve);
        }
Exemple #8
0
        protected override void Process(IFCAnyHandle ifcCurve)
        {
            base.Process(ifcCurve);

            bool found = false;

            bool sameSense = IFCImportHandleUtil.GetRequiredBooleanAttribute(ifcCurve, "SenseAgreement", out found);

            if (!found)
            {
                sameSense = true;
            }

            IFCAnyHandle basisCurve    = IFCImportHandleUtil.GetRequiredInstanceAttribute(ifcCurve, "BasisCurve", true);
            IFCCurve     ifcBasisCurve = IFCCurve.ProcessIFCCurve(basisCurve);

            if (ifcBasisCurve == null || (ifcBasisCurve.IsEmpty()))
            {
                // LOG: ERROR: Error processing BasisCurve # for IfcTrimmedCurve #.
                return;
            }
            if (ifcBasisCurve.Curve == null)
            {
                // LOG: ERROR: Expected a single curve, not a curve loop for BasisCurve # for IfcTrimmedCurve #.
                return;
            }

            IFCData trim1 = ifcCurve.GetAttribute("Trim1");

            if (trim1.PrimitiveType != IFCDataPrimitiveType.Aggregate)
            {
                // LOG: ERROR: Invalid data type for Trim1 attribute for IfcTrimmedCurve #.
                return;
            }

            IFCData trim2 = ifcCurve.GetAttribute("Trim2");

            if (trim2.PrimitiveType != IFCDataPrimitiveType.Aggregate)
            {
                // LOG: ERROR: Invalid data type for Trim1 attribute for IfcTrimmedCurve #.
                return;
            }

            // Note that these are the "unprocessed" values.  These can be used for, e.g., adding up the IFC parameter length
            // of the file, to account for export errors.  The "processed" values can be determined from the Revit curves.
            Trim1 = GetRawTrimParameter(trim1);
            Trim2 = GetRawTrimParameter(trim2);

            IFCTrimmingPreference trimPreference = IFCEnums.GetSafeEnumerationAttribute <IFCTrimmingPreference>(ifcCurve, "MasterRepresentation", IFCTrimmingPreference.Parameter);

            double param1 = 0.0, param2 = 0.0;
            Curve  baseCurve = ifcBasisCurve.Curve;

            try
            {
                GetTrimParameters(ifcBasisCurve.Id, trim1, trim2, baseCurve, trimPreference, out param1, out param2);
                if (NeedToReverseBaseCurve(baseCurve, param1, param2, trimPreference))
                {
                    Importer.TheLog.LogWarning(Id, "Invalid Param1 > Param2 for non-cyclic IfcTrimmedCurve using Cartesian trimming preference, reversing.", false);
                    baseCurve = baseCurve.CreateReversed();
                    GetTrimParameters(ifcBasisCurve.Id, trim1, trim2, baseCurve, trimPreference, out param1, out param2);
                }
            }
            catch (Exception ex)
            {
                Importer.TheLog.LogError(ifcCurve.StepId, ex.Message, false);
                return;
            }

            if (MathUtil.IsAlmostEqual(param1, param2))
            {
                Importer.TheLog.LogError(Id, "Param1 = Param2 for IfcTrimmedCurve #, ignoring.", false);
                return;
            }

            Curve curve = null;

            if (baseCurve.IsCyclic)
            {
                double period = baseCurve.Period;
                if (!sameSense)
                {
                    MathUtil.Swap(ref param1, ref param2);
                }

                // We want to make sure both values are within period of one another.
                param1 = MathUtil.PutInRange(param1, 0, period);
                param2 = MathUtil.PutInRange(param2, 0, period);
                if (param2 < param1)
                {
                    param2 = MathUtil.PutInRange(param2, param1 + period / 2, period);
                }

                // This is effectively an unbound curve.
                double numberOfPeriods = (param2 - param1) / period;
                if (MathUtil.IsAlmostEqual(numberOfPeriods, Math.Round(numberOfPeriods)))
                {
                    Importer.TheLog.LogWarning(Id, "Start and end parameters indicate a zero-length closed curve, assuming unbound is intended.", false);
                    curve = baseCurve;
                }
                else
                {
                    curve = baseCurve.Clone();
                    if (!SafelyBoundCurve(curve, param1, param2))
                    {
                        return;
                    }
                }
            }
            else
            {
                if (param1 > param2 - MathUtil.Eps())
                {
                    Importer.TheLog.LogWarning(Id, "Param1 > Param2 for IfcTrimmedCurve #, reversing.", false);
                    MathUtil.Swap(ref param1, ref param2);
                    sameSense = !sameSense;
                }

                Curve copyCurve = baseCurve.Clone();

                double length = param2 - param1;
                if (length <= IFCImportFile.TheFile.Document.Application.ShortCurveTolerance)
                {
                    string lengthAsString = IFCUnitUtil.FormatLengthAsString(length);
                    Importer.TheLog.LogError(Id, "curve length of " + lengthAsString + " is invalid, ignoring.", false);
                    return;
                }

                if (!SafelyBoundCurve(copyCurve, param1, param2))
                {
                    return;
                }

                if (sameSense)
                {
                    curve = copyCurve;
                }
                else
                {
                    curve = copyCurve.CreateReversed();
                }
            }

            CurveLoop curveLoop = new CurveLoop();

            curveLoop.Append(curve);
            SetCurveLoop(curveLoop);
        }
Exemple #9
0
        override protected void Process(IFCAnyHandle item)
        {
            base.Process(item);

            IFCAnyHandle localOrigin = IFCImportHandleUtil.GetRequiredInstanceAttribute(item, "LocalOrigin", false);
            XYZ          origin      = null;

            if (localOrigin != null)
            {
                origin = IFCPoint.ProcessScaledLengthIFCCartesianPoint(localOrigin);
            }
            else
            {
                origin = XYZ.Zero;
            }

            IFCAnyHandle axis1 = IFCImportHandleUtil.GetOptionalInstanceAttribute(item, "Axis1");
            XYZ          xAxis = null;

            if (axis1 != null)
            {
                xAxis = IFCPoint.ProcessNormalizedIFCDirection(axis1);
            }

            IFCAnyHandle axis2 = IFCImportHandleUtil.GetOptionalInstanceAttribute(item, "Axis2");
            XYZ          yAxis = null;

            if (axis2 != null)
            {
                yAxis = IFCPoint.ProcessNormalizedIFCDirection(axis2);
            }

            Scale = IFCImportHandleUtil.GetOptionalRealAttribute(item, "Scale", 1.0);

            XYZ zAxis = null;

            if (IFCAnyHandleUtil.IsSubTypeOf(item, IFCEntityType.IfcCartesianTransformationOperator2DnonUniform))
            {
                ScaleY = IFCImportHandleUtil.GetOptionalRealAttribute(item, "Scale2", Scale);
            }
            else if (IFCAnyHandleUtil.IsSubTypeOf(item, IFCEntityType.IfcCartesianTransformationOperator3D))
            {
                IFCAnyHandle axis3 = IFCImportHandleUtil.GetOptionalInstanceAttribute(item, "Axis3");
                if (axis3 != null)
                {
                    zAxis = IFCPoint.ProcessNormalizedIFCDirection(axis3);
                }
                if (IFCAnyHandleUtil.IsSubTypeOf(item, IFCEntityType.IfcCartesianTransformationOperator3DnonUniform))
                {
                    ScaleY = IFCImportHandleUtil.GetOptionalRealAttribute(item, "Scale2", Scale);
                    ScaleZ = IFCImportHandleUtil.GetOptionalRealAttribute(item, "Scale3", Scale);
                }
            }

            // Set the axes based on what is specified.
            // If all three axes are set, ensure they are truly orthogonal.
            // If two axes are set, ensure they are orthogonal and set the 3rd axis to be the cross product.
            // If one axis is set, arbitrarily set the next axis to be the basis vector which
            // If no axes are set, use identity transform.
            if (xAxis == null)
            {
                if (yAxis == null)
                {
                    if (zAxis == null)
                    {
                        xAxis = XYZ.BasisX;
                        yAxis = XYZ.BasisY;
                        zAxis = XYZ.BasisZ;
                    }
                }
                else if (zAxis == null)
                {
                    // Special case - Y axis is in XY plane.
                    if (MathUtil.IsAlmostZero(yAxis[2]))
                    {
                        xAxis = new XYZ(yAxis[1], -yAxis[0], 0.0);
                        zAxis = XYZ.BasisZ;
                    }
                    else
                    {
                        throw new InvalidOperationException("#" + item.StepId + ": IfcCartesianTransformOperator has only y axis defined, ignoring.");
                    }
                }
                else
                {
                    xAxis = yAxis.CrossProduct(zAxis);
                }
            }
            else if (yAxis == null)
            {
                if (zAxis == null)
                {
                    // Special case - X axis is in XY plane.
                    if (MathUtil.IsAlmostZero(xAxis[2]))
                    {
                        yAxis = new XYZ(xAxis[1], -xAxis[0], 0.0);
                        zAxis = XYZ.BasisZ;
                    }
                    else
                    {
                        throw new InvalidOperationException("#" + item.StepId + ": IfcCartesianTransformOperator has only x axis defined, ignoring.");
                    }
                }
                else
                {
                    yAxis = zAxis.CrossProduct(xAxis);
                }
            }
            else if (zAxis == null)
            {
                zAxis = xAxis.CrossProduct(yAxis);
            }

            // Make sure that the axes are really orthogonal.
            if (!MathUtil.IsAlmostZero(xAxis.DotProduct(zAxis)))
            {
                zAxis = xAxis.CrossProduct(yAxis);
            }
            if (!MathUtil.IsAlmostZero(xAxis.DotProduct(yAxis)))
            {
                yAxis = zAxis.CrossProduct(xAxis);
            }

            Transform = Transform.CreateTranslation(origin);
            Transform.set_Basis(0, xAxis);
            Transform.set_Basis(1, yAxis);
            Transform.set_Basis(2, zAxis);
        }