Пример #1
0
        /// <summary>
        /// Process IfcTriangulatedFaceSet instance
        /// </summary>
        /// <param name="ifcTriangulatedFaceSet">the handle</param>
        protected override void Process(IFCAnyHandle ifcTriangulatedFaceSet)
        {
            base.Process(ifcTriangulatedFaceSet);

            IList <IList <double> > normals = IFCImportHandleUtil.GetListOfListOfDoubleAttribute(ifcTriangulatedFaceSet, "Normals");

            if (normals != null)
            {
                if (normals.Count > 0)
                {
                    Normals = normals;
                }
            }

            bool?closed = IFCAnyHandleUtil.GetBooleanAttribute(ifcTriangulatedFaceSet, "Closed");

            if (closed != null)
            {
                Closed = closed;
            }

            IList <IList <int> > coordIndex = IFCImportHandleUtil.GetListOfListOfIntegerAttribute(ifcTriangulatedFaceSet, "CoordIndex");

            if (coordIndex != null)
            {
                if (coordIndex.Count > 0)
                {
                    CoordIndex = coordIndex;
                }
            }

            // Note that obsolete IFC4 files had a "NormalIndex".
            // We ignore this because we can't actually distinguish between these files.
            // "PnIndex" is new to IFC4Add2, so we'll protect here in case we see an obsolete file.
            try
            {
                if (IFCImportFile.TheFile.SchemaVersionAtLeast(IFCSchemaVersion.IFC4))
                {
                    IList <int> pnIndex = IFCAnyHandleUtil.GetAggregateIntAttribute <List <int> >(ifcTriangulatedFaceSet, "PnIndex");
                    if (pnIndex != null)
                    {
                        if (pnIndex.Count > 0)
                        {
                            PnIndex = pnIndex;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                if (IFCImportFile.HasUndefinedAttribute(ex))
                {
                    IFCImportFile.TheFile.DowngradeIFC4SchemaTo(IFCSchemaVersion.IFC4Add1Obsolete);
                }
                else
                {
                    throw ex;
                }
            }
        }
Пример #2
0
        /// <summary>
        /// Creates an IFCImportFile from a file on the disk.
        /// </summary>
        /// <param name="ifcFilePath">The path of the file.</param>
        /// <param name="options">The IFC import options.</param>
        /// <param name="doc">The optional document argument.  If importing into Revit, not supplying a document may reduce functionality later.</param>
        /// <returns>The IFCImportFile.</returns>
        public static IFCImportFile Create(string ifcFilePath, IFCImportOptions options, Document doc)
        {
            m_sIFCImportFile = new IFCImportFile();
            bool success = TheFile.Process(ifcFilePath, options, doc);

            if (success)
            {
                // Store the original levels in the template file for Open IFC.  On export, we will delete these levels if we created any.
                // Note that we always have to preserve one level, regardless of what the ActiveView is.
                // TODO: Only for open, not import.
                if (doc != null)
                {
                    IFCBuildingStorey.ExistingLevelIdToReuse = ElementId.InvalidElementId;

                    View activeView = doc.ActiveView;
                    if (activeView != null)
                    {
                        Level genLevel = activeView.GenLevel;
                        if (genLevel != null)
                        {
                            IFCBuildingStorey.ExistingLevelIdToReuse = genLevel.Id;
                        }
                    }

                    FilteredElementCollector levelCollector   = new FilteredElementCollector(doc);
                    ICollection <Element>    levels           = levelCollector.OfClass(typeof(Level)).ToElements();
                    ICollection <ElementId>  levelIdsToDelete = new HashSet <ElementId>();
                    foreach (Element level in levels)
                    {
                        if (IFCBuildingStorey.ExistingLevelIdToReuse == ElementId.InvalidElementId)
                        {
                            IFCBuildingStorey.ExistingLevelIdToReuse = level.Id;
                        }
                        else if (level.Id != IFCBuildingStorey.ExistingLevelIdToReuse)
                        {
                            levelIdsToDelete.Add(level.Id);
                        }
                    }
                    doc.Delete(levelIdsToDelete);

                    // Collect material names, to avoid reusing.
                    FilteredElementCollector materialCollector = new FilteredElementCollector(doc);
                    ICollection <Element>    materials         = materialCollector.OfClass(typeof(Material)).ToElements();
                    foreach (Element materialAsElem in materials)
                    {
                        Material        material = materialAsElem as Material;
                        IFCMaterialInfo info     = IFCMaterialInfo.Create(material.Color, material.Transparency, material.Shininess,
                                                                          material.Smoothness, material.Id);
                        Importer.TheCache.CreatedMaterials.Add(material.Name, info);
                    }
                }
            }
            else
            {
                // Close up the log file, set m_sIFCImportFile to null.
                TheFile.Close();
            }

            return(m_sIFCImportFile);
        }
Пример #3
0
 /// <summary>
 /// Close files at end of import.
 /// </summary>
 public void Close()
 {
     if (m_IfcFile != null)
     {
         m_IfcFile.Close();
     }
     m_sIFCImportFile = null;
 }
Пример #4
0
        /// <summary>
        /// Processes an IfcRepresentationItem entity handle.
        /// </summary>
        /// <param name="ifcRepresentationItem">The IfcRepresentationItem handle.</param>
        /// <returns>The IFCRepresentationItem object.</returns>
        public static IFCRepresentationItem ProcessIFCRepresentationItem(IFCAnyHandle ifcRepresentationItem)
        {
            if (IFCAnyHandleUtil.IsNullOrHasNoValue(ifcRepresentationItem))
            {
                Importer.TheLog.LogNullError(IFCEntityType.IfcRepresentationItem);
                return(null);
            }

            if (IFCAnyHandleUtil.IsValidSubTypeOf(ifcRepresentationItem, IFCEntityType.IfcMappedItem))
            {
                return(IFCMappedItem.ProcessIFCMappedItem(ifcRepresentationItem));
            }
            if (IFCImportFile.TheFile.SchemaVersionAtLeast(IFCSchemaVersion.IFC2x2) && IFCAnyHandleUtil.IsSubTypeOf(ifcRepresentationItem, IFCEntityType.IfcStyledItem))
            {
                return(IFCStyledItem.ProcessIFCStyledItem(ifcRepresentationItem));
            }
            if (IFCAnyHandleUtil.IsSubTypeOf(ifcRepresentationItem, IFCEntityType.IfcTopologicalRepresentationItem))
            {
                return(IFCTopologicalRepresentationItem.ProcessIFCTopologicalRepresentationItem(ifcRepresentationItem));
            }

            // TODO: Move everything below to IFCGeometricRepresentationItem, once it is created.
            if (IFCAnyHandleUtil.IsValidSubTypeOf(ifcRepresentationItem, IFCEntityType.IfcBooleanResult))
            {
                return(IFCBooleanResult.ProcessIFCBooleanResult(ifcRepresentationItem));
            }
            if (IFCAnyHandleUtil.IsValidSubTypeOf(ifcRepresentationItem, IFCEntityType.IfcCurve))
            {
                return(IFCCurve.ProcessIFCCurve(ifcRepresentationItem));
            }
            if (IFCAnyHandleUtil.IsValidSubTypeOf(ifcRepresentationItem, IFCEntityType.IfcFaceBasedSurfaceModel))
            {
                return(IFCFaceBasedSurfaceModel.ProcessIFCFaceBasedSurfaceModel(ifcRepresentationItem));
            }
            if (IFCAnyHandleUtil.IsValidSubTypeOf(ifcRepresentationItem, IFCEntityType.IfcGeometricSet))
            {
                return(IFCGeometricSet.ProcessIFCGeometricSet(ifcRepresentationItem));
            }
            if (IFCAnyHandleUtil.IsValidSubTypeOf(ifcRepresentationItem, IFCEntityType.IfcPoint))
            {
                return(IFCPoint.ProcessIFCPoint(ifcRepresentationItem));
            }
            if (IFCAnyHandleUtil.IsValidSubTypeOf(ifcRepresentationItem, IFCEntityType.IfcShellBasedSurfaceModel))
            {
                return(IFCShellBasedSurfaceModel.ProcessIFCShellBasedSurfaceModel(ifcRepresentationItem));
            }
            if (IFCAnyHandleUtil.IsValidSubTypeOf(ifcRepresentationItem, IFCEntityType.IfcSolidModel))
            {
                return(IFCSolidModel.ProcessIFCSolidModel(ifcRepresentationItem));
            }

            // TODO: Move the items below to IFCGeometricRepresentationItem->IFCTessellatedItem->IfcTessellatedFaceSet.
            if (IFCImportFile.TheFile.SchemaVersionAtLeast(IFCSchemaVersion.IFC4Obsolete) && IFCAnyHandleUtil.IsSubTypeOf(ifcRepresentationItem, IFCEntityType.IfcTriangulatedFaceSet))
            {
                return(IFCTriangulatedFaceSet.ProcessIFCTriangulatedFaceSet(ifcRepresentationItem));
            }
            // There is no way to actually determine an IFC4Add2 file vs. a "vanilla" IFC4 file, which is
            // obsolete.  The try/catch here allows us to read these obsolete files without crashing.
            try
            {
                if (IFCImportFile.TheFile.SchemaVersionAtLeast(IFCSchemaVersion.IFC4) && IFCAnyHandleUtil.IsSubTypeOf(ifcRepresentationItem, IFCEntityType.IfcPolygonalFaceSet))
                {
                    return(IFCPolygonalFaceSet.ProcessIFCPolygonalFaceSet(ifcRepresentationItem));
                }
            }
            catch (Exception ex)
            {
                // Once we fail once, downgrade the schema so we don't try again.
                if (IFCImportFile.HasUndefinedAttribute(ex))
                {
                    IFCImportFile.TheFile.DowngradeIFC4SchemaTo(IFCSchemaVersion.IFC4Add1Obsolete);
                }
                else
                {
                    throw ex;
                }
            }

            Importer.TheLog.LogUnhandledSubTypeError(ifcRepresentationItem, IFCEntityType.IfcRepresentationItem, true);
            return(null);
        }
Пример #5
0
        /// <summary>
        /// Creates an IFCImportFile from a file on the disk.
        /// </summary>
        /// <param name="ifcFilePath">The path of the file.</param>
        /// <param name="options">The IFC import options.</param>
        /// <param name="doc">The optional document argument.  If importing into Revit, not supplying a document may reduce functionality later.</param>
        /// <returns>The IFCImportFile.</returns>
        public static IFCImportFile Create(string ifcFilePath, IFCImportOptions options, Document doc)
        {
            m_sIFCImportFile = new IFCImportFile();
            bool success = TheFile.Process(ifcFilePath, options, doc);

            if (success)
            {
                // Store the original levels in the template file for Open IFC.  On export, we will delete these levels if we created any.
                // Note that we always have to preserve one level, regardless of what the ActiveView is.
                if (doc != null)
                {
                    IFCBuildingStorey.ExistingLevelIdToReuse = ElementId.InvalidElementId;

                    View activeView = doc.ActiveView;
                    if (activeView != null)
                    {
                        Level genLevel = activeView.GenLevel;
                        if (genLevel != null)
                        {
                            IFCBuildingStorey.ExistingLevelIdToReuse = genLevel.Id;
                        }
                    }

                    // For Link IFC, we will delete any unused levels at the end.  Instead, we want to try to reuse them.
                    // The for loop does a little unnecessary work if deleteLevelsNow, but the performance implications are very small.
                    bool deleteLevelsNow = (Importer.TheOptions.Action != IFCImportAction.Link);

                    FilteredElementCollector levelCollector   = new FilteredElementCollector(doc);
                    ICollection <Element>    levels           = levelCollector.OfClass(typeof(Level)).ToElements();
                    ICollection <ElementId>  levelIdsToDelete = new HashSet <ElementId>();
                    foreach (Element level in levels)
                    {
                        if (level == null)
                        {
                            continue;
                        }

                        if (IFCBuildingStorey.ExistingLevelIdToReuse == ElementId.InvalidElementId)
                        {
                            IFCBuildingStorey.ExistingLevelIdToReuse = level.Id;
                        }
                        else if (level.Id != IFCBuildingStorey.ExistingLevelIdToReuse)
                        {
                            levelIdsToDelete.Add(level.Id);
                        }
                    }

                    if (deleteLevelsNow)
                    {
                        doc.Delete(levelIdsToDelete);
                    }

                    // Collect material names, to avoid reusing.
                    FilteredElementCollector materialCollector = new FilteredElementCollector(doc);
                    ICollection <Element>    materials         = materialCollector.OfClass(typeof(Material)).ToElements();
                    foreach (Element materialAsElem in materials)
                    {
                        Material        material = materialAsElem as Material;
                        IFCMaterialInfo info     = IFCMaterialInfo.Create(material.Color, material.Transparency, material.Shininess,
                                                                          material.Smoothness, material.Id);
                        Importer.TheCache.CreatedMaterials.Add(material.Name, info);
                    }
                }
            }
            else
            {
                // Close up the log file, set m_sIFCImportFile to null.
                TheFile.Close();
            }

            return(m_sIFCImportFile);
        }
Пример #6
0
 /// <summary>
 /// Close files at end of import.
 /// </summary>
 public void Close()
 {
     if (m_IfcFile != null)
         m_IfcFile.Close();
     if (m_Log != null)
         m_Log.Close();
     m_sIFCImportFile = null;
 }
Пример #7
0
        /// <summary>
        /// Creates an IFCImportFile from a file on the disk.
        /// </summary>
        /// <param name="ifcFilePath">The path of the file.</param>
        /// <param name="options">The IFC import options.</param>
        /// <param name="doc">The optional document argument.  If importing into Revit, not supplying a document may reduce functionality later.</param>
        /// <returns>The IFCImportFile.</returns>
        public static IFCImportFile Create(string ifcFilePath, IFCImportOptions options, Document doc)
        {
            m_sIFCImportFile = new IFCImportFile();
            bool success = TheFile.Process(ifcFilePath, options, doc);
            if (success)
            {
                // Store the original levels in the template file for Open IFC.  On export, we will delete these levels if we created any.
                // Note that we always have to preserve one level, regardless of what the ActiveView is.
                // TODO: Only for open, not import.
                if (doc != null)
                {
                    IFCBuildingStorey.ExistingLevelIdToReuse = ElementId.InvalidElementId;

                    View activeView = doc.ActiveView;
                    if (activeView != null)
                    {
                        Level genLevel = activeView.GenLevel;
                        if (genLevel != null)
                            IFCBuildingStorey.ExistingLevelIdToReuse = genLevel.Id;
                    }

                    FilteredElementCollector levelCollector = new FilteredElementCollector(doc);
                    ICollection<Element> levels = levelCollector.OfClass(typeof(Level)).ToElements();
                    ICollection<ElementId> levelIdsToDelete = new HashSet<ElementId>();
                    foreach (Element level in levels)
                    {
                        if (IFCBuildingStorey.ExistingLevelIdToReuse == ElementId.InvalidElementId)
                            IFCBuildingStorey.ExistingLevelIdToReuse = level.Id;
                        else if (level.Id != IFCBuildingStorey.ExistingLevelIdToReuse)
                            levelIdsToDelete.Add(level.Id);
                    }
                    doc.Delete(levelIdsToDelete);

                    // Collect material names, to avoid reusing.
                    FilteredElementCollector materialCollector = new FilteredElementCollector(doc);
                    ICollection<Element> materials = materialCollector.OfClass(typeof(Material)).ToElements();
                    foreach (Element materialAsElem in materials)
                    {
                        Material material = materialAsElem as Material;
                        IFCMaterialInfo info = IFCMaterialInfo.Create(material.Color, material.Transparency, material.Shininess,
                            material.Smoothness, material.Id);
                        Importer.TheCache.CreatedMaterials.Add(material.Name, info);
                    }
                }
            }
            else
            {
                // Close up the log file, set m_sIFCImportFile to null.
                TheFile.Close();
            }

            return m_sIFCImportFile;
        }
Пример #8
0
        protected override void Process(IFCAnyHandle ifcCurve)
        {
            base.Process(ifcCurve);

            IFCAnyHandle points = IFCAnyHandleUtil.GetInstanceAttribute(ifcCurve, "Points");

            if (IFCAnyHandleUtil.IsNullOrHasNoValue(points))
            {
                Importer.TheLog.LogMissingRequiredAttributeError(ifcCurve, "Points", true);
                return;
            }

            IList <IFCData> segments = null;

            try
            {
                // The Segments attribute is new to IFC4 Add1, and we don't know that we may have a
                // vanilla IFC4 file.  If we can't find the attribute, we will assume the points represent
                // the vertices of a polyline.
                segments = IFCAnyHandleUtil.GetAggregateAttribute <List <IFCData> >(ifcCurve, "Segments");
            }
            catch (Exception ex)
            {
                if (IFCImportFile.HasUndefinedAttribute(ex))
                {
                    IFCImportFile.TheFile.DowngradeIFC4SchemaTo(IFCSchemaVersion.IFC4);
                }
                else
                {
                    throw ex;
                }
            }

            IFCCartesianPointList pointList     = IFCCartesianPointList.ProcessIFCCartesianPointList(points);
            IList <XYZ>           pointListXYZs = pointList.CoordList;
            int numPoints = pointListXYZs.Count;

            CurveLoop   curveLoop = null;
            IList <XYZ> pointXYZs = null;

            if (segments == null)
            {
                // Simple case: no segment information, just treat the curve as a polyline.
                pointXYZs = pointListXYZs;
                curveLoop = IFCGeometryUtil.CreatePolyCurveLoop(pointXYZs, null, Id, false);
            }
            else
            {
                curveLoop = new CurveLoop();

                // Assure that we don't add the same point twice for a polyline segment.  This could
                // happen by error, or, e.g., there are two IfcLineIndex segments in a row (although
                // this could also be considered an error condition.)
                int lastIndex = -1;

                // The list of all of the points, in the order that they are added.  This can be
                // used as a backup representation.
                pointXYZs = new List <XYZ>();

                IList <XYZ> currentLineSegmentPoints = new List <XYZ>();
                foreach (IFCData segment in segments)
                {
                    string indexType = ValidateSegment(segment);
                    if (indexType == null)
                    {
                        Importer.TheLog.LogError(Id, "Unknown segment type in IfcIndexedPolyCurve.", false);
                        continue;
                    }

                    IFCAggregate segmentInfo = segment.AsAggregate();

                    if (indexType.Equals("IfcLineIndex", StringComparison.OrdinalIgnoreCase))
                    {
                        foreach (IFCData segmentInfoIndex in segmentInfo)
                        {
                            int?currentIndex = GetValidIndex(segmentInfoIndex, numPoints);
                            if (currentIndex == null)
                            {
                                continue;
                            }

                            int validCurrentIndex = currentIndex.Value;
                            if (lastIndex != validCurrentIndex)
                            {
                                pointXYZs.Add(pointListXYZs[validCurrentIndex]);
                                currentLineSegmentPoints.Add(pointListXYZs[validCurrentIndex]);
                                lastIndex = validCurrentIndex;
                            }
                        }
                    }
                    else if (indexType.Equals("IfcArcIndex", StringComparison.OrdinalIgnoreCase))
                    {
                        // Create any line segments that haven't been already created.
                        CreateLineSegments(curveLoop, currentLineSegmentPoints);

                        if (segmentInfo.Count != 3)
                        {
                            Importer.TheLog.LogError(Id, "Invalid IfcArcIndex in IfcIndexedPolyCurve.", false);
                            continue;
                        }

                        int?startIndex = GetValidIndex(segmentInfo[0], numPoints);
                        int?pointIndex = GetValidIndex(segmentInfo[1], numPoints);
                        int?endIndex   = GetValidIndex(segmentInfo[2], numPoints);

                        if (startIndex == null || pointIndex == null || endIndex == null)
                        {
                            continue;
                        }

                        Arc arcSegment = null;
                        XYZ startPoint = pointListXYZs[startIndex.Value];
                        XYZ pointOnArc = pointListXYZs[pointIndex.Value];
                        XYZ endPoint   = pointListXYZs[endIndex.Value];
                        try
                        {
                            arcSegment = Arc.Create(startPoint, pointOnArc, endPoint);
                            if (arcSegment != null)
                            {
                                curveLoop.Append(arcSegment);
                            }
                        }
                        catch
                        {
                            // We won't do anything here; it may be that the arc is very small, and can
                            // be repaired as a gap in the curve loop.  If it can't, this will fail later.
                            // We will monitor usage to see if anything more needs to be done here.
                        }

                        if (lastIndex != startIndex.Value)
                        {
                            pointXYZs.Add(startPoint);
                        }
                        pointXYZs.Add(pointOnArc);
                        pointXYZs.Add(endPoint);
                        lastIndex = endIndex.Value;
                    }
                    else
                    {
                        Importer.TheLog.LogError(Id, "Unsupported segment type in IfcIndexedPolyCurve.", false);
                        continue;
                    }
                }

                // Create any line segments that haven't been already created.
                CreateLineSegments(curveLoop, currentLineSegmentPoints);
            }

            SetCurveLoop(curveLoop, pointXYZs);
        }